【问题标题】:Deadlock in SELECT FOR UPDATE querySELECT FOR UPDATE 查询中的死锁
【发布时间】:2013-10-17 20:53:23
【问题描述】:

我有桌子说

TAB1

ID, TARGET, STATE, NEXT

ID 列是主键。

显示死锁的查询与此类似

SELECT * 
FROM TAB1 
WHERE NEXT = (SELECT MIN(NEXT) FROM TAB1 WHERE TARGET=? AND STATE=?) FOR UPDATE

我做了一个解释计划,我看到这样的东西:

| Id  | Operation             | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |               |     1 |  8095 |     6   (0)| 00:00:01 |
|   1 |  FOR UPDATE           |               |       |       |            |          |
|   2 |   BUFFER SORT         |               |       |       |            |          |
|*  3 |    TABLE ACCESS FULL  | TAB1          |     1 |  8095 |     3   (0)| 00:00:01 |
|   4 |     SORT AGGREGATE    |               |     1 |  2083 |            |          |
|*  5 |      TABLE ACCESS FULL| TAB1          |     1 |  2083 |     3   (0)| 00:00:01 |

由于查询执行 TABLE ACCESS FULL 两次,所以我怀疑执行相同查询的 2 个会话将以不同的顺序访问行。

列索引是否有助于防止死锁?说在 NEXT 上创建索引???或者通过将主键更改为非集群键?注意:正常情况下,表格最多有 1000 行。

【问题讨论】:

  • SQL 只是 结构化查询语言 - 许多数据库系统使用的语言,但不是数据库产品...许多事情是特定于供应商的 - 所以我们真的需要知道您正在使用什么数据库系统(以及哪个版本)(请相应地更新标签)......
  • 这里可能会出现死锁,索引也无济于事,请给我们更多信息——你想做什么?
  • 我假设您没有索引。建议在 TARGET/STATE 和可能的 NEXT(即 one 索引)上设置一个,在 NEXT 上设置一个单独的索引。但是,有更有效的方法可以做到这一点,而无需再次扫描表。 For instanceNothing 将在您锁定表时停止锁定。唯一的解决方案是不锁定表或让您的其他查询使用nowait,以便它们忽略锁定的行。
  • 无需猜测哪些查询导致了死锁。每个死锁都会生成一个跟踪文件,该跟踪文件会告诉您究竟是哪些语句导致了问题。如果您知道其中一个死锁发生的确切时间,请让 DBA 查找当时生成的跟踪文件。
  • 请显示整个事务 --> 事务执行的所有命令,直到提交。 Trace 显示SELECT * ... FOR UPDATE,但这不一定是导致死锁的主要原因。

标签: oracle oracle11g database-deadlocks


【解决方案1】:

在 NEXT 列上添加非聚集索引确实会提高性能并减少死锁问题。

【讨论】:

  • 减少,但不是消除,我猜是mysql,所以如果表中有几行具有相同的NEXT值,这个查询有时会产生死锁
  • 你错误地怀疑@IlyaBursov,这是Oracle,并且被标记为Oracle 和SQL Server 而不是MySQL。
  • 为什么向 NEXT 列添加索引会有所帮助?您仍然需要评估谓词。
  • 我需要索引 TARGET 和 STATE 列吗?我认为 MIN() 正在执行 FULL SCAN,然后 WHERE 子句也在执行,因为 WHERE 子句中没有主键。 NEXT 值为 System.currentTimeMillis()。因此,具有相同 NEXT 的行是最少的。
  • @Ben,主要查询谓词使用下一列。这就是为什么它应该做点什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-24
  • 2013-10-19
  • 1970-01-01
  • 2010-10-31
  • 1970-01-01
  • 2019-06-13
  • 2015-10-21
相关资源
最近更新 更多