MySQL的ACID、死锁、MVCC问题
1 ACID
ACID代表原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability)。一个确保数据安全的事务处理系统,必须满足这些密切相关的标准。
- 原子性: 一个事务必须被视为一个不可分割的工作单元,整个事务中的操作要么全部提交成功,要么全部失败回滚。对于一个事务来说,不可能只执行其中的一部分操作,这就是事务的原子性。
- 一致性: 数据库总是从一个一致性状态转换到下一个一致性状态。如果事务最终没有提交,该事务所做的任何修改都不会被保存到数据库中。
- 隔离性: 通常来说,一个事务所做的修改在最终提交以前,对其他事务是不可见的,这就是隔离性带来的结果。
- 持久性: 一旦提交,事务所做的修改就会被永久保存到数据库中。此时即使系统崩溃,数据也不会丢失。持久性是一个有点模糊的概念,实际上持久性也分很多不同的级别。有些持久性策略能够提供非常强的安全保障,而有些则未必。而且不可能有100%的持久性保障。(如果数据库本身能做到真正的持久性,那么备份又怎么能增加持久性呢?)
ACID事务和InnoDB引擎提供的保证是MySQL中最强大、最成熟的特性之一。虽然它们在吞吐量方面做了一定的权衡,但如果应用得当,就可以避免在应用层实现大量复杂逻辑。
2 死锁
死锁是指两个或多个事务互相持有和请求相同资源的锁,产生了循环依赖。当多个事务试图以不同的顺序锁定资源时会导致死锁。当多个事务锁定相同资源时,也可能会发生死锁。例如下述例子的两个事务因试图以不同顺序访问资源时会导致死锁。
# 事务1
begin
update stock_price set close = 45.50 where stock_id = 4 and date = '2020-05-01';
update stock_price set close = 19.80 where stock_id = 3 and date = '2020-05-02';
end;
# 事务2
begin
update stock_price set close = 20.12 where stock_id = 3 and date = '2020-05-02';
update stock_price set close = 47.20 where stock_id = 4 and date = '2020-05-01';
end;
为了解决这个问题,数据库系统实现了各种死锁检测和锁超时机制。更复杂的系统,比如InnoDB存储引擎,检测到循环依赖后会立即返回一个错误信息。这可能是一件好事——否则,死锁将表现为非常缓慢的查询。还有一种方式,当超过锁等待超时时间限制直接终止查询,这样做通常来说不太好。InnoDB目前处理死锁的方式是将持有最少行级排他锁的事务回滚(这是一种最容易回滚的近似算法)。
锁的行为和顺序是和存储引擎相关的。同样的一系列查询语句,有些存储引擎会产生死锁,有些则不会。死锁的产生有双重原因:有些是因为真正的数据冲突,这种情况通常很难避免,但有些则完全是由于存储引擎的实现方式导致的。
一旦发生死锁,如果不回滚其中一个事务(部分或全部),就无法打破死锁。对于事务型的系统,这是无法避免的,所以应用程序在设计时必须考虑如何处理死锁。大多数情况下只需重新从头开始执行被回滚的事务即可,除非又遇到另一个死锁。
3 多版本并发控制(MVCC)
MySQL的大多数事务型存储引擎用的都不是简单的行级锁机制。它们会将行级锁和可以提高并发性能的多版本并发控制(MVCC)技术结合使用。不仅是MySQL,包括Oracle、PostgreSQL以及其他一些数据库系统也都使用了MVCC,但各自的实现机制不尽相同,因为MVCC如何工作没有统一的标准。
可以认为MVCC是一个行级锁的一个变种,但是它在很多情况下避免了加锁操作,因此开销更低。根据其实现方式,不仅实现了非阻塞的读操作,写操作也只能锁定必要的行。
MVCC的工作原理是使用数据在某个时间点的快照来实现的。这意味着,无论事务运行多长时间,都可以看作数据的一致性视图,也意味着不同的事务可以在同一时间看到同一张表中的不同数据。
每个存储引擎实现MVCC的方式都不同。其中一些变体包括乐观并发控制和悲观并发控制。可以通过序列图解释一下InnoDB的行为,以此来展示MVCC的一种实现方式。

