Lock:transactionid
当事务正在等待行级锁定时,会发生 Lock:transactionid
事件。
支持的引擎版本
Aurora PostgreSQL 的所有版本均支持此等待事件信息。
上下文
当事务试图获取已被授予同时运行的事务的行级锁时,会发生事件 Lock:transactionid
。显示 Lock:transactionid
等待事件的会话因此锁定被阻止。当阻止事务在 COMMIT
或 ROLLBACK
语句中结束后,被阻止的事务可以继续进行。
Aurora PostgreSQL 的多版本并发控制语义保证读取器不会阻止写入器,写入器也不会阻止读取器。为了发生行级冲突,正在阻止和已阻止的事务必须发出以下类型的冲突语句:
-
UPDATE
-
SELECT … FOR UPDATE
-
SELECT … FOR KEY SHARE
语句 SELECT … FOR KEY SHARE
是一种特殊情况。数据库使用子句 FOR KEY
SHARE
以优化参照完整性的性能。一行上的行级锁定可以组织引用该行的其他表上的 INSERT
、UPDATE
和 DELETE
命令。
等待次数增加的可能原因
当此事件出现频率超过正常时,原因通常是 UPDATE
、SELECT …
FOR UPDATE
或 SELECT … FOR KEY SHARE
语句结合以下条件。
高并发性
Aurora PostgreSQL 可以使用精细的行级锁定语义。满足以下条件时,行级冲突的可能性会增加:
-
高度并发的工作负载争用相同的行。
-
并发性增加。
空闲事务
有时,pg_stat_activity.state
列会显示值 idle in transaction
。对于已开始事务但尚未发布 COMMIT
或 ROLLBACK
的会话,会显示此值。如果 pg_stat_activity.state
值不为 active
,pg_stat_activity
中显示的查询是完成运行的最新版本。阻止会话没有主动处理查询,因为未完成的事务持有锁定。
如果空闲事务获得了行级锁,则可能会阻止其他会话获取它。这种情况导致等待事件 Lock:transactionid
频繁发生。要诊断问题,请检查来自的 pg_stat_activity
和 pg_locks
的输出。
长时间运行的事务
长时间运行的事务会获得很长一段时间的锁定。这些长期保留的锁定可以阻止其他事务运行。
操作
行锁定是 UPDATE
、SELECT … FOR
UPDATE
或 SELECT … FOR KEY SHARE
语句之间发生的冲突。在尝试解决方案之前,请先了解这些语句何时在同一行上运行。使用此信息选择以下各部分所述的策略。
响应高并发
如果并发性是问题,请尝试以下方法之一:
-
降低应用程序中的并发率。例如,减少活动会话的数量。
-
实施连接池。要了解如何使用 RDS 代理进行池连接,请参阅 将 Amazon RDS 代理用于 Aurora。
-
设计应用程序或数据模型以避免争用
UPDATE
和SELECT … FOR UPDATE
语句。您还可以减少SELECT … FOR KEY SHARE
语句访问的外键的数量。
回应空闲事务
如果 pg_stat_activity.state
显示 idle in transaction
,请使用以下策略:
-
尽可能开启自动提交。这种方法可防止事务在等待
COMMIT
或ROLLBACK
时阻止其他事务。 -
搜索缺失
COMMIT
、ROLLBACK
或END
的代码路径。 -
确保应用程序中的异常处理逻辑始终具有通向有效
end of transaction
的路径。 -
确保您的应用程序在结束与
COMMIT
或ROLLBACK
的事务后处理查询结果。
响应长期运行的事务
如果长时间运行的事务导致频繁发生 Lock:transactionid
,请尝试以下策略:
-
在长时间运行的事务中保持行锁定。
-
尽可能通过实现自动提交来限制查询的长度。