MYSQL加锁的测验

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介:  存储引擎  支持的锁定级别  myisam      表级别  memory     表级别    inndb       行级别   bdb:        页级别    lock锁定类型  锁定方式            目的  读锁                   自己与其他线程只能读取该表   写锁                  只有当前线程能够对表进行写入操作(其他线程也无法读这部分数据)     读锁的英文叫法是shared locks,shared是共享的意思,共享锁,就是所有用户都可以共享进行读(包括加锁的用户),不能写。

 

 存储引擎  支持的锁定级别 

myisam      表级别 

memory     表级别 

  inndb       行级别 

 bdb:        页级别 

 

lock锁定类型

 锁定方式            目的

 读锁                   自己与其他线程只能读取该表

  写锁                  只有当前线程能够对表进行写入操作(其他线程也无法读这部分数据)

 

 

读锁的英文叫法是shared locks,shared是共享的意思,共享锁,就是所有用户都可以共享进行读(包括加锁的用户),不能写。

 

写锁的英文叫法是Exclusive Locks,Exclusive是独有、排外的意思,只有自己(加锁的用户)才能进行些写入操作,其他用户只能读。有些书籍中有不同叫法,比如互斥锁、排他锁。

 

纠正一下:以前理解错误了。加了排他锁定,其他事务是无法读取数据的。网上的资料比较零散。

最近看了jim Gray那本《事务处理概念与技术》,里面提到排他锁时:保留对该节点写的权利,防止其他事务在该节点及其后代节点加{x,u,s,six,is,ix}锁。

 

提到的s就是共享锁了,既然防止其他事务加s锁,那么其他线程是无法读的(所有线程获取数据之前必须先申请锁才能操作)。文章下面加的试验也会证明了这点。

 

ps:看来总结也好,加深了理解,如果不总结,也不会发现细节理解偏差。

 

 

 测试一:测验读锁

 运行一个读锁:“lock table `cat` READ”

然后尝试使用update语句操作 :

update `cat` set remark= 'ceshi'

 

报错如下:

 

Table 'a' was locked with a READ lock and can't be updated

现在解锁(针对当前线程锁定的所有表解锁):"unlock tables" 

 

然后再次运行update语句,报错消失。完成更新操作。说明已经解除读锁了(可以进行更新) 

 

 测验二:测验写锁 

1、 我在一个客户端SQLyog中运行一个写锁sql:LOCK TABLE cat WRITE;

2、另外开一个客户端(线程),尝试运行更新:

update `cat` set remark= 'jgjgjg'

 

情况:因为使用了写锁,只有自己能够修改数据,其他线程无法执行update操作,此时服务器端的php程序一直等待数据库给予响应结果,数据被锁定了,根本没法执行sql语句,处于等待中,数据库并不会报错,因为这本来就是一个很正常的情况,需要等待释放锁才能执行update操作,其实大并发环境下就是这种情况(很多用户同时在执行sql操作,有的加了写锁定),于是速度就慢下来了。

结果phpmyadmin一直处于等待中,等待服务器给予客户端(浏览器)数据,截图如下:

 

 

 

 经验:使用phpmyadmin无法模拟出一个线程的情况。因为每次php运行完毕后,与数据库的连接就会自动断开(php脚本特性)。

而SQLyog这样的工具能够保持连接不断掉。所以,测验写锁的时候完全可以使用同一个工具测验出来。

 

 

 增加测验:测验加写锁后,其他事务无法读数据的情况

同样也是在SQLyog这样的工具中运行:LOCK TABLE cat WRITE

 

因为加了x锁后,其他事务是无法获得s锁,所以根本无法读数据。phpmyadmin这边查询这个表,都是等待状态。

 

 

 

 下面我在SQLyog释放掉写锁后,phpmyadmin这边就能读取数据了

 

 

 

 

 

 

 

 

 

 

 

 

InnoDB使用行锁定,BDB使用页锁定。对于这两种存储引擎,都可能存在死锁。这是因为,在SQL语句处理期间,InnoDB自动获得行锁定和BDB获得页锁定,而不是在事务启动时获得。

 

update语句默认比select语句优先权高。可以修改,在启动mysql的时候加上参数,用--low-priority-updates启动mysqld 

 

 

在大流量、大数量的网站,往往瓶颈不在于具体的语言,其实.net、java、php等语言速度的差别是有,但是很小,忽略不计。往往瓶颈在于数据库。我是这样理解:

 


$conn->query("update where ....");

...php其他代码

 

//php需要等待数据库(比如mysql)给予返回结果,才能继续往下面执行代码,但里mysql被锁定了,一直没有执行完毕。所以卡死了,一直在等待中。这就是为什么语言不是瓶颈,瓶颈往往在数据库(数据量大的时候,数据库压力很大),这就是同步执行,需要等到上面代码执行完毕才能继续执行,以前听过阿里巴巴的分享,使用一种异步执行方案。并行加载数据,那么代码的执行耗时取决于最耗时的操作(因为所有操作都是并行开始运行)



 

其他测验办法:还可以开多个mysql命令行界面来测验。每个界面就是一个session。

 

 

 

 

 

关于大表查询少用left join的原因

进行select查操作,加的是共享锁(对整个表还是对行,要看什么存储引擎)。共享锁,则其他线程只能读数据。那么insert,update操作就会阻塞,等待select操作完成后释放掉共享锁后,这些线程才能进行写数据操作。

如果使用left join进行关联查询,一张表的数据量大,就会导致copyingd table操作了,意思是要先复制一张临时表,在临时表上面进行计算操作。这个时间比较长,就会阻塞掉其他线程的写入操作,一直处在等待状态。需要进行写入的线程越多,那么越多的线程等待。

 

解决办法是:要迅速的查询,拆分成多步骤来操作,这样就算是加读锁的时候,也是针对当前操作的表。操作释放后,可以快速的释放掉锁。

 

我想到用现实生活中哲学来理解:一次干多件事情,当然是爽,但是非常揪心,搞的复杂,影响的面广,大面积的受到影响。如果拆分成小部分,一次干一小部分,那么受到影响的面积小。逐个逐个来分解任务。

 

在实际场景中,left join导致的阻塞其他线程的写操作的场景,刚好被我遇到了:

 

上面是show processlist命令查看出来的,这个命令可以查看mysql当前有哪些查询线程,会列出查询的语句出来。

 

上面情况显示,好几个insert操作被阻塞掉,一直在延迟,time项如果我没理解错的话,就是已经等待了这么多秒数了。

信息显示:waiting for table level lock。更新操作需要先获取锁(myisam存储引擎只支持表级别的锁,所以先获取表锁)。

 

 

问:到底是什么情况导致无法获取表锁?

肯定是其他线程在对别加了锁,一直没有执行完毕。从下面这张图能看出是什么原因:

显示的状态栏表示Coping to tmp table,正在将数据复制到临时表(tmp table)。左侧显示是查询语句,是left join。

貌似进入死锁状态了,a想要获取表的锁,才能继续操作。b线程也要获取,但是有个线程一直没有释放掉。

 

什么情况下会出现 copying to tmp table的操作呢?

有英文这样解释:

Copying to tmp table on disk The temporary result set was larger than tmp_table_size and the thread is now changing the in memory-based temporary table to a disk based one to save memory.

 

临时结果比tmp_table_size(这是一个内存缓存区)要大,存不下了,就会保持到磁盘去。

方案:

1、可以考虑把这个myisam存储引擎调整为innodb,innodb就支持行锁。

 

2、但是我觉得本质还是要减少left join查询,需要这样查询,拆分成多条sql,分步骤来执行会更好。

 

在互联网的应用结构中。联表查询,还是要慎重,因为数据库是共享资源,很多应用程序都要来访问。一旦一个线程锁定数据表了,就会造成其他线程操作数据被阻塞了。

 

所以思想是尽量快速完成查询。传统的数据库开发中使用复合查询,尽量一条sql可以完成很多事情的思想。在互联网是不要这样子做。

 

拆分成多条sql进行查询,应用程序编码还是增加了很多复杂度,本来一条sql丢入到query($sql)中就完成,现在要分成多个步骤。程序员会觉得麻烦。

