我在死锁分析中遇到了死点。根据msdn:
RangeX-X 为 Exclusive range,独占资源锁;在更新范围内的键时使用。RangeI-N 是插入范围,空资源锁;用于在将新键插入索引之前测试范围。
所以我明白,如果我在 2 个键列上有一个索引 - 并且我插入一个新键,我将拥有 RangeI-N 锁,但如果我从索引更新现有键,我将拥有 RangeX-X。
但我的问题或多或少复杂。假设我在 A、B 列和 C 列上有索引 IX_keys_included。
在 Serializable 隔离模式下,我为包含的列 C 插入一个新值。索引 IX_keys_included 是否会有 RangeI-N 或 RangeX-X 锁?实际上,鉴于我为索引中包含的列插入了一个新列,是否会有任何锁定?
我知道如何检查数据库是否处于锁定状态,但我的问题是如何找出导致表 /db 锁定的查询。
如果数据库发生意外情况,是否会创建任何日志文件?
大约每周一次,我必须解决 SQL Server 2005 数据库上的阻塞链,这是由 Access 2003 前端的长期读取锁引起的。每当用户打开某个表单时就会解除锁定,并在用户完成滚动表单或关闭表单后解除锁定。由于我们的许多用户打开此表单作为参考,因此这些锁会保留一段时间。对该表的任何更新都会导致阻塞,突然间没有人可以从该表中进行选择,因为他们都在等待第一个锁。这对我们来说是一个很大的问题,因为许多应用程序都依赖于这些数据。我知道这种锁定行为是 Access 如何处理链接表的一部分。
我一直在通过 Activity Monitor 解决这个问题,只要我发现它,就会杀死任何一个是 Head Blocker 的 SELECT 进程。这是一个问题,不仅因为我手动完成它需要时间,还因为它是被动的。当我听说它时,它已经成为很多人的问题。
我想知道是否有一种自动方法来检查这些持久的阻塞链,并通过电子邮件发送或自动解决问题。逻辑看起来很简单(“如果任何与此 SELECT 查询匹配的进程阻塞了超过一分钟,请通知我/杀死它”)但我不知道如何使用 SQL Server 实现这一点。
对于它的价值,我认为正确的解决方案是修复或重写应用程序。然而,由于部门政治,这不是未来几个月的选择,所以我正在寻找一个权宜之计。
我们使用 ASPState 数据库在 SQL Server 2005 群集上保留 .NET 会话状态。我们在高峰期看到一些奇怪的行为
DeleteExpiredSessions 过程通过代理作业每分钟运行一次。有时这项工作需要花费几分钟来运行和删除过期的会话
从应用程序到 ASPState 数据库的请求非常缓慢。我相信这是因为 DeleteExpiredSessions 过程在表上持有排他锁
代码:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[DeleteExpiredSessions]
AS
SET NOCOUNT ON
SET DEADLOCK_PRIORITY LOW
DECLARE @now datetime
SET @now = GETUTCDATE()
DECLARE @tblExpiredSessions TABLE
(
SessionID nvarchar(88) NOT NULL PRIMARY KEY
)
INSERT INTO @tblExpiredSessions (SessionID)
SELECT SessionID
FROM [ASPState].dbo.ASPStateTempSessions WITH (READUNCOMMITTED)
WHERE Expires < @now
--EXPIRED SESSION LOGGING
/*
DECLARE @ExpiredSessionCount Int;
SELECT @ExpiredSessionCount = COUNT(SessionID)
FROM @tblExpiredSessions; …Run Code Online (Sandbox Code Playgroud) 我们已经让数据库挂了两次并试图找到原因。
show processlist
Waiting for global read lock | INSERT INTO {myisam_table} ...
Run Code Online (Sandbox Code Playgroud)
在这里,磁盘空间已满,所以我们认为问题在给它一些后就解决了,但第二天中午它又挂了:
show processlist
Waiting for table level lock | UPDATE {myisam_table} ...
Run Code Online (Sandbox Code Playgroud)
是什么原因造成的?
Mysql 默认引擎:InnoDB。
数据库混合了带有 MyISAM 和 InnoDB 引擎的表。
日志贴在这里:
http://arturito.net/2013/08/28/mysql-waiting-for-table-level-lock-errors/
在高并发期间,我们遇到了返回无意义结果的查询的问题 - 结果违反了所发出查询的逻辑。需要一段时间才能重现该问题。我已经设法将可重现的问题归结为几个 T-SQL。
注意:有问题的实时系统部分由 5 个表、4 个触发器、2 个存储过程和 2 个视图组成。对于已发布的问题,我已将实际系统简化为更易于管理的系统。事情已经被削减,列被删除,存储过程被内联,视图变成了公共表表达式,列的值发生了变化。这是一个很长的说法,虽然下面的内容会重现错误,但可能更难以理解。您必须避免想知道为什么某些事物的结构是这样的。我在这里试图弄清楚为什么错误情况会在这个玩具模型中重复发生。
/*
The idea in this system is that people are able to take days off.
We create a table to hold these *"allocations"*,
and declare sample data that only **1** production operator
is allowed to take time off:
*/
IF OBJECT_ID('Allocations') IS NOT NULL DROP TABLE Allocations
CREATE TABLE [dbo].[Allocations](
JobName varchar(50) PRIMARY KEY NOT NULL,
Available int NOT NULL
)
--Sample allocation; there is 1 avaialable slot …Run Code Online (Sandbox Code Playgroud) 我一直在阅读诊断 MySQL InnoDB 锁文章。Karl E. Jørgensen 写于 2008 年,所以我混淆了它是否有效。
我想提供以下内容的片段SHOW ENGINE INNODB STATUS:
---TRANSACTION 20532F16, ACTIVE 386 sec starting index read
mysql tables in use 6, locked 6
LOCK WAIT 2 lock struct(s), heap size 1248, 1 row lock(s)
MySQL thread id 96238, query id 81681916 192.168.6.31 thanhnt updating
DELETE FROM `v3_zone_date`
WHERE `dt` = NAME_CONST('_currDate',_latin1'2012-03-02' COLLATE 'latin1_swedish_ci')
------- TRX HAS BEEN WAITING 8 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 482988 …Run Code Online (Sandbox Code Playgroud) 类似问题:Mongodb 上的高全局锁定百分比
我们在 v2.4.8 mongodb 中有一个生产设置副本集,它运行在五个 4 核、28gb RAM 虚拟机上,标准 azure 数据磁盘 HDD 运行在 64 位 CentOS 6 上。我们以大约 600-700 ops/sec/secondary 的速度在辅助节点上分配读取。每个辅助节点的 CPU 使用率约为 15%。主服务器上的 CPU 使用率约为 5-10%。我们目前在我们的主服务器上遇到高全局写锁和后台刷新平均值的问题。尽管每秒只有大约 200 次插入/更新/删除(请参阅下面的 MMS 输出),但我们的主服务器上的全局写锁定在 30-40% 之间。我们还注意到,我们的后台刷新平均值在 2 到 15 秒之间。不幸的是,这会导致大量缓慢的查询(每秒最多 50 次更新/插入 > 100 毫秒)。我们已经考虑过分片,但觉得 mongodb 应该表现得比这更好。
这告诉我,我们在写入 HDD 时遇到问题,但运行一个简单的 iostat 显示我们在 sdc(我们正在写入的磁盘)上的利用率没有达到最大值,并且在 20% 到 40% 之间:
$ iostat -x 1
Run Code Online (Sandbox Code Playgroud)
4秒结果:
Linux 2.6.32-279.14.1.el6.openlogic.x86_64 (mongodb3-wus) 05/08/2014 _x86_64_ (4 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
5.28 0.00 1.82 …Run Code Online (Sandbox Code Playgroud) 在我的应用程序中,我必须执行分布式锁定模式。因为我们已经有一个 SQL Server 实例可以使用,所以我们决定在我们的 Web 应用程序的 SQL 层实现锁定是最容易的。
可以根据多种条件获得锁,包括:
出于所有意图和目的,将上述两个条件视为int数据类型。
在这种模式中,我们希望将我们所有的锁都视为 FIFO,我相信SERIALIZABLE隔离级别会给我们带来这种好处。
以下是我们建议如何执行“锁定”:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
IF EXISTS (SELECT 1 FROM locks WHERE LockType = @LockType AND ApplicationIdentifier = @ApplicationIdentifier)
BEGIN
-- Awesome, the lock will be acquired
INSERT INTO locks OUTPUT INSERTED.LockId VALUES (2,3)
END
ELSE
BEGIN
-- Someone already has the lock
SELECT -1
END
SET TRANSACTION ISOLATION LEVEL READ COMITTED
Run Code Online (Sandbox Code Playgroud)
和“解锁”:
DELETE FROM locks WHERE LockId = @LockId
Run Code Online (Sandbox Code Playgroud)
所以我的问题有两个方面: …
我们正在运行 Postgres 9.3,偶尔会出现死锁问题。目前有人注意到并将手动终止进程。当它们发生时,是否有处理这些问题的最佳实践?我知道有一个statement_timeout,lock_timeout而deadlock_timeout但大多数地方,我读状态,你不想设置此的postgres.conf文件。
只是想看看是否有典型/最佳实践方法。看起来将 deadlock_timeout 设置为 10 分钟就足够了,但我想确保我没有遗漏一些关键的东西,为什么这会是一个坏主意。
locking ×10
sql-server ×4
deadlock ×2
innodb ×2
mysql ×2
concurrency ×1
db2 ×1
linux ×1
mongodb ×1
ms-access ×1
myisam ×1
postgresql ×1
session ×1