行锁与行锁出现的问题

记一次Cat监控longSql时间过长问题(mysql慢查询机制) 起因:生产监控使用cat监控服务性能,记录longsql 1000ms 语句很简单update table set field='1' where fieldb='any';(字段b有索引) 将语句单独拿出来在测试环境执存在慢的问题,将生产slowlog拿下来也没有发现有记录该语句,对应同事沟通发现存在longsql的语句对应的feildb都是某业务条件下同一时间存在更新频率很高的情况估计有一两百次。所以怀疑是同一时间更新mysql等待导致。另外了解到慢sql记录并记录获取的时间,而cat监. 阅读详情

 1.疯狂的“独占”行锁

 

原文地址:
http://www.brokenwire.net/bw/Programming/115/the-madness-of-exclusive-row-locks


译文:
昨天我发现了SQL SERVER一些确实很怪异的行为。我有一个案例我竟然可以读取被其他会话置了“独占”锁的记录。看到“独占”这个词,你想到的一定是:一个事务拥有独占行锁那么其它事务就不能读取该行了。但是这有特例:你可以读取被其它被别人独占锁定的行。
它花了我和同事很多时间,最终才发现到底是怎么回事。

为了重现这种行为,你需要一个测试表,表里有一些随机数据。

CREATE TABLE [MyTable]
 ([Col1] bigint PRIMARY KEY CLUSTERED, [Col2] bigint)
INSERT INTO [MyTable] ([Col1], [Col2]) VALUES (1,10)
INSERT INTO [MyTable] ([Col1], [Col2]) VALUES (2,20)
INSERT INTO [MyTable] ([Col1], [Col2]) VALUES (3,30)
INSERT INTO [MyTable] ([Col1], [Col2]) VALUES (4,40)
INSERT INTO [MyTable] ([Col1], [Col2]) VALUES (5,50)

只要数据库没有打开快照隔离,你可以将测试表放在任何数据库中,而且恢复模式也对它没有影响。
下面我们来运行一些查询,看看会发生什么。为了能正确地测试,你需要对同一测试表运行两个不同的会话。为了能一直持有已分配的锁,你需要启动一个事务、运行一些命令,但是千万不要结束事务。
首先在查询分析器的第一个窗口中(我们称之为会话1)查询表中的某一行,并且使用提示XLOCK和ROWLOCK获得一个独占的行锁。
会话 1:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
BEGIN TRAN
SELECT Col1 FROM [MyTable] WITH (XLOCK, ROWLOCK) WHERE [Col1] = 3

为了核实锁的情况,我们运行sp_locks来看看到底为会话1授予了哪些锁:

spid   dbid   ObjId       IndId  Type Resource                   Mode     Status
------ ------ ----------- ------ ---- -------------------------------- --------    ------
56     21     69575286    1      PAG  1:41                              IX       GRANT
56     21     69575286    1      KEY  (030075275214)           X        GRANT
56     21     69575286    0      TAB                                       IX       GRANT

 

你可以看到有一个“X”(独占)锁在表的第一个键上。(其他的锁是“IX”意向锁)。现在开始第2个连接,看看如果要读这条记录会发生什么?
会话 2:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
BEGIN TRAN
SELECT Col1 FROM [MyTable] WHERE [Col1] = 3

我很希望这条语句被“挂住”,一直等到这条记录有效为止。但我吃惊地发现这条记录可以被非常顺利的读出。同时,sp_locks显示系统没有为这条指令分配任何其他锁,即使一个共享锁也没有。

如果你回滚会话2(为了撇清所有其它可能的情况)然后用表提示HOLDLOCK重新执行就会得到你想要的结果了:会话2中现在需要等待会话1中的事务完成了。

为了理解所发生的事,你需要回忆一下读提交隔离级别中的一条规则:可以读任何已经被提交的行。这里我们读的行时“干净的”(它没有被系统标为“脏的”),此时系统优化器会决定可以直接通过索引取数据而不需要检查锁的情况,所以表中甚至都不需要主键,只要有索引包含请求的数据,行锁就不需要了。

所以如果被锁住的记录并没有变化,被请求的列包含在索引中,那么从READ COMMITTTED隔离级别上就独占锁可能就没什么用了。

一种解决方法是在会话2的SELECT上加“HOLDLOCK”表提示。或者你也可以真的在会话1中更新记录,这样该记录就拥有独占锁了(而且还被标为“脏的”)。还有一种解决方法是用PAGLOCK锁住整个也而不仅仅是一行,此时独占锁会锁住该页中的所有行。

