温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

PostgreSQL中怎么控制文件在初始化时生成

发布时间:2021-06-21 17:44:47 来源:亿速云 阅读:148 作者:Leah 栏目:大数据

PostgreSQL中怎么控制文件在初始化时生成,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

控制文件是在初始化时生成,记录PG运行过程中的关键信息,大致分为以下几类。

  • 初始化时自动生成,运行过程中不允许修改,例如系统标识符;

  • 允许用户在初始化时一次性定制,不再允许修改,例如WAL段尺寸;

  • 记录创建数据库的编译时信息,例如catalog版本,启动此数据库的程序也必须具有相同属性;

  • 实时信息,比如检查点记录,崩溃中重启能够知道从哪里开始恢复。

1、初始化时传递给postgres参数

这个过程这里不多讲,initdb使用 postgres --boot -x1 启动数据库程序,进入bootstrap 模式:

	if (argc > 1 && strcmp(argv[1], "--boot") == 0)
		AuxiliaryProcessMain(argc, argv);	/* does not return */

这段代码在 main(int argc, char *argv[]) 函数中,以前的文章提到过它。

AuxiliaryProcessMain 中的参数解析:

	case 'x':
		MyAuxProcType = atoi(optarg);
		break;

这里取得辅助进程的类型,其它参数遇到的时候再讲。

2、辅助进程定义

typedef enum
{
	NotAnAuxProcess = -1,
	CheckerProcess = 0,
	BootstrapProcess,
...
	NUM_AUXPROCTYPES			/* Must be last! */
} AuxProcType;

可知,initdb启动了一个 BootstrapProcess 进程。

3、初始化时自动生成参数(系统标识符)

继续往下看会看到 BootStrapXLOG 的调用(src/backend/access/transam/xlog.c),系统标识符在这里边生成并最终写入磁盘:

void
BootStrapXLOG(void)
{
...
	gettimeofday(&tv, NULL);
	sysidentifier = ((uint64) tv.tv_sec) << 32;
	sysidentifier |= ((uint64) tv.tv_usec) << 12;
	sysidentifier |= getpid() & 0xFFF;
...
  ControlFile->system_identifier = sysidentifier;
...
	WriteControlFile();
...

4、用户定制参数

initdb 有参数 --wal-segsize=SIZE,在启动时 postgres 时用 'X' 传入:

postgres —boot -x1 -X %u

这地方稍微别扭的地方是initdb和postgres两个程序的X参数含义竟然不一致,好在是内部实现,使用者并不需要知道。

启动时,参数 X 赋值给 wal_segment_size

	case 'X':
		{
			int			WalSegSz = strtoul(optarg, NULL, 0);
...
			SetConfigOption("wal_segment_size", optarg, PGC_INTERNAL,
							PGC_S_OVERRIDE);
		}
		break;

随后,在 WriteControlFile 中记入控制文件:

ControlFile->xlog_seg_size = wal_segment_size;

5、编译时选项

函数 WriteControlFile 写入控制文件

	ControlFile->pg_control_version = PG_CONTROL_VERSION;
	ControlFile->catalog_version_no = CATALOG_VERSION_NO;

	ControlFile->maxAlign = MAXIMUM_ALIGNOF;
	ControlFile->floatFormat = FLOATFORMAT_VALUE;

	ControlFile->blcksz = BLCKSZ;
	ControlFile->relseg_size = RELSEG_SIZE;
...

6、实时信息

系统在运行过程中更新 ControlFile,然后在某些节点写入磁盘(调用 UpdateControlFile),比如CheckPoint时,可以看到像系统标识符这类信息是不会变的。

7、校验

写入和更新时都会计算CRC,也写入控制文件内,

	/* Contents are protected with a CRC */
	INIT_CRC32C(ControlFile->crc);
	COMP_CRC32C(ControlFile->crc,
				(char *) ControlFile,
				offsetof(ControlFileData, crc));
	FIN_CRC32C(ControlFile->crc);

读取文件时校验它保证完整性:

	/* Now check the CRC. */
	INIT_CRC32C(crc);
	COMP_CRC32C(crc,
				(char *) ControlFile,
				offsetof(ControlFileData, crc));
	FIN_CRC32C(crc);

	if (!EQ_CRC32C(crc, ControlFile->crc))
		ereport(FATAL,
				(errmsg("incorrect checksum in control file")));

看完上述内容,你们掌握PostgreSQL中怎么控制文件在初始化时生成的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI