FAIRYFAR-INTERNAL
 
  FAIRYFAR-INTERNAL  |  SITEMAP  |  ABOUT-ME  |  HOME  
PostgreSQL查询启动过程

本文PG代码版本为:REL_14_STABLE(PG 14稳定分支)。

psql连接创建服务进程

客户端psql连接PG server成功后,PostMaster(守护进程)会fork出来一个服务进程(Backend),如下所示:

[yz@localhost ~]$ ps -ef | grep postgres
yz       14560     1  0 11:25 ?        00:00:00 /home/yz/postgresql/pg_bin/bin/postgres -D /home/yz/postgresql/pg_data
yz       14627 14560  0 11:25 ?        00:00:00 postgres: checkpointer
yz       14628 14560  0 11:25 ?        00:00:00 postgres: background writer
yz       14629 14560  0 11:25 ?        00:00:00 postgres: walwriter
yz       14630 14560  0 11:25 ?        00:00:00 postgres: autovacuum launcher
yz       14631 14560  0 11:25 ?        00:00:00 postgres: stats collector
yz       14632 14560  0 11:25 ?        00:00:00 postgres: logical replication launcher
yz       14637 14431  0 11:25 pts/0    00:00:00 psql -p 7404 postgres
yz       14638 14560  0 11:25 ?        00:00:00 postgres: yz postgres [local] idle

14638是为14637服务的进程,其父进程为14560。

监听端口

之后,服务进程进入无限循环,监听连接端口上的消息,即:

snippet.c
void
PostgresMain(int argc, char *argv[], const char *dbname, const char *username)
{
	/*
	 * Non-error queries loop here.
	 */
 
	for (;;)
	{
	  // read a command
	  firstchar = ReadCommand(&input_message);
	  switch (firstchar)
		{
			case 'Q': /* simple query */
			{
         exec_simple_query(query_string);
       }
	}
}

psql发送查询

假设psql执行一条select命令,则psql通过libpq将消息发送给后端服务进程:

(gdb) bt
#0  0x00007f4ef75b2400 in PQsendQuery () from /home/yz/postgresql/pg_bin/lib/libpq.so.5
#1  0x00007f4ef75b3260 in PQexec () from /home/yz/postgresql/pg_bin/lib/libpq.so.5
#2  0x000000000040d2af in SendQuery ()
#3  0x000000000041ebb4 in MainLoop ()
#4  0x0000000000406347 in main ()

PQsendQuery实际调用PQsendQueryInternal,可以看到以下代码:

snippet.c
		if (pqPutMsgStart('Q', conn) < 0 ||
			pqPuts(query, conn) < 0 ||
			pqPutMsgEnd(conn) < 0)
		{
			/* error message should be set up already */
			pqRecycleCmdQueueEntry(conn, entry);
			return 0;
		}

'Q'指令就是在这里生成的。

执行

服务进程收到查询请求,执行主要由:

exec_simple_query

负责执行,包括语法解析、生成执行计划、优化、算子执行等。

执行过程中,如果有并行,则需要发信号(signal)给PostMaster,PostMaster会fork worker进程。



打赏作者以资鼓励:
移动端扫码阅读: