PostgreSQL参数解析autovacuum_work_mem
PostgreSQL 提供了参数 autovacuum_work_mem 用来控制每个 autovacuum 工作进程可以使用的最大内存数量。如果指定该参数时没有带单位,那么其默认单位是 KB。该参数默认值为 -1,其大小等同于 maintenance_work_mem 参数值。该参数可以在 postgresql.conf 文件中或者数据库启动的命令行中设置。
对于收集死元组的集合,autovacuum 最多只能使用 1GB 的内存,因此将 autovacuum_work_mem 设置为高于 1GB的值时,对 autovacuum 在扫描表收集的死元组数量是没有影响的。
- 默认值,-1,表示使用 maintenance_work_mem 参数的值作为本参数的值
- 最小值 1024,即 1MB,如果设置的小于 1024,自动转成 1024
- 最大值为 (INT_MAX / 1024)
在内核实现上,对于 autovacuum_work_mem 参数的使用场所有 2 处:
- 计算表最大死元组数量,在 compute_max_dead_tuples() 函数中通过 autovacuum_work_mem 参数计算使用索引场景下的表死元组的最大数量,最大数量不会超过 1GB。
- 在ginInsertCleanup() 函数中,forceCleanup 为 true 的情况下,workMemory 就是 autovacuum_work_mem 的值。当满足 accum.allocatedMemory >= workMemory * 1024L 时就会考虑将内存中的数据刷盘处理。
相关代码:
如果 autovacuum_work_mem 为 -1,则使用 maintenance_work_mem 参数的值:
autovacuum_work_mem != -1 ?
autovacuum_work_mem : maintenance_work_mem;
计算表的最大死元组数量:
static long
compute_max_dead_tuples(BlockNumber relblocks, bool useindex)
{
long maxtuples;
int vac_work_mem = IsAutoVacuumWorkerProcess() &&
autovacuum_work_mem != -1 ?
autovacuum_work_mem : maintenance_work_mem;
if (useindex)
{
maxtuples = MAXDEADTUPLES(vac_work_mem * 1024L);
maxtuples = Min(maxtuples, INT_MAX);
maxtuples = Min(maxtuples, MAXDEADTUPLES(MaxAllocSize));
/* curious coding here to ensure the multiplication can't overflow */
if ((BlockNumber) (maxtuples / LAZY_ALLOC_TUPLES) > relblocks)
maxtuples = relblocks * LAZY_ALLOC_TUPLES;
/* stay sane if small maintenance_work_mem */
maxtuples = Max(maxtuples, MaxHeapTuplesPerPage);
}
else
maxtuples = MaxHeapTuplesPerPage;
return maxtuples;
}
ginInsertCleanup() 函数 forceCleanup 模式下超过最大内存限制时内存数据刷盘。
void
ginInsertCleanup(GinState *ginstate, bool full_clean,
bool fill_fsm, bool forceCleanup,
IndexBulkDeleteResult *stats)
{
if (forceCleanup)
{
workMemory =
(IsAutoVacuumWorkerProcess() && autovacuum_work_mem != -1) ?
autovacuum_work_mem : maintenance_work_mem;
}
if (GinPageGetOpaque(page)->rightlink == InvalidBlockNumber ||
(GinPageHasFullRow(page) &&
(accum.allocatedMemory >= workMemory * 1024L)))
{
... /* 内存刷盘 */
}
} 文章评论
共0条评论