使用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參數的數量,增加最大連接數實際也可以。