MySQL事务,锁,MVCC总结

mysql中最重要的就是事务,其四大特性让我们维持了数据的平衡,一致。那么事务究竟是什么,与什么相关,他的使用步骤,以及使用过程中我们会遇到什么问题呢?下面我们一起学习交流!

1.MySQL的存储引擎:

存储引擎是数据库底层软件组织,数据库管理系统使用存储引擎存储,管理数据,不同的存储引擎提供不同的功能(存储机制,索引技巧,锁定水平)。

MySQL提供了许多不同的存储引擎,如InnoDB,MyISAM,此处我们只这两种作对比

|------|-----------------------------|-----------------------------------------|
| 对比项 | MyISAM | InnoDB |
| 外键 | 不支持 | 支持 |
| 事务 | 不支持 | 支持 |
| 行表锁 | 表锁,即使操作一条记录也会所著整个表,不适合高并发操作 | 行锁,操作时治所铸某一行,不对其他行有影响,适合高并发操作 |
| 缓存 | 只缓存索引,不缓存真实数据 | 不仅缓存索引还要缓存真实数据,对内存要求较高,而且内存大小对性能有决定性的影响 |
| 默认安装 | Y | Y |
| 默认使用 | N | Y |
| 关注点 | 性能:节省资源,消耗少,简单业务 | 事务:并发写,事务,更大资源 |

2.什么是事务,事务的特点,限制

事务:就是将一组SQL语句放在同一批次内去执行,如果一个SQL语句出错,则该批次内的所有SQL都将被取消执行

事务特点:一个事务中如果有一个数据库操作失败,那么整个事务的所有数据库操作都会失败,数据库数据就会回滚到该事务开始之前的状态。

限制:MySQL数据库中仅InnoDB和BDB类型的数据库表支持事务

3.MySQL开启事务的步骤
复制代码
-- 1.关闭MySQL自动提交
set autocommit=0;
-- 2.开启一个事务,标志事务的起始点
start transaction;

-- 一组SQL语句


-- 结束事务,逻辑判断
       if  条件
            -- 向数据库提交事务
                commit;
       else 
            -- 将事务回滚,所有的数据库操作取消
                rollback;

-- 开启MySQL自动提交
set  autocommit=1
4.事务的四大特性:

原子性:数据库中的事务执行是作为原子粒度,即不可再分,整个语句要莫执行,要莫不执行

一致性:即事务开始之前和事务结束之后,数据库的完整性约束没有被破坏

隔离性:事务的执行是互不干扰的,一个事务不可能看到其他事务运行时,中间某一刻的数据

持久性:事务完成后,该事务对数据库所做的更改便持久的保存在数据库中,并不会回滚

5.事务日志以及其和四大特性的关系:

Redo log(重做日志):提供再写入操作,恢复提交事务修改的页操作。

,用来保证事务的持久性

undo log(回滚日志):回滚行记录到某个特定的版本,用来保证事务的原子性,一致性

redo的流程:保证事务的持久性

第一步:先将原始数据从磁盘读取到内存中,修改数据的内存拷贝

第二步:生成一条重做日志并写入redo log buffer ,记录的是数据被修改后的值

第三步:当事务commit时,将redo log buffer 中的内容刷新到redo log file采用追加写的方式。

第四步:定期将内存中修改的数据刷新到磁盘中

undo日志:保证事务原子性和一致性。在事务中 更新数据的前置操作,其实时要先写入一个undo log
两种日志分别保证了,事务的持久性,与原子性,一致性,那个事务的隔离性又通过什么方式实现的呢

首先,事务的隔离性,就是为了不同的事务之间不存在干扰,就需要对事务的操作进行隔离,也就是说事务的隔离性就是将操作同一个数据的事务互相分离,让操作之间分开有序的执行。

Mysql数据库为保证隔离性,所以对时间采用加锁的机制。下面我们对锁的类型研究分析

6.MySQL中的锁

|--------|---------------------|
| 分类 | 锁 |
| 基于锁的属性 | 共享锁(s,读锁),排他锁(X,写锁) |
| 基于锁的粒度 | 表锁,行锁(记录锁,间隙锁,临键锁) |
| 基于锁得状态 | 意向共享锁,意向排他锁 |

在MySQL中,特别是针对InnoDB存储引擎,存在多种类型的锁,用于控制事务之间的并发访问,确保数据的一致性和隔离性。以下是一些常见的锁类型:

1.共享性(s):也称读锁。当一个事务对某个数据项加了共享锁,其他事务可以同时对该数据项加共享锁,但不能加排他锁(写锁)。共享锁主要用于支持读取操作。

2.排他锁(X):也称为写锁。当一个事务对某个数据项加了排他锁,其他事务不能对该数据项加任何类型的锁。排他锁主要用于支持写入操作,如更新,插入,删除数据。

3.意向共享锁(IS):事务想要获取一个表上的多个行的共享锁时,可以在表级别加意向共享锁,这样可以减少锁的粒度,提高并发性能。

4.意向排他锁(IX):事务想要获取一个表上的多个行的排他锁时,可以在表级别加意向排他锁。这种锁表明事务可能需要对这些行加排他锁。

5.表锁:这种锁是在表级别上加的,通常用于MYISAM存储引擎,表锁包括表共享读锁,和表排他写锁,它们分别对应共享锁和排他锁。

6.行级锁:这种锁是在行级别上加的,主要用于InnoDB存储引擎。行级锁包括记录锁,间隙锁和临键锁。这些锁主要用于实现MVCC(多版本并发控制)和避免幻读现象。

7.乐观锁:这种锁机制假设并发冲突较少,事务在提交时才检查是否有冲突。通常通过版本号或时间戳来实现。

8.悲观锁:这种锁机制假设并发冲突较多,事务在开始时就枷锁,以防止其他事务的修改。这种方式可能导致锁等待和性能下降。

在实际应用中,MySQL会根据事务的需要和配置参数自动选择合适的锁类型,以平衡并发性能和数据一致性。

7.行锁中,间隙锁,临键锁的介绍

间隙锁:是InnoDB存储引擎用来解决幻读问题的一种锁机制,间隙锁锁定的是索引记录之间的间隙,或者是第一个索引记录之前或最后一个索引巨鹿之后的空间,而不是索引记录本身。

间隙锁的作用:阻止其他事务在锁定的间隙内插入新的索引记录。这样当一个事务在执行范围查询时,即使其他事务尝试插入新的记录到这个范围内,也不会影响当前事务的查询结果,从而避免幻读。

间隙锁的工作原理:

1.锁定间隙:当一个事务执行一个带范围条件的查询语句,或者执行一个带范围条件的修改,或删除语句,InnoDB会锁定满足条件的索引巨鹿之间的间隙

2.共享和排他锁间隙锁:间隙锁可以是共享的或排他的,共享间隙锁不会阻止其他事务获得共享间隙锁,但会组织排他间隙锁。排它间隙锁则会组织其他事务获得任何类型的间隙锁。

3.间隙锁或索引:间隙锁只在事务隔离级别为 可重复读或序列化时使用。而且。间隙锁只在与某些类型的索引一起使用时才会生效。例如聚簇索引或辅助索引。

**临键锁:**在MySQL中,临键锁是InnoDB存储引擎用来解决幻读问题的一种锁机制。临键锁是记录锁和间隙锁的组合,它不仅能锁定记录本身,还能锁定记录下一个值得间隙,从而防止其他事务在该间隙内插入新的记录。

临键锁的作用:

1.防止幻读:通过锁定记录下一个值的间隙,林间锁可以防止其他事务在该间隙内插入新的记录,从而避免了幻读现象。

2.提高并发性能:临键锁的使用可以减少锁的竞争,提高系统的并发性能。

临键锁的工作原理:

临键锁是在记录锁的基础上扩展而来的。当一个事务执行一个带有范围条件的select查询语句,或者执行一个带范围条件的update和delete语句时,InnoDB不仅会锁定满足条件的索引记录,还会锁定这些记录下一个值得间隙。

临键锁和间隙锁的注意事项:

1.性能影响:间隙锁可能会增加锁竞争,从而影响性能。因此设计数据库时应该考虑索引的选择或事务隔离级别的设置。

2.死锁风险:由于间隙锁的存在,事务之间可能会发生死锁。例如,两个事务可能都试图锁定同一个间隙,导致互相等待。

3.锁的释放:间隙锁旨在事务提交或回滚时释放,而不是在语句执行完毕时释放。

通过使用间隙锁,MySQL的InnoDB存储引擎能够提供更高的事务隔离级别,同时尽可能地减少锁竞争,提高并发性能。然而,间隙锁的使用也需要谨慎,因为其可能引入死锁的风险,并对性能产生一定的影响。

8.事务的隔离级别:

在事务并发执行时,如果不进行事务隔离,那么就会产生脏写,脏读,重复读,幻读的问题。所以MySQL为我们提供了不同的事务隔离级别。每个隔离级别都针对事务并发问题中的一种或几种继续宁解决,事务级别越高,解决的并发事务问题也就越多,同时意味着加的锁就越多,所以性能也会越差。

1.read_uncommited 读未提交 :含义读取到未提交的数据,但是数据未提交,如果回滚,就会出现脏读

2.read_comminted 读提交(不可重复读):读取到已提交的数据,(但是不能保证在数据变化之前你提交之前读过一次,两次数据有差异,会出现幻读,所以也叫不可重复读。)。

3.repeatable_read 可重复读:可以重复读取数据,但是只有在两个事务都结束后,才能读取到正确数据,会出现幻读

4.serializable 串行化 :这是为了解决幻读问题,第一个事务执行时,不允许第二个事务操作,只有前一个完成操作,后面下一个才会操作,保证数据了一致性。但是执行效率很低。

9.事务并发出现的问题:

对于SessionA 和SessionB

1.脏写:就是A 修改 了B 未提交 但修改过的数据,

2.脏读:A 读取了 B 更新但还没提交的数据 若B回滚 A读取数据无效不存在,

3.不可重复读:A读取了一份数据后,B修改了数据,A再读,数据变了,这就叫不可重复读

4.幻读:指在一个事务中多次执行相同的查询,但第二次返回的结果集比第一次多出了一些不存在的数据,

避免幻读的方法:

1.使用事务隔离级别:重复读,串行化

2.使用锁:行级锁,间隙锁

3.使用悲观锁,乐观锁

4.使用事务的保存点和回滚

5.使用数据库约束

6.查询优化

10.MySQL的MVCC

MySQL的多版本并发控制是一种用于实现事务隔离的技术,它允许多个事务在同一时刻对同一数据进行操作而不互相阻塞。MVCC通过维护数据的多个版本来实现这一点,每个事务看到的版本是基于该事务开始时的数据版本。

基本原理:

1.版本号:每个数据行都有一个隐藏的版本号,用于表示该行数据的版本。当一行数据倍修改时,其版本号也会被更新。

2.读取操作:读取操作会读取符合其事务开始时版本号的数据版本。而不是最新的版本。这样可以保证事务在读取过程中看到的数据一致

3.写入操作:写入操作会创建一个新的数据版本,并更新改行数据的版本号,旧的数据版本仍然保留,知道垃圾回收器清理。

MySQL中MVCC的实现:

mysql的InnoDB存储引擎使用了一种"乐观锁定"的技术来实现MVCC,包含以下机制:

1.行班本链:每行数据都有一个版本链,包含该行数据的所有版本,每个版本都有关联的时间戳,表示该版本的创建时间。

2.事务快照:每个事务在开始时会创建一个快照,记录当前所有的活动事务。事务在读取数据时,会使用这个快照来确定哪些数据版本是可见的。

3.间隙锁:为了防止幻读,InnoDB使用了间隙锁,它可以锁定结果集之间的间隙,防止其他事务插入新的记录

优点:

1.提高并发性能:MVCC减少锁的使用,提高系统的并发性能

2.减少锁争用:由于每个事务看到的是自己快照中的数据版本,减少了锁争用情况

3.简化事务管理:MVCC使得事务的管理和隔离更加简单和高效

缺点:

1.额外的存储开销:维护多个数据版本会占用更多的存储空间

2.垃圾回收开销:需要定期清理不再需要的数据版本,否则回导致存储空间浪费

相关推荐
长征coder4 分钟前
AWS MySQL 读写分离配置指南
mysql·云计算·aws
醇醛酸醚酮酯19 分钟前
Qt项目锻炼——TODO清单(二)
开发语言·数据库·qt
ladymorgana39 分钟前
【docker】修改 MySQL 密码后 Navicat 仍能用原密码连接
mysql·adb·docker
PanZonghui43 分钟前
Centos项目部署之安装数据库MySQL8
linux·后端·mysql
GreatSQL社区1 小时前
用systemd管理GreatSQL服务详解
数据库·mysql·greatsql
掘根1 小时前
【MySQL进阶】错误日志,二进制日志,mysql系统库
数据库·mysql
weixin_438335401 小时前
基础知识:mysql-connector-j依赖
数据库·mysql
小明铭同学1 小时前
MySQL 八股文【持续更新ing】
数据库·mysql
Mr_Xuhhh1 小时前
信号与槽的总结
java·开发语言·数据库·c++·qt·系统架构
Fireworkitte2 小时前
Redis 源码 tar 包安装 Redis 哨兵模式(Sentinel)
数据库·redis·sentinel