实际并行workers数量不等于postgresql.conf中设置的max_parallel_workers_per_gather数量

1 前言

  • 本文件的源码来自PostgreSQL 14.5,其它版本略有不同
  • 并行workers并不能显箸提升性能。个人不建议使用并行worker进程,大多数情况下采用postgresql.conf默认配置即可。

PostgreSQL的并行workers是由compute_parallel_worker函数决定的,compute_parallel_worker是估算扫描所需的并行工作线程数,并不是您在postgresql.conf中设置的max_parallel_workers_per_gather数量,compute_parallel_worker会根据heap_pages、index_pages、max_workers(max_parallel_workers_per_gather)来决定并行工作线程数量。

2 源码和调用位置

compute_parallel_worker共有4个地方调用

src\backend\optimizer\path\allpaths.c(801,21)
src\backend\optimizer\path\allpaths.c(3724,21)
src\backend\optimizer\path\costsize.c(707,33)
src\backend\optimizer\plan\planner.c(5953,21)

compute_parallel_worker的声明

src\include\optimizer\paths.h(59,12)

compute_parallel_worker的实现

src\backend\optimizer\path\allpaths.c(3750,1)

compute_parallel_worker的源码

/*
 * Compute the number of parallel workers that should be used to scan a
 * relation.  We compute the parallel workers based on the size of the heap to
 * be scanned and the size of the index to be scanned, then choose a minimum
 * of those.
 *
 * "heap_pages" is the number of pages from the table that we expect to scan, or
 * -1 if we don't expect to scan any.
 *
 * "index_pages" is the number of pages from the index that we expect to scan, or
 * -1 if we don't expect to scan any.
 *
 * "max_workers" is caller's limit on the number of workers.  This typically
 * comes from a GUC.
 * "max_workers"就是postgresql.conf中max_parallel_workers_per_gather的值
 */
int
compute_parallel_worker(RelOptInfo *rel, double heap_pages, double index_pages,
						int max_workers)
{
	int			parallel_workers = 0;

	/*
	 * If the user has set the parallel_workers reloption, use that; otherwise
	 * select a default number of workers.
     * 不需要优化,直接来自表级存储参数parallel_workers
     * 详见第3节直接使用postgresql.conf中设置的max_parallel_workers_per_gather数量
	 */
	if (rel->rel_parallel_workers != -1)
		parallel_workers = rel->rel_parallel_workers;
	else
	{
		/*
		 * If the number of pages being scanned is insufficient to justify a
		 * parallel scan, just return zero ... unless it's an inheritance
		 * child. In that case, we want to generate a parallel path here
		 * anyway.  It might not be worthwhile just for this relation, but
		 * when combined with all of its inheritance siblings it may well pay
		 * off.
		 */
		if (rel->reloptkind == RELOPT_BASEREL &&
			((heap_pages >= 0 && heap_pages < min_parallel_table_scan_size) ||
			 (index_pages >= 0 && index_pages < min_parallel_index_scan_size)))
			return 0;

		if (heap_pages >= 0)
		{
			int			heap_parallel_threshold;
			int			heap_parallel_workers = 1;

			/*
			 * Select the number of workers based on the log of the size of
			 * the relation.  This probably needs to be a good deal more
			 * sophisticated, but we need something here for now.  Note that
			 * the upper limit of the min_parallel_table_scan_size GUC is
			 * chosen to prevent overflow here.
			 */
			heap_parallel_threshold = Max(min_parallel_table_scan_size, 1);
			while (heap_pages >= (BlockNumber) (heap_parallel_threshold * 3))
			{
				heap_parallel_workers++;
				heap_parallel_threshold *= 3;
				if (heap_parallel_threshold > INT_MAX / 3)
					break;		/* avoid overflow */
			}

			parallel_workers = heap_parallel_workers;
		}

		if (index_pages >= 0)
		{
			int			index_parallel_workers = 1;
			int			index_parallel_threshold;

			/* same calculation as for heap_pages above */
			index_parallel_threshold = Max(min_parallel_index_scan_size, 1);
			while (index_pages >= (BlockNumber) (index_parallel_threshold * 3))
			{
				index_parallel_workers++;
				index_parallel_threshold *= 3;
				if (index_parallel_threshold > INT_MAX / 3)
					break;		/* avoid overflow */
			}

			if (parallel_workers > 0)
				parallel_workers = Min(parallel_workers, index_parallel_workers);
			else
				parallel_workers = index_parallel_workers;
		}
	}

	/* In no case use more than caller supplied maximum number of workers */
	parallel_workers = Min(parallel_workers, max_workers);

	return parallel_workers;
}

3 直接使用postgresql.conf中设置的max_parallel_workers_per_gather数量

如果要使用指定数量的并行worker数,必须使用存储参数parallel_workers。

alter table tab set (parallel_workers=8);

配置了存储参数后,compute_parallel_worker就不在对并行worker数优化,直接返回配置的parallel_workers数量。

if (rel->rel_parallel_workers != -1)
		parallel_workers = rel->rel_parallel_workers;
  • 注意:如果不设置表级存储参数parallel_workers,实际的并行工作线程数由compute_parallel_worker根据heap_pages、index_pages、max_workers来决定并行工作线程数量,因此会出现实际并行工作数量不等于postgresql.conf中设置的max_parallel_workers_per_gather的情况。
    在这里插入图片描述
    在这里插入图片描述

  • 在次强制:并行workers并不能显箸提升性能。个人不建议使用并行worker进程,大多数情况下采用postgresql.conf默认配置即可。

<think>好的,用户想了解PostgreSQL配置文件中max_connections参数的含义。首先,我需要回忆一下相关的知识,并结合提供的引用内容来组织答案。 根据引用[4],max_connections参数决定数据库的最大并发连接数,建议值不超过物理内存(GB)乘以50。这点很重要,用户需要知道如何根据服务器配置来调整这个参数。 接下来要注意的是配置文件之间的优先级问题。引用[1]和[2]提到,postgresql.auto.conf会覆盖postgresql.conf中的设置。所以在修改max_connections时,如果postgresql.auto.conf中存在该参数,必须同时修改,否则可能无效。这一点必须强调,避免用户遇到配置不生效的问题。 另外,引用[3]提到某些参数只能在postgresql.conf设置,但max_connections是否属于这类参数呢?根据已有的信息,可能不需要特别说明这一点,但需要确认。不过根据常见情况,max_connections可以通过ALTER SYSTEM命令修改,这会写入postgresql.auto.conf,所以覆盖问题很重要。 用户可能需要设置步骤,比如如何修改参数、重启服务等,以及注意事项,比如资源消耗。需要分步骤说明,结构清晰。 最后生成相关问题,需要围绕max_connections的影响、优化、配置冲突、监控等展开,确保覆盖用户可能进一步的问题。</think>### PostgreSQLmax_connections参数详解 $max\_connections$参数是PostgreSQL数据库的核心配置项,用于控制数据库服务端允许的最大并发客户端连接数。该参数的设置直接影响数据库性能和资源分配。 #### 核心特性 1. **并发控制** 设置公式为:$$max\_connections = N$$ 表示数据库同时接受$N$个客户端连接请求[^4]。例如$max\_connections=300$表示允许300个并发连接。 2. **资源分配** 每个连接会预分配: - 约10MB共享内存 - 独立的后台进程 - 事务状态跟踪资源 建议值:物理内存(GB) × 50 3. **配置优先级** 当同时存在$postgresql.conf$和$postgresql.auto.conf$配置时,后者具有更高优先级[^1][^2]。若修改不生效,需检查两个配置文件。 #### 配置示例 ```conf # postgresql.conf max_connections = 200 # 基准值 ``` ```conf # postgresql.auto.conf max_connections = 300 # 实际生效值 ``` #### 修改步骤 1. 通过SQL修改(生成auto.conf) ```sql ALTER SYSTEM SET max_connections = 250; ``` 2. 直接编辑postgresql.conf 3. 重载配置 ```bash pg_ctl reload -D /var/lib/pgsql/data ``` #### 注意事项 - 超过设定值的连接会收到"too many clients already"错误 - 连接数增加会提升内存消耗,可能引发OOM问题 - 需要配合$work_mem$等参数进行综合调优
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kmblack1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值