Postgresql入口函数main功能十分简单,主要完成参数检查,内存上下文初始化,并根据启动参数选择入口分支,流程图及关键代码如下所示:
main(int argc, char *argv[]){
……
MemoryContextInit(); //初始化TopMemoryContext内存上下文,内存管理机制以后再详细分析
……
if (argc > 1) //判断参数是否合法,针对help以及version参数进行对应的信息提示
{
if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
{
help(progname);
exit(0);
}
if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
{
puts("postgres (PostgreSQL) " PG_VERSION);
exit(0);
}
//以下两种情况允许使用根用户启动,因为为只读操作
if (strcmp(argv[1], "--describe-config") == 0)
do_check_root = false;
else if (argc > 2 && strcmp(argv[1], "-C") == 0)
do_check_root = false;
}
……
if (argc > 1 && strcmp(argv[1], "--boot") == 0)
AuxiliaryProcessMain(argc, argv); /* does not return */
else if (argc > 1 && strcmp(argv[1], "--describe-config") == 0)
GucInfoMain(); /* does not return */
else if (argc > 1 && strcmp(argv[1], "--single") == 0)
PostgresMain(argc, argv,
NULL, /* no dbname */
strdup(get_user_name_or_exit(progname))); //单机启动
else
PostmasterMain(argc, argv); //正常启动
abort();
}
上图中三个启动分支含义如下:
- --boot:数据库初始化时的入口
- --single:单用户启动模式
- PostmasterMain:正常启动PG,该进程实际为PG的守护进程,它管理数据库文件,监听并接受来自客户端的连接请求,并为客户端创建一个服务进程
- *--describe-config(未画出):不启动数据库,仅读取GUC配置参数后退出