mysql加锁处理分析_MySQL 加锁处理分析 ---非常牛逼
工作需要,接触到以下两个mysql sql语法:
select lock in share mode
select for update
1
2
从官网上查找到对应的章节,属于Locking Reads里面的内容,具体链接如下:
根据官网介绍,这两个语句是在事务内起作用的,所涉及的概念是行锁。它们能够保证当前session事务所锁定的行不会被其他session所修改(这里的修改指更新或者删除)。两个语句不同的是,一个是加了共享锁而另外一个是加了排它锁。可以这么理解,共享锁允许其他事务加共享锁读取,但是,不允许其他事务去做修改,或者加排它锁。而排它锁显得更加严格,不允许其他事务加共享锁或者排它锁,更加不允许其他事务修改加锁的行。
说到这里,行锁有什么用呢?设想下面这种场景:
1) 读取一行数据
2) 根据读取到的数据去更新其他数据
假设在1)和2)之间,有个其他的user session刚好修改了你读取的那行数据,那么你下面的更新就有可能会出错!因为关联的数据产生了变化!
行锁就能够保证不会出现上面所说的这种尴尬的场景。
实践了一把,下面记录它们的用处:
测试用的表结构并插入一行记录:
use test;
create table tb_test (
id int primary key,
col1 varchar(20)
) engine = innodb default character set = 'utf8';
insert into tb_test(id, col1) values(1, 'AAA');
1
2
3
4
5
6
7
1. select lock in share mode
1.1 使用示例
session 1:
set autocommit = 0;
select * from tb_test where id = 1 lock in share mode;
1
2
open session 2:
update tb_test set col1 = 'BBB' where id = 1;
1
这个时候可以观察到session2处于blocking状态….
直到
session 1:
commit;
1
这个时候session2更新成功了。
这里也就验证了lock in share mode可以在事务中保证锁定的行不被其他session所更改。
1.2 注意死锁
使用lock in share mode具有很高的风险,看下面的案例:
session 1:
set autocommit = 0;
select * from tb_test where id = 1 lock in share mode;
1
2
open session2:
set autocommit = 0;
select * from tb_test where id = 1 lock in share mode;
1
2
这个时候两个session同时持有id = 1这行数据的共享锁。这个时候我们在session 1里面执行update操作:
session 1:
update tb_test set col1 = 'AAA' where id = 1;
1
卡住了!!!! ????
这个时候session1必须等待session2退出事务或者等待直到锁超时:
锁超时的情况:
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
如果我们在session 2里面执行:
session2:
update tb_test set col1 = 'BBB' where id = 1;
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
1
2
3
这个时候mysql检测到会发生死锁,会中断当前事务该语句的执行,重新开启一个新的事务(应该就是相当于session2先退出事务,然后再开启一个事务吧)。
这个时候session1可以更新成功了。
上面的例子可以看出使用lock in share mode比较危险,很可能因为其他session同时加了这种锁,导致当前session无法进行更新,进而阻塞住。
2. select for update
select for update加的是排它锁,所以没有上面lock in share mode所产生的死锁,因为一个session加了这种锁,其他session除了读取操作,其他操作都不能进行,如更改操作,或者加锁,共享锁和排它锁都不可以。
2.1 使用示例
下面演示一下用法:
session 1:
set autocommit = 0;
select * from tb_test where id = 1 for update;
1
2
open session 2:
update tb_test set col1 = 'BBB' where id = 1;
1
这个时候session 2处于blocking状态
我们手动kill掉session 2, 按Ctrl + C。
然后执行:
session 2:
set autocommit = 0;
select * from tb_test where id = 1 for update;
1
2
还是blocking状态,证明其他session的事务不能对已经加了排它锁(for update)的行再加排它锁。
kill掉,再来
session 2:
set autocommit = 0;
select * from tb_test where id = 1 lock in share mode;
1
2
还是blocking状态,证明其他session的事务不能对已经加了排它锁(for update)的行再加共享锁(lock in share mode)。
当然,如果使用select for update的时候,如果锁定当前行的事务一直不退出,将会导致其他进行这个行更改操作的session一直阻塞。(没有试是否有超时的情况)
2. 总结
因此,无论在使用select lock in share mode 或者 select for update,都应该尽快释放锁。
确实是这样的,LOCK IN SHARE MODE是读锁(只是不让别人写),FOR UPDATE是写锁(还不让别人加读锁),读锁升级成写锁是可能产生死锁的(但写锁降级成读锁则不会,我还真不知道MySQL如何对锁降级),所以程序中需要考虑超时的问题(或者重试或者放弃)。
所以大部分情况下都如果SELECT后接下来会有UPDATE动作的话,一般会用FOR UPDATE而不是LOCK IN SHARE MODE。
mysql加锁处理分析_MySQL 加锁处理分析 ---非常牛逼相关推荐
- linux mysql 释放x锁_MySQL 加锁处理分析-转载
背景 MySQL/InnoDB的加锁分析,一直是一个比较困难的话题.我在工作过程中,经常会有同事咨询这方面的问题.同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题.本文,准备 ...
- mysql udf提权_MySQL日志安全分析技巧
常见的数据库攻击包括弱口令.SQL注入.提升权限.窃取备份等.对数据库日志进行分析,可以发现攻击行为,进一步还原攻击场景及追溯攻击源. 0x01 Mysql日志分析 general query log ...
- 阿里云 mysql日志分析_mysql 慢日志分析-阿里云开发者社区
启用 slow log 有两种启用方式: 1, 在my.cnf 里 通过 log-slow-queries[=file_name] 2, 在mysqld进程启动时,指定--log-slow-queri ...
- mysql用户阻塞数_MySQL实例阻塞分析一例(线程statistics状态)
本文用实例来分析MySQL阻塞-线程statistics状态. 一. 现象 某日下午下班后低峰期,现网MySQL一个库突然报出大量慢sql,状态是 statistics,但是过后拿这些sql去执行的时 ...
- mysql 执行效率命令_MySQL优化--explain 分析sql语句执行效率
MySQL优化--explain 分析sql语句执行效率 explain 命令 explain 命令在解决数据库性能上市第一推荐使用命令,大部分的性能问题可以通过此命令来简单解决,explain可以用 ...
- mysql 慢日志可视化_Mysql 慢日志分析系统搭建 —— Box Anemometer
背景: 慢日志是分析定位问题的利器,但是在日常实际应用中,mysql自动生成的慢日志是杂乱无章的,不便于我们的使用. 这里介绍利用开源项目 Box Anemometer来搭建一个图形可视化的慢日志分 ...
- mysql启动失败分析_MySQL启动失败分析与解决
1, 背景 早上过来发现电脑非正常关机了,进mysql发现报错: mysql -uroot -p Enter password: ERROR 2002 (HY000): Can"t conn ...
- mysql源码分析_MySQL · 源码分析 · 词法分析及其性能优化
简介 MySQL 支持标准的 SQL 语言,具体实现的时候必然要涉及到词法分析和语法分析.早期的程序可能会优先考虑手工实现词法分析和语法分析,现在大多数场合下都会采用工具来简化实现.MySQL.Pos ...
- mysql insert执行过程_MySQL · 源码分析 · 一条insert语句的执行过程
本文只分析了insert语句执行的主路径,和路径上部分关键函数,很多细节没有深入,留给读者继续分析 create table t1(id int); insert into t1 values(1) ...
最新文章
- up 手环服务器不稳定,Up手环停产:曾经风光无限的Jawbone快不行了
- 开源自制6通道航模遥控器,Arduino Pro Mini NRF24L01模块
- LiveVideoStackCon 倒数计时:0
- 各种组件的js 获取值 / js动态赋值
- java utf8 转换al32utf8_java与Unicode
- static和extern的用法总结
- Python中表达式和语句及for、while循环练习
- mysql双一参数_MySQL 的双1设置-数据安全的关键参数(案例分享)
- mysql将一个表的字段更新到另一个表中
- Android开发:keytool' 不是内部或外部命令 也不是可运行的程序
- Servlet的原理和基础使用
- 盘点2017 CES展会所有亮眼黑科技 (上)
- libfacedetection 人脸检测库的基本使用
- 数据挖掘实战(9.5)--使用神经网络识别MINIST数据集
- 不安分的 android 开发者(小程序初尝试)
- halcon提取区域的拐点、折点
- 微商代理系统APP软件
- 正版office 2007 简体中文专业版(附正版序列号)高速下载正版office 2007 简体中文专业版...
- 数字图像处理(2)正交变换
- 深度学习之目标检测(一)—— 目标检测算法介绍
热门文章
- IT人的八大修炼神器
- Worktile荣登2020中关村国际前沿科技创新大赛大数据与云计算领域TOP10
- 适合小团队协作、任务管理和进度跟踪的项目管理工具
- C语言循环选择还有,C语言第五讲,语句 顺序循环选择.(示例代码)
- 以Lazada为例,看电商系统架构演进
- 4、题目要求:读入N名学生的成绩,将获得某一给定分数的学生人数输出。 * * 	输入格式:测试输入包含若干测试用例,每个测试用例的格式为 	第1行:N 	第2行:N名学生的成绩,相邻两数字用一个
- 《孤独是一个人的清欢》读书感悟
- C++中最好不要在构造函数和析构函数中调用虚函数!!!
- python 光标位置输入文字_Python 移动光标位置的方法
- 伦敦大学学院开源物体级语义SLAM!支持单/双目+LiDAR!