一篇文章让你搞懂 MySQL 的锁

news2024/11/15 15:54:18

一篇文章让你搞懂 MySQL 的锁

  • 1、并发问题的解决方案
  • 2、MySQL的各类型锁
    • 2.1、从数据操作的类型划分 (读锁、写锁)
    • 2.2、从数据操作的粒度划分
      • 2.2.1、表锁
        • 2.2.1.1、表级别的S 锁、X 锁
        • 2.2.1.2、意向锁(IS、IX)
        • 2.2.1.3、自增锁
        • 2.2.1.4、元数据锁
      • 2.2.2、行锁
        • 2.2.2.1、记录锁(Record Locks)
        • 2.2.2.2、间隙锁(Gap Locks)
        • 2.2.2.3、临键锁(Next-Key Locks)
        • 2.2.2.4、插入意向锁(Insert Intention Locks)
      • 2.2.3、页锁
    • 2.3、从对锁态度划分:乐观锁、悲观锁
      • 2.3.1、悲观锁
      • 2.3.2、乐观锁
    • 2.4、从加锁方式划分
      • 2.4.1、 隐式锁
      • 2.4.2、显式锁
    • 2.5、其他锁
      • 2.5.1、全局锁
      • 2.5.2、死锁
  • 3、锁监控

 
      在数据库中,除传统的计算资源(如 CPU、RAM、I/O等)的争用以外,数据也是一种供许多用户 共享的资源。为 保证数据的一致性,需要对 并发操作进行控制,因此产生了锁。同时 锁机制也为实现 MySQL 的各个隔离级别提供了保证。锁冲突也是影响数据库 并发访问性能的一个重要因素。所以锁对数据库非常重要,且复杂。并发事务访问同一记录的情况,大致分为:读-读、写-写、读-写。

 

1、并发问题的解决方案

 
并发问题的解决方案:

  • ① 读操作利用多版本并发控制MVCC),写操作进行加锁

    • 采用 MVCC 方式,读-写操作彼此并不冲突性能更高

    • MVCC:就是生成一个ReadView,通过ReadView找到符合条件的记录版本(历史版本由 undo 日志构建)。查询语句只能到在生成ReadView 之前 已提交事务所做的更改,在生成 ReadView 之前未提交的事务或者之后才开启的事务所做的更改是看不到的。而写操作是针对最新版本的记录,读记录的历史版本和改动记录的最新版本本身并不冲突。所以,采用MVCC时,读-写操作并不冲突

      普通的 SELECT 语句在 READ COMMITTED 和 REPEATABLE READ 隔离级别下会使用到 MVCC 读取记录。

      • READ COMMITTED 隔离级别下,一个事务在执行过程中,每次执行 select 操作时都会生成一个 ReadView。ReadView 保证了 事务不可读取到未提交的事务所做的修改 ,即避免了脏读现象。
      • REPEATABLE READ 隔离级别下,一个事务在执行过程中,只有**第一次执行 select 操作** 才会生成一个 ReadView,之后的 select 操作都是**复用**这个 ReadView ,即避免了不可重复读和幻读的问题。
  • ② 读、写操作都采用加锁的方式。

    • 采用加锁方式,读-写操作彼此需要排队执行,影响性能。

       一般情况下都是采用 MVCC来解决读-写操作并发执行的问题,但是在某些特殊业务情况下(比如银行在存取款业务中),必须采用加锁的方式执行。
 

2、MySQL的各类型锁

在这里插入图片描述

2.1、从数据操作的类型划分 (读锁、写锁)

 

从数据操作的类型划分:读锁、写锁。

数据库中并发事务的 读-读并不会引发问题。在使用加锁的方式,解决并发事务的读-写问题时,MySQL 实现了一个由两种类型的锁组成的锁系统来解决,即S锁和X锁。

  • 读锁(也称共享锁 或 S锁):针对同一份数据,多个事务的读操作可以同时进行,而不会相互影响,相互不阻塞。
  • 写锁(也称排它锁 或 X 锁):当前写操作没有完成前,它会阻断其他写锁和读锁。可以确保在给定的时间里,只有一个事务能执行写入,并防止其他用户读取正在写入的同一资源。

注意:对于 InnoDB 存储引擎而言,读锁和写锁可以加在表上,也可以加在行上

S 锁、X 锁彼此的兼容性如下:

