【MySQL高级】Mysql锁问题(上)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 【MySQL高级】Mysql锁问题

5. Mysql锁问题

5.1 锁概述

锁是计算机协调多个进程或线程并发访问某一资源的机制(避免争抢)。


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


5.2 锁分类


从对数据操作的粒度分 :


1) 表锁:操作时,会锁定整个表。


2) 行锁:操作时,会锁定当前操作行。


从对数据操作的类型分:


1) 读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响。


2) 写锁(排它锁):当前操作没有完成之前,它会阻断其他写锁和读锁。


5.3 Mysql 锁


相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。下表中罗列出了各存储引擎对锁的支持情况:


存储引擎 表级锁 行级锁 页面锁
MyISAM 支持 不支持 不支持
InnoDB 支持 支持 不支持
MEMORY 支持 不支持 不支持
BDB 支持 不支持 支持

MySQL这3种锁的特性可大致归纳如下 :


锁类型 特点
行级锁 偏向InnoDB 存储引擎,开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
页面锁 开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
表级锁 偏向MyISAM 存储引擎,开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。


从上述特点可见,很难笼统地说哪种锁更好,只能就具体应用的特点来说哪种锁更合适!仅从锁的角度来说:表级锁更适合于以查询为主,只有少量按索引条件更新数据的应用,如Web 应用;而行级锁则更适合于有大量按索引条件并发更新少量不同数据,同时又有并查询的应用,如一些在线事务处理(OLTP)系统。


5.2 MyISAM 表锁


MyISAM 存储引擎只支持表锁,这也是MySQL开始几个版本中唯一支持的锁类型。


5.2.1 如何加表锁


MyISAM 在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATE、DELETE、INSERT 等)前,会自动给涉及的表加写锁,这个过程并不需要用户干预,因此,用户一般不需要直接用 LOCK TABLE 命令给 MyISAM 表显式加锁。


显示加表锁语法:


加读锁 : lock table table_name read;

加写锁 : lock table table_name write;


5.2.2 读锁案例


准备环境


create database demo_03 default charset=utf8mb4;
use demo_03;
CREATE TABLE `tb_book` (
  `id` INT(11) auto_increment,
  `name` VARCHAR(50) DEFAULT NULL,
  `publish_time` DATE DEFAULT NULL,
  `status` CHAR(1) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=myisam DEFAULT CHARSET=utf8 ;
INSERT INTO tb_book (id, name, publish_time, status) VALUES(NULL,'java编程思想','2088-08-01','1');
INSERT INTO tb_book (id, name, publish_time, status) VALUES(NULL,'solr编程思想','2088-08-08','0');
CREATE TABLE `tb_user` (
  `id` INT(11) auto_increment,
  `name` VARCHAR(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=myisam DEFAULT CHARSET=utf8 ;
INSERT INTO tb_user (id, name) VALUES(NULL,'令狐冲');
INSERT INTO tb_user (id, name) VALUES(NULL,'田伯光');


客户端 一 :


1)获得tb_book 表的读锁


lock table tb_book read;

2) 执行查询操作


select * from tb_book;

e800b7f675ef4670ba706372535d8d07.png


可以正常执行 , 查询出数据。


客户端 二 :


3) 执行查询操作


select * from tb_book;


b897215b524c4577b4d96963a82b9fe0.png


客户端 一 :


4)查询未锁定的表


select name from tb_seller;


03e592c5817542b79676c89c032d4183.png


客户端 二 :


5)查询未锁定的表


select name from tb_seller;


537549cb188e4fb3950494c2b05fe871.png


可以正常查询出未锁定的表;


客户端 一 :


6) 执行插入操作


insert into tb_book values(null,'Mysql高级','2088-01-01','1');


4b4b775e30ae41eead61125834c9b404.png


执行插入, 直接报错 , 由于当前tb_book 获得的是 读锁, 不能执行更新操作。


客户端 二 :


7) 执行插入操作


insert into tb_book values(null,'Mysql高级','2088-01-01','1');


0c1ee928753749b880eacff8db6b6f34.png


当在客户端一中释放锁指令 unlock tables 后 , 客户端二中的 inesrt 语句 , 立即执行 ;


unlock tables;

5.2.3 写锁案例


客户端 一 :


1)获得tb_book 表的写锁


lock table tb_book write ;

2)执行查询操作


select * from tb_book ;


9d4f8f2323b54c60af9c04ce009b523c.png


查询操作执行成功;


3)执行更新操作


update tb_book set name = 'java编程思想(第二版)' where id = 1;


bf98a9c96c944267a4d3d5b32ca7dd73.png


更新操作执行成功 ;


客户端 二 :


4)执行查询操作


select * from tb_book ;


c010c17eec194fea87db13e7b84c6bca.png


当在客户端一中释放锁指令 unlock tables 后 , 客户端二中的 select 语句 , 立即执行

cc837478789548b9a92ce4f17d0c317c.png


5.2.4 结论


锁模式的相互兼容性如表中所示:


