我们最近升级到 postgresql 9.1.6(从 8.3)。我们的测试服务器表明 max_pred_locks_per_transaction 应至少设置为 900(这远远超出了建议设置 64)。
我们现在正在生产中,我不得不多次增加这个参数,因为我们的日志将开始填充:
ERROR: 53200: out of shared memory
HINT: You might need to increase max_pred_locks_per_transaction.
客户端连接设置为 600(但池系统永远不会超过 100 个客户端):
max_pred_locks_per_transaction: 我们去了3000。大约一天就用完了。 去了9000,大概3天就用完了。
我现在将其设置为 30000,因为这个数字是每个允许的客户端连接的平均分配数,我现在有大约 5 GB 的共享内存专用于锁定空间!
我确实将 shared_buffers 设置得相当高(目前为 24GB),超过了 40% 的 RAM 数字。 (我计划在下次重启时将其调低至 RAM 的 25% 左右)。
编辑:这个调整被证明是个坏主意。我的数据库有很多繁重的查询,并且有一半的大 RAM 专用于 shared_buffers 可以防止它阻塞,因为它可以完全缓存更大的表。
平均而言,我一次会看到大约 5-10 个活跃查询。我们的查询负载远超过了我们的更新负载。
有人愿意告诉我如何找出这里出了什么问题吗?对于这么小的更新集,我真的不明白为什么我们经常用完锁……我真的闻起来像泄漏。
有人知道如何检查锁的去向吗? (例如,关于这个问题,我如何阅读 pg_locks 的内容)
最佳答案
这听起来很可能是由长时间运行的事务引起的。在所有重叠的读写事务完成之前,不能释放一个事务的谓词锁。这包括准备好的交易。
查看 pg_stat_activity
和 pg_prepared_xacts
,了解几分钟前开始(或准备)的任何事务。
我能想到的唯一其他可能的非错误解释是您的表有数百或数千个分区。
如果这些解释都没有道理,我很想得到一个可重现的测试用例。有什么方法可以创建表,使用 generate_series() 用查询填充它们并以可预测的方式实现这一点?有了这样的测试用例,我绝对可以追查原因。
关于locking - PostgreSQL 9.1 会泄漏锁吗? (共享内存不足/增加 max_pred_locks_per_transaction),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12946715/