本文主要是介绍PostgreSQL源码分析——pg_archivecleanup,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
pg_archivecleanup用于清理PostgreSQL WAL归档文件。指定归档目录,指定一个最老的日志段文件(在此之前的WAL日志都删掉), 用法如下:
postgres@slpc:~$ pg_archivecleanup --help
pg_archivecleanup removes older WAL files from PostgreSQL archives.Usage:pg_archivecleanup [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILEOptions:-d generate debug output (verbose mode)-n dry run, show the names of the files that would be removed-V, --version output version information, then exit-x EXT clean up files if they have this extension-?, --help show this help, then exitFor use as archive_cleanup_command in postgresql.conf:archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %r'
e.g.archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %r'Or for use as a standalone archive cleaner:
e.g.pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup
可参考文档:http://www.postgres.cn/docs/14/pgarchivecleanup.html
源码分析
源码不多,在pg_archivecleanup.c
中。
main(int argc, char **argv)
--> Initialize(); // 检查归档目录是否有效
--> SetWALFileNameForCleanup(); // 检查the oldest file we want to remain in archive是否有效
--> CleanupPriorWALFiles(); // 具体的清理归档日志
清理的代码实现如下:
static void CleanupPriorWALFiles(void)
{int rc;DIR *xldir;struct dirent *xlde;char walfile[MAXPGPATH];if ((xldir = opendir(archiveLocation)) != NULL){while (errno = 0, (xlde = readdir(xldir)) != NULL){strlcpy(walfile, xlde->d_name, MAXPGPATH);TrimExtension(walfile, additional_ext);// 比较的时候,忽略时间线,/** We ignore the timeline part of the XLOG segment identifiers in* deciding whether a segment is still needed. This ensures that* we won't prematurely remove a segment from a parent timeline.* We could probably be a little more proactive about removing* segments of non-parent timelines, but that would be a whole lot* more complicated.** We use the alphanumeric sorting property of the filenames to* decide which ones are earlier than the exclusiveCleanupFileName* file. Note that this means files are not removed in the order* they were originally written, in case this worries you.*/if ((IsXLogFileName(walfile) || IsPartialXLogFileName(walfile)) &&strcmp(walfile + 8, exclusiveCleanupFileName + 8) < 0){char WALFilePath[MAXPGPATH * 2]; /* the file path* including archive *//** Use the original file name again now, including any* extension that might have been chopped off before testing* the sequence.*/snprintf(WALFilePath, sizeof(WALFilePath), "%s/%s",archiveLocation, xlde->d_name);if (dryrun){/** Prints the name of the file to be removed and skips the* actual removal. The regular printout is so that the* user can pipe the output into some other program.*/printf("%s\n", WALFilePath);pg_log_debug("file \"%s\" would be removed", WALFilePath);continue;}pg_log_debug("removing file \"%s\"", WALFilePath);rc = unlink(WALFilePath);if (rc != 0)pg_fatal("could not remove file \"%s\": %m",WALFilePath);}}if (errno)pg_fatal("could not read archive location \"%s\": %m",archiveLocation);if (closedir(xldir))pg_fatal("could not close archive location \"%s\": %m",archiveLocation);}elsepg_fatal("could not open archive location \"%s\": %m",archiveLocation);
}
这篇关于PostgreSQL源码分析——pg_archivecleanup的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!