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

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 【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 背景知识


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
SQL 存储 关系型数据库
【MySQL 数据库】11、学习 MySQL 中的【锁】
【MySQL 数据库】11、学习 MySQL 中的【锁】
76 0
|
2月前
|
SQL 关系型数据库 MySQL
【MySQL】一文带你搞懂MySQL中的各种锁
【MySQL】一文带你搞懂MySQL中的各种锁
60 0
|
2月前
|
存储 SQL 关系型数据库
MySQL - 深入理解锁机制和实战场景
MySQL - 深入理解锁机制和实战场景
|
1月前
|
存储 关系型数据库 MySQL
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
174 0
|
2月前
|
SQL 关系型数据库 MySQL
Mysql事务隔离级别和锁特性
Mysql事务隔离级别和锁特性
|
6天前
|
关系型数据库 MySQL 索引
MySQL 锁机制
MySQL 锁机制
7 0
|
14天前
|
关系型数据库 MySQL 数据库
MySQL锁三部曲:临键、间隙与记录的奇妙旅程
MySQL锁三部曲:临键、间隙与记录的奇妙旅程
18 0
|
1月前
|
SQL 关系型数据库 MySQL
MySQL中的锁(简单)
MySQL中的锁(简单)
|
2月前
|
存储 关系型数据库 MySQL
mysql的锁机制实现原理
mysql的锁机制实现原理
|
2月前
|
存储 关系型数据库 MySQL
mysql锁的应用
mysql锁的应用