锁类型X 锁(排它锁/写锁)S 锁(共享锁/读锁)
X 锁(排它锁/写锁)互斥互斥
S 锁(共享锁/读锁)互斥兼容

 

2.2、从数据操作的粒度划分

 
从数据操作的粒度划分:表级锁、页级锁、行锁。

 

2.2.1、表锁

表锁分为:表级别的S锁和X锁、意向锁、自增锁、元数据锁。

2.2.1.1、表级别的S 锁、X 锁

 
表级别的S 锁、X 锁:

       在对某个表执行增删查改语句时,InnoDB 是不会对该表添加表级别的S锁X锁。当对表执行 ALTER TABLEDROP TABLE 这类 DDL 语句时,其他事务对该表并发执行增删查改语句时,会发生阻塞。同理,一个事务对某表执行增删查改语句时,在其他会话中对该表执行 DDL 语句时,也会发生阻塞。该过程是通过在数据库的 server层使用 元数据锁 结构来实现。

      通常不会使用 InnoDB 提供的表级别的 S锁和 X锁。特殊情况除外,比如在 崩溃恢复 等过程中使用。

 

2.2.1.2、意向锁(IS、IX)

 
      InnoDB 支持 多粒度锁,它允许 行级锁表级锁共存,而 意向锁 就是其中的一种 表锁

       意向锁是由存储引擎自己维护的,用户无法手动操作意向锁,在为数据行加共享/排他锁之前,InnoDB 会先获取该数据行 所在数据表的对应意向锁。如果我们给某一行数据加上了排它锁(X锁),数据库会自动给更大一级的空间(比如数据页或数据表)加上意向锁,告诉其他人这个数据页或数据表已经有人上过排他锁了。意向锁分为两种:

  • 意向共享锁(IS):事务有意向对表种的某些行加共享锁(S锁)。

    • 如果事务要获取某些行的 S 锁,必须先获得表的 IS 锁
  • 意向排它锁(IX):事务有意向对表中的某些行加排它锁(X锁)。

    • 如果事务要获取某些行的 X 锁,必须先获得表的 IX 锁

IS 锁、IX 锁彼此的兼容性如下:

锁类型意向共享锁(IS)意向排他锁(IX)
意向共享锁(IS)兼容兼容
意向排他锁(IX)兼容兼容

IS 锁、S锁、IX 锁、X锁的兼容性(这里的S锁和X锁是表锁级别的,需要明确 意向锁是不会与行级的S锁、X锁互斥的)如下:

锁类型意向共享锁(IS)意向排他锁(IX)
共享锁(S)兼容互斥
排他锁(X)互斥互斥

 
意向锁总结:

  • 意向锁的存在是为了协调行锁和表锁的关系,支持多粒度(表锁与行锁)的锁共存。
  • 意向锁是一种 不与行级锁冲突的表级锁,且意向锁之间互不排斥。
  • 意向锁表明 某个事务正在某些行持有了锁或该事务准备去 持有锁
  • 意向锁在保证并发性的前提下,实现了 行锁和表锁共存,且满足事务隔离性的要求

 

2.2.1.3、自增锁

 
       MySQL表级锁的自增锁(Auto-increment Lock),是为了确保自增主键的唯一性连续性而使用的一种锁机制。当一个表具有自增主键(AUTO_INCREMENT)时,每当插入新行时,主键的值会自动递增。它通过在插入操作时获取表级锁来防止并发事务之间的冲突和重复,确保每个事务获得唯一的自增值。在高并发场景下,表级别的自增锁可能会成为性能瓶颈

 

2.2.1.4、元数据锁

 
       元数据锁(MDL锁)属于表锁范畴,当对一个表做增删查改操作的时候,加 MDL 读锁当要对表做结构变更操作的时候,加 MDL 写锁。读锁之间不互斥,读写锁之间、写锁之间是互斥的,用来保证变更表结构操作的安全性,解决了DMLDDL 操作之间的一致性问题。不需要显式使用,在访问一个表的时候会被自动加上。

  • DDL(Data Definition Languages、数据定义语言),这些语句定义了不同的数据库、表、视图、索引等数据库对象,还可以用来创建、删除、修改数据库和数据表的结构。主要的语句关键字包括 CREATE 、 DROP 、 ALTER 等。

  • DML(Data Manipulation Language、数据操作语言),用于添加、删除、更新和查询数据库记录,并检查数据完整性。主要的语句关键字包括 INSERT 、 DELETE 、 UPDATE 、 SELECT 等。

  • DCL(Data Control Language、数据控制语言),用于定义数据库、表、字段、用户的访问权限和安全级别。主要的语句关键字包括 GRANT 、 REVOKE 、 COMMIT 、 ROLLBACK 、 SAVEPOINT 等。

 

2.2.2、行锁

 
      MySQL 服务器层并没有实现行锁机制行锁只是在存储引擎层实现,以下行锁我们都讨论 InnoDB 下的行锁。InnoDB 和 MyISAM 最大的不同点:① 支持事务 ② 采用了行级锁。

行锁优点行锁缺点
锁定粒度小,发生锁冲突概率低,可实现的并发度高锁的开销比较大加锁比较慢易出现死锁情况。

       MySQL的行级别锁有 记录锁(Record Locks)、间隙锁(Gap Locks)、临键锁(Next-Key Locks)、插入意向锁(Insert Intention Locks)。

 

2.2.2.1、记录锁(Record Locks)

 
       记录锁(Record Lock),用于锁定数据库表中的特定记录。当事务需要对某条记录进行修改或访问时,可以使用记录锁来确保数据的一致性和并发控制。记录锁的主要作用是防止多个事务同时对同一条记录进行修改,从而避免数据冲突和不一致的结果。当一个事务获取了一条记录的锁时,其他事务无法对该记录进行修改,直到锁被释放。

记录锁分为S型记录锁X型记录锁

  • 当一个事务获取了一条记录的 S 型记录锁后,其他事务可以继续获取该记录的 S 型记录锁,但不能继续获取该记录的 X 型记录锁。

  • 当一个事务获取了一条记录的 X 型记录锁后,其他事务既不可以获取该记录的 S 型记录锁,也不可以获取该记录的 X 型记录锁。

2.2.2.2、间隙锁(Gap Locks)

 
      间隙锁是在 innodb的 可重复读级别才会生效,且 Next-Key Locks 实际上是由间隙锁加行锁实现的

      间隙锁(Gap Locks) 是为了 防止 并发事务中的 幻读 问题,并确保数据的一致性。许多公司的配置为:读已提交隔离级别,加上 binlog_format=row,业务上不需要可重复读的保证,就可以考虑 读已提交下操作数据的锁范围更小(没有间隙锁)。
 
间隙锁的工作机制

    1. 锁定间隙间隙锁不仅锁定实际存在的记录,还会锁定索引中不存在的间隙。这意味着如果一个事务执行范围查询,间隙锁将会锁定查询范围内的索引条目,以及范围边缘的间隙。
    1. 结合行锁:间隙锁通常与行锁一起使用。当一个事务获取行锁时,InnoDB会自动获取相应的间隙锁,以确保间隙不被其他事务修改。
       
2.2.2.3、临键锁(Next-Key Locks)

 
      Next-Key Locks 是在InnoDB 存储引擎下,事务级别在 可重复读 的情况下使用的数据库锁,InnoDB 默认的锁就是 Next-Key Locks. Next-Key 锁本质就**是一个记录锁和一个 Gap 锁的合体**,它既能保护该条数据记录,又能阻止别的事务将新记录插入被保护记录前边的间隙。

Next-Key locks 的加锁规则,两原则、两优化、一Bug :

  • 原则 ① :加锁的基本单位是 next-key lock,next-key lock 是前开后闭区间
  • 原则 ② :查找过程中访问到的对象才会加锁。任何辅助索引上的锁,或者非索引列上的锁,最终都要回溯到主键上,在主键上也要加一把锁。
  • 优化 ①:索引上的等值查询,给唯一索引加锁的时候,next-key lock 退化为行锁。也就是说如果 InnoDB 扫描的是一个主键,或者是一个唯一索引的话,那 InnoDB 只会采用行锁方式来加锁。
  • 优化 ②:索引上(不一定是唯一索引)的等值查询,向右遍历时且最后一个值不满足等值条件的时候,next-key lock 退化为间隙锁。
  • 一个Bug:唯一索引上的范围查询,会访问到不满足条件的第一个值为止。

 
示例表 tb_table 结构及数据:

id(主键)user_nametel_phone
1张三13166666667
5李四13166666668
10王五13166666669
# 以下示例在 innoDB 存储引擎 可重复读 的隔离级别前提下展开
## 情况一: Session 会话1 
begin;
#这一步会锁定id区间为 (1,5)之间的数据,如果其他 session会话2插入id为2,3,4的数据会阻塞。
select * from tb_table where id = 3 FOR update;
commit;
-- --------------------
## 情况二: Session 会话1 
begin;
# 这一步会锁定id区间为 (1,10]之间的数据,
# 如果其他 session会话2插入id区间为(2,3,4]和[6,10)的数据会阻塞,更新id=5或id=10的数据也会阻塞。  
select * from zim_user where id >3 and id <7 FOR update;
commit;

-- --------------------
## 情况三: Session 会话1 
begin;
# 这一步会锁定id区间为 (1,5]之间的数据,  
select * from zim_user where id >3 and id <5 FOR update;
commit;

-- --------------------
## 情况四: Session 会话1 
begin;
# 这一步会锁定id区间为 (1,10]之间的数据,  
select * from zim_user where id >3 and id <=5 FOR update;
commit;

-- --------------------
## 情况四: Session 会话1 
begin;
# 这一步会锁定id = 5 的数据,就是单纯的行记录锁。  
select * from zim_user where id =5 FOR update;
commit;

 

2.2.2.4、插入意向锁(Insert Intention Locks)

 

       一个事务在插入一条记录时,需要判断一下插入位置是不是被其他事务加了 gap 锁next-key 锁也包含了 gap 锁),如果有的话,插入操作需要等待,直到 gap 锁的那个事务提交。但是 InnoDB 规定事务在等待的时候,也需要在内存中生成一个锁结构,表明有事务想在某个间隙插入新记录,但是现在在等待。InnoDB 就把这种类型的锁称为 插入意向锁插入意向锁是一种 Gap 锁,在 insert 操作时产生

  • 插入意向锁之间互不排斥,即使多个事务在同一区间插入多条记录,只要记录本身(主键、唯一索引)不冲突,那么事务之间就不会出现冲突等待。

示例表 tb_table 结构及数据:

id(主键)user_nametel_phone
1张三13166666667
5李四13166666668
10王五13166666669
# 事务T1 给 id = 5 的数据加一个gap 锁。
begin;
# 这一步会锁定id区间为 (1,5]之间的数据,  
select * from zim_user where id >3 and id <5 FOR update;
# 这里不 执行 commit;  保证事务 T1 一直持有锁
-------------------------------------------
# 事务 T2 插入一条数据
begin;
# 由于 T1 的间隙锁,导致 这一步阻塞,同时这里添加一个插入意向锁
insert into tb_table (id,user_name,tel_phone) values (2,'tom','13166666662');
-------------------------------------------
# 事务 T3 插入一条数据
begin;
# 由于 T1 的间隙锁,导致 这一步阻塞,同时这里添加一个插入意向锁
insert into tb_table (id,user_name,tel_phone) values (3,'jey','13166666663');
-------------------------------------------
## 事务 T1 提交后,事务T2 和事务T3 的插入并不互斥,插入意向锁之间互不排斥。

在这里插入图片描述

2.2.3、页锁

 
       页锁就是在 页的粒度 上进行的锁,锁定的数据资源比行锁要多,因为一个页可以有多个行记录。页锁的开销介于表锁和行锁之间,会出现死锁锁粒度介于表锁和行锁之间,并发度一般

       由于锁会占用内存空间,锁空间的大小是有限的,所以每个层级的锁数量是有限制的。当某个层级的锁数量超过了这个层级的阈值时,就会进行**锁升级**。锁升级就是用更大粒度的锁,代替多个更小粒度的锁,比如 InnoDB 中行锁升级为表锁,这个做可以降低占用的所空间,但是数据的并发度会降低。

 

2.3、从对锁态度划分:乐观锁、悲观锁

 
       从对待数据并发思维方式的角度来看,可将锁分为乐观锁和悲观锁。这里说的乐观锁悲观锁不是锁,而是锁的设计思想

 

2.3.1、悲观锁

 

     悲观锁 对数据被其他事务的修改,持悲观的保守态度,会通过数据库自身的锁机制来实现,从而保证数据操作的排他性。

       悲观锁每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其他线程阻塞,用完后再把资源转让给其他线程)。比如行锁,表锁,读锁,写锁等,都是在操作之前先上锁,当其他线程想要访问数据时,都需要阻塞挂起。Java 中 synchronizedReentrantLock 等独占锁就是悲观锁思想的实现。

select … for update 是 MySQL 中的悲观锁。

select … for update 语句执行过程中所有扫描的行都会被锁上,因此**在 MySQL 中用悲观锁必须确定使用了索引,而不是全表扫描,否则将会把整个表锁住**。

-- 对于并发量不高的场景,悲观锁解决 超卖示例(1、2、3步在同一个事务中):
# 第1步:查出商品库存
select quantity from tb_item where id = 1099 for update;
# 第2步:如果库存大于0,则根据商品信息产生订单
insert into tb_orders(item_id) values(1099);
# 第3步:修改商品的库存,num 表示购买数量
update tb_items set quantity = quantity-num where id = 1099;

      悲观锁大多数情况下依靠数据库的锁机制来实现,以保证程序的并发访问性,但是这样对数据库性能开销影响很大,特别是对 长事务 而言,这样的开销往往无法承受,就需要乐观锁来解决。
 

2.3.2、乐观锁

 

       乐观锁对同一数据的并发操作,不用每次都对数据上锁,但是在更新的时候会判断一下,在此期间别人有没有去更新这个数据。乐观锁不采用数据库自身的锁机制,而**是通过在程序上采用 版本号 或者 CAS 机制实现**。乐观锁 适用于多读 的应用类型,可以提高吞吐量。在 Java 中 java.util.concurrent.atomic 包下的原子变量类,就是使用了乐观锁的一种实现方式:CAS 实现的。

  • ① 乐观锁的版本号机制

    在表中设计一个 版本字段 version,第一个读的时候获取 version 的值 version_value,然后对数据进行更新或者删除时,执行 update … set version = version+1 where version = version_value,此时如果已经有事务对这条数据进行了更改,修改就不会成功。

  • ② 乐观锁的时间戳机制

    • 时间戳和版本号机制一样,也是在更新提交的时候,将当前数据的时间戳和更新之前取得的时间戳进行比较,如果两者一致则更新成功,否则就是版本冲突。
-- 对于并发量不高的场景,乐观锁解决超卖问题 示例(1、2、3步在同一个事务中):
# 第1步:查出商品库存
select quantity from tb_item where id = 1099;
# 第2步:如果库存大于0,则根据商品信息产生订单
insert into tb_orders(item_id) values(1099);
# 第3步:修改商品的库存,num 表示购买数量
update tb_items set quantity = quantity-num,version = version+1 where id = 1099 and version = #{version};

### 注意:以上方案存在两个问题:
###    - ① 如果数据表是读写分离的表,当 master表中写入的数据没有及时同步到slave表中时,会造成更新一直失            败,此时需要强制读取 master表中的数据(即将select 语句放到事务中即可)。
###    - ② 如果高并发场景下,每次修改库存只有一个事务能更新成功,在业务感知上就有大量的失败操作。

###  优化方案(1、2、3步在同一个事务中):
# 第1步:查出商品库存
select quantity from tb_item where id = 1099;
# 第2步:如果库存大于0,则根据商品信息产生订单
insert into tb_orders(item_id) values(1099);
# 第3步:修改商品的库存,num 表示购买数量
update tb_items set quantity = quantity-num where id = 1099 and quantity-num > 0;

 

乐观锁和悲观锁的适用场景:

  • 乐观锁适合 读操作多的场景,相对来说写的操作比较少。它的**优点在于 程序实现,不存在死锁问题**。乐观锁阻止不了除了程序以外的数据库操作,所以适用场景也会相对乐观。
  • 悲观锁适合写操作多的场景,因为写的操作具体排他性。采用 悲观锁 的方式, 可以在数据库层面阻止其他事务对该数据的操作权限,防止 读-写 和写-写 冲突

在这里插入图片描述

2.4、从加锁方式划分

 
从加锁方式划分,可以分为 隐式锁、显式锁。
 

2.4.1、 隐式锁

 
       隐式锁并不是在SQL语句中明确指定的,而是由InnoDB引擎根据特定操作自动添加的。

       一个事务对新插入的记录可以不显式的加锁(生成一个锁结构),但是由于事务id 的存在,相当于加了一个 隐式锁。别的事务在对这条记录加 S 锁X 锁 时,由于 隐式锁 的存在,会先帮助当前事务生成一个锁结构,然后自己再生成一个锁结构后进入等待状态。隐式锁是一种 延迟加锁 的机制,从而来减少加锁的数量。隐式锁在实际内存对象中,并不含有这个锁信息,只有当产生锁等待时,隐式锁转化为显式锁。

 

