PostgreSQL服务过程中的那些事一:启动postgres服务进程一.八:加载DB基础设施,完成服务进程初始化

         话说调用 InitPostgres 方法给 portgres 服务进程做相关初始化,这个方法里初始化了 relcache catcache ,初始化了执行查询计划的 portal 的管理器,填充本进程 PGPROC 结构相关部分成员等,上一节讨论了 portal 管理环境的初始化,这一节继续讨论剩余的相关初始化。

 

1

先看 InitPostgres 方法的调用序列梗概图



 

InitPostgres 方法的调用序列梗概图

         InitPostgres 方法为初始化这个 postgres 服务进程做了一系列的工作,具体如下:

1 )调用 InitProcessPhas e2 方法,把本进程的 PGPROC 结构注册到 PGPROC 数组,就是让 共享内存里的 PGPROC 数组( 初始化 PGPROC 数组的文章见《 PostgreSQL 启动过程中的那些事七:初始化共享内存和信号十一: shmem 中初始化 SharedProcArray )的第一个空元素指向这个 PGPROC 结构 ,并注册退出时做内存清理的函数。

2 )调用 SharedInvalBackendInit 方法,在该后台进程数据的 共享失效管理器数组获取一个 ProcState 结构(相关数据结果见《 PostgreSQL 启动过程中的那些事七:初始化共享内存和信号十三: shmem 中初始化 SharedInvalidationState 》)给该进程并初始化相关项,并注册退出方法以在退出时标记本进程的项非活跃。

3 )调用 ProcSignalInit 方法, ProcSignalSlot 结构 数组(关于 ProcSignalSlot 结构 数组参见《 PostgreSQL 启动过程中的那些事七:初始化共享内存和信号十四: shmem 中初始化 PMSignal 》) ProcSignalSlot s 里给当前进程获取一个元素,元素下标是 MyBackendId-1 ,并注册以在进程退出时释放这个槽。

4 )为访问 XLOG ,调用 RecoveryInProgress 方法做共享内存相关初始化。

5 )调用 RelationCacheInitlisze 方法做管理 relcache 的环境的初始化。

6 )调用 InitCatalogCache 方法做管理 catcache 的环境的初始化。

7 )调用 EnablePortalManager 方法初始化 portal 管理器。

8 )调用 RelationCacheInitializePhase2 方法初始化共享系统表。

9 )调用 GetTransactionSnapshot 方法获取一个事务快照。这个方法在后面讨论简单查询时再讨论。

10 )调用 PerformAuthentication 方法根据 hba 文件设置进行客户端认证。

11 )调用 GetDatabaseTuple 方法根据数据库名字从 pg_database 系统表获取要访问的数据库对应的元组。

12 )调用 RelationCacheInitializePhase3 方法完成 relcache 初始化。

13 )调用 CheckMyDatabase 方法检查当前用户的数据库访问权限,从 cache 里的 pg_database 取当前数据库的相关属性字段。

14 )调用 InitializeClientEncoding 方法初始化客户端字符编码。

15 )调用 pgstat_bestart 方法在 PgBackendStatus 设置本进程状态。

 

2

这一节概论第 8 步到第 15 步。先看一下后续方法的调用序列图,为了图能大一点, PostgresMain 以前的调用流程序列就从下面的图中省略了,要回顾可以参考上面的“ InitPostgres 方法的调用序列梗概图 ”。



相关方法 调用序列图

 

下面讨论第( 8 )步, RelationCacheInitializePhase2 方法初始化共享 catalog 。先看一下为什么要有第( 5 )、( 8 )、( 12 )步三步来初始化 relcache 。当前还处在数据库服务器和客户端建立连接的过程中,数据库服务器的服务进程要根据连接串中指定数据库加载其相关对象,但此时服务器端还没有加载访问数据库的基础设施,比如系统表 "pg_database" "pg_authid" "pg_auth_members" 等的描述符及其相关索引 信息,因此无法通过系统表访问数据库的相关信息。第( 5 )步初始化 relcache 的管理环境,参见《

PostgreSQL服务过程中的那些事一:启动postgres服务进程一.五:初始化relcache管理环境

》。第( 8 )步通过 "global/pg_filenode.map" "global/pg_internal.init" 文件初始化共享 catalog "pg_catalog" ,将系统表 "pg_database" "pg_authid" "pg_auth_members" 等的描述符信息加载到 relcache 里。 "global/pg_filenode.map" 文件里存放的是数据库中关系和文件节点的映射信息, "global/pg_internal.init" 文件里存放的是 "pg_class" "pg_attribute" "pg_proc" "pg_type" 等系统关系信息。然后完成设置数据库快照(第 9 步)、根据 hba 文件完成客户端认证(第 10 步)、 pg_database 获取客户端要访问的数据库的对应元组(第11步),第 12 )步根据要访问的数据库 ID ,加载该数据库本地的 "pg_filenode.map" "pg_internal.init" 文件完成初始化。加载 "pg_class" "pg_attribute" "pg_proc" "pg_type" 等及其索引信息。如果从相关 "pg_filenode.map" "pg_internal.init" 文件初始化失败,系统会从硬编码的代码中初始化基础设施相关关系信息,下面摘录了 "pg_database" "pg_authid" "pg_auth_members" 的硬编码信息。不管加载那个文件,完成相关信息初始化后如有必要将重新该文件。重写时先写临时文件,写完后改文件名为正式文件。这样做是为了避免并发的后台进程读相关文件时崩溃。关于文件名举个例子,例如文件 "data/global/pg_internal.init" ,对应的临时文件名是 "data/global/pg_internal.init.pid" ,最后的 "pid" 是当前进程 ID

第( 13 )步调用 CheckMyDatabase 方法检查当前用户的数据库访问权限,从 cache 里的 pg_database 取当前数据库的相关属性字段。第( 14 )调用 InitializeClientEncoding 方法初始化客户端字符编码。第( 15 )调用 pgstat_bestart 方法在 PgBackendStatus 设置本进程状态。至此 pg 服务进程的初始化工作告一段落。

下面是部分系统关系硬编码信息:

DATA(insert OID = 11 ( "pg_catalog" PGUID _null_ ));

DESCR( "system catalog schema" );

#define PG_CATALOG_NAMESPACE 11

 

 

 

#define DatabaseRelationId  1262

#define DatabaseRelation_Rowtype_Id  1248

 

CATALOG(pg_database,1262) BKI_SHARED_RELATION BKI_ROWTYPE_OID(1248) BKI_SCHEMA_MACRO

{

    NameData   datname;      /* database name */

    Oid        datdba;           /* owner of database */

    int4       encoding;     /* character encoding */

    NameData   datcollate;       /* LC_COLLATE setting */

    NameData   datctype;     /* LC_CTYPE setting */

    bool        datistemplate;    /* allowed as CREATE DATABASE template? */

    bool        datallowconn; /* new connections allowed? */

    int4       datconnlimit; /* max connections allowed (-1=no limit) */

    Oid        datlastsysoid;    /* highest OID to consider a system OID */

    TransactionId datfrozenxid; /* all Xids < this are frozen in this DB */

    Oid        dattablespace;    /* default table space for this DB */

    aclitem       datacl[1];    /* access permissions (VAR LENGTH) */

} FormData_pg_database;

 

/* ----------------

  *     Form_pg_database corresponds to a pointer to a tuple with

  *     the format of pg_database relation.

  * ----------------

  */

typedef FormData_pg_database * Form_pg_database ;

 

 

 

/* ----------------

  *     pg_authid definition.  cpp turns this into

  *     typedef struct FormData_pg_authid

  * ----------------

  */

#define AuthIdRelationId 1260

#define AuthIdRelation_Rowtype_Id   2842

 

CATALOG(pg_authid,1260) BKI_SHARED_RELATION BKI_ROWTYPE_OID(2842) BKI_SCHEMA_MACRO

{

    NameData   rolname;      /* name of role */

    bool        rolsuper;     /* read this field via superuser() only! */

    bool        rolinherit;       /* inherit privileges from other roles? */

    bool        rolcreaterole;    /* allowed to create more roles? */

    bool        rolcreatedb;  /* allowed to create databases? */

    bool        rolcatupdate; /* allowed to alter catalogs manually? */

    bool        rolcanlogin;  /* allowed to log in as session user? */

    bool        rolreplication; /* role used for streaming replication */

    int4       rolconnlimit; /* max connections allowed (-1=no limit) */

 

    /* remaining fields may be null; use heap_getattr to read them! */

    text       rolpassword;  /* password, if any */

    timestamptz rolvaliduntil;  /* password expiration time, if any */

} FormData_pg_authid;

 

#undef timestamptz

 

 

/* ----------------

  *     Form_pg_authid corresponds to a pointer to a tuple with

  *     the format of pg_authid relation.

  * ----------------

  */

typedef FormData_pg_authid * Form_pg_authid ;

 

 

 

/* ----------------

  *     pg_auth_members definition.  cpp turns this into

  *     typedef struct FormData_pg_auth_members

  * ----------------

  */

#define AuthMemRelationId   1261

#define AuthMemRelation_Rowtype_Id 2843

 

CATALOG(pg_auth_members,1261) BKI_SHARED_RELATION BKI_WITHOUT_OIDS BKI_ROWTYPE_OID(2843) BKI_SCHEMA_MACRO

{

    Oid        roleid;           /* ID of a role */

    Oid        member;           /* ID of a member of that role */

    Oid        grantor;      /* who granted the membership */

    bool        admin_option; /* granted with admin option? */

} FormData_pg_auth_members;

 

/* ----------------

  *     Form_pg_auth_members corresponds to a pointer to a tuple with

  *     the format of pg_auth_members relation.

  * ----------------

  */

typedef FormData_pg_auth_members * Form_pg_auth_members ;

 

就到这儿吧!




------------
转载请著明出处,来自博客:
blog.csdn.net/beiigang
beigang.iteye.com


猜你喜欢

转载自beigang.iteye.com/blog/1680797