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; 进行添加意向锁

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

相关推荐
溜达的大象13 小时前
数据库选型不踩坑:从关系型到向量库的全景技术图谱
数据库
白藏y13 小时前
【数据库】SQLite的基础使用
数据库·sqlite
你才是臭弟弟14 小时前
window sever 2019 安装~时序数据库TDengine TSDB 和 视图工具dbeaver
数据库·时序数据库·tdengine
J超会运14 小时前
MySQL核心SQL语句速查宝典
数据库·mysql
Memory_荒年14 小时前
TiDB 单机部署与监控完整指南
运维·数据库·后端
殷紫川14 小时前
吃透分库分表:分片策略、跨库事务与平滑扩容全解
mysql·架构
殷紫川14 小时前
SQL 性能优化全解:从执行计划到底层逻辑,根治 99% 的慢 SQL 与规范落地
数据库·mysql
Memory_荒年14 小时前
TiDB:当 MySQL 遇上分布式,生了个“超级混血儿”
java·数据库·后端
殷紫川14 小时前
MySQL高可用生产落地全解:主从同步、MGR集群、读写分离从原理到实战
mysql·架构
asom2214 小时前
DDD(领域驱动设计) 核心概念详解
java·开发语言·数据库·spring boot