隐式锁的逻辑过程如下:

  • ① InnoDB 的每条记录中,都有一个隐含的 trx_id 字段,这个字段存在于聚簇索引的 B+Tree 中。
  • ② 在操作一条记录前,首先根据记录中的 trx_id 检查该事务是否是活动的事务(未提交或未回滚),如果是活动的事务,首先将隐式锁转换为显式锁(就是为该事务添加一个锁)。
  • ③ 检查是否有锁冲突,如果有冲突,创建锁,并设置为 waiting 状态。如果没有冲突不加锁,跳到第 ⑤ 步。
  • ④ 等待加锁成功,被唤醒,或者超时。
  • ⑤ 写数据,并将自己的 trx_id 写入 trx_id 字段。

 

2.4.2、显式锁

 

通过特定的语句进行加锁,我们一般称之为显式锁,例如:

# 显式加共享锁:
selectlock in share mode;
# 显式加排它锁
selectfor update;

 

2.5、其他锁

 

2.5.1、全局锁

 

       全局锁就是对 整个数据库实例 加锁,当需要对整个数据库处于 只读状态 的时候,可以使用该命令,之后其他线程的以下语句会被阻塞:数据更新语句(数据的增删改)、数据定义语句(包括建表、修改表结构等)和更新类事务的提交语句。全局锁的典型使用场景是:做全库逻辑备份

# 全局锁命令:
Flush tables with read lock;

 

2.5.2、死锁

 

       死锁:两个及以上事务,都持有对方需要的锁,并且在等待对方释放,并且双方都不会释放自己的锁。示例:

步骤事务1事务2
1start transaction;
update account set money =50 where id =2;
start transaction;
2update account set money = 10 where id =4;
3update account set money = 20 where id =4;
4update account set money =60 where id =2;

产生死锁的必要条件:

① 两个或者两个以上的事务,每个事务都已经持有锁,并且申请新的锁。

② 锁资源同时只能被同一个事务持有或者不兼容。

③ 事务之间因为持有锁和申请锁导致彼此循环等待。

死锁的关键在于:两个及以上的 Session会话加锁的顺序不一致。

 
如何处理死锁:

  • ① 等待,直到超时(innodb_lock_wait_timeout=50s).

    • 当两个事务相互等待时,当一个事务等待时间超过设置的阈值时,就将其回滚,另外事务继续进行。InnoDB中,参数 innodb_lock_wait_timeout 用来设置超时时间。
    • 缺点:对于在线服务来说,该等待时间往往无法接受。
  • ② 使用 InnoDB 的 wait-for graph 算法来主动进行死锁检测,从而处理死锁。

    • 每当加锁请求无法立即满足需要,并进入等待时,wait-for-graph 算法都会被触发。
    • wait-for graph 死锁检测的原理,是构建一个以事务为顶点、锁为边的有向图,判断有向图是否存在环,存在既有死锁。
    • 一旦检测到回路、有死锁,InnoDB会选择 回滚undo量最小的事务,让其他事务继续执行(innodb_deadlock_detect=on 表示开启这个逻辑)。
    • 缺点:每个新的被阻塞的线程,都有判断是不是由于自己的加入导致了死锁,该操作的时间复杂度为O(n),如果100个并发线程同时更新同一行,意味着要检测 100*100=1万次。可以使用消息中间件,控制同一行数据的并发访问。

 

如何避免死锁:

  • ① 合理设计索引,使业务 SQL 尽可能通过索引定位更少的行,减少锁竞争。
  • ② 调整业务逻辑 SQL 执行顺序,避免 update/delete 长时间持有锁的 SQL 在事务前面。
  • ③ 避免大事务,尽量将大事务拆成多个小事务来处理,小事务缩短锁定资源的时间,发生锁冲突的几率也更小。
  • ④ 在并发比较高的系统中,不要显式加锁,特别是在事务里显式加锁。(如 select … fro update 语句,如果在事务里运行了 start transaction 或设置了 autocommit = 0,那么就会锁定所查找到的记录)
  • ⑤ 降低隔离级别。如果业务允许,将隔离级别降低也可避免死锁。比如将隔离级别从 RR 调整到 RC,可以避免很多因为 gap 锁造成的死锁。

 

