*** a/doc/src/sgml/ref/pg_xlogdump.sgml --- b/doc/src/sgml/ref/pg_xlogdump.sgml *************** *** 215,220 **** PostgreSQL documentation --- 215,226 ---- Only the specified timeline is displayed (or the default, if none is specified). Records in other timelines are ignored. + + + pg_xlogdump cannot read WAL files with suffix + .partial. If those files need to be read, .partial + suffix needs to be removed from the filename. + *** a/doc/src/sgml/ref/pgarchivecleanup.sgml --- b/doc/src/sgml/ref/pgarchivecleanup.sgml *************** *** 60,67 **** archive_cleanup_command = 'pg_archivecleanup archivelocation %r' When used as a standalone program all WAL files logically preceding the oldestkeptwalfile will be removed from archivelocation. ! In this mode, if you specify a .backup file name, then only the file prefix ! will be used as the oldestkeptwalfile. This allows you to remove all WAL files archived prior to a specific base backup without error. For example, the following example will remove all files older than WAL file name 000000010000003700000010: --- 60,69 ---- When used as a standalone program all WAL files logically preceding the oldestkeptwalfile will be removed from archivelocation. ! In this mode, if you specify a .partial or .backup ! file name, then only the file prefix will be used as the ! oldestkeptwalfile. This treatment of .backup ! file name allows you to remove all WAL files archived prior to a specific base backup without error. For example, the following example will remove all files older than WAL file name 000000010000003700000010: *** a/src/bin/pg_archivecleanup/pg_archivecleanup.c --- b/src/bin/pg_archivecleanup/pg_archivecleanup.c *************** *** 125,131 **** CleanupPriorWALFiles(void) * file. Note that this means files are not removed in the order * they were originally written, in case this worries you. */ ! if (IsXLogFileName(walfile) && strcmp(walfile + 8, exclusiveCleanupFileName + 8) < 0) { /* --- 125,131 ---- * 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) { /* *************** *** 181,187 **** CleanupPriorWALFiles(void) * SetWALFileNameForCleanup() * * Set the earliest WAL filename that we want to keep on the archive ! * and decide whether we need_cleanup */ static void SetWALFileNameForCleanup(void) --- 181,187 ---- * SetWALFileNameForCleanup() * * Set the earliest WAL filename that we want to keep on the archive ! * and decide whether we need cleanup */ static void SetWALFileNameForCleanup(void) *************** *** 192,200 **** SetWALFileNameForCleanup(void) /* * 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 (IsXLogFileName(restartWALFileName)) --- 192,201 ---- /* * 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)) *************** *** 202,207 **** SetWALFileNameForCleanup(void) --- 203,228 ---- 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; *** a/src/bin/pg_resetxlog/pg_resetxlog.c --- b/src/bin/pg_resetxlog/pg_resetxlog.c *************** *** 906,912 **** FindEndOfXLOG(void) while (errno = 0, (xlde = readdir(xldir)) != NULL) { ! if (IsXLogFileName(xlde->d_name)) { unsigned int tli, log, --- 906,913 ---- while (errno = 0, (xlde = readdir(xldir)) != NULL) { ! if (IsXLogFileName(xlde->d_name) || ! IsPartialXLogFileName(xlde->d_name)) { unsigned int tli, log, *************** *** 976,982 **** KillExistingXLOG(void) while (errno = 0, (xlde = readdir(xldir)) != NULL) { ! if (IsXLogFileName(xlde->d_name)) { snprintf(path, MAXPGPATH, "%s/%s", XLOGDIR, xlde->d_name); if (unlink(path) < 0) --- 977,984 ---- while (errno = 0, (xlde = readdir(xldir)) != NULL) { ! if (IsXLogFileName(xlde->d_name) || ! IsPartialXLogFileName(xlde->d_name)) { snprintf(path, MAXPGPATH, "%s/%s", XLOGDIR, xlde->d_name); if (unlink(path) < 0) *************** *** 1028,1034 **** KillExistingArchiveStatus(void) { if (strspn(xlde->d_name, "0123456789ABCDEF") == XLOG_FNAME_LEN && (strcmp(xlde->d_name + XLOG_FNAME_LEN, ".ready") == 0 || ! strcmp(xlde->d_name + XLOG_FNAME_LEN, ".done") == 0)) { snprintf(path, MAXPGPATH, "%s/%s", ARCHSTATDIR, xlde->d_name); if (unlink(path) < 0) --- 1030,1038 ---- { if (strspn(xlde->d_name, "0123456789ABCDEF") == XLOG_FNAME_LEN && (strcmp(xlde->d_name + XLOG_FNAME_LEN, ".ready") == 0 || ! strcmp(xlde->d_name + XLOG_FNAME_LEN, ".done") == 0 || ! strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.ready") == 0 || ! strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.done") == 0)) { snprintf(path, MAXPGPATH, "%s/%s", ARCHSTATDIR, xlde->d_name); if (unlink(path) < 0)