/* * SetWALFileNameForCleanup() * * Set the earliest WAL filename that we want to keep on the archive * and decide whether we need_cleanup */ static void SetWALFileNameForCleanup(void) { bool fnameOK = false; TrimExtension(restartWALFileName, additional_ext); /* * If restartWALFileName is a WAL file name then just use it directly. If * restartWALFileName is a .backup filename, make sure we use the prefix * of the filename, otherwise we will remove wrong files since * 000000010000000000000010.00000020.backup is after * 000000010000000000000010. */ if (strlen(restartWALFileName) == XLOG_DATA_FNAME_LEN && strspn(restartWALFileName, "0123456789ABCDEF") == XLOG_DATA_FNAME_LEN) { strcpy(exclusiveCleanupFileName, restartWALFileName); fnameOK = true; } else if (strlen(restartWALFileName) == XLOG_BACKUP_FNAME_LEN) { int args; uint32 tli = 1, log = 0, seg = 0, offset = 0; args = sscanf(restartWALFileName, "%08X%08X%08X.%08X.backup", &tli, &log, &seg, &offset); if (args == 4) { fnameOK = true; /* * Use just the prefix of the filename, ignore everything after * first period */ XLogFileName(exclusiveCleanupFileName, tli, log, seg); } } if (!fnameOK) { fprintf(stderr, "%s: invalid filename input\n", progname); fprintf(stderr, "Try \"%s --help\" for more information.\n", progname); exit(2); } }
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) { /* * Truncation is essentially harmless, because we skip names of * length other than XLOG_DATA_FNAME_LEN. (In principle, one * could use a 1000-character additional_ext and get trouble.) */ 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 (strlen(walfile) == XLOG_DATA_FNAME_LEN && strspn(walfile, "0123456789ABCDEF") == XLOG_DATA_FNAME_LEN && strcmp(walfile + 8, exclusiveCleanupFileName + 8) < 0) { /* * Use the original file name again now, including any * extension that might have been chopped off before testing * the sequence. */ snprintf(WALFilePath, MAXPGPATH, "%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); if (debug) fprintf(stderr, "%s: file \"%s\" would be removed\n", progname, WALFilePath); continue; } if (debug) fprintf(stderr, "%s: removing file \"%s\"\n", progname, WALFilePath); rc = unlink(WALFilePath); if (rc != 0) { fprintf(stderr, "%s: ERROR: could not remove file \"%s\": %s\n", progname, WALFilePath, strerror(errno)); break; } } } if (errno) fprintf(stderr, "%s: could not read archive location \"%s\": %s\n", progname, archiveLocation, strerror(errno)); if (closedir(xldir)) fprintf(stderr, "%s: could not close archive location \"%s\": %s\n", progname, archiveLocation, strerror(errno)); } else fprintf(stderr, "%s: could not open archive location \"%s\": %s\n", progname, archiveLocation, strerror(errno)); }
/* * SetWALFileNameForCleanup() * * Set the earliest WAL filename that we want to keep on the archive * and decide whether we need cleanup */ static void SetWALFileNameForCleanup(void) { bool fnameOK = false; TrimExtension(restartWALFileName, additional_ext); /* * If restartWALFileName is a WAL file name then just use it directly. If * restartWALFileName is a .partial or .backup filename, make sure we use * the prefix of the filename, otherwise we will remove wrong files since * 000000010000000000000010.partial and * 000000010000000000000010.00000020.backup are after * 000000010000000000000010. */ if (IsXLogFileName(restartWALFileName)) { strcpy(exclusiveCleanupFileName, restartWALFileName); fnameOK = true; } else if (IsPartialXLogFileName(restartWALFileName)) { int args; uint32 tli = 1, log = 0, seg = 0; args = sscanf(restartWALFileName, "%08X%08X%08X.partial", &tli, &log, &seg); if (args == 3) { fnameOK = true; /* * Use just the prefix of the filename, ignore everything after * first period */ XLogFileNameById(exclusiveCleanupFileName, tli, log, seg); } } else if (IsBackupHistoryFileName(restartWALFileName)) { int args; uint32 tli = 1, log = 0, seg = 0, offset = 0; args = sscanf(restartWALFileName, "%08X%08X%08X.%08X.backup", &tli, &log, &seg, &offset); if (args == 4) { fnameOK = true; /* * Use just the prefix of the filename, ignore everything after * first period */ XLogFileNameById(exclusiveCleanupFileName, tli, log, seg); } } if (!fnameOK) { fprintf(stderr, "%s: invalid filename input\n", progname); fprintf(stderr, "Try \"%s --help\" for more information.\n", progname); exit(2); } }