初步学习pg_control文件之二

接前文:初步认识pg_control文件

继续学习,pg_control文件在何处形成的?是在initdb的时候,运用的函数如下:
/*
 * This func must be called ONCE on system install.  It creates pg_control
 * and the initial XLOG segment.
 */
void
BootStrapXLOG(void)
{

    CheckPoint    checkPoint;
    char       *buffer;
    XLogPageHeader page;
    XLogLongPageHeader longpage;
    XLogRecord *record;
    bool        use_existent;
    uint64        sysidentifier;
    struct timeval tv;
    pg_crc32    crc;

    /*
     * Select a hopefully-unique system identifier code for this installation.
     * We use the result of gettimeofday(), including the fractional seconds
     * field, as being about as unique as we can easily get.  (Think not to
     * use random(), since it hasn't been seeded and there's no portable way
     * to seed it other than the system clock value...)  The upper half of the
     * uint64 value is just the tv_sec part, while the lower half is the XOR
     * of tv_sec and tv_usec.  This is to ensure that we don't lose uniqueness
     * unnecessarily if "uint64" is really only 32 bits wide.  A person
     * knowing this encoding can determine the initialization time of the
     * installation, which could perhaps be useful sometimes.
     */
    gettimeofday(&tv, NULL);
    sysidentifier = ((uint64) tv.tv_sec) << 32;
    sysidentifier |= (uint32) (tv.tv_sec | tv.tv_usec);

    ...

    /* Now create pg_control */

    memset(ControlFile, 0, sizeof(ControlFileData));

    /* Initialize pg_control status fields */
    ControlFile->system_identifier = sysidentifier;
    ControlFile->state = DB_SHUTDOWNED;
    ControlFile->time = checkPoint.time;
    ControlFile->checkPoint = checkPoint.redo;
    ControlFile->checkPointCopy = checkPoint;

    /* Set important parameter values for use when replaying WAL */
    ControlFile->MaxConnections = MaxConnections;
    ControlFile->max_prepared_xacts = max_prepared_xacts;
    ControlFile->max_locks_per_xact = max_locks_per_xact;
    ControlFile->wal_level = wal_level;

    /* some additional ControlFile fields are set in WriteControlFile() */

    WriteControlFile();

    /* Bootstrap the commit log, too */
    BootStrapCLOG();
    BootStrapSUBTRANS();
    BootStrapMultiXact();

    pfree(buffer);
}
说起来
system_identifier 这个东西 ,是随机算出来的一个值:
    /*
     * Select a hopefully-unique system identifier code for this installation.
     * We use the result of gettimeofday(), including the fractional seconds
     * field, as being about as unique as we can easily get.  (Think not to
     * use random(), since it hasn't been seeded and there's no portable way
     * to seed it other than the system clock value...)  The upper half of the
     * uint64 value is just the tv_sec part, while the lower half is the XOR
     * of tv_sec and tv_usec.  This is to ensure that we don't lose uniqueness
     * unnecessarily if "uint64" is really only 32 bits wide.  A person
     * knowing this encoding can determine the initialization time of the
     * installation, which could perhaps be useful sometimes.
     */
    gettimeofday(&tv, NULL);
    sysidentifier = ((uint64) tv.tv_sec) << 32;
    sysidentifier |= (uint32) (tv.tv_sec | tv.tv_usec);

...
    ControlFile->system_identifier = sysidentifier;

 state 在初始化的时候,是有SHUTDOWNED。另外可能的值也都可以在pg_control.h中看到:

/*
 * System status indicator.  Note this is stored in pg_control; if you change
 * it, you must bump PG_CONTROL_VERSION
 */
typedef enum DBState
{
    DB_STARTUP = 0,
    DB_SHUTDOWNED,
    DB_SHUTDOWNED_IN_RECOVERY,
    DB_SHUTDOWNING,
    DB_IN_CRASH_RECOVERY,
    DB_IN_ARCHIVE_RECOVERY,
    DB_IN_PRODUCTION
} DBState;

这几个值何时用,状态如何变化,应该是一个很有意思的话题。  

posted @ 2013-07-31 13:28  健哥的数据花园  阅读(1165)  评论(0编辑  收藏  举报