MySQL的锁-全局锁及表锁

(1)锁的概述

锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU, RAM, I/0)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。

MySQL中的锁,按照锁的粒度分,分为以下三类:

  1. 全局锁:锁定数据库中的所有表。

  2. 表级锁:每次操作锁住整张表。

  3. 行级锁:每次操作锁住对应的行数据。

(2)全局锁

全局锁就是对整个数据库实例加锁,加锁后整个实例就处于只读状态,后续的DML的写语句,DDL语句,已经更新操作的事务提交语句都将被阻塞。

其典型的使用场景是做全库的逻辑备份,对所有的表进行锁定,从而获取一致性视图,保证数据的完整性。

加全局锁

flush tables with read lock;

加了全局锁之后,只能查不能写;

释放锁

unlock tables;

数据库中加全局锁,是一个比较重的操作,存在以下问题:

1)如果在主库上备份,那么在备份期间都不能 执行更新,业务基本上就得停摆。

2)如果在从库上备份,那么在备份期间从库不能执行主库同步过来的二进制日志(binlog),会导致主从延迟。

在InnoDB引擎中,我们可以在备份时加上参数 --single-transaction参数来完成不加锁的一致性数据备份。

mysqldump --single-transaction -uroot -p123456 xxxx>xxxx.sql

(3)表级锁

表级锁,每次操作锁住整张表。锁定粒度大,发生锁冲突的概率最高,并发度最低。

对于表级锁,主要分为以下三类:

(1)表锁

1)表共享读锁(read lock)

2)表独占写锁(write lock)

加锁: lock tables xxx read/write

释放锁: unlock tables / 客户端断开连接

lock table score read;

加读锁之后,可以正常select * from score, 进行表数据的读取。

其他客户端也可以进行正常的读取

加读锁之后,无法对表进行update、insert等操作

update score set math=100 where id=2; 报错 table 'score' was locked with a read lock and can't be updated;

其他客户端进行update、insert操作时,会被阻塞,直到读锁被解除.

客户端对表加了写锁之后, 当前客户端可以对表进行写和读; 其他客户端不能对表进行写和读.

其他客户端对这张表进行读取时,会一直堵塞; 对表进行写时,也会一直堵塞, 直到锁释放为主.

(2)元数据锁(meta data locak, MDL)

MDL加锁过程是系统自动控制,无需显式使用,在访问一张表的时候会自动加上. MDL锁主要作用是维护表元数据的数据一致性, 在表上有活动事务的时候,不可以对元数据进行写入操作.

当对表进行select, insert, update, delete, select ... for update时, MDL加的是shared_read, shared_write锁; 而alter table操作时,MDL锁类型时exclusive;

shared_read, shared_write与exclusive是相互互斥的.

可以通过select object_type, object_schema, object_name,lock_type, lock_duration from performance_schema.metadata_locks; 查询MDL锁

(3)意向锁

为了避免DML在执行时, 加的行锁与表锁的冲突, 在InnoDB中引入了意向锁, 使得表锁不用检查每行数据是否加锁, 使用意向锁来减少表锁的检查.

意向锁分为:

(1) 意向共享锁(IS): 右语句select ... lock in share mode添加; 与表锁共享锁(read)兼容, 与表锁排它锁(write)互斥.

(2) 意向排它锁(IX): 由insert, update, delete, select ... for update添加. 与表锁共享锁(read)及排它锁(write)都互斥. 意向锁之间不会互斥.

可以通过以下sql, 查看意向锁及行锁的加锁情况

select object_schema, object_name, index_name, lock_type, lock_mode, lock_data from performance_schema.data_locks

通过select * from score where id = 1 lock in share mode; 进行添加意向锁

意向共享锁, 可以和表的读锁共享,不互斥

相关推荐
自不量力的A同学13 小时前
Redisson 4.2.0 发布,官方推荐的 Redis 客户端
数据库·redis·缓存
Exquisite.13 小时前
Mysql
数据库·mysql
全栈前端老曹13 小时前
【MongoDB】深入研究副本集与高可用性——Replica Set 架构、故障转移、读写分离
前端·javascript·数据库·mongodb·架构·nosql·副本集
R1nG86313 小时前
CANN资源泄漏检测工具源码深度解读 实战设备内存泄漏排查
数据库·算法·cann
阿钱真强道14 小时前
12 JetLinks MQTT直连设备事件上报实战(继电器场景)
linux·服务器·网络·数据库·网络协议
逍遥德14 小时前
Sring事务详解之02.如何使用编程式事务?
java·服务器·数据库·后端·sql·spring
笨蛋不要掉眼泪14 小时前
Redis哨兵机制全解析:原理、配置与实战故障转移演示
java·数据库·redis·缓存·bootstrap
Coder_Boy_14 小时前
基于SpringAI的在线考试系统-整体架构优化设计方案
java·数据库·人工智能·spring boot·架构·ddd
fen_fen1 天前
Oracle建表语句示例
数据库·oracle
砚边数影1 天前
数据可视化入门:Matplotlib 基础语法与折线图绘制
数据库·信息可视化·matplotlib·数据可视化·kingbase·数据库平替用金仓·金仓数据库