3、锁监控

 

       MySQL 锁的监控,一般通过检查 innodb_row_lock 等状态变量来分析系统上的行锁的争夺情况。

show status like 'innodb_row_lock%';

在这里插入图片描述

  • Innodb_row_lock_current_waits : 当前正在等待锁定的数量。
  • Innodb_row_lock_time : 从系统启动到现在锁定总时间长度;(等待总时长)。
  • Innodb_row_lock_time_avg : 每次等待所花平均时间;(等待平均时长)。
  • Innodb_row_lock_time_max : 从系统启动到现在,等待最常的一次所花的时间。
  • Innodb_row_lock_waits : 系统启动后到现在总共等待的次数;(等待总次数)。

 

       MySQL 把事务和锁信息记录在 information_schema 库中,涉及到的三张表分别是 INNODB_LOCKSINNODB_LOCK_WAITSINNODB_TRX.

MySQL8.0 版本删除了 information_schema.INNODB_LOCKS,添加了 performance_schema.data_locks 查看事务的锁情况,其可以看到阻塞该事务的锁,也可看到该事务所持有的锁。

MySQL8.0 版本 information_schema.INNODB_LOCK_WAITSperformance_schema.data_lock_waits 所取代。

 
 
 
 
 
 
 
 
.

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

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

相关文章

亚马逊收到CPSC查验通知后卖家需要怎么弄?ASTM F963标准测试 ,CPC认证

收到CPSC查验亚马逊卖家需要怎么做&#xff1f; 。CPSC消费品安全协会&#xff0c;成立于1972年&#xff0c;它的责任是保护广大消费者的利益&#xff0c;通过减少消费品存在的伤害及死亡的危险来维护人身及家庭安全。CPSC现在负责对超过15000种消费品的安全监控&#xff0c;具…

【送书福利-第二十七期】《边缘计算系统设计与实践》

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公粽号&#xff1a;程序员洲洲。 &#x1f388; 本文专栏&#xff1a;本文…

基于Genio 700 (MT8390)芯片的AR智能眼镜方案

AR眼镜是一种具有前所未有发展机遇的设备&#xff0c;无论是显示效果、体积还是功能都有明显的提升。AR技术因其智能、实时、三维、多重交互和开放世界的特点备受关注。 AR眼镜集成了AR技术、语音识别、智能控制等多项高科技功能&#xff0c;可以帮助用户实现更加便捷、高效、个…

电脑桌面任务提醒便签选择哪一个好用?

伴随着科技现代化的发展&#xff0c;电脑成为大家日常办公及生活中必不可少的工具&#xff0c;如在日常办公中大家可以借助电脑上的任务提醒便签来合理规划自己的工作时间&#xff0c;督促任务的完成&#xff0c;提高工作的效率。 当前&#xff0c;支持在电脑上安装的任务提醒…

RGB转Bayer,一个小数点引发的血案

前几天写了一个RGB数据转Bayer格式的函数&#xff0c;经过测试功能正常。后来把这个函数用到一个数据库构建中&#xff0c;结果数据库出来的结果一直是一张黑图&#xff0c;追查了好几个小时&#xff0c;总算把这只虫子找出来了&#xff0c;原来是一个整数后面的小数点作祟。 …

基础课4——客服中心管理者面临的挑战

客服管理者在当今的数字化时代也面临着许多挑战。以下是一些主要的挑战&#xff1a; 同行业竞争加剧&#xff1a;客服行业面临着来自同行业的竞争压力。为了获得竞争优势&#xff0c;企业需要不断提高自身的产品和服务质量&#xff0c;同时还需要不断降低成本、提高效率。然而…

热烈庆祝瑞森半导体成立10周年

瑞森半导体10年芯路&#xff0c;衷心感谢全球合作伙伴、 客户、员工、朋友的帮助与支持。 弹指一挥间&#xff0c;瑞森半导体已在功率半导体行业奋勇前行了十年。3650个白天与黑夜&#xff0c;瑞森半导体在风雨兼程中砥砺前行&#xff0c;在倾情奉献中不负初心。十年里有太多的…

Go ZIP压缩文件读写操作

创建zip文件 golang提供了archive/zip包来处理zip压缩文件&#xff0c;下面通过一个简单的示例来展示golang如何创建zip压缩文件&#xff1a; func createZip(filename string) {// 缓存压缩文件内容buf : new(bytes.Buffer)// 创建zipwriter : zip.NewWriter(buf)defer writ…