网上有人发了一篇帖子 讲述了同样的怪异行为,一个微软员工回复道:
“在SELECT语句中使用XLOCK并不能阻止读。这是因为SQL SERVER在读提交隔离级别上有一种特殊的优化,即检查行是否已被修改,如果未被修改则忽略XLOCK。因为在读提交隔离级别上这确实是可以接受的。”

可能最糟糕的事是没能在联机图书上找到这种行为。哪怕在section about table hints 中能有一个小小的说明也是好的。知识库KB324417 中(适用于SQL SERVER 2000)只有一点点的提示。综合上面所有的事实,优化器选择这种行为比较随便,因此你的SQL代码中的BUG是很难被发现的。


结论:
这花了我很多时间来找出到底发生了什么事。所以记住:在SELECT语句中使用XLOCK和ROWLOCK提示并不意味着只有你一个人能读这些数据行。

 

 

2.UPDATE 时, 如何避免数据定位处理被阻塞

 

问题描述:

数据库PUBS中的authors表,想锁定CITY为aaa的记录,为什么执行下面的命令后,CITY为bbb的记录也被锁定了,无法进行UPDATE.

BEGIN TRANSACTION    

    SELECT * FROM authors

    WITH (HOLDLOCK)

    WHERE city='aaa'

如何才能锁定CITY为AAA的记录,而且CITY为BBB的记录依然能SELECT和UPDATE?

 

问题分析:

应该不是被锁住,应该只是检索数据的时候,需要从aaa的记录扫描到bbb的记录,而aaa被锁住了,所以扫描无法往下进行,这样看起来似乎就是bbb也被锁住了。

当然,也有可能确实是被锁住了,SQL Server的锁定默认是行级的,如果你的资源不足,则可能导致锁自动升级为页级甚至表级锁,这样会导致更多的记录被锁定。

使用下面的语句, 如果能读出数据, 则多半是第1种情况.

SELECT *

FROM authors WITH (READPAST)

WHERE city='bbb'

如果读不出数据, 则一般是第2种情况.

 

问题解决方法:

让SELECT 和UPDATE 走不同的索引,这样在UPDATE 的时候,不用扫描已经锁定的数据就可以定义到记录,UPDATE 也就不会被阻塞了

指定索引用类似下面的语句:

SELECT *

FROM authors WITH (HOLDLOCK, INDEX=索引名)

WHERE city='aaa'

 

UPDATE A SET

    xx = xx

FROM authors A WITH (INDEX=索引名)

WHERE city='bbb'

当然,要保证仅扫描索引就可以定义到记录,否则可能还是会被阻塞。

  

补充

对于熟悉SQL Server锁的读者,可以通过 sp_lock,或者查询系统表 master.dbo.syslocks、master.dbo.syslockinfo来确定行为。

 

 

git连接华为软件开发云 我用的是github客户端的git shell 连接。用git bash也可以github客户端下载地址:https://desktop.github.com/1.在华为软件开发云上创建代码仓库2.在本地创建密钥SSH密钥帮助文档公钥是代码托管服务(CodeHub)识别您的用户身份的一种认证方式,通过公钥,您可以将本地git项目代码托管服务(CodeHub)建立联系, 然后您就可以很方便的将本地... 阅读详情

相关推荐

基于形状的模板匹配之候选点选择

基于形状的匹配匹配,顶层金字塔提取候选点

manuoo的专栏 2700

疯狂的“独占”

疯狂的“独占” 原文地址: http://www.brokenwire.net/bw/Programming/115/the-madness-of-exclusive-row-locks 相关阅读:(2011-10-13) 消失的共享 译文:

misterliwei的专栏 2555

Lada-马赛克去除工具Python 源码

Lada-马赛克去除工具 一款恢复像素化或马赛克区域视频质量的软件,通过使用先进的算法,能够有效地修复视频中的模糊区域,使其视觉效果更加清晰和可观看。可以通过图形用户界面或命令界面来操作软件,观看或导出恢复后的视频。

数据库 悲观| 乐观 (关系到事物)

数据库的并发问题:什么是高并发:高并发是指:在同一时间有很多人执一个操作例如:在某个时间段,同时有2个用户A和B要购买火车票,在购买火车票前比如要查询下火车票数据库是否有票,是会有一个查询的操作 select * from chepiao where chepiaoCount>0 如果查询到还有火车票的时候,就会下订单,于是就会下订单,下订单就是将数据库的车票数量减1Update che...

Fanbin168的专栏 944

MSSql数据库

在使用MSSql的时候,在多用户的情况下免要进并发控制。微软提供了机制。这里分为两个部分,一个是的范围(、页面、表),另一个是的粒度(共享、持有等)在定数据的时候要配合的范围和粒度。例如 select * from Table with(RowLockXLock) where ID=1 就可以将Table的一设置独占。一般情况下在事务的开始可以先使用U

henreash的专栏 7608

SQL Server中的 详解 nolock,rowlock,tablock,xlock,paglock

SQL Server中的 详解 nolock,rowlock,tablock,xlock,paglock 摘自: http://www.myexception.cn/sql-server/385562.html 高手进 nolock,rowl...

weixin_30384217的博客 849

第七讲总结 MySQL 深度剖析:原理、问题优化策略

MySQL

KELLENSHAW的博客 1141

mysql内部_MySQL 深入研究(的内部优化问题

做项目时由于业务逻辑的需要,必须对数据表的一或多加入,举个最简单的例子,图书借阅系统。假设id=1的这本书库存为1,但是有2个人同时来借这本书,此处的逻辑为Selectrestnumfrombookwhereid=1;--如果restnum大于0,执updateUpdatebooksetrestnum=restnum-1wh...

weixin_28984379的博客 147

mysql问题分析,表的原因

文章目录1. 死是怎样产生的?2. 死解决方案3. 表的现象和原因 准备工作,建一张表 CREATE TABLE `testtable` ( `id` bigint NOT NULL AUTO_INCREMENT, `name` varchar(500) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '名字', `age` int DEFAULT NULL COMMENT '年龄', `id_card` int NOT NULL

qq_1149513559的博客 3172

开发项目时遇到的横向越权、事务的关联区别、超卖问题

首先需要明确,乐观可以是,也可以是一种思想。乐观的思想是,仅在非读操作的情况下进检测加。也就是” 先,假设会发生冲突;在写入前检测是否有冲突,若检测到冲突则重试或报错 “对应的悲观思想就是在操作之前进。比如在解决超卖问题,读写分离时可以新建一个version列:进读:读出当前version进写:判断写时的version是否是读时的version,如果是,则重试或者报错。

Hellyc的博客 695

Oracle - 机制详解,解决阻塞问题

Oracle 的机制,是其四十年工程智慧的结晶。它追求“简单易懂”,而致力于“绝对可靠”。敬畏意识:每一UPDATE都是一把隐形的,它响,却能拖垮整个系统。可观测意识:在应用中埋点,在关键路径打印,让为“看得见”。协同意识: DBA 建立联合巡检机制,每月 Review中等等待事件 Top 10,将治理纳入 DevOps 流水线。“好的策略,是消灭,而是让成为可预测、可计量、可调度的基础设施资源。

千淘万漉虽辛苦,吹尽狂沙始到金 1万+

开发易忽视的问题:InnoDB 设计实现

【代码】开发易忽视的问题:InnoDB 设计实现。

IT枫斗者的博客 2058

InnoDB②:算法问题

InnoDB存储引擎使用3种的算法: Record Lock:单个记录上的 Gap Lock:间隙定一个范围 Next-key Lock:Gap Lock+Record Lock 定本身以及下一个范围 InnoDB对的查询采取Next-key Lock算法。 例如,包含索引10 11 13 20 采取Next-key Lock方式,定的区间为: (10,11】 (11,13】 (13,20】 插入新的记录12后: (10,11】 (11,12】 (1...

一只老风铃 187

MySQL 问题排查实战:批量更新脚本「卡住」 1205 超时(MDL / 完整复盘)

以 UAT 环境 1094 条品类税率批量更新为例,复盘 DROP TABLE 元数据卡住、UPDATE 1205 超时两类问题,详解 innodb_trx、Holder/Waiter 排查思路分批 UPDATE 改造方案。

heyongjin22的博客 258

有关数据库 的几个问题rowlock

的基本说明: SELECTau_lnameFROMauthorsWITH(NOLOCK)定提示 描述HOLDLOCK 将共享保留到事务完成,而是在相应的表、或数据页再需要时就立即释放。HOLDLOCK 等同于SERIALIZABLE。...

aikenqiu5098的博客 209

【MySQL】 ---- 共享、独占、表

共享、独占、表

TheWhc 1127

SQL2008 使用RowLock

一直有个疑问,使用 select * from dbo.A with(RowLock) WHRE a=1 这样的语句,系统是什么时候释放呢?? 经过官方文档考证后,原来 RowLock使用组合的情况下是没有任何意义的,所谓“解铃还须系铃人~” With(RowLock,UpdLock) 这样的组合才成立,查询出来的数据使用RowLock定,当数据被Updat

张国富的专栏 2989

SQL ServerROWLOCK

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34341229的博客 700
上一篇: SQLServer和ORACLE 存储过程的调用(返回结果集)
下一篇: Oracle游标
siegebaoniu
博客等级 码龄18年 50粉丝 22原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值