InnoDB通过为每个事务在启动时分配一个事务ID来实现MVCC。该ID在事务首次读取任何数据时分配。在该事务中修改记录时,将向Undo日志写入一条说明如何恢复该更改的Undo记录,并且事务的回滚指针指向该Undo日志记录。这就是事务如何在需要时执行回滚的方法。
当不同的会话读取聚簇主键索引记录时,InnoDB会将该记录的事务ID与该会话的读取视图进行比较。如果当前状态下的记录不应可见(更改它的事务尚未提交),那么Undo日志记录将被跟踪并应用,直到会话达到一个符合可见条件的事务ID。 这个过程可以一直循环到完全删除这一行的Undo记录,然后向读取视图发出这一行不存在的信号。
事务中的记录可以通过在记录的“info flags”中设置“deleted”位来删除。这在Undo日志中也被作为“删除标记”进行跟踪。
值得注意的是,所有Undo日志写入也都会写入Redo日志,因为Undo日志写入是服务器崩溃恢复过程的一部分,并且是事务性的。这些Redo日志和Undo日志的大小也是高并发事务工作机制中的重要影响因素。
在记录中保留这些额外的信息带来的结果是,大多数读取查询都不需要额外获取锁。他们只是尽可能快的读取数据,确保仅查询符合条件的行即可。缺点是存储引擎必须在每一行中存储更多的数据,在检查行时需要做更多的工作,并处理一些额外的内部操作。
MVCC仅使用REPEATABLE READ和READ COMMITTED隔离级别。READ UNCOMMITTED与MVCC不兼容,是因为查询不会读取适合其事务版本的行版本,而是不管怎样都读最新版本。SERIALIZABLE和MVCC也不兼容,是因为读取会锁定他们返回的每一行。
返回面试宝典
相关文章:
MySQL的ACID、死锁、MVCC问题
1 ACID ACID代表原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability)。一个确保数据安全的事务处理系统,必须满足这些密切相关的标准。 原…...
Docker 可视化工具
1、Portainer 概念介绍 Portainer是一款轻量级的应用,它提供了图形化界面,用于方便地管理Docker环境,包括单机环境和集群环境。 Portainer分为开源社区版(CE版)和商用版(BE版/EE版)。 Porta…...
【C++】友元:友元函数与友元类
一、友元 友元(friend)是C中的一种特殊关系,用于在类之间共享访问权限。通过将一个函数或类声明为另一个类的友元,我们可以允许友元访问声明类的非公有成员。 二、友元函数 问题:现在尝试去重载operator<<&am…...
linux之wsl2安装远程桌面
0. 安装后的效果 1. wsl中打开terminal并安装库 sudo apt-get purge xrdp sudo apt install -y xrdp sudo apt install -y xfce4 sudo apt install -y xfce4-goodies 2.优化显示 sudo sed -i s/max_bpp32/#max_bpp32\nmax_bpp128/g /etc/xrdp/xrdp.ini sudo sed -i s/xserverbp…...
如何以管理员身份删除node_modules文件
今天拉项目,然后需要安装依赖,但是一直报错,如下: 去搜这个问题会让把node_modules文件先删掉 再去安装依赖。我在删除的过程中会说请以管理员身份来删除。 那么windows如何以管理员身份删除node_modules文件呢? wi…...
【Linux】环境基础开发工具的使用之gdb详解(三)
前言:上一篇文章中我们讲解了Linux下的gcc与g的使用,今天我们将进一步的学习gdb与makefile来帮我们更好的理解与使用基础开发工具。 💖 博主CSDN主页:卫卫卫的个人主页 💞 👉 专栏分类:Linux的深度刨析 👈 …...
SpringBoot源码解读与原理分析(二十四)IOC容器的刷新(五)
文章目录 7.11 初始化所有剩下的单实例bean对象7.11.1 beanFactory.preInstantiateSingletons7.11.2 getBean7.11.2.1 别名的解析处理7.11.2.2 判断是否已注册过7.11.2.3 创建前的检查7.11.2.4 标记准备创建的bean对象7.11.2.5 合并BeanDefinition7.11.2.6 bean对象的创建7.11.…...
最大子数组和
一、题目 给你一个整数数组nums,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组 是数组中的一个连续部分。 示例 1: 输入:nums [-2,1,-3,4,-1,2,1,-5,4] 输出&#…...
Node.js版本管理工具之_Volta
Node.js包管理工具之_Volta 文章目录 Node.js包管理工具之_Volta1. 官网1. 官网介绍2. 特点1. 快( Fast)2. 可靠(Reliable)3. 普遍( Universal) 2. 下载与安装1. 下载2. 安装3. 查看 3. 使用1. 查看已安装的工具包2. 安装指定的node版本3.切换项目中使用的版本 1. 官网 1. 官网…...
Redis 命令大全
文章目录 启动与连接Key(键)相关命令String(字符串)Hash(哈希)List(列表)Set(集合)Sorted Set(有序集合)其他常见命令HyperLogLog&…...
再这么烂下去,离糊就不远了。别让才华被埋没。
♥ 为方便您进行讨论和分享,同时也为能带给您不一样的参与感。请您在阅读本文之前,点击一下“关注”,非常感谢您的支持! 文 |猴哥聊娱乐 编 辑|徐 婷 校 对|侯欢庭 近日,胡歌凭借电视剧《繁花》荣登《环球银幕》二月…...
Unity BuffSystem buff系统
Unity BuffSystem buff系统 一、介绍二、buff系统架构三、架构讲解四、框架使用buff数据Json数据以及工具ShowTypeBuffTypeMountTypeBuffOverlapBuffShutDownTypeBuffCalculateType时间和层数这里也不过多说明了如何给生物添加buff 五、总结 一、介绍 现在基本做游戏都会需要些…...
Android rom定制 修改system分区的容量大小
1、写在前面 系统ROM定制化,预置app太多,会导致系统rom很大,原生系统system分区已经不够用了,要加大系统systemui分区 2.修改system分区的容量大小的核心类 device/mediatekprojects/$project/BoardConfig.mk build/make/core/Makefile3、修改system 分区的容量大小的核…...
速盾:服务器接入免备案CDN节点的好处有哪些
本文将探讨服务器接入免备案CDN节点的好处,包括提高网站的访问速度、增加网站的稳定性和可靠性、降低带宽成本等方面的优势。同时,还将提供一些相关问题的解答,帮助读者更好地了解这一技术。 随着互联网的迅猛发展,网站的访问速度…...
Redisson看门狗机制
一、背景 网上redis分布式锁的工具方法,大都满足互斥、防止死锁的特性,有些工具方法会满足可重入特性。如果只满足上述3种特性会有哪些隐患呢?redis分布式锁无法自动续期,比如,一个锁设置了1分钟超时释放,…...
【Java数据结构】双向 不带头 非循环 链表实现(模拟实现LinkedList类)
LinkedList底层实际上是双向、不带头结点、非循环的链表 链表的分类有八种,常用的有两种:一是单向、不带头结点、非循环的(基本上网上的题型都是这种);二是双向、不带头结点、非循环(LinkedList的底层实现…...
深度学习系列55:深度学习加速技术概述
总体有两个方向:模型优化 / 框架优化 1. 模型优化 1.1 量化 最常见的量化方法为线性量化,权重从float32量化为int8,将输入数据映射在[-128,127]的范围内。在 nvdia gpu,x86、arm 和 部分 AI 芯片平台上,均支持 8bit…...
使用python启动一个roslaunch文件
roslaunch 的实现源码主要位于 ROS 的 ros_comm 仓库中的 tools/roslaunch 目录下。源码主要由 Python 脚本和少量的 C 代码组成。 在Python程序中导入roslaunch包并启动一个ROS launch文件,你需要确保ROS环境已经设置好,并且相关的roslaunch包已经安装…...
JavaEE企业级应用软件开发—Spring框架入门学习笔记(一)
一、认识框架 实际开发中,随着业务的发展,软件系统变得越来越复杂,如果所有的软件都从底层功能开始开发,那将是一个漫长而繁琐的过程。此外,团队协作开发时,由于没有统一的调用规范,系统会出现大…...
ElasticSearch-SpringBoot整合ElasticSearch
六、SpringBoot整合ElasticSearch 1、浏览官方文档 1、查找跟ES客户端相关的文档 使用Java REST Client 选择Java Hight Level REST Client 2、创建项目的准备 1.找到原生的依赖 2.找到对象 3.分析这个类里面的方法 3、正式创建项目 1.创建工程 2.导入依赖 注意依赖版本…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...
Qt 事件处理中 return 的深入解析
Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...
