dont_archive_restored_walfile_v2.patch
application/octet-stream
Filename: dont_archive_restored_walfile_v2.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: context
Series: patch v2
| File | + | − |
|---|---|---|
| src/backend/access/transam/xlogarchive.c | 59 | 0 |
| src/backend/replication/walreceiver.c | 19 | 0 |
| src/include/access/xlog_internal.h | 1 | 0 |
*** a/src/backend/access/transam/xlogarchive.c
--- b/src/backend/access/transam/xlogarchive.c
***************
*** 474,479 **** KeepFileRestoredFromArchive(char *path, char *xlogfname)
--- 474,485 ----
path, xlogfpath)));
/*
+ * Create .done file forcibly to prevent the restored segment from
+ * being archived again later.
+ */
+ XLogArchiveForceDone(xlogfname);
+
+ /*
* If the existing file was replaced, since walsenders might have it
* open, request them to reload a currently-open segment. This is only
* required for WAL segments, walsenders don't hold other files open, but
***************
*** 545,550 **** XLogArchiveNotifySeg(XLogSegNo segno)
--- 551,609 ----
}
/*
+ * XLogArchiveForceDone
+ *
+ * Emit notification forcibly that an XLOG segment file has been successfully
+ * archived, by creating <XLOG>.done regardless of whether <XLOG>.ready
+ * exists or not.
+ */
+ void
+ XLogArchiveForceDone(const char *xlog)
+ {
+ char archiveReady[MAXPGPATH];
+ char archiveDone[MAXPGPATH];
+ struct stat stat_buf;
+ FILE *fd;
+
+ /* Exit if already known done */
+ StatusFilePath(archiveDone, xlog, ".done");
+ if (stat(archiveDone, &stat_buf) == 0)
+ return;
+
+ /* If .ready exists, rename it to .done */
+ StatusFilePath(archiveReady, xlog, ".ready");
+ if (stat(archiveReady, &stat_buf) == 0)
+ {
+ if (rename(archiveReady, archiveDone) < 0)
+ ereport(WARNING,
+ (errcode_for_file_access(),
+ errmsg("could not rename file \"%s\" to \"%s\": %m",
+ archiveReady, archiveDone)));
+
+ return;
+ }
+
+ /* insert an otherwise empty file called <XLOG>.done */
+ fd = AllocateFile(archiveDone, "w");
+ if (fd == NULL)
+ {
+ ereport(LOG,
+ (errcode_for_file_access(),
+ errmsg("could not create archive status file \"%s\": %m",
+ archiveDone)));
+ return;
+ }
+ if (FreeFile(fd))
+ {
+ ereport(LOG,
+ (errcode_for_file_access(),
+ errmsg("could not write archive status file \"%s\": %m",
+ archiveDone)));
+ return;
+ }
+ }
+
+ /*
* XLogArchiveCheckDone
*
* This is called when we are ready to delete or recycle an old XLOG segment
*** a/src/backend/replication/walreceiver.c
--- b/src/backend/replication/walreceiver.c
***************
*** 83,89 **** walrcv_disconnect_type walrcv_disconnect = NULL;
/*
* These variables are used similarly to openLogFile/SegNo/Off,
* but for walreceiver to write the XLOG. recvFileTLI is the TimeLineID
! * corresponding the filename of recvFile, used for error messages.
*/
static int recvFile = -1;
static TimeLineID recvFileTLI = 0;
--- 83,89 ----
/*
* These variables are used similarly to openLogFile/SegNo/Off,
* but for walreceiver to write the XLOG. recvFileTLI is the TimeLineID
! * corresponding the filename of recvFile.
*/
static int recvFile = -1;
static TimeLineID recvFileTLI = 0;
***************
*** 528,539 **** WalReceiverMain(void)
--- 528,548 ----
*/
if (recvFile >= 0)
{
+ char xlogfname[MAXFNAMELEN];
+
XLogWalRcvFlush(false);
if (close(recvFile) != 0)
ereport(PANIC,
(errcode_for_file_access(),
errmsg("could not close log segment %s: %m",
XLogFileNameP(recvFileTLI, recvSegNo))));
+
+ /*
+ * Create .done file forcibly to prevent the streamed segment from
+ * being archived later.
+ */
+ XLogFileName(xlogfname, recvFileTLI, recvSegNo);
+ XLogArchiveForceDone(xlogfname);
}
recvFile = -1;
***************
*** 865,870 **** XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
--- 874,881 ----
*/
if (recvFile >= 0)
{
+ char xlogfname[MAXFNAMELEN];
+
XLogWalRcvFlush(false);
/*
***************
*** 877,882 **** XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
--- 888,900 ----
(errcode_for_file_access(),
errmsg("could not close log segment %s: %m",
XLogFileNameP(recvFileTLI, recvSegNo))));
+
+ /*
+ * Create .done file forcibly to prevent the streamed segment from
+ * being archived later.
+ */
+ XLogFileName(xlogfname, recvFileTLI, recvSegNo);
+ XLogArchiveForceDone(xlogfname);
}
recvFile = -1;
*** a/src/include/access/xlog_internal.h
--- b/src/include/access/xlog_internal.h
***************
*** 278,283 **** extern void ExecuteRecoveryCommand(char *command, char *commandName,
--- 278,284 ----
extern void KeepFileRestoredFromArchive(char *path, char *xlogfname);
extern void XLogArchiveNotify(const char *xlog);
extern void XLogArchiveNotifySeg(XLogSegNo segno);
+ extern void XLogArchiveForceDone(const char *xlog);
extern bool XLogArchiveCheckDone(const char *xlog);
extern bool XLogArchiveIsBusy(const char *xlog);
extern void XLogArchiveCleanup(const char *xlog);