3ad85dad0ba24d68aba226f6ce57cae6.png


由上表可见:


1) 对MyISAM 表的读操作,不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写请求;


2) 对MyISAM 表的写操作,则会阻塞其他用户对同一表的读和写操作;


简而言之,就是读锁会阻塞写,但是不会阻塞读。而写锁,则既会阻塞读,又会阻塞写。


此外,MyISAM 的读写锁调度是写优先,这也是MyISAM不适合做写为主的表的存储引擎的原因。因为写锁后,其他线程不能做任何操作,大量的更新会使查询很难得到锁,从而造成永远阻塞。


5.2.5 查看锁的争用情况


show open tables;


acf59a9290ea4522a4a184586fc6af39.png


In_user : 表当前被查询使用的次数。如果该数为零,则表是打开的,但是当前没有被使用。


Name_locked:表名称是否被锁定。名称锁定用于取消表或对表进行重命名等操作。


show status like 'Table_locks%';


987ec44d97d84f5b864e9acde5276fbe.png


Table_locks_immediate : 指的是能够立即获得表级锁的次数,每立即获取锁,值加1。


Table_locks_waited : 指的是不能立即获取表级锁而需要等待的次数,每等待一次,该值加1,此值高说明存在着较为严重的表级锁争用情况。


5.3 InnoDB 行锁


5.3.1 行锁介绍


行锁特点 :偏向InnoDB 存储引擎,开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。


InnoDB 与 MyISAM 的最大不同有两点:一是支持事务;二是 采用了行级锁。


5.3.2 背景知识


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
SQL 关系型数据库 MySQL
MySQL 锁
MySQL里常见的几种锁
53 3
|
2月前
|
存储 关系型数据库 MySQL
优化 MySQL 的锁机制以提高并发性能
【10月更文挑战第16天】优化 MySQL 锁机制需要综合考虑多个因素,根据具体的应用场景和需求进行针对性的调整。通过不断地优化和改进,可以提高数据库的并发性能,提升系统的整体效率。
71 1
|
2月前
|
关系型数据库 MySQL Java
MySQL数据锁:Record Lock,Gap Lock 和 Next-Key Lock
本文基于 MySQL 8.0.30 版本及 InnoDB 引擎,深入解析三种行锁机制:记录锁(Record Lock)、间隙锁(Gap Lock)和临键锁(Next-key Lock)。记录锁锁定索引记录,确保事务唯一修改;间隙锁锁定索引间的间隙,防止新记录插入;临键锁结合两者,锁定范围并记录自身,有效避免幻读现象。通过具体示例展示了不同锁的作用机制及其在并发控制中的应用。
152 2
|
2月前
|
存储 关系型数据库 MySQL
MySQL数据库锁:共享锁和独占锁
本文详细介绍了`InnoDB`存储引擎中的两种行级别锁:共享锁(S锁)与排他锁(X锁)。通过具体示例展示了这两种锁的工作机制及其在`InnoDB`与`MyISAM`引擎中的表现差异。文章还提供了锁的兼容性矩阵,帮助读者更好地理解锁之间的互斥关系。最后总结了两种锁的特点及适用场景。适合希望深入了解`MySQL`并发控制机制的读者阅读。
59 1
|
3月前
|
监控 关系型数据库 MySQL
MySQL锁机制与解决死锁问题
MySQL锁机制与解决死锁问题
299 5
|
2月前
|
存储 关系型数据库 MySQL
MySQL锁,锁的到底是什么?
【10月更文挑战第16天】MySQL 锁锁定的是与数据和资源相关的对象,其目的是为了保证数据的一致性、避免冲突,并在并发环境下合理协调事务或操作的执行。理解锁的对象和意义对于优化数据库性能、处理并发问题至关重要。
63 0
|
2月前
|
关系型数据库 MySQL 数据库
mysql锁详解
通过理解并合理运用MySQL中的锁机制,开发者可以有效管理数据库并发访问,平衡性能与数据一致性需求。更多关于MySQL锁的深入探讨和最佳实践,请参考专业的数据库管理资源[[深入MySQL锁机制详解
40 0
|
3月前
|
关系型数据库 MySQL 数据库
Mysql的锁
本文介绍了MySQL中表级锁和行级锁的区别,其中MyISAM仅支持表级锁,而InnoDB支持表级锁和行级锁,默认为行级锁。表级锁锁定整个表,实现简单,资源消耗少,但并发度低;行级锁仅锁定相关记录,减少冲突,提高并发度,但加锁开销大。此外,还介绍了共享锁和排他锁的概念及意向锁的作用。
|
3月前
|
存储 SQL 关系型数据库
MySQL 的锁机制,那么多的锁,该怎么区分?
MySQL 的锁机制,那么多的锁,该怎么区分?
43 0
|
4月前
|
关系型数据库 MySQL 数据库
MySQL MVCC和间隙锁有什么区别?
【8月更文挑战第24天】MySQL MVCC和间隙锁有什么区别?
105 0
下一篇
无影云桌面