postgresql 旧的已提交事务如何影响正在进行的事务?

xv8emn3q  于 2024-01-07  发布在  PostgreSQL
关注(0)|答案(1)|浏览(188)

SQL大师!
我的postgres 15数据库在SERIALIZABLE隔离级别下运行,我偶尔会看到带有奇怪错误消息的serialization_failure (40001)错误:

DETAIL: Reason code: Canceled on identification as a pivot, with conflict out to old committed transaction 39594340.

字符串
对于这类错误,我们限制了自动重试,但在最近的一个案例中,在一个多小时内,没有任何东西可以触及受影响的表--任何UPDATE尝试都会失败,并出现相同的错误。
对我来说奇怪的是,这个错误引用了txn 39594340,它在错误消息开始出现在我们的日志中之前成功提交了15分钟。
这个错误的特殊变体在Google上并没有产生太大的影响。也许最相关的是https://www.mail-archive.com/[email protected]/msg156458.html,它讨论了耗尽共享内存的 predicate 锁(或达到max_pred_locks_per_transaction限制的txns)如何失去很多粒度,特别是如果它们交换到磁盘(甚至DB也可能丢失!?!?)
无论如何,在我们的例子中,似乎我们有一个非常复杂的,长时间运行的txn(称之为txnA),几乎肯定会达到默认的max_pred_locks_per_transaction=64限制。然后我们有其他简单得多的txn,基本上只执行1-2个UPDATE语句(txnB)。
committed txn(old committed transaction 39594340)和failing-with-serialization-error txn都是简单的txnB类型,但可能与txnA并发发生。同时,txnAtxnB没有接触相同的表,但在两者之前启动,并且在我们开始看到错误时仍然运行。
看起来可能有一些错综复杂的依赖关系,与长期运行的txn的 predicate 锁中的特定性丢失有关。这个假设疯了吗?
否则一个 * 已提交的 * txn如何影响当前的txn?
TIA在这里的任何见解!

kd3sttzy

kd3sttzy1#

很难说到底发生了什么,但是在SERIALIZABLE隔离级别上获取的 predicate 锁会一直保留到最后一个并发事务结束,所以肯定涉及到一个长时间运行的事务。

相关问题