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中怎么控制文件在初始化时生成的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。