不过,为了性能优化,是要这样子。数据库资源毕竟有限。有时候程序员调整一下思路,对于数据库压力的缓解是很大的。

 

 

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
1月前
|
SQL 关系型数据库 MySQL
MySQL底层概述—10.InnoDB锁机制
本文介绍了:锁概述、锁分类、全局锁实战、表级锁(偏读)实战、行级锁升级表级锁实战、间隙锁实战、临键锁实战、幻读演示和解决、行级锁(偏写)优化建议、乐观锁实战、行锁原理分析、死锁与解决方案
105 24
MySQL底层概述—10.InnoDB锁机制
|
1月前
|
关系型数据库 MySQL 网络安全
如何排查和解决PHP连接数据库MYSQL失败写锁的问题
通过本文的介绍,您可以系统地了解如何排查和解决PHP连接MySQL数据库失败及写锁问题。通过检查配置、确保服务启动、调整防火墙设置和用户权限,以及识别和解决长时间运行的事务和死锁问题,可以有效地保障应用的稳定运行。
139 25
|
5月前
|
SQL 关系型数据库 MySQL
MySQL 锁
MySQL里常见的几种锁
91 3
|
2月前
|
存储 关系型数据库 MySQL
MySQL进阶突击系列(06)MySQL有几种锁?| 别背答案,现场演示一下
本文详细解析了MySQL InnoDB存储引擎的锁机制,涵盖读锁、写锁、意向锁、记录锁、间隙锁和临键锁等8种锁类型。重点探讨了不同锁类型的加锁与释放方式,以及事务并发场景下的实战验证。通过具体示例,展示了在不同情况下锁的行为及其对事务的影响。文章还特别强调了锁的作用范围主要是索引,并解释了锁如何影响数据的读写操作。最后总结了并发事务中加锁规则,帮助读者深入理解MySQL的锁机制。
|
5月前
|
存储 关系型数据库 MySQL
优化 MySQL 的锁机制以提高并发性能
【10月更文挑战第16天】优化 MySQL 锁机制需要综合考虑多个因素,根据具体的应用场景和需求进行针对性的调整。通过不断地优化和改进,可以提高数据库的并发性能,提升系统的整体效率。
360 1
|
5月前
|
关系型数据库 MySQL Java
MySQL数据锁:Record Lock,Gap Lock 和 Next-Key Lock
本文基于 MySQL 8.0.30 版本及 InnoDB 引擎,深入解析三种行锁机制:记录锁(Record Lock)、间隙锁(Gap Lock)和临键锁(Next-key Lock)。记录锁锁定索引记录,确保事务唯一修改;间隙锁锁定索引间的间隙,防止新记录插入;临键锁结合两者,锁定范围并记录自身,有效避免幻读现象。通过具体示例展示了不同锁的作用机制及其在并发控制中的应用。
630 2
|
5月前
|
存储 关系型数据库 MySQL
MySQL数据库锁:共享锁和独占锁
本文详细介绍了`InnoDB`存储引擎中的两种行级别锁:共享锁(S锁)与排他锁(X锁)。通过具体示例展示了这两种锁的工作机制及其在`InnoDB`与`MyISAM`引擎中的表现差异。文章还提供了锁的兼容性矩阵,帮助读者更好地理解锁之间的互斥关系。最后总结了两种锁的特点及适用场景。适合希望深入了解`MySQL`并发控制机制的读者阅读。
236 1
|
6月前
|
监控 关系型数据库 MySQL
MySQL锁机制与解决死锁问题
MySQL锁机制与解决死锁问题
451 5
|
5月前
|
存储 关系型数据库 MySQL
MySQL锁,锁的到底是什么?
【10月更文挑战第16天】MySQL 锁锁定的是与数据和资源相关的对象,其目的是为了保证数据的一致性、避免冲突,并在并发环境下合理协调事务或操作的执行。理解锁的对象和意义对于优化数据库性能、处理并发问题至关重要。
190 0
|
5月前
|
关系型数据库 MySQL 数据库
mysql锁详解
通过理解并合理运用MySQL中的锁机制,开发者可以有效管理数据库并发访问,平衡性能与数据一致性需求。更多关于MySQL锁的深入探讨和最佳实践,请参考专业的数据库管理资源[[深入MySQL锁机制详解
132 0