PG服务进程(Postgres)——初始化Postgres的运行环境

  Postgres进程是实际的接受查询请求并调用相应模块处理查询的PostgreSQL服务进程。它直接接受用户的命令进行编译执行,并将结果返回给用户。如此循环,直到用户断开连接。用户的命令分为两种:一种是查询命令,即插入、删除、更新和选择四种命令;另一种是非查询命令,如创建/删除表、视图、索引等命令。服务进程Postgres根据不同的命令类型选择不同的策略进行处理。

Postgres可以以一下三种模式启动:

  • Bootstrap模式:从无到有创建数据库的模式,postgres --boot -x1 -k -F
  • Single模式:单用户模式,只允许单个用户执行SQL命令。Bootstrap创建了最核心的元数据之后使用single模式创建其他数据,对应着postbootstrap阶段
  • Normal模式:多用户的正常模式

  对于单用户模式,Postgres服务器进程必须自己完成初始化内存环境、配置参数等操作,在多用户的正常模式下,这些配置工作是由Posmaster服务器进程完成(PG守护进程(Postmaster)——初始化GUC配置参数)。Postgres进程的主要源代码位于src/backend/tcop文件夹中,入口位于postgres.c文件中的PostresMain函数。该文件夹下其他文件包括:对于查询命令进行处理的源代码文件pquery.c,它执行一个分析好的查询命令;对于非查询命令进行处理的源代码文件utility.c,它执行各种非查询命令;dest.c中的代码主要处理Postgres和远端客户的一些消息通信操作,并负责返回命令的执行结果。如下图为单用户模式下Postgres服务器进程的执行流程。

 

 

 

初始化内存环境

   全局布尔变量IsUnderPostmaster表明进程的运行状态,该变量值为true表明运行在多用户模式下,在多用户模式下Postmaster初始化内存环境。在单用户模式下,内存初始化由postgres进程调用MemoryContextInit完成。

配置运行参数和处理客户端传递的GUC参数

   和Postmaster一样,这里的配置参数也包括三个步骤,即将参数设置为默认值根据命令行参数配置参数读配置文件重新设置参数。其中,第一步和第三步在多用户模式下(即IsUnderPostmaster为true时)已由Postmaster完成,而在单用户模式下这三步都和Postmaster完全相同。命令行方式的参数设置优先级是高于缺省设置的,将会覆盖缺省设置。命令行参数有很多,和Postmaster一样,在Postgres中仍使用while+switch控制结构读入参数并进行配置。之后Postgres还将从Port结构得到客户端传递的GUC选项,然后根据GUC选项的具体情况调用SetConfigOption进行设置。

设置信号处理和信号屏蔽

   Postgres中信号的注册方式和Postmaster类似,因此这里只对Postgres中处理的信号及其意义进行介绍。

信号 信号处理函数
SIGHUP SigHupHandler
SIGINT StatementCancelHandler
SIGTERM die
SIGQUIT quickdie
SIGALRM handle_sig_alarm
SIGPIPE SIG_IGN
SIGUSER1 CatchupInterruptHandler
SIGUSER2 NotifyInterruptHandler
SIGFPE FloatExceptionHandler
SIGCHLD 默认

 

初始化Postgres的运行环境

   基本参数和信号量处理函数初始化完成后,将进行Postgres进程运行环境的初始化工作。Postgres进程首先会检查DataDir变量,确保给定的DataDir字符串是一个格式正确的数据目录路径。在多用户模式下,此工作由Postmaster进程完成。在有效数据目录路径下,检查PG_VERSION文件中的版本信息是否与当前版本的程序兼容。在版本兼容的前提下,将当前工作目录转到DataDir字符串表示的目录,以方便Postmaster进程及其他后台进程使用相对路径访问数据目录。

  路径设置完成后,Postgres的初始化工作分为两个阶段:首先调用BaseInit函数来完成基本初始化,之后调用InItPostgres来完成Postgres的初始化。之所以将BaseInit和InitPostgres划分为两个阶段,是因为与XLog相关的初始化工作必须在InitPostgres之前。

  在BaseInit中,第一步调用InitCommunication创建共享内存和信号量并进行初始化,第二步调用DebugFileOpen初始化input/output/debugging文件描述符,第三步调用InitFileAccess初始化文件访问,第四步调用Smgrinit初始化或者关闭存储管理器,最后调用InitBufferPoolAccess初始化共享缓冲器。在整个BaseInit阶段,将完成Postgres进程的内存、信号量以及文件句柄的创建和初始化工作。

创建内存上下文并设置查询取消跳跃点

 

循环等待处理查询

###############################

# 下面的功能在后序章节分析

###############################

简单查询的执行流程 

执行parse协议信息

执行bind消息来创建portal

执行execute消息来创建portal

终端发出的功能性调用

 

posted @ 2021-01-19 23:36  肥叔菌  阅读(1521)  评论(0编辑  收藏  举报