使用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: SetupLockInTable
lock = (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参数的数量,增加最大连接数实际也可以。