Skip to content

Commit 6f4b8a4

Browse files
Force archive_status of .done for xlogs created by dearchival/replication.
This prevents spurious attempts to archive xlog files after promotion of standby, a bug introduced by cascading replication patch in 9.2. Fujii Masao, simplified and extended to cover streaming by Simon Riggs
1 parent 7c055d6 commit 6f4b8a4

File tree

3 files changed

+78
-2
lines changed

3 files changed

+78
-2
lines changed

src/backend/access/transam/xlog.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,6 +1335,59 @@ XLogArchiveNotifySeg(uint32 log, uint32 seg)
13351335
XLogArchiveNotify(xlog);
13361336
}
13371337

1338+
/*
1339+
* XLogArchiveForceDone
1340+
*
1341+
* Emit notification forcibly that an XLOG segment file has been successfully
1342+
* archived, by creating <XLOG>.done regardless of whether <XLOG>.ready
1343+
* exists or not.
1344+
*/
1345+
void
1346+
XLogArchiveForceDone(const char *xlog)
1347+
{
1348+
char archiveReady[MAXPGPATH];
1349+
char archiveDone[MAXPGPATH];
1350+
struct stat stat_buf;
1351+
FILE *fd;
1352+
1353+
/* Exit if already known done */
1354+
StatusFilePath(archiveDone, xlog, ".done");
1355+
if (stat(archiveDone, &stat_buf) == 0)
1356+
return;
1357+
1358+
/* If .ready exists, rename it to .done */
1359+
StatusFilePath(archiveReady, xlog, ".ready");
1360+
if (stat(archiveReady, &stat_buf) == 0)
1361+
{
1362+
if (rename(archiveReady, archiveDone) < 0)
1363+
ereport(WARNING,
1364+
(errcode_for_file_access(),
1365+
errmsg("could not rename file \"%s\" to \"%s\": %m",
1366+
archiveReady, archiveDone)));
1367+
1368+
return;
1369+
}
1370+
1371+
/* insert an otherwise empty file called <XLOG>.done */
1372+
fd = AllocateFile(archiveDone, "w");
1373+
if (fd == NULL)
1374+
{
1375+
ereport(LOG,
1376+
(errcode_for_file_access(),
1377+
errmsg("could not create archive status file \"%s\": %m",
1378+
archiveDone)));
1379+
return;
1380+
}
1381+
if (FreeFile(fd))
1382+
{
1383+
ereport(LOG,
1384+
(errcode_for_file_access(),
1385+
errmsg("could not write archive status file \"%s\": %m",
1386+
archiveDone)));
1387+
return;
1388+
}
1389+
}
1390+
13381391
/*
13391392
* XLogArchiveCheckDone
13401393
*
@@ -2814,6 +2867,12 @@ XLogFileRead(uint32 log, uint32 seg, int emode, TimeLineID tli,
28142867
*/
28152868
strncpy(path, xlogfpath, MAXPGPATH);
28162869

2870+
/*
2871+
* Create .done file forcibly to prevent the restored segment from
2872+
* being archived again later.
2873+
*/
2874+
XLogArchiveForceDone(xlogfname);
2875+
28172876
/*
28182877
* If the existing segment was replaced, since walsenders might have
28192878
* it open, request them to reload a currently-open segment.

src/backend/replication/walreceiver.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,12 @@ walrcv_disconnect_type walrcv_disconnect = NULL;
6666
#define NAPTIME_PER_CYCLE 100 /* max sleep time between cycles (100ms) */
6767

6868
/*
69-
* These variables are used similarly to openLogFile/Id/Seg/Off,
70-
* but for walreceiver to write the XLOG.
69+
* These variables are used similarly to openLogFile/SegNo/Off,
70+
* but for walreceiver to write the XLOG. recvFileTLI is the TimeLineID
71+
* corresponding the filename of recvFile.
7172
*/
7273
static int recvFile = -1;
74+
static TimeLineID recvFileTLI = 0;
7375
static uint32 recvId = 0;
7476
static uint32 recvSeg = 0;
7577
static uint32 recvOff = 0;
@@ -492,6 +494,8 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
492494
*/
493495
if (recvFile >= 0)
494496
{
497+
char xlogfname[MAXFNAMELEN];
498+
495499
XLogWalRcvFlush(false);
496500

497501
/*
@@ -504,13 +508,21 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
504508
(errcode_for_file_access(),
505509
errmsg("could not close log file %u, segment %u: %m",
506510
recvId, recvSeg)));
511+
512+
/*
513+
* Create .done file forcibly to prevent the restored segment from
514+
* being archived again later.
515+
*/
516+
XLogFileName(xlogfname, recvFileTLI, recvId, recvSeg);
517+
XLogArchiveForceDone(xlogfname);
507518
}
508519
recvFile = -1;
509520

510521
/* Create/use new log file */
511522
XLByteToSeg(recptr, recvId, recvSeg);
512523
use_existent = true;
513524
recvFile = XLogFileInit(recvId, recvSeg, &use_existent, true);
525+
recvFileTLI = ThisTimeLineID;
514526
recvOff = 0;
515527
}
516528

src/include/access/xlog_internal.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,11 @@ extern const RmgrData RmgrTable[];
263263
extern pg_time_t GetLastSegSwitchTime(void);
264264
extern XLogRecPtr RequestXLogSwitch(void);
265265

266+
/*
267+
* Exported to support xlog archive status setting from WALReceiver
268+
*/
269+
extern void XLogArchiveForceDone(const char *xlog);
270+
266271
/*
267272
* These aren't in xlog.h because I'd rather not include fmgr.h there.
268273
*/

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy