PostgreSQL ERROR: out of shared memory处理
使用pg_dump命令导出一个库的时候,报
pg_dump: error: query failed: ERROR: out of shared memory
HINT: You might need to increase "max_locks_per_transaction".
从错误字面上看是超出内存大小了,建议增加max_locks_per_transaction参数
本环境中:
[postgres174@geoscene ~]$ psql
psql (17.4)
Type "help" for help.postgres=# show max_locks_per_transaction ;max_locks_per_transaction
---------------------------64
(1 row)
原因:
pg_dump -d dbname的时候会对库中所有的表执行lock table in shared mode 操作。
该操作会将表锁记录到表锁所在的共享结构中。
lock.c: SetupLockInTablelock = (LOCK *) hash_search_with_hash_value(LockMethodLockHash,locktag,hashcode,HASH_ENTER_NULL,&found);
LockMethodLockHash 结构在InitLocks初始化
lock.c
InitLocks(void)
{HASHCTL info;long init_table_size,max_table_size;bool found;/** Compute init/max size to request for lock hashtables. Note these* calculations must agree with LockShmemSize!*///最大表大小max_table_size = NLOCKENTS();init_table_size = max_table_size / 2;/** Allocate hash table for LOCK structs. This stores per-locked-object* information.*/info.keysize = sizeof(LOCKTAG);info.entrysize = sizeof(LOCK);info.num_partitions = NUM_LOCK_PARTITIONS;LockMethodLockHash = ShmemInitHash("LOCK hash",init_table_size,max_table_size,&info,HASH_ELEM | HASH_BLOBS | HASH_PARTITION);
...
查看
#define NLOCKENTS() \mul_size(max_locks_per_xact, add_size(MaxBackends, max_prepared_xacts))Size
mul_size(Size s1, Size s2)
{Size result;if (s1 == 0 || s2 == 0)return 0;result = s1 * s2;/* We are assuming Size is an unsigned type here... */if (result / s2 != s1)ereport(ERROR,(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),errmsg("requested shared memory size overflows size_t")));return result;
}
可以看出来,跟最大连接数和max_prepared_xacts相关
所以解决这个问题除了增加max_locks_per_xact参数的数量,增加最大连接数实际也可以。