3

我已经知道在序列化失败的情况下应该重试可序列化级别的事务。

我只是对引发 40001 错误的 2 个场景感到好奇:

  1. 运行 INSERT 命令时。
  2. 发出准备交易声明时。

在每种情况下,序列化问题的根本原因是什么?您对这些特殊情况有何经验?

我想通过查看并发事务来尝试减少这些问题。

TIA。

更新 1

PostgreSQL wiki我了解到,在可序列化的事务中,第一个 COMMIT 获胜。PREPARE 似乎表现得像一个 COMMIT 所以我可以理解为什么它可能会失败。

但是,对于 INSERT 情况,如果没有执行 SELECT 的并发可序列化事务,我就错过了重点。从我目前看到的情况来看,只有多个并发 INSERT。

更新 2

我发现我在同一张桌子上有并发 SELECT ... FOR SHARE。

更新 3

这里似乎有一种模式,当交易失败时,交易的持续时间比平时长。这是因为我们正在处理文件,这可能需要比预期更长的时间。我将尝试通过重新处理各种任务来减少事务的持续时间。

4

1 回答 1

2

文档对如何发生 40001 进行了很好的讨论:

http://www.postgresql.org/docs/current/static/transaction-iso.html

引用,而不是冗长地解释不好,适用的注意事项和注意事项:

不要在单个事务中投入超出完整性目的所需的更多内容。

不要让连接在“事务中闲置”的时间过长。

当系统因为谓词锁表内存不足而被迫将多个页级谓词锁合并为一个关系级谓词锁时,可能会增加序列化失败率。您可以通过增加 max_pred_locks_per_transaction 来避免这种情况。

顺序扫描总是需要关系级别的谓词锁。这可能导致序列化失败率增加。通过减少 random_page_cost 和/或增加 cpu_tuple_cost 来鼓励使用索引扫描可能会有所帮助。请务必权衡事务回滚和重新启动的任何减少与查询执行时间的任何整体变化。

换句话说,在写作时尽可能快地提交,并避免在整个地方读取或写入的大量查询。

于 2013-10-02T13:11:56.807 回答