专业编程基础技术教程

网站首页 > 基础教程 正文

PostgreSQL数据库守护进程(Postmaster)——读取控制文件

ccvgpt 2024-08-05 12:16:53 基础教程 41 ℃

LocalProcessControlFile(false)

LocalProcessControlFile函数会读取控制文件,设置respective GUC。该函数是在启动过程中调用,包括在crash recovery cycle(除了bootstrap模式,因为这个模式下还没有生产控制文件)。这时还没有建立共享内存,所以需要将控制文件的内容放置本地被称中,并在XLOGShmemInit函数中拷贝到共享内存中。

void LocalProcessControlFile(bool reset) {

PostgreSQL数据库守护进程(Postmaster)——读取控制文件

Assert(reset || ControlFile == NULL);

ControlFile = palloc(sizeof(ControlFileData));

ReadControlFile();

}

执行过程

1 打开控制文件,读取控制文件

static void ReadControlFile(void) {

pg_crc32ccrc;

intfd;

static char wal_segsz_str[20];

intr;

/* Read data... */

fd = BasicOpenFile(XLOG_CONTROL_FILE, O_RDWR | PG_BINARY); // 打开文件

if (fd < 0) ereport(PANIC,(errcode_for_file_access(),errmsg("could not open file \"%s\": %m", XLOG_CONTROL_FILE)));

pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_READ); // 将WAIT_EVENT_CONTROL_FILE_READ事件设置到MyProc->wait_event_info中

r = read(fd, ControlFile, sizeof(ControlFileData));

if (r != sizeof(ControlFileData)) {

if (r < 0) ereport(PANIC,(errcode_for_file_access(), errmsg("could not read file \"%s\": %m",XLOG_CONTROL_FILE)));

else ereport(PANIC,(errcode(ERRCODE_DATA_CORRUPTED),errmsg("could not read file \"%s\": read %d of %zu", XLOG_CONTROL_FILE, r, sizeof(ControlFileData))));

}

pgstat_report_wait_end();

close(fd);

2 检查控制文件:版本,CRC,兼容性检查

为错误检查和配置信息读取控制文件。我们已经检查了控制文件的CRC,需要的CRC run-time test支持设施已经加载。postmaster在启动过程中会进行测试CRC,子进程会继承该函数指针,不需要重复进行测试。

3 设置respective GUC:wal_segment_size、data_checksums

wal_segment_size = ControlFile->xlog_seg_size;

if (!IsValidWalSegSize(wal_segment_size)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),errmsg_plural("WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte","WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes",wal_segment_size,wal_segment_size)));

snprintf(wal_segsz_str, sizeof(wal_segsz_str), "%d", wal_segment_size);

SetConfigOption("wal_segment_size", wal_segsz_str, PGC_INTERNAL,PGC_S_OVERRIDE);

/* check and update variables dependent on wal_segment_size */

if (ConvertToXSegs(min_wal_size_mb, wal_segment_size) < 2)

ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),errmsg("\"min_wal_size\" must be at least twice \"wal_segment_size\"")));

if (ConvertToXSegs(max_wal_size_mb, wal_segment_size) < 2)

ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),errmsg("\"max_wal_size\" must be at least twice \"wal_segment_size\"")));

UsableBytesInSegment =(wal_segment_size / XLOG_BLCKSZ * UsableBytesInPage) - (SizeOfXLogLongPHD - SizeOfXLogShortPHD);

CalculateCheckpointSegments();

/* Make the initdb settings visible as GUC variables, too */

SetConfigOption("data_checksums", DataChecksumsEnabled() ? "yes" : "no", PGC_INTERNAL, PGC_S_OVERRIDE);

最近发表
标签列表