如何高效收集数据?

在当今这个信息爆炸的时代&#xff0c;数据已经成为了一种新的资源&#xff0c;其价值不可估量。收集数据的重要性日益凸显&#xff0c;无论是对于企业、政府还是个人&#xff0c;数据都已经成为了一种宝贵的财富。分享一些网站。 一、宏观数据 1.国家统计局&#xff08;数据…

智慧工地综合管理平台-项目开发管理规范

目的 本规范制定旨在规范项目的开发流程,提高软件开发质量和效率,降低开发成本和风险。该规范包括但不限于以下几个方面: 项目管理 包括项目计划、需求分析、设计、开发、测试、发布等环节,以及项目进度、质量和风险管理等方面项目计划管理:制定项目计划,包括确定项目目…

基于Springboot+Vue的社区医院管理系统

基于SpringbootVue的社区医院管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 医生列表 医生详情 登录界面 管理员界面 医生界面 摘要 社区医院管…

day22_mysql

今日内容 零、 复习昨日 一、MySQL 一、约束 1.1 约束 是什么? 约束,即限制,就是通过设置约束,可以限制对数据表数据的插入,删除,更新 怎么做? 约束设置的语法,大部分是 create table 表名( 字段 数据类型(长度) 约束, 字段 数据类型(长度) 约束 );1.1 数据类型 其实数据类型…

HDFS入门--学习笔记

1&#xff0c;大数据介绍 定义 数据指的是&#xff1a;一种可以被鉴别的、对客观事件进行记录的符号&#xff0c;除了可以是最简单的 数字外&#xff0c;也可以是各类符号、文字、图像、声音等。 通俗地说&#xff0c;数据就是对人类的行为及发生事件的一种记录。 存在的价值…

【验证码逆向专栏】百某网数字九宫格验证码逆向分析

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 本文章未…

Debezium-Embedded 实时监控MySQL数据变更

1.Debezium-Embedded 简介 Debezium连接器的操作通常是将它们部署到Kafka Connect服务&#xff0c;并配置一个或多个连接器来监控上游数据库&#xff0c;并为它们在上游数据库中看到的所有更改生成数据更改事件。这些数据更改事件被写入Kafka&#xff0c;在那里它们可以被许多不…

Wireshark抓包工具配置以及MQTT抓包分析

1、Wireshark抓包工具使用 打开Wireshark选择&#xff0c;需要抓取的物理网卡&#xff0c;添加过滤设置。 单击“捕获”&#xff0c;选择选项&#xff0c;输入需要捕获的IP地址和端口号。 如&#xff1a; ip host 10.60.4.45 and tcp port 1883 ip host 10.60.4.45 and http p…

JVM虚拟机:垃圾回收之三色标记

本文重点 在前面的课程中我们已经学习了垃圾回收器CMS和G1,其中CMS和G1中的mixedGC都存在四个过程,这四个过程中有一个过程叫做并发标记,也就是说程序一边运行,一边标记垃圾。这个过程最困难的是:如果在标记垃圾的时候,如果对象的引用关系发生了改变,此时应该如何处理?…

吴恩达《机器学习》8-5->8-6:特征与直观理解I、样本与值观理解II

8.5、特征与直观理解I 一、神经网络的学习特性 神经网络通过学习可以得出自身的一系列特征。相对于普通的逻辑回归&#xff0c;在使用原始特征 x1​,x2​,...,xn​ 时受到一定的限制。虽然可以使用一些二项式项来组合这些特征&#xff0c;但仍然受到原始特征的限制。在神经网…

mysql之搭建MHA架构实现高可用

1、定义 全称是masterhigh avaliabulity。基于主库的高可用环境下可以实现主从复制及故障切换&#xff08;基于主从复制才能故障切换&#xff09; MHA最少要求一主两从&#xff0c;半同步复制模式 2、作用 解决mysql的单点故障问题。一旦主库崩溃&#xff0c;MHA可以在0-30…

Postman工具简介

介绍 Postman是一个商业的接口测试工具。免费的版本也可以使用不少功能。 官网&#xff1a;https://www.postman.com/ 下载、安装、应用界面 下载 安装、安装成功以后的应用界面 双击下载下来的可执行文件进行安装&#xff0c;出现如下界面&#xff1a; 可以注册一个账…