【问题标题】:AccessExclusive lock origin访问排他锁原点
【发布时间】:2021-08-30 22:28:43
【问题描述】:

我在第一个事务中运行以下查询:

BEGIN ISOLATION LEVEL repeatable read;
SELECT balance from "Users" WHERE id = 1 FOR UPDATE;
UPDATE "Users" SET "balance"="balance"+1 WHERE id = 1;
   

然后是第二个,来自不同的连接,完全相同。在SELECT ... FOR UPDATE 它正在等待。

然后我运行以下命令来查看锁

select t.relname,l.locktype,l.tuple,page,virtualtransaction,pid,mode,granted from pg_locks l, pg_stat_all_tables t where l.relation=t.relid order by relation asc;

它显示行锁(ROW SHARE、ROW EXCLUSIVE),这很好。但我也看到了

Users   tuple   9   0   11/17085    199957  AccessExclusiveLock TRUE

根据文档AccessExclusiveLock来自:

被 ALTER TABLE、DROP TABLE、TRUNCATE、REINDEX、CLUSTER、 和 VACUUM FULL 命令。这也是LOCK的默认锁定模式 未明确指定模式的 TABLE 语句。

我没有明确地做任何事情,我在文档中找不到这个锁是如何隐式获取的。还有,元组锁类型和9是什么意思?

更新 #1:

我使用以下查询来获取更多信息:

SELECT a.datname,
         l.relation::regclass,
         l.transactionid,
         l.mode,
         l.GRANTED,
         a.usename,
         a.query,
         a.query_start,
         age(now(), a.query_start) AS "age",
         a.pid
FROM pg_stat_activity a
JOIN pg_locks l ON l.pid = a.pid
ORDER BY a.query_start;   

所以确实数据库是一样的,查询是被阻塞的。

mydb    "Users"     AccessExclusiveLock TRUE    appuserdev  SELECT balance from "Users" WHERE id = 1 for update;    2021-08-30 08:06:38.864007+00   00:08:06.978082 205464

【问题讨论】:

  • 你是对的,这些查询不会在表上使用ACCESS EXCLUSIVE 锁定。那一定是别的东西,也许在不同的数据库上。
  • 好吧,我的两个事务都是为同一个数据库启动的。如何查看导致AccessExclusiveLock 的查询?
  • 您必须记录所有查询才能确定。将数据库添加到查询中,看看是否相同。如果是,则必须是您自己的事务中的不同语句。
  • @LaurenzAlbe:我已经更新了我的帖子。 DB 是一样的。
  • 我会说这是不可能的......

标签: postgresql


【解决方案1】:

您正在阅读的文档适用于 tables 上的 AccessExclusiveLock。但是您看到的不是表锁。我认为非表的锁定模式在任何地方都没有明确记录,但是您通常可以通过类比来弄清楚。

另一方面,我也看不到你所看到的。我看到元组上持有的是 ExclusiveLock,而不是 AccessExclusiveLock。

【讨论】:

  • 会不会和集群有关系?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-29
  • 1970-01-01
  • 2013-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多