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

本文涉及的产品
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: 【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 背景知识


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
10月前
|
SQL AliSQL 关系型数据库
MYSQL的全局锁和表锁
本文介绍了MySQL中的锁机制,包括全局锁、表级锁及其应用场景。全局锁通过`Flush tables with read lock (FTWRL)`实现,主要用于全库逻辑备份,但会阻塞更新和结构变更操作。表级锁分为显式表锁(`lock tables`)和元数据锁(MDL),前者用于控制并发访问,后者自动加锁以确保读写正确性。文章还探讨了如何安全地为小表添加字段,建议通过设置DDL等待时间或使用MariaDB/AliSQL的NOWAIT/WAIT功能避免业务阻塞。这些方法有助于在高并发场景下优化数据库性能与安全性。
276 0
|
SQL 关系型数据库 MySQL
MySQL 锁
MySQL里常见的几种锁
284 3
|
关系型数据库 MySQL 网络安全
如何排查和解决PHP连接数据库MYSQL失败写锁的问题
通过本文的介绍,您可以系统地了解如何排查和解决PHP连接MySQL数据库失败及写锁问题。通过检查配置、确保服务启动、调整防火墙设置和用户权限,以及识别和解决长时间运行的事务和死锁问题,可以有效地保障应用的稳定运行。
467 25
|
存储 关系型数据库 MySQL
MySQL进阶突击系列(06)MySQL有几种锁?| 别背答案,现场演示一下
本文详细解析了MySQL InnoDB存储引擎的锁机制,涵盖读锁、写锁、意向锁、记录锁、间隙锁和临键锁等8种锁类型。重点探讨了不同锁类型的加锁与释放方式,以及事务并发场景下的实战验证。通过具体示例,展示了在不同情况下锁的行为及其对事务的影响。文章还特别强调了锁的作用范围主要是索引,并解释了锁如何影响数据的读写操作。最后总结了并发事务中加锁规则,帮助读者深入理解MySQL的锁机制。
|
存储 关系型数据库 MySQL
优化 MySQL 的锁机制以提高并发性能
【10月更文挑战第16天】优化 MySQL 锁机制需要综合考虑多个因素,根据具体的应用场景和需求进行针对性的调整。通过不断地优化和改进,可以提高数据库的并发性能,提升系统的整体效率。
794 1
|
关系型数据库 MySQL Java
MySQL数据锁:Record Lock,Gap Lock 和 Next-Key Lock
本文基于 MySQL 8.0.30 版本及 InnoDB 引擎,深入解析三种行锁机制:记录锁(Record Lock)、间隙锁(Gap Lock)和临键锁(Next-key Lock)。记录锁锁定索引记录,确保事务唯一修改;间隙锁锁定索引间的间隙,防止新记录插入;临键锁结合两者,锁定范围并记录自身,有效避免幻读现象。通过具体示例展示了不同锁的作用机制及其在并发控制中的应用。
1410 2
|
存储 关系型数据库 MySQL
MySQL数据库锁:共享锁和独占锁
本文详细介绍了`InnoDB`存储引擎中的两种行级别锁:共享锁(S锁)与排他锁(X锁)。通过具体示例展示了这两种锁的工作机制及其在`InnoDB`与`MyISAM`引擎中的表现差异。文章还提供了锁的兼容性矩阵,帮助读者更好地理解锁之间的互斥关系。最后总结了两种锁的特点及适用场景。适合希望深入了解`MySQL`并发控制机制的读者阅读。
583 1
|
存储 关系型数据库 MySQL
MySQL锁,锁的到底是什么?
【10月更文挑战第16天】MySQL 锁锁定的是与数据和资源相关的对象,其目的是为了保证数据的一致性、避免冲突,并在并发环境下合理协调事务或操作的执行。理解锁的对象和意义对于优化数据库性能、处理并发问题至关重要。
407 0
|
关系型数据库 MySQL 数据库
mysql锁详解
通过理解并合理运用MySQL中的锁机制,开发者可以有效管理数据库并发访问,平衡性能与数据一致性需求。更多关于MySQL锁的深入探讨和最佳实践,请参考专业的数据库管理资源[[深入MySQL锁机制详解
290 0
|
存储 SQL 关系型数据库
MySQL 的锁机制,那么多的锁,该怎么区分?
MySQL 的锁机制,那么多的锁,该怎么区分?
231 0

推荐镜像

更多