话说调用 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