PG守护进程(Postmaster)——读取控制文件LocalProcessControlFile

该内容描述了在数据库启动过程中,如何进行控制文件的读取和错误检查。LocalProcessControlFile函数负责读取控制文件并设置相关GUC参数。ReadControlFile函数打开并读取控制文件,检查其CRC和内容的完整性,然后设置如wal_segment_size等参数,并进行兼容性验证。此过程确保了数据库在启动和恢复时的数据一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

LocalProcessControlFile(false)

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

void LocalProcessControlFile(bool reset) {
	Assert(reset || ControlFile == NULL);
	ControlFile = palloc(sizeof(ControlFileData));
	ReadControlFile();
}

执行过程

  1. 打开控制文件,读取控制文件
static void ReadControlFile(void) {
	pg_crc32c	crc;
	int			fd;
	static char wal_segsz_str[20];
	int			r;

	/* 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);
  1. 检查控制文件:版本,CRC,兼容性检查
  2. 设置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);

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值