Mysql锁与MVCC

文章目录

  • Mysql锁的类型
  • 锁使用
  • MVCC
    • 快照读和当前读
    • 读视图【Read View】
    • 串行化的解决
  • exlpain字段解析
  • ACID的原理
  • 日志
  • 引擎
  • 整合SpringBoot
  • 博客记录


Mysql锁的类型

MySQL中有哪些锁:

  1. 乐观锁(Optimistic Locking):假设并发操作时不会发生冲突,只在提交事务时检查数据是否被其他事务修改过。常用于读多写少的场景。

  2. 悲观锁(Pessimistic Locking):假设并发操作时会发生冲突,因此在操作期间持有锁来避免冲突。常用于写多读少的场景。

  3. 全局锁(Global Lock):对整个数据库实例加锁,限制除了超级用户外的所有查询和修改操作。一般用于备份、恢复等操作。

  4. 表级锁(Table Lock):对整个表加锁,其他连接无法修改或读取该表的数据,但可以对其他表进行操作。

  5. 意向共享锁(Intention Shared Lock):表级锁的辅助锁,表示事务要在某个表或页级锁上获取共享锁。

  6. 意向排它锁(Intention Exclusive Lock):表级锁的辅助锁,表示事务要在某个表或页级锁上获取排它锁。

  7. 页级锁(Page Lock):对数据页(通常是连续的几个行)加锁,控制并发事务对该页的访问。适用于数据较大且并发量较高的场景。

  8. 行级锁(Row Lock):对单个行加锁,只锁定需要修改的数据行,其他行可以被同时修改或读取。并发性高,但锁管理较复杂。

  9. 记录锁(Record Lock):行级锁的特定类型,锁定单个行,确保其他事务无法同时修改或读取该行。

  10. 共享锁(Shared Lock):也称为读锁,多个事务可以同时持有共享锁并读取数据,但不能修改数据。适用于同时读取同一数据的场景。

  11. 排它锁(Exclusive Lock):也称为写锁,事务持有排它锁时,其他事务无法同时持有共享锁或排它锁,用于保护数据的写操作。

  12. 间隙锁(Gap Lock):锁定一个范围的键,但不包括这些键的实际值。用于防止其他事务在范围内插入数据。

  13. 临建锁(Metadata Lock):锁定数据库对象的元数据,如表结构,用于保证数据定义的一致性。

各种锁解析

锁使用

使用方式:
乐观锁示例:

悲观锁:
悲观锁的实现通常通过使用SELECT … FOR UPDATE或使用LOCK IN SHARE MODE语句来加锁。

-- 事务1:查询并修改订单状态
START TRANSACTION;
-- 查询订单状态,并持有排它锁
SELECT order_id, status FROM orders WHERE order_id = 1 FOR UPDATE;
-- 执行一些业务逻辑判断...
-- 修改订单状态
UPDATE orders SET status = 'completed' WHERE order_id = 1;
COMMIT;

全局锁:

-- 事务1:加全局锁
FLUSH TABLES WITH READ LOCK;
-- 执行一些需要全局锁的操作...
-- 解除全局锁
UNLOCK TABLES;

表级锁的使用:

-- Session 1
START TRANSACTION;
-- 在Session 1中加共享锁
#显式上锁(手动)
lock table tableName read;//读锁
lock table tableName write;//写锁
#隐式上锁(默认,自动加锁自动释放
insertupdatedelete //上写锁
-- 解锁
UNLOCK TABLES;
COMMIT;

InnoDB引擎的页级锁的示例

-- Session 1
START TRANSACTION;
-- 获取某个数据页的共享锁
SELECT * FROM products WHERE id = 1 LOCK IN SHARE MODE;
-- 执行一些只读操作
-- 解锁
COMMIT;

行级锁:

-- Session 1
START TRANSACTION;
-- 在Session 1中对某个行加共享锁
SELECT * FROM products WHERE id = 1 FOR SHARE;
-- 执行一些只读操作,例如SELECT语句,可以读取被共享锁保护的行
-- 解锁
COMMIT;

共享锁:

-- Session 1
START TRANSACTION;
-- 在Session 1中对某个行加共享锁
SELECT * FROM products WHERE id = 1 FOR SHARE;
-- 执行一些只读操作,例如SELECT语句,可以读取被共享锁保护的行
-- 解锁
COMMIT;

排它锁:

-- Session 1
START TRANSACTION;
-- 在Session 1中对某个行加排它锁
SELECT * FROM products WHERE id = 1 FOR UPDATE;
-- 执行一些修改操作,例如UPDATE、INSERT、DELETE等
-- 解锁
COMMIT;

意向共享锁:

-- Session 1
START TRANSACTION;
-- 在Session 1中获取意向共享锁
LOCK TABLES products INTENTIONAL READ;
-- 执行一些只读操作,例如SELECT语句,对表进行读操作
-- 解锁
UNLOCK TABLES;

意向排它锁:

-- Session 1
START TRANSACTION;-- 在Session 1中获取意向排它锁
LOCK TABLES products INTENTIONAL WRITE;-- 执行一些修改操作,例如UPDATE、INSERT、DELETE等-- 解锁
UNLOCK TABLES;

间隙锁:

-- Session 1
START TRANSACTION;
-- 在Session 1中使用范围查询,并对查询结果的间隙加锁
SELECT * FROM products WHERE price BETWEEN 10 AND 20 FOR UPDATE;
-- 执行一些需要对查询结果进行修改的操作,例如UPDATE、DELETE等
-- 解锁
COMMIT;

临建锁:

-- Session 1
SELECT GET_LOCK('my_lock', 10);-- 执行一些需要加锁的操作SELECT RELEASE_LOCK('my_lock');

记录锁:

-- Session 1
START TRANSACTION;-- 获取某个记录的共享锁
SELECT * FROM products WHERE id = 1 FOR SHARE;-- 执行一些读操作-- 释放锁
COMMIT;-- Session 2
START TRANSACTION;-- 获取某个记录的排他锁
SELECT * FROM products WHERE id = 1 FOR UPDATE;-- 执行一些写操作-- 释放锁
COMMIT;

锁使用详细示例
锁解析及使用-微信

MVCC

MVCC(Mutil-Version Concurrency Control),多版本并发控制。是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问。用于支持读已提交(RC)和可重复读(RR)隔离级别的实现

数据库通过加锁,可以实现事务的隔离性,串行化隔离级别就是加锁实现的,但是加锁会降低数据库性能。
因此,数据库引入了MVCC多版本并发控制,在读取数据不用加锁的情况下,实现读取数据的同时可以修改数据,修改数据时同时可以读取数据。

MVCC主要是用来解决【读-写】冲突的无锁并发控制,可以解决以下问题:

在并发读写数据时,可以做到在读操作时不用阻塞写操作,写操作不用阻塞读操作,提高数据库并发读写的性能。
可以解决脏读,幻读,不可重复读等事务隔离问题,但不能解决【写-写】引起的更新丢失问题。

一般数据库中都会采用以上MVCC与锁的两种组合来解决并发场景的问题,以此最大限度的提高数据库性能。

MVCC + 悲观锁:MVCC解决读-写冲突,悲观锁解决写-写冲突。
MVCC + 乐观锁:MVCC解决读-写冲突,乐观锁解决写-写冲突。

在InnoDB存储引擎,针对每行记录都有固定的两个隐藏列【DB_TRX_ID】【DB_ROLL_PTR】以及一个可能存在的隐藏列【DB_ROW_ID】。

隐式字段描述是否必须存在
DB_TRX_ID事物Id,也叫事物版本号,占用6byte的标识,事务开启之前,从数据库获得一个自增长的事务ID,用其判断事务的执行顺序
DB_ROLL_PTR占用7byte,回滚指针,指向这条记录的上一个版本的undo log记录,存储于回滚段(rollback segment)中
DB_ROW_ID隐含的自增ID(隐藏主键),如果表中没有主键和非NULL唯一键时,则会生成一个单调递增的行ID作为聚簇索引

MVCC实际上是使用的update undo log 实现的快照读。

当事务对某一行数据进行改动时,会产生一条Undo日志,多个事务同时操作一条记录时,就会产生多个版本的Undo日志,这些日志通过回滚指针(DB_ROLL_PTR)连成一个链表,称为版本链。

MVCC能否解决幻读问题:
首先可以明确的是,MVCC在快照读的情况下可以解决幻读问题,但是在当前读的情况下是不能解决幻读的。

快照读和当前读

快照读【Consistent Read】

也叫普通读,读取的是记录数据的可见版本(可能是过期的数据),不加锁,不加锁的普通select语句都是快照读,即不加锁的非阻塞读。
快照读的执行方式是生成 ReadView,直接利用 MVCC 机制来进行读取,并不会对记录进行加锁。

如下语句:

select * from tableName;

当前读
也称锁定读【Locking Read】,读取的是记录数据的最新版本,并且需要先获取对应记录的锁,并且当前读返回的记录都会加上锁,保证其他事务不会再并发的修改这条记录。update、insert、delete 都是当前读。排它锁。如下语句:

SELECT * FROM student LOCK IN SHARE MODE;  # 共享锁
SELECT * FROM student FOR UPDATE; # 排他锁
INSERT INTO student values ...  # 排他锁
DELETE FROM student WHERE ...  # 排他锁
UPDATE student SET ...  # 排他锁

当前读每次都会重新生成一个Read View,新增、删除、修改、排他锁、共享锁都是当前读。

当前读状态下可以解决幻读问题

读视图【Read View】

Read View提供了某一时刻事务系统的快照,主要是用来做可见性判断, 里面保存了对本事务不可见的其他活跃事务

当事务在开始执行的时候,会产生一个读视图(Read View),用来判断当前事务可见哪个版本的数据,即可见性判断
实际上在innodb中,每个SQL语句执行前都会生成一个Read View

Read View重要的四个属性:

  • creator_trx_id
    创建当前read view的事务ID
  • m_ids
    当前系统中所有的活跃事务的 id,活跃事务指的是当前系统中开启了事务,但还没有提交的事务;
  • m_low_limit_id
    表示在生成ReadView时,当前系统中活跃的读写事务中最小的事务id,即m_ids中的最小值。
  • m_up_limit_id
    当前系统中事务的 id 值最大的那个事务 id 值再加 1,也就是系统中下一个要生成的事务 id。

ReadView 会根据这 4 个属性,结合 undo log 版本链,来实现 MVCC 机制,决定一个事务能读取到数据那个版本。

读已提交只能读Read View中比自己小的事务ID,可重复读能读取比自己大的已提交的事务ID

在读已提交(Read Committed)的隔离级别下实现MVCC,同一个事务里面,【每一次查询都会产生一个新的Read View副本】,这样可能造成同一个事务里前后读取数据可能不一致的问题(不可重复读并发问题)。
读已提交下只要数据的事务ID不在m_ids中,就能查到当前数据

在可重复读(Repeatable read)的隔离级别下实现MVCC,【同一个事务里面,多次查询,都只会产生一个共用Read View】,所有就算期间有事务已经提交m_ids也不会改变,以此解决不可重复读的并发问题。

原博客
MVCC解析-微信

mvcc案例解析

串行化的解决

读取的是记录数据的最新版本,并且当前读返回的记录都会加上锁,保证其他事务不会再并发的修改这条记录。update、insert、delete 都是当前读。排它锁

exlpain字段解析

通过EXPLAIN,可以分析出以下结果:

表的读取顺序
数据读取操作的操作类型
哪些索引被实际使用
表之间的引用
每张表有多少行被优化器查询

在这里插入图片描述

  • id表示查询语句的序号,自动分配,顺序递增,值越大,执行优先级越高。id相同时,优先级由上而下。
  • select_type
    select_type表示查询类型,常见的有SIMPLE简单查询、PRIMARY主查询、SUBQUERY子查询、UNION联合查询、UNION RESULT联合临时表结果等。
  • table列
    table表示SQL语句查询的表名、表别名、临时表名。
  • partitions列
    partitions表示SQL查询匹配到的分区,没有分区的话显示NULL。
  • type列
    type表示表连接类型或者数据访问类型,就是表之间通过什么方式建立连接的,或者通过什么方式访问到数据的。具体有以下值,性能由好到差依次是:
    system > const > eq_ref > ref > ref_or_null > index_merge > range > index > ALL
    • system
      当表中只有一行记录,也就是系统表,是 const 类型的特列。
    • const
      表示使用主键或者唯一性索引进行等值查询,最多返回一条记录。性能较好,推荐使用。
    • eq_ref
      表示表连接使用到了主键或者唯一性索引,下面的SQL就用到了user表主键id。
    • ref
      表示使用非唯一性索引进行等值查询。
    • ref_or_null
      表示使用非唯一性索引进行等值查询,并且包含了null值的行。
    • index_merge
      表示用到索引合并的优化逻辑,即用到的多个索引。
    • range
      表示用到了索引范围查询。
    • index
      表示使用索引进行全表扫描。
    • ALL
      表示全表扫描,性能最差。
  • possible_keys列
    表示可能用到的索引列,实际查询并不一定能用到。
  • key列
    表示实际查询用到索引列。
  • key_len列
    表示索引所占的字节数。
  • ref列
    表示where语句或者表连接中与索引比较的参数,常见的有const(常量)、func(函数)、字段名。如果没用到索引,则显示为NULL。
  • rows列
    表示执行SQL语句所扫描的行数。
  • filtered列
    表示按条件过滤的表行的百分比。
  • Extra列
    表示一些额外的扩展信息,不适合在其他列展示,却又十分重要。
    • Using where
      表示使用了where条件搜索,但没有使用索引。
    • Using index
      表示用到了覆盖索引,即在索引上就查到了所需数据,无需二次回表查询,性能较好。
    • Using filesort
      表示使用了外部排序,即排序字段没有用到索引。
    • Using temporary
      表示用到了临时表,下面的示例中就是用到临时表来存储查询结果。
    • Using join buffer
      表示在进行表关联的时候,没有用到索引,使用了连接缓存区存储临时结果。
    • Using index condition
      表示用到索引下推的优化特性。

explain案例解析

explain案例解析

ACID的原理

mysql将数据存储到数据库之前都是先通过日志的方式来存储数据,因为日志的存储是顺序存储,可以通过偏移量来控制或者查找,而数据库的持久化存储,是见缝插针,这样可能最大化利用磁盘空间,存储完还需要记录数据的地址,所以相比日志存储比较慢。

    原子性的实现:通过`Redo log`和`Undo log`,重做和回滚。如果事务提交了,那么就会执行Redo log写到数据库,如果没有提交就会执行undo log。

日志

redo log和binlog区别 :

redo log是属于innoDB层面,
binlog属于MySQL Server层面的,这样在数据库用别的存储引擎时可以达到一致性的要求。

redo log是物理日志,记录该数据页更新的内容;
binlog是逻辑日志,记录的是这个更新语句的原始逻辑

redo log是循环写,日志空间大小固定;
binlog是追加写,是指一份写到一定大小的时候会更换下一个文件,不会覆盖。

binlog可以作为恢复数据使用,主从复制搭建,
redo log作为异常宕机或者介质故障后的数据恢复使用。

redo log(重做日志)和binlog(归档日志)。redo log是InnoDB存储引擎层的日志,binlog是MySQL Server层记录的日志, 两者都是记录了某些操作的日志(不是所有)自然有些重复(但两者记录的格式不同)。

引擎

MySQL5.5版本后,MySQL的默认内置存储引擎已经从MyISAM变成InnoDB

InnoDB:

  • 支持事务;

  • 行级锁定(更新数据时一般指锁定当前行):通过索引实现、全表扫描忍让时表锁、注意间隙所的影响;

  • 读写阻塞与事务的隔离级别相关;

  • 具有非常高的缓存特性(既能缓存索引、也能缓存数据);

  • 这个表和主键以组(Cluster)的方式存储、组成一颗平衡树;

  • 所有的辅助索引(secondary indexes)都会保存主键信息;

  • 支持分区、表空间类似与oracle 数据库;

  • 支持外键约束、不支持全文检索(5.5.5之前的MyISAM支持全文检索、5.5.5之后就不在支持);

  • 相对MyISAM而言、对硬件的要求比较高

MyISAM特性

  • 不支持事务

  • 表级锁定,数据更新时锁定整个表:其锁定机制是表级锁定,这虽然可以让锁定的实现成本很小但是也同时大大降低了其并发性能。

  • 读写互相阻塞:不仅会在写入的时候阻塞读取,myisam还会在读取的时候阻塞写入,但读本身并不会阻塞另外的读。

  • 只会缓存索引:MyISAM可以通过key_buffer_size缓存索引,以大大提高访问性能,减少产品IO,但是这个缓存区只会缓存索引,而不会缓存数据。

  • 读取速度较快,占用资源相对少。

  • 不支持外键约束,但支持全文索引。

整合SpringBoot

整合博客

博客记录

mvcc解析

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

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

相关文章

Database Connectivity using Python使用 Python 进行数据库连接

Introduction • The Python programming language has powerful features for database programming • Python supports various databases like MySQL, Oracle, Sybase, PostgreSQL, etc • Python also supports Data Definition Language (DDL), Data Manipulation Langua…

ARMV8-aarch64的虚拟内存(mmutlbcache)介绍-概念扫盲

🔥博客主页: 小羊失眠啦. 🎥系列专栏:《C语言》 《数据结构》 《C》 《Linux》 《Cpolar》 ❤️感谢大家点赞👍收藏⭐评论✍️ 思考: 1、cache的entry里都是有什么? 2、TLB的entry里都是有什么? 3、MMU操作…

unity3d Animal Controller的Animal组件中Speeds,States和modes基础部分理解

Speeds 速度集是修改你可以做的原始动画,增加或减少运动,旋转,或动画速度。它们与 州 所以,当动物在运动状态下,在飞行或游泳时,你可以有不同的速度 如果你的性格动画是 (已到位), 你一定要调整速度 位置 和 旋转 每一种的价值观 速度装置 …否则,它们不会移动或旋转。 每个速…

计算机行业在数字经济时代的角色与数字化转型之路

目录 前言1 数字经济时代下的计算机行业角色与定位1.1 数字经济支撑者1.2 创新引领者1.3 产业融合者 2 数字化转型对计算机行业的影响与挑战2.1 技术更新换代的压力2.2 人才培养与流动的问题2.3 数据隐私与安全的挑战 3 数字化转型如何提升行业竞争力3.1 提高生产效率与优化产品…

Prometheus 监控告警配置

文章目录 一、告警通知1.邮件通知2.钉钉通知2.1.获取钉钉机器人webhook2.2.prometheus-webhook-dingtalk2.3.配置信息2.4.自定义模板 3.自定义 二、告警规则1.Prometheus2.Linux3.Docker4.Nginx5.Redis6.PostgreSQL7.MySQL8.RabbitMQ9.JVM10.Elasticsearch 开源中间件 # Prome…

OpenCV的常用数据类型

OpenCV涉及的常用数据类型除包含C的基本数据类型,如:char、uchar,int、unsigned int,short 、long、float、double等数据类型外, 还包含Vec,Point、Scalar、Size、Rect、RotatedRect、Mat等类。C中的基本数据类型不需再做说明下面重点介绍一下…

揭秘WMM:wifi中的QOS

更多内容在 WiFi WMM(无线多媒体)是一种用于无线局域网(WLAN)的QoS(服务质量)标准。WMM旨在提供更好的网络性能,特别是在传输多媒体内容(如音频和视频)时。它通过对不同类…

42.坑王驾到第八期:uniCloud报错

uniCloud 报错 今天调用云函数来调试小程序的时候突然暴了一个奇葩错误,require(…).main is not a function。翻官方文档后发现,原来是这样:**如果你写的是云对象,入口文件应为 index.obj.js,如果你写的是云函数入口…

python学习2:日志记录的用法

一些日志记录的简单记录: 用basicConfig可以进行配置 注意日志的等级: 上述代码得到的日志如下(最基础的日志): 关于记录下来的日志格式可以有很多内容:如等级、发生的时间、发生的位置、发生的进程、…

WinRAR功能之【加密文件名】

很多人知道,WinRAR解压缩软件可以给压缩包设置密码,这样就可以保护压缩包里的文件,不被随意打开。 设置密码后,双击压缩包还是可以打开的,但要打开里面的文件时,就需要输入原本设置的密码才能打开。 虽然…

蓝桥杯-Python组(一)

1. 冒泡排序 算法步骤: 比较相邻元素,如果第一个大于第二个则交换从左往右遍历一遍,重复第一步,可以保证最大的元素在最后面重复上述操作,可以得到第二大、第三大、… n int(input()) a list(map(int, input()…

三、NLP中的句子关系判断

句子关系判断是指判断句子是否相似,是否包含,是否是问答关系等,常应用在文本去重、检索(用户输入和文档的相关性)、推荐(和用户喜好文章是否相似)等场景中。 3.0、文本相似度计算 3.0.0 传统机…

计算机网络-认识设备

一、概述 前面我们其实已经讲了一些关于设备的知识了,从现在开始进入下一阶段的理解。 网络基础设施由交换机、路由器、防火墙等构成,那我们的数据怎样从一个接口转发到另外一个接口最终实现网络访问的呢? 二、设备基础 2.1 网络设备硬件架构 我们分别以…

Axure原型设计项目效果 全国职业院校技能大赛物联网应用开发赛项项目原型设计题目

目录 前言 一、2022年任务书3效果图 二、2022年任务书5效果图 三、2022年国赛正式赛卷 四、2023年国赛第一套样题 五、2023年国赛第二套样题 六、2023年国赛第三套样题 七、2023年国赛第四套样题 八、2023年国赛第七套样题 九、2023年国赛正式赛题(第八套…

SSA-LSTM多输入回归预测 | 樽海鞘优化算法-长短期神经网络 | Matlab

目录 一、程序及算法内容介绍: 基本内容: 亮点与优势: 二、实际运行效果: 三、算法介绍: 四、完整程序下载: 一、程序及算法内容介绍: 基本内容: 本代码基于Matlab平台编译&am…

智慧路灯杆如何提升智慧城市文旅形象

今年以来,全国多地城市凭借本地独特物产、独特旅游环境等亮点火爆出圈,为城市带来显著经济增长和形象提升。文旅经济作为高附加值产业,具有高收益、高潜力等特点,还有助于推动城市经济转型和可持续发展。 推动城市文旅经济发展&am…

力扣每日一题 最大二进制奇数 模拟 贪心

Problem: 2864. 最大二进制奇数 由于奇数的二进制末尾一定是 111,我们可以把一个 111 放在末尾,其余的 111 全部放在开头,这样构造出的奇数尽量大。 复杂度 时间复杂度: O ( n ) O(n) O(n) 空间复杂度: O ( 1 ) O(1) O(1) Code class…

全国降雨侵蚀力因子R值/土壤侵蚀模型RUSLE

降雨侵蚀力因子其实是反应降雨对土壤侵蚀的潜在能力,就是降雨的冲刷对土壤的侵蚀效应。 在过去几天查阅文献资料的过程中,本人亲眼看见过的关于因子R的计算方法就超过30种,着实大开了眼界。 不过总结这些计算方法,其实核心思路大…

第六篇【传奇开心果系列】Python的自动化办公库技术点案例示例:大学生数据全方位分析挖掘经典案例

传奇开心果博文系列 系列博文目录Python的自动化办公库技术点案例示例系列 博文目录前言一、Pandas库全方位分析挖掘大学生数据能力介绍二、大学生学生成绩数据分析数据挖掘示例代码三、大学生选课数据分析数据挖掘示例代码四、大学生活动参与数据分析数据挖掘示例代码五、大学…

让若依生成的service、mapper继承mybatisPlus的基类

前言:若依继承mybatisPlus后,生成代码都要手动去service、serviceImpl、mapper文件去继承mybatisplus的基类,繁琐死了。这里通过修改若依生成模版从而达到生成文件后直接使用mybatisPlus的方法。 一、首先找到若依生成模版文件位置&#xff…