这一节写图中红色方框圈起来的部分,上面的部分基本上在前面已经写过了,有小部分有略过。红色框中的部分就是初始化Timezones的过程调用,这主要做了两件事,一是创建了一个 ”Timezones”AllocSet/MemoryContext,二是建了一个pg中的动态哈希表,来管理/存放timezone。 2初始化全局时区global_timezones的过程
话说main()->…->PostmasterMain()->…-> pg_timezone_initialize()(以后用“->” 表示调用),先到前面的文章《pg启动过程中的那些事三》里提到的config_generic **类型的有序GUC参数数组guc_variables里用二分法查找config_string类型参数timezone,此时该参数还没有设置,接着->select_default_timezone()->identify_system_timezone()函数根据OS环境变量识别操作系统的timezone设置,再->select_default_timezone()->set_global_timezone()->pg_tzset()在内存里初始化一个静态全局变量动态哈希表static HTAB * timezone_cache,在哈希表timezone_cache里记录时区结构pg_tz_cache类型的实例。然后使pg_tz *类型全局指针变量 global_timezone指向哈希表中的pg_tz_cache结构类型实例中pg_tz结构的成员tz。最后->SetConfigOption()设置GUC参数“timezone”为“ASIA/Hong_Kong”(这个是我PC上跑的结果)。
下面是pg_tz_cache、pg_tz等机构定义。
typedef struct
{
/* tznameupper contains the all-upper-case name of thetimezone */
char tznameupper[TZ_STRLEN_MAX+ 1];
pg_tz tz;
} pg_tz_cache;
struct pg_tz
{
/* TZname contains the canonically-cased name of thetimezone */
char TZname[TZ_STRLEN_MAX+ 1];
struct state state;
};
struct state
{
int leapcnt;
int timecnt;
int typecnt;
int charcnt;
pg_time_t ats[TZ_MAX_TIMES];
unsigned chartypes[TZ_MAX_TIMES];
struct ttinfo ttis[TZ_MAX_TYPES];
char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS+ 1, 3 /* sizeof gmt */ ),
(2 * (TZ_STRLEN_MAX + 1)))];
struct lsinfo lsis[TZ_MAX_LEAPS];
};
struct ttinfo
{ /* time type information */
long tt_gmtoff; /* UTC offset inseconds */
int tt_isdst; /* used to settm_isdst */
int tt_abbrind; /* abbreviationlist index */
int tt_ttisstd; /* TRUE iftransition is std time */
int tt_ttisgmt; /* TRUE iftransition is UTC */
};
struct lsinfo
{ /* leap second information */
pg_time_t ls_trans; /* transition time */
long ls_corr; /* correctionto apply */
};
pg_tz_cache的结构在内存里看起来是这样的。