mysql锁

1.全局锁

//加全局锁
flush tables with read lock

//释放全局锁
unlock tables

执行后,整个数据库就处于只读状态,加上了全局锁。全局锁颗粒度比表级锁大,此时所有线程对表结构、表数据只能执行读了。

当然,如果当前加全局锁的会话断开,全局锁会被自动释放。

全局锁主要用于全库逻辑备份,这样在备份数据库期间,不会因为数据或表结构的更新
而出现备份文件的数据与预期的不一样。

2.表级锁

2.1表锁

//表级别的共享锁,也就是读锁;
//允许当前会话读表,阻止其他会话写表。同时本会话不能访问其他表
lock tables student read;

//表级别的独占锁,也就是写锁;
//允许当前会话对表进行读写操作,阻止其他会话对表进行任何操作(读或写)。
lock tables student write;

2.2意向锁

当要使用表锁时,如何判断表中的记录没有行锁呢,一行一行遍历肯定是不行,性能太差。要用意向锁来快速判断是否可以对某个表使用表锁。

  • 意向共享锁(Intention Shared Lock,IS 锁):事务有意向对表中的某些记录加共享锁(S 锁),加共享锁前必须先取得该表的 IS 锁。
  • 意向排他锁(Intention Exclusive Lock,IX 锁):事务有意向对表中的某些记录加排他锁(X 锁),加排他锁之前必须先取得该表的 IX 锁。

意向锁之间兼容,与行级的共享锁和排他锁兼容,但是和表级的共享锁和排他锁互斥。
所以说当执行增、删、改操作,需要先对表加上「意向独占锁」,然后对该记录加独占锁。

另外当前读的select也会加共享锁、独占锁。

3.行锁

3.1间隙锁

间隙锁是一种加在两个索引之间的锁,锁的是一个开区间只存在于可重复读隔离级别。

假设,表中有一个范围id为(3,5]的next-key lock,那么其他事务即不能插入id=4记录,也不能修改id=5这条记录。

临建锁和间隙锁在幻读中的使用场景

详解 MySql InnoDB 中的三种行锁(记录锁、间隙锁与临键锁) - HappyDeveloper - 博客园

  • 使用间隙锁的情况

    • 非唯一索引的等值查询:例如SELECT * FROM table WHERE non_unique_col = 5 FOR UPDATE,若5存在,会锁定5周围的间隙;若5不存在,则锁定其应存在的间隙。

    • 范围查询:如WHERE id > 10,若未命中记录,会锁定符合条件的间隙。

    • 唯一索引的等值查询(未命中):如SELECT * FROM table WHERE unique_col = 15 FOR UPDATE,当15不存在时,锁定其所在的间隙。

  • 临键锁触发条件

    • 非唯一索引的范围查询:如WHERE non_unique_col BETWEEN 5 AND 10

    • 唯一索引的范围查询:如WHERE unique_col > 10

    • 默认锁机制:在可重复读级别下,InnoDB默认对索引扫描使用临键锁

3.2记录锁

记录锁是最简单的行锁,仅锁住一行,有读锁和写锁之分,读写锁互斥。

如:SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE

如果C1字段是主键或者是唯一索引的话,这个SQL会加一个记录锁,记录锁永远都是加在索引上的,即使一个表没有索引,InnoDB也会隐式的创建一个索引,并使用这个索引实施记录锁。它会阻塞其他事务对这行记录的插入、更新、删除。

3.3临键锁

Next-key锁是记录锁和间隙锁的组合解决了锁定读的幻读问题(非锁定读用快照读即可解决幻读),它指的是加在某条记录以及这条记录前面间隙上的锁。说得更具体一点就是:临键锁会封锁索引记录本身,以及索引记录之前的区间,即它的锁区间是左开右闭,比如 (5,10]

在 InnoDB 默认的隔离级别 可重复读 下,行锁默认使用的是临键锁。但是,如果操作的索引是唯一索引或主键,InnoDB 会对临键锁进行优化,将其降级为 记录锁 ,即仅锁住索引本身,而不是范围。

3.4自增锁(表级锁)

专门针对AUTO_INCREMENT类型的列,对于这种列,如果表中新增数据时就会去持有自增锁。简言之,如果一个事务正在往表中插入记录,所有其他事务的插入必须等待,以便第一个事务插入的行,是连续的主键值。

3.5插入意向锁

假设事务 A 已经对表加了一个范围 id 为(3,5)间隙锁。

当事务A还没提交的时候,事务B向该表插入一条id=4的新记录,这时会判断到插入的位置已经被事务A加了间隙锁,于是事物B会生成一个插入意向锁,然后将锁的状态设置为等待状态(PS:MySQL加锁时,是先生成锁结构,然后设置锁的状态,如果锁状态是等待状态,并不是意味着事务成功获取到了锁,只有当锁状态为正常状态时,才代表事务成功获取到了唢,此时事务B就会发生阻塞,直到事务A提交了事务。

行级锁和表级锁对比

  • 表级锁: MySQL 中锁定粒度最大的一种锁(全局锁除外),是针对非索引字段加的锁,对当前操作的整张表加锁,实现简单,资源消耗也比较少,加锁快,不会出现死锁。不过,触发锁冲突的概率最高,高并发下效率极低。表级锁和存储引擎无关,MyISAM 和 InnoDB 引擎都支持表级锁。
  • 行级锁: MySQL 中锁定粒度最小的一种锁,是 针对索引字段加的锁 ,只针对当前操作的行记录进行加锁。行级锁能大大减少数据库操作的冲突。其加锁粒度最小,并发度高,但加锁的开销也最大,加锁慢,会出现死锁。行级锁和存储引擎有关,是在存储引擎层面实现的。
  • InnoDB 的行锁是针对索引字段加的锁表级锁是针对非索引字段加的锁。当我们执行 UPDATEDELETE 语句时,如果 WHERE条件中字段没有命中唯一索引或者索引失效的话,就会导致扫描全表对表中的所有行记录进行加锁。 
### MySQL 机制详解 MySQL 中的机制是为了保障数据库在高并发环境下的数据一致性和稳定性而设计的重要功能之一。以下是关于 MySQL 机制的具体解析: #### 1. 的分类 MySQL 主要分为两种类型的:表级和行级。 - **表级 (Table-Level Lock)** 表级是最简单的定策略,适用于 MyISAM 存储引擎。它会在整个表上施加,无论是读操作还是写操作都会影响到整张表。对于 `SELECT` 操作,MyISAM 会自动给涉及的所有表加上读;而对于 `UPDATE`, `INSERT`, 和 `DELETE` 则会自动加上写[^3]。 - **行级 (Row-Level Lock)** 行级由 InnoDB 存储引擎实现,提供更高的并发能力。只有涉及到具体记录的操作才会触发行级。例如,在执行 `SELECT ... FOR UPDATE` 或者 `SELECT ... LOCK IN SHARE MODE` 时,InnoDB 只会对符合条件的特定行加而不是封整个表[^2]。 #### 2. 不同存储引擎的特性 不同的存储引擎有不同的行为: - **MyISAM**: 默认使用的是表级别的,这意味着即使是一个小范围内的更新也会阻塞其他线程对该表任何部分的访问[^3]。 - **InnoDB**: 支持事务以及更细粒度的行级,这使得它可以更好地处理复杂的多用户场景下的并发请求[^4]。 #### 3. 常见类型及其作用 除了基本的表级与行级区分外,还有几种具体的形式用于满足不同需求: - **共享 (Shared Lock, S-Lock)** 当一个客户端通过命令如 `LOCK TABLES table_name READ` 获取了一个表上的共享之后,其它客户也可以获得该表上的共享,但不能再获取排他直到当前持有共享的所有连接释放它们为止[^2]。 - **排他 (Exclusive Lock, X-Lock)** 排他允许独占式的修改权限。如果某个事务已经获得了某条记录或者某些列上的排他,则在此期间不允许别的事务再对此同一组资源申请任何形式的新——既包括另外的排他也包括新的共享[^2]。 - **GAP ** 这种特殊的用来阻止新纪录插入到现有两条连续记录之间的空隙(gap)里去。比如当我们运行下面这条SQL语句的时候就会用到gap lock:`SELECT * FROM table_name WHERE id > 10 FOR UPDATE;` - **Next-Key Lock** 是一种组合了索引记录本身(record)和其前面那个区间(gap)两者一起保护起来的一种复合型模式。主要用于解决可重复读(repeatable read)隔离级别下可能出现的幻影问题(phantom problem)[^4]。 #### 4. 死现象及预防措施 死是指两个或更多事务相互等待对方持有的资源从而进入僵局的状态。为避免这种情况发生可以采取以下方法: - 尽量按照固定的顺序访问资源; - 减少单次事务持续时间; - 设置合理的超时参数让系统能够及时发现并终止潜在的死循环状况等等[^4]。 ```sql -- 示例:如何手动解表 UNLOCK TABLES; ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值