批量维护表或分区时,PostgreSQL报out of shared memory,并提示可能需要增加max_locks_per_transaction。错误文字已经给出方向,但并不意味着任何共享内存错误都该调这个参数。
先确认完整报错和当时的事务操作,尤其是一次涉及多少不同对象。

这项参数限制的是什么
PostgreSQL官方锁管理文档说明,共享锁表为每个服务器进程或预备事务预留一定数量的锁对象条目,规模受max_locks_per_transaction与最大连接数等配置影响。它控制可被同时锁定的不同对象容量,不是每个事务只能拿到该数目的锁。
大型分区表、一次遍历许多关系的DDL或长事务可能增加锁对象数量。仅凭当前连接数低也不能排除锁表空间耗尽。
先定位占用来源
保留完整错误日志、发生时刻和SQL。通过pg_locks查看当前锁记录,并结合pg_stat_activity的会话、事务状态和查询文本定位高负载操作;这些视图只反映查询时刻,事后快照可能看不到已结束事务。
不要随意终止未知会话或清空业务表。先与任务负责人确认批处理边界和回滚影响。
缩小批次还是调大参数
优先检查是否可以把涉及大量关系的操作拆成较小批次,缩短事务存活时间;仍有合理需求时再评估提高max_locks_per_transaction。官方文档指出这项参数只可在配置文件或服务器命令行设置,改动通常需要重启才能生效,同时会增加共享内存需求。
提高参数不能修复无限扩张的批处理设计。VPS内存紧张时还要考虑更大的锁表和其他数据库内存预算。
如何验收
可在萤光云或LightNode的隔离VPS用相同的分区数量和SQL形态复现,再验证分批或新参数。生产维护窗口重启后确认SHOW max_locks_per_transaction;生效、批任务完成且连接与内存稳定。
验收不能只看错误消失,还要核对业务事务结果和内存余量。
区分其他共享内存错误
如果日志没有关于锁对象的提示,需继续核对具体SQL、扩展及操作系统共享内存状况;不同错误可能来自不同资源池。pg_locks显示的是现有锁,不能单靠一条查询准确推算下一次峰值。
只针对已定位的锁容量问题调整锁表参数。
FAQ
问:把shared_buffers调大能解决吗?答:这不是该锁表参数的直接替代,先按错误提示与锁视图确定资源类型。
问:可以在线直接SET吗?答:官方文档将其列为只能在配置或启动命令中设置的参数,应安排重启窗口。
温馨提示
温馨提示:修改参数前记录现值、连接上限、业务批次规模和回滚方案;不要在内存已告急的VPS上盲目加大配置。


