mysql各种锁介绍

本文深入探讨MySQL在并发场景下事务可能遇到的安全问题,包括脏读、不可重复读及幻读现象。详解InnoDB引擎如何通过MVCC与锁机制解决这些问题,包括行级锁、表级锁、页级锁,以及共享锁、排他锁和意向锁的使用。

mysql并发情况下引起的事务的安全问题?
脏读::一个事务读取另一个事务未提交的问题
不可重复读:: 在同一事务中,两次读取同一数据,得到内容不同
幻读::同一事务中,用同样的操作读取两次,得到的记录数不相同
mysql的默认的RR(允许重复度)隔离级别下,如何避免事务的安全问题?
在mysql的innodb的引擎下,采用MVCC机制+锁 方式解决事务的安全问题,但在RR(允许重复读)的级别下没有完全解决幻读的问题.
解决脏读 修改时加排他锁(写锁),直到事务提交后才释放,读取时加共享锁(读锁),其他事务只能读取,不能再有更新操作 。防止脏读。
解决不可重复读
innodb引擎采用了mvcc(多版本并发控制)来解决不可重复读问题。mvcc是利用在每条数据后面加了隐藏的两列(创建版本号和删除版本号)当执行查询的时, 当前查询版本号>= 创建版本号 并且 >删除版本号 , MVCC可以在大多数情况下代替行级锁,使用MVCC,能降低其系统开销。
解决幻读
Mysql官方给出的幻读解释是:只要在一个事务中,第二次select多出了row就算幻读。
分2种,快照读和当前读
(1)快照读(mvcc) 普通的 select 就是快照读。将历史数据存一份快照,所以其他事务增加与删除数据,对于当前事务来说是不可见的。事务每次取数据的时候都会取创建版本<当前事务的数据,以及删除版本号码>当前版本的数据。
(2)当前读 执行数据库的增删改操作的时, 就是当前读
采用next-key锁的方式解决问题
next-key 锁包含两部分: 记录锁(行锁)+ 间隙锁 就是在索引和索引之间上面加锁
1 按锁粒度分类-行级锁&表级锁&表级锁&页级锁
1 行级锁
(1) 描述
行级锁是mysql中锁定粒度最细的一种锁。表示只针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突,其加锁粒度最小,但加锁的开销也最大。行级锁分为共享锁和排他锁
(2)特点
开销大,加锁慢,会出现死锁。发生锁冲突的概率最低,并发度也最高。

2 表级锁
(1) 描述
表级锁是mysql中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分mysql引擎支持。最常使用的MyISAM与InnoDB都支持表级锁定。表级锁定分为表共享读锁(共享锁)与表独占写锁(排他锁)
(2)特点
开销小,加锁快,不会出现死锁。发生锁冲突的概率最高,并发度也最低。

3 页级锁
(1) 描述
页级锁是 MySQL 中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。因此,采取了折衷的页级锁,一次锁定相邻的一组记录。BDB 支持页级锁。
(2)特点
开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
2 锁级别分类 - 共享锁 & 排他锁 & 意向锁
1 共享锁(Share Lock)
共享锁又称读锁,是读取操作创建的锁。其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁。
如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。
用法
SELECT … LOCK IN SHARE MODE;
在查询语句后面增加LOCK IN SHARE MODE,MySQL 就会对查询结果中的每行都加共享锁,当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请共享锁,否则会被阻塞。其他线程也可以读取使用了共享锁的表,而且这些线程读取的是同一个版本的数据。

2 排他锁(Exclusive Lock)
排他锁又称写锁、独占锁,如果事务T对数据A加上排他锁后,则其他事务不能再对A加任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。
用法
SELECT … FOR UPDATE;
在查询语句后面增加FOR UPDATE,MySQL 就会对查询结果中的每行都加排他锁,当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请排他锁,否则会被阻塞。

3 意向锁(Intention Lock)
意向锁是表级锁,其设计目的主要是为了在一个事务中揭示下一行将要被请求锁的类型。InnoDB 中的两个表锁:
意向共享锁(IS):表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的IS锁;
意向排他锁(IX):类似上面,表示事务准备给数据行加入排他锁,说明事务在一个数据行加排他锁前必须先取得该表的IX锁。
意向锁是 InnoDB 自动加的,不需要用户干预。
对于INSERT、UPDATE和DELETE,InnoDB 会自动给涉及的数据加排他锁;对于一般的SELECT语句,InnoDB 不会加任何锁,事务可以通过以下语句显式加共享锁或排他锁。
共享锁:SELECT … LOCK IN SHARE MODE;
排他锁:SELECT … FOR UPDATE;

### 三级标题:MySQL 机制概述 MySQL机制是确保并发事务一致性与隔离性的重要组成部分。通过使用不同类型的粒度,MySQL 提供了灵活而强大的并发控制能力。机制不仅决定了多个事务如何访问共享数据,还影响数据库的性能和可扩展性。 MySQL可以按照粒度分为表级、行级和页级。其中,表级适用于 MyISAM 存储引擎,具有加速度快、开销小的特点,但并发性能较差;而行级是 InnoDB 存储引擎的重要特性,适用于并发操作频繁的场景,能够显著提升系统的并发性能和数据一致性保障能力[^1]。 ### 三级标题:MySQL 类型介绍 #### 表级 MySQL 的表级有两种模式:共享(S Lock)和排他(X Lock)。共享允许事务读取数据,阻止其他事务获取排他;而排他允许事务读取和修改数据,阻止其他事务获取任何类型的。在 MyISAM 引擎中,读和写分别对应 S 和 X 。例如: ```sql LOCK TABLES tablename READ; -- 加共享 LOCK TABLES tablename WRITE; -- 加排他 UNLOCK TABLES; -- 解 ``` 通过命令 `SHOW OPEN TABLES WHERE In_use > 0;` 可以查看当前被加的表[^2]。 #### 行级 InnoDB 支持多种行级,包括共享、排他、记录、间隙、临键和插入意向: - **共享**(S Lock):允许多个事务同时读取同一行数据。 - **排他**(X Lock):阻塞其他事务对该行的读写操作。 - **记录**(Record Lock):定特定的索引记录,是最基本的行类型。 - **间隙**(Gap Lock):定索引记录之间的间隙,防止其他事务插入新记录,从而避免幻读问题。 - **临键**(Next-Key Lock):是记录和间隙的组合,用于实现可重复读的隔离级别。 - **插入意向**(Insert Intention Lock):用于插入数据时,表示事务意图在某个索引间隙中插入记录。 - **隐式**:InnoDB 在插入记录时不会立即加,而是通过事务 ID 判断当前事务是否活跃,并在必要时自动加上排他[^4]。 #### 页级 页级是介于表级和行级之间的一种机制,定的是数据页。虽然页级的并发性能优于表级,但不如行级精细,因此在实际应用中较少使用[^3]。 ### 三级标题:机制的优缺点 **优点**: - 支持多粒度机制,适应不同并发场景的需求。 - 提供事务隔离与一致性保障,防止脏读、不可重复读和幻读等问题。 - InnoDB 的行机制能够显著提升并发性能,适用于高并发系统。 **缺点**: - 的管理成本较高,可能增加系统开销。 - 在高并发环境下,可能引发死,需要数据库引擎进行检测和处理。 - 不合理使用索引可能导致行退化为表,影响性能。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值