初步学习pg_control文件之二

时间:2025-01-26 10:05:26

接前文:初步认识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) << ;
sysidentifier |= (uint32) (tv.tv_sec | tv.tv_usec); ... /* Now create pg_control */ memset(ControlFile, , 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) << ;
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 = ,
DB_SHUTDOWNED,
DB_SHUTDOWNED_IN_RECOVERY,
DB_SHUTDOWNING,
DB_IN_CRASH_RECOVERY,
DB_IN_ARCHIVE_RECOVERY,
DB_IN_PRODUCTION
} DBState;

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