PG守护进程(Postmaster)——后台一等公民进程

AuxiliaryProcessMain函数是后台一等公民进程的入口,我们来看一看哪里调用了该入口函数:

  1. src/backend/main/main.c main函数,如下图所示,argv第二个参数为–boot
    PG守护进程(Postmaster)——后台一等公民进程
  2. src/backend/postmaster/postmaster.c SubPostmasterMain函数 argv第二个参数为–forkboot
    PG守护进程(Postmaster)——后台一等公民进程
  3. src/backend/postmaster/postmaster.c StartChildProcess函数,我们以该函数为主要讲解点。主要看这个分支流程,上面两个分支流程不重要。
    PG守护进程(Postmaster)——后台一等公民进程
    调用链:StartChildProcess --> AuxiliaryProcessMain

StartChildProcess函数

StartChildProcess函数为postmaster启动一个an auxiliary process。为AuxiliaryProcessMain拼接输入参数数组argv:“postgres -x%d”。fork一个子进程,调用函数AuxiliaryProcessMain(ac, av)。

static pid_t StartChildProcess(AuxProcType type) {
	pid_t		pid;
	char	   *av[10]; int			ac = 0;
	char		typebuf[32];

	/* Set up command-line arguments for subprocess */
	av[ac++] = "postgres";
	snprintf(typebuf, sizeof(typebuf), "-x%d", type);
	av[ac++] = typebuf;
	av[ac] = NULL;
	Assert(ac < lengthof(av));

	pid = fork_process();
	if (pid == 0) {				/* child 子进程 */
		InitPostmasterChild();		
		ClosePostmasterPorts(false); /* Close the postmaster's sockets */
		/* Release postmaster's working memory context */
		MemoryContextSwitchTo(TopMemoryContext);
		MemoryContextDelete(PostmasterContext);
		PostmasterContext = NULL;
		AuxiliaryProcessMain(ac, av);
		ExitPostmaster(0);
	}

	if (pid < 0) {
		/* in parent, fork failed */
		int			save_errno = errno; errno = save_errno;
		switch (type) {
			case StartupProcess:
				ereport(LOG,(errmsg("could not fork startup process: %m"))); break;
			case BgWriterProcess:
				ereport(LOG, (errmsg("could not fork background writer process: %m"))); break;
			case CheckpointerProcess:
				ereport(LOG, (errmsg("could not fork checkpointer process: %m"))); break;
			case WalWriterProcess:
				ereport(LOG, (errmsg("could not fork WAL writer process: %m"))); break;
			case WalReceiverProcess:
				ereport(LOG, (errmsg("could not fork WAL receiver process: %m"))); break;
			default:
				ereport(LOG, (errmsg("could not fork process: %m")));
				break;
		}
		/* fork failure is fatal during startup, but there's no need to choke immediately if starting other child types fails. 如果是StartupProcess子进程fork失败,fatal级别的错误,需要调用ExitPostmaster(1) */
		if (type == StartupProcess) ExitPostmaster(1);
		return 0;
	}

	/*
	 * in parent, successful fork
	 */
	return pid;
}

AuxProcType的类型如下,下面就是后台一等公民进程,和PG的执行逻辑紧密耦合。
PG守护进程(Postmaster)——后台一等公民进程

后台一等公民进程

第一组一等公民:StartupProcess、BgWriterProcess、CheckpointerProcess、WalWriterProcess、WalReceiverProcess。调用流程如下:

  • PostmasterMain --> StartupDataBase
  • pmdie/reaper/sigusr1_handler -> PostmasterStateMachine --> StartupDataBase
  • ServerLoop(postmaster.c)/reaper/sigusr1_handler --> StartBackgroundWriter
  • ServerLoop(postmaster.c)/reaper/PostmasterStateMachine/sigusr1_handler --> StartCheckpointer
  • ServerLoop(postmaster.c)/reaper --> StartWalWriter
  • ServerLoop(postmaster.c)/sigusr1_handler --> MaybeStartWalReceiver --> StartWalReceiver

PG守护进程(Postmaster)——后台一等公民进程
第二组一等公民:CheckerProcess、BootstrapProcess

  • AuxiliaryProcessMain -> CheckerProcess
  • AuxiliaryProcessMain -> BootstrapProcess
上一篇:MVC模式:实现数据库中数据的增删改查功能


下一篇:PG长短连接-性能测试