PostgreSQL服务过程中的那些事一:启动postgres服务进程一.六:初始化系统表缓存catcache

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

 

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

下面讨论第( 6 )步, InitCatalogCache 方法初始化 relcache 相关对象。 Relcache 是存放系统表元组的地方。为了图能大一点, PostgresMain 以前的调用流程序列就从下面的图中省略了,要回顾可以参考上面的“ InitPostgres 方法的调用序列梗概图 ”。

 


相关方法调用序列图

 

InitCatalogCache -> InitCatCache -> MemoryContextSwitchTo 将内存上下文切换到 "CacheMemoryContext" ,然后 InitCatalogCache -> InitCatCache -> palloc 在内存上下文 "CacheMemoryContext" 里分配管理 catcache 的相关结构。相关结构和图形见下面。

 

定义一个 syscache 的信息

struct cachedesc

{

    Oid         reloid ;           /* OID of the relation being cached */

    Oid         indoid ;           /* OID of index relation for this cache */

    int         nkeys ;        /* # of keys needed for cache lookup */

    int         key [4];           /* attribute numbers of key attrs */

    int         nbuckets ;     /* number of hash buckets for this cache */

};

 

static const struct cachedesc cacheinfo [] = {

    {AggregateRelationId,       /* AGGFNOID */

       AggregateFnoidIndexId,

       1,

       {

           Anum_pg_aggregate_aggfnoid,

           0,

           0,

           0

       },

       32

    },

    …… ,

…… ,

…… ,

    {UserMappingRelationId,     /* USERMAPPINGOID */

       UserMappingOidIndexId,

       1,

       {

           ObjectIdAttributeNumber,

           0,

           0,

           0

       },

       128

    },

    {UserMappingRelationId,     /* USERMAPPINGUSERSERVER */

       UserMappingUserServerIndexId,

       2,

       {

           Anum_pg_user_mapping_umuser,

           Anum_pg_user_mapping_umserver,

           0,

           0

       },

       128

    }

};

 

 

typedef struct catcache

{

    int         id ;           /* cache identifier --- see syscache.h */

    struct catcache * cc_next ;   /* link to next catcache */

    const char * cc_relname ;     /* name of relation the tuples come from */

    Oid         cc_reloid ;    /* OID of relation the tuples come from */

    Oid         cc_indexoid ;  /* OID of index matching cache keys */

    bool        cc_relisshared ; /* is relation shared across databases? */

    TupleDesc   cc_tupdesc ;       /* tuple descriptor (copied from reldesc ) */

    int         cc_ntup ;      /* # of tuples currently in this cache */

    int         cc_nbuckets ;  /* # of hash buckets in this cache */

    int         cc_nkeys ;     /* # of keys (1..CATCACHE_MAXKEYS) */

    int         cc_key [CATCACHE_MAXKEYS];       /* AttrNumber of each key */

    PGFunction cc_hashfunc [CATCACHE_MAXKEYS];  /* hash function for each key */

    ScanKeyData cc_skey [CATCACHE_MAXKEYS];    /* precomputed key info for

                                            * heap scans */

    bool        cc_isname [CATCACHE_MAXKEYS];    /* flag "name" key columns */

    Dllist      cc_lists ;     /* list of CatCList structs */

#ifdef CATCACHE_STATS

    long        cc_searches;  /* total # searches against this cache */

    long        cc_hits;      /* # of matches against existing entry */

    long        cc_neg_hits;  /* # of matches against negative entry */

    long        cc_newloads;  /* # of successful loads of new entry */

 

    /*

      * cc_searches - (cc_hits + cc_neg_hits + cc_newloads) is number of failed

      * searches, each of which will result in loading a negative entry

      */

    long        cc_invals;    /* # of entries invalidated from cache */

    long        cc_lsearches; /* total # list-searches */

    long        cc_lhits;     /* # of matches against existing lists */

#endif

    Dllist      cc_bucket [1]; /* hash buckets --- VARIABLE LENGTH ARRAY */

} CatCache ;                     /* VARIABLE LENGTH STRUCT */

 

       struct catcacheheader :   管理所有 cache 的信息 .

typedef struct catcacheheader

{

    CatCache    * ch_caches ;       /* head of list of CatCache structs */

    int         ch_ntup ;      /* # of tuples in all caches */

} CatCacheHeader ;

 


catcache 和管理它的相关结构图

         系统表和 SysCache 中的 catcache 一一对应。静态数组 cacheinfo 的元素 cachedesc 描述系统表的 catcache 信息。系统表中的元组存放在 catcache 的双向链表数组 cc_bucket 的元素 Dllist 里。




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


猜你喜欢

转载自beigang.iteye.com/blog/1671451
今日推荐