标签: locking

行级和页级锁定的区别和后果

尝试运行我的维护计划时,我收到以下错误:

执行查询“”失败,出现以下错误:“无法重新组织表“”上的索引“”(分区 1),因为禁用了页级锁定。”

我们目前在此索引上启用了行级锁定。我可以启用页面级别锁定,但我不确定影响是什么。

我的问题是:这两种锁定方案有什么区别,它们在现实世界(生产中)的后果是什么?

sql-server maintenance locking

12
推荐指数
2
解决办法
2万
查看次数

即使在 READ COMMITTED 中,MySQL InnoDB 也会在删除时锁定主键

前言

我们的应用程序运行多个DELETE并行执行查询的线程。查询影响孤立的数据,即不应该存在并发DELETE发生在来自不同线程的相同行上的可能性。但是,根据文档,MySQL 对DELETE语句使用所谓的“next-key”锁,它同时锁定匹配的键和一些间隙。这会导致死锁,我们找到的唯一解决方案是使用READ COMMITTED隔离级别。

问题

DELETE使用JOIN大表执行复杂语句时会出现问题。在特定情况下,我们有一个带有警告的表,只有两行,但查询需要从两个单独的INNER JOINed 表中删除属于某些特定实体的所有警告。查询如下:

DELETE pw 
FROM proc_warnings pw 
INNER JOIN day_position dp 
   ON dp.transaction_id = pw.transaction_id 
INNER JOIN ivehicle_days vd 
   ON vd.id = dp.ivehicle_day_id 
WHERE vd.ivehicle_id=? AND dp.dirty_data=1
Run Code Online (Sandbox Code Playgroud)

当 day_position 表足够大时(在我的测试用例中有 1448 行),那么即使使用READ COMMITTED隔离模式,任何事务也会阻塞整个 proc_warnings表。

该问题始终在此示例数据上重现 - http://yadi.sk/d/QDuwBtpW1BxB9在 MySQL 5.1(在 5.1.59 上检查)和 MySQL 5.5(在 MySQL 5.5.24 上检查)中。

编辑:链接的示例数据还包含查询表的架构和索引,为方便起见,在此处复制:

CREATE TABLE  `proc_warnings` (
    `id` int(11) NOT NULL AUTO_INCREMENT, …
Run Code Online (Sandbox Code Playgroud)

mysql innodb mysql-5.5 locking isolation-level

12
推荐指数
1
解决办法
6876
查看次数

当Oracle中的一条记录被锁定时,我们能知道哪条记录被锁定了吗?

当一条记录被锁定时,我们能知道哪个记录被锁定了吗?

如何获取记录 rowid 或其他信息?


我可以通过这个 sql 得到一些信息

SELECT c.ROW_WAIT_OBJ#,c.ROW_WAIT_FILE#,c.ROW_WAIT_BLOCK#,c.ROW_WAIT_ROW#
   FROM v$locked_object a, dba_objects b, v$session c    
WHERE a.object_id = b.object_id    
    AND a.SESSION_ID = c.sid(+) 
Run Code Online (Sandbox Code Playgroud)

我在 web 中找到了一种使用函数获取 rowid 的方法 DBMS_ROWID.ROWID_CREATE()

但它似乎不起作用。

oracle locking

12
推荐指数
1
解决办法
5万
查看次数

CREATE TABLE AS SELECT 时 MySQL 锁定

我正在运行以下(虚拟)查询

CREATE TABLE large_temp_table AS 
    SELECT a.*, b.*, c.* 
    FROM a
    LEFT JOIN b ON a.foo = b.foo
    LEFT JOIN c ON a.bar = c.bar
Run Code Online (Sandbox Code Playgroud)

假设查询运行需要 10 分钟。在运行时尝试更新表 a、b 或 c 中的值将等待上述查询首先完成。我想避免这个锁(不关心数据一致性)。我怎样才能做到这一点?

使用:MySQL 5.1.41 和 InnoDB 表

ps 设置事务隔离级别读取未提交;不会改变行为

更新 在执行查询时,显示 ENGINE INNODB STATUS 的输出如下(我特意在这里做了一个非常慢的查询)

=====================================
120323 15:26:29 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 8 seconds
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 1470, signal count 1468
Mutex spin waits 0, rounds 7525, …
Run Code Online (Sandbox Code Playgroud)

mysql locking ctas

11
推荐指数
1
解决办法
8026
查看次数

如何使用PostgreSQL保持每行唯一的计数器?

我需要在 document_revisions 表中保留一个唯一的(每行)修订号,其中修订号的范围仅限于文档,因此它不是整个表唯一的,仅适用于相关文档。

我最初想出了类似的东西:

current_rev = SELECT MAX(rev) FROM document_revisions WHERE document_id = 123;
INSERT INTO document_revisions(rev) VALUES(current_rev + 1);
Run Code Online (Sandbox Code Playgroud)

但是有一个竞争条件!

我试图用 解决它pg_advisory_lock,但文档有点稀缺,我不完全理解它,我不想错误地锁定某些东西。

以下是可以接受的,还是我做错了,或者有更好的解决方案?

SELECT pg_advisory_lock(123);
current_rev = SELECT MAX(rev) FROM document_revisions WHERE document_id = 123;
INSERT INTO document_revisions(rev) VALUES(current_rev + 1);
SELECT pg_advisory_unlock(123);
Run Code Online (Sandbox Code Playgroud)

我不应该为给定的操作 (key2) 锁定文档行 (key1) 吗?所以这将是正确的解决方案:

SELECT pg_advisory_lock(id, 1) FROM documents WHERE id = 123;
current_rev = SELECT MAX(rev) FROM document_revisions WHERE document_id = 123;
INSERT INTO document_revisions(rev) VALUES(current_rev + 1);
SELECT pg_advisory_unlock(id, 1) FROM …
Run Code Online (Sandbox Code Playgroud)

postgresql locking

11
推荐指数
2
解决办法
2万
查看次数

优化 Postgres 中的并发更新

我正在运行这样的并发 Postgres 查询:

UPDATE foo SET bar = bar + 1 WHERE baz = 1234
Run Code Online (Sandbox Code Playgroud)

每个查询都会影响固定的 K 行数,我找不到强制执行更新行顺序的方法,最终导致死锁。目前我通过手动执行订单来解决这个问题,但这意味着我必须执行比平时更多的查询,同时还将搜索复杂度从 O(log N + K) 提高到 O(K log N)。

有没有办法提高性能而不会最终容易陷入死锁?我怀疑如果Postgres 以扫描它们的相同顺序更新行,用(baz)索引替换(baz, id)索引可能会起作用,这是一种值得追求的方法吗?

postgresql deadlock locking update

11
推荐指数
1
解决办法
1万
查看次数

Sch-M WAIT 阻止 SQL Server 2014 中的 Sch-S 而不是 SQL Server 2008 R2?

我们最近将生产实例从 SQL 2008 R2 迁移到全新的 SQL 2014 服务器。这是我们在使用 Service Broker 时发现的一个有趣场景。考虑一个Broker Enabled = true带有MyService和的数据库MyQueue。此队列上禁用了毒物消息处理。队列中至少有 2 个与消息的活动对话。

在一个进程 (SPID 100) 中执行:

BEGIN TRANSACTION;
DECLARE @conversation_group_id UNIQUEIDENTIFIER;
RECEIVE TOP (1) @conversation_group_id = conversation_handle FROM MyQueue;
Run Code Online (Sandbox Code Playgroud)

请注意,我们将事务保持打开状态。假设它是一个 .NET 程序,它在某些外部资源上等待了很长时间。通过sys.dm_tran_locks我们看到该 SPID 已被授予对队列的 IX 锁。

| type   | resource_id | mode | status | spid |
| OBJECT | 277576027   | IX   | GRANT  | 100  |
Run Code Online (Sandbox Code Playgroud)

在单独的进程 (SPID 101) 中执行五次

BEGIN TRANSACTION;
DECLARE @conversation_group_id …
Run Code Online (Sandbox Code Playgroud)

sql-server service-broker locking

11
推荐指数
1
解决办法
2810
查看次数

“签出”记录以进行处理的策略

我不确定是否有一个命名模式,或者是否没有,因为这是一个糟糕的主意。但我需要我的服务在主动/主动负载平衡环境中运行。这只是应用程序服务器。数据库将位于单独的服务器上。我有一个服务,需要为表中的每条记录运行一个过程。此过程可能需要一两分钟,并且每 n 分钟重复一次(可配置,通常为 15 分钟)。

有一个需要此处理的 1000 条记录表,以及针对同一数据集运行的两个服务,我希望每个服务“签出”要处理的记录。我需要确保一次只有一个服务/线程在处理每条记录。

我有同事过去使用过“锁表”。将一条记录写入此表以在逻辑上锁定另一个表中的记录(顺便说一句,该其他表非常静态,并且添加了非常偶然的新记录),然后删除以释放锁定。

我想知道如果新表有一个列指示它何时被锁定,并且它当前被锁定,而不是不断插入删除,是否会更好。

有没有人有这种事情的提示?是否存在长期(ish)期限逻辑锁定的既定模式?关于如何确保一次只有一项服务获取锁的任何提示?(我的同事使用 TABLOCKX 锁定整个表。)

sql-server sql-server-2008-r2 locking

11
推荐指数
1
解决办法
4179
查看次数

当我们在一个有大量数据的现有表中添加索引时会发生什么?

我有一个包含大约 1500 万条记录的表。现在我需要向表中添加一个索引。

添加索引需要一些时间来更新表中的每个条目。

我很困惑添加索引是否会导致停机。

如果是,那么我怎样才能克服停机时间?

postgresql index concurrency locking

11
推荐指数
1
解决办法
2375
查看次数

使用 SELECT... WITH XLOCK 的好理由?

我正面临着一些重复发生的死锁,其中一个是 Keylock 并且包含一个带有 XLOCK 提示的 SELECT 查询,该查询成为死锁的受害者。另一个语句是对作为第一个查询视图的一部分的一个表的 INSERT。

看法:

create view dbo.viewE
 as
    select * from dbo.E  
    where myValue > 13000 
Run Code Online (Sandbox Code Playgroud)

选择查询:

select * from dbo.viewE with (XLOCK) where A > GETUTCDATE() 
Run Code Online (Sandbox Code Playgroud)

插入语句:

INSERT INTO [dbo].[E] (myValue,A) VALUES (10,GetDate())
Run Code Online (Sandbox Code Playgroud)

基础表 dbo.E 在大约 20 列中包含大约 300 万行,其中一些是 ntext。

取出查询并使用两个事务手动模拟它,该行为是可重现的。如果从选择中删除 XLOCK,则行为会发生变化。

死锁图:

<deadlock-list>
 <deadlock victim="process222222221">
  <process-list>
   <process id="process222222221" taskpriority="0" logused="0" waitresource="KEY: 5:72057604035644444 (ccdf51accc0c)" waittime="2522" ownerId="27202256401" transactionname="SELECT" lasttranstarted="2015-09-14T16:32:36.160" XDES="0x2f1ec5ca0" lockMode="RangeX-X" schedulerid="15" kpid="12936" status="suspended" spid="359" sbid="0" ecid="0" priority="0" trancount="0" lastbatchstarted="2015-09-14T16:32:36.160" lastbatchcompleted="2015-09-14T16:32:36.160" clientapp="x" hostname="x" hostpid="14536" …
Run Code Online (Sandbox Code Playgroud)

sql-server deadlock sql-server-2008-r2 index-tuning locking

11
推荐指数
1
解决办法
1万
查看次数