Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit96b6650

Browse files
committed
Revert "Avoid creating archive status ".ready" files too early"
This reverts commit515e3d8 and equivalent commits in backbranches. This solution to the problem has a number of problems, sowe'll try again with a different approach.Per note from Andres FreundDiscussion:https://postgr.es/m/20210831042949.52eqp5xwbxgrfank@alap3.anarazel.de
1 parent87ad491 commit96b6650

File tree

8 files changed

+24
-234
lines changed

8 files changed

+24
-234
lines changed

‎src/backend/access/transam/timeline.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ writeTimeLineHistory(TimeLineID newTLI, TimeLineID parentTLI,
452452
if (XLogArchivingActive())
453453
{
454454
TLHistoryFileName(histfname,newTLI);
455-
XLogArchiveNotify(histfname, true);
455+
XLogArchiveNotify(histfname);
456456
}
457457
}
458458

‎src/backend/access/transam/xlog.c

Lines changed: 11 additions & 209 deletions
Original file line numberDiff line numberDiff line change
@@ -724,18 +724,6 @@ typedef struct XLogCtlData
724724
XLogRecPtrlastFpwDisableRecPtr;
725725

726726
slock_tinfo_lck;/* locks shared variables shown above */
727-
728-
/*
729-
* Variables used to track segment-boundary-crossing WAL records. See
730-
* RegisterSegmentBoundary. Protected by segtrack_lck.
731-
*/
732-
XLogSegNolastNotifiedSeg;
733-
XLogSegNoearliestSegBoundary;
734-
XLogRecPtrearliestSegBoundaryEndPtr;
735-
XLogSegNolatestSegBoundary;
736-
XLogRecPtrlatestSegBoundaryEndPtr;
737-
738-
slock_tsegtrack_lck;/* locks shared variables shown above */
739727
}XLogCtlData;
740728

741729
staticXLogCtlData*XLogCtl=NULL;
@@ -932,7 +920,6 @@ static void RemoveXlogFile(const char *segname, XLogSegNo recycleSegNo,
932920
XLogSegNo*endlogSegNo);
933921
staticvoidUpdateLastRemovedPtr(char*filename);
934922
staticvoidValidateXLOGDirectoryStructure(void);
935-
staticvoidRegisterSegmentBoundary(XLogSegNoseg,XLogRecPtrpos);
936923
staticvoidCleanupBackupHistory(void);
937924
staticvoidUpdateMinRecoveryPoint(XLogRecPtrlsn,boolforce);
938925
staticXLogRecord*ReadRecord(XLogReaderState*xlogreader,
@@ -1167,56 +1154,23 @@ XLogInsertRecord(XLogRecData *rdata,
11671154
END_CRIT_SECTION();
11681155

11691156
/*
1170-
* If we crossed page boundary, update LogwrtRqst.Write; if we crossed
1171-
* segment boundary, register that and wake up walwriter.
1157+
* Update shared LogwrtRqst.Write, if we crossed page boundary.
11721158
*/
11731159
if (StartPos /XLOG_BLCKSZ!=EndPos /XLOG_BLCKSZ)
11741160
{
1175-
XLogSegNoStartSeg;
1176-
XLogSegNoEndSeg;
1177-
1178-
XLByteToSeg(StartPos,StartSeg,wal_segment_size);
1179-
XLByteToSeg(EndPos,EndSeg,wal_segment_size);
1180-
1181-
/*
1182-
* Register our crossing the segment boundary if that occurred.
1183-
*
1184-
* Note that we did not use XLByteToPrevSeg() for determining the
1185-
* ending segment. This is so that a record that fits perfectly into
1186-
* the end of the segment causes the latter to get marked ready for
1187-
* archival immediately.
1188-
*/
1189-
if (StartSeg!=EndSeg&&XLogArchivingActive())
1190-
RegisterSegmentBoundary(EndSeg,EndPos);
1191-
1192-
/*
1193-
* Advance LogwrtRqst.Write so that it includes new block(s).
1194-
*
1195-
* We do this after registering the segment boundary so that the
1196-
* comparison with the flushed pointer below can use the latest value
1197-
* known globally.
1198-
*/
11991161
SpinLockAcquire(&XLogCtl->info_lck);
1162+
/* advance global request to include new block(s) */
12001163
if (XLogCtl->LogwrtRqst.Write<EndPos)
12011164
XLogCtl->LogwrtRqst.Write=EndPos;
12021165
/* update local result copy while I have the chance */
12031166
LogwrtResult=XLogCtl->LogwrtResult;
12041167
SpinLockRelease(&XLogCtl->info_lck);
1205-
1206-
/*
1207-
* There's a chance that the record was already flushed to disk and we
1208-
* missed marking segments as ready for archive. If this happens, we
1209-
* nudge the WALWriter, which will take care of notifying segments as
1210-
* needed.
1211-
*/
1212-
if (StartSeg!=EndSeg&&XLogArchivingActive()&&
1213-
LogwrtResult.Flush >=EndPos&&ProcGlobal->walwriterLatch)
1214-
SetLatch(ProcGlobal->walwriterLatch);
12151168
}
12161169

12171170
/*
12181171
* If this was an XLOG_SWITCH record, flush the record and the empty
1219-
* padding space that fills the rest of the segment.
1172+
* padding space that fills the rest of the segment, and perform
1173+
* end-of-segment actions (eg, notifying archiver).
12201174
*/
12211175
if (isLogSwitch)
12221176
{
@@ -2467,7 +2421,6 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
24672421

24682422
/* We should always be inside a critical section here */
24692423
Assert(CritSectionCount>0);
2470-
Assert(LWLockHeldByMe(WALWriteLock));
24712424

24722425
/*
24732426
* Update local LogwrtResult (caller probably did this already, but...)
@@ -2633,12 +2586,11 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
26332586
* later. Doing it here ensures that one and only one backend will
26342587
* perform this fsync.
26352588
*
2636-
* If WAL archiving is active, we attempt to notify the archiver
2637-
* of any segments that are now ready for archival.
2638-
*
2639-
* This is also the right place to update the timer for
2640-
* archive_timeout and to signal for a checkpoint if too many
2641-
* logfile segments have been used since the last checkpoint.
2589+
* This is also the right place to notify the Archiver that the
2590+
* segment is ready to copy to archival storage, and to update the
2591+
* timer for archive_timeout, and to signal for a checkpoint if
2592+
* too many logfile segments have been used since the last
2593+
* checkpoint.
26422594
*/
26432595
if (finishing_seg)
26442596
{
@@ -2650,7 +2602,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
26502602
LogwrtResult.Flush=LogwrtResult.Write;/* end of page */
26512603

26522604
if (XLogArchivingActive())
2653-
NotifySegmentsReadyForArchive(LogwrtResult.Flush);
2605+
XLogArchiveNotifySeg(openLogSegNo);
26542606

26552607
XLogCtl->lastSegSwitchTime= (pg_time_t)time(NULL);
26562608
XLogCtl->lastSegSwitchLSN=LogwrtResult.Flush;
@@ -2738,9 +2690,6 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
27382690
XLogCtl->LogwrtRqst.Flush=LogwrtResult.Flush;
27392691
SpinLockRelease(&XLogCtl->info_lck);
27402692
}
2741-
2742-
if (XLogArchivingActive())
2743-
NotifySegmentsReadyForArchive(LogwrtResult.Flush);
27442693
}
27452694

27462695
/*
@@ -4379,131 +4328,6 @@ ValidateXLOGDirectoryStructure(void)
43794328
}
43804329
}
43814330

4382-
/*
4383-
* RegisterSegmentBoundary
4384-
*
4385-
* WAL records that are split across a segment boundary require special
4386-
* treatment for archiving: the initial segment must not be archived until
4387-
* the end segment has been flushed, in case we crash before we have
4388-
* the chance to flush the end segment (because after recovery we would
4389-
* overwrite that WAL record with a different one, and so the file we
4390-
* archived no longer represents truth.) This also applies to streaming
4391-
* physical replication.
4392-
*
4393-
* To handle this, we keep track of the LSN of WAL records that cross
4394-
* segment boundaries. Two such are sufficient: the ones with the
4395-
* earliest and the latest end pointers we know about, since the flush
4396-
* position advances monotonically. WAL record writers register
4397-
* boundary-crossing records here, which is used by .ready file creation
4398-
* to delay until the end segment is known flushed.
4399-
*/
4400-
staticvoid
4401-
RegisterSegmentBoundary(XLogSegNoseg,XLogRecPtrendpos)
4402-
{
4403-
XLogSegNosegnoPG_USED_FOR_ASSERTS_ONLY;
4404-
4405-
/* verify caller computed segment number correctly */
4406-
AssertArg((XLByteToSeg(endpos,segno,wal_segment_size),segno==seg));
4407-
4408-
SpinLockAcquire(&XLogCtl->segtrack_lck);
4409-
4410-
/*
4411-
* If no segment boundaries are registered, store the new segment boundary
4412-
* in earliestSegBoundary. Otherwise, store the greater segment
4413-
* boundaries in latestSegBoundary.
4414-
*/
4415-
if (XLogCtl->earliestSegBoundary==MaxXLogSegNo)
4416-
{
4417-
XLogCtl->earliestSegBoundary=seg;
4418-
XLogCtl->earliestSegBoundaryEndPtr=endpos;
4419-
}
4420-
elseif (seg>XLogCtl->earliestSegBoundary&&
4421-
(XLogCtl->latestSegBoundary==MaxXLogSegNo||
4422-
seg>XLogCtl->latestSegBoundary))
4423-
{
4424-
XLogCtl->latestSegBoundary=seg;
4425-
XLogCtl->latestSegBoundaryEndPtr=endpos;
4426-
}
4427-
4428-
SpinLockRelease(&XLogCtl->segtrack_lck);
4429-
}
4430-
4431-
/*
4432-
* NotifySegmentsReadyForArchive
4433-
*
4434-
* Mark segments as ready for archival, given that it is safe to do so.
4435-
* This function is idempotent.
4436-
*/
4437-
void
4438-
NotifySegmentsReadyForArchive(XLogRecPtrflushRecPtr)
4439-
{
4440-
XLogSegNolatest_boundary_seg;
4441-
XLogSegNolast_notified;
4442-
XLogSegNoflushed_seg;
4443-
XLogSegNoseg;
4444-
boolkeep_latest;
4445-
4446-
XLByteToSeg(flushRecPtr,flushed_seg,wal_segment_size);
4447-
4448-
SpinLockAcquire(&XLogCtl->segtrack_lck);
4449-
4450-
if (XLogCtl->latestSegBoundary <=flushed_seg&&
4451-
XLogCtl->latestSegBoundaryEndPtr <=flushRecPtr)
4452-
{
4453-
latest_boundary_seg=XLogCtl->latestSegBoundary;
4454-
keep_latest= false;
4455-
}
4456-
elseif (XLogCtl->earliestSegBoundary <=flushed_seg&&
4457-
XLogCtl->earliestSegBoundaryEndPtr <=flushRecPtr)
4458-
{
4459-
latest_boundary_seg=XLogCtl->earliestSegBoundary;
4460-
keep_latest= true;
4461-
}
4462-
else
4463-
{
4464-
SpinLockRelease(&XLogCtl->segtrack_lck);
4465-
return;
4466-
}
4467-
4468-
last_notified=XLogCtl->lastNotifiedSeg;
4469-
4470-
/*
4471-
* Update shared memory and discard segment boundaries that are no longer
4472-
* needed.
4473-
*
4474-
* It is safe to update shared memory before we attempt to create the
4475-
* .ready files. If our calls to XLogArchiveNotifySeg() fail,
4476-
* RemoveOldXlogFiles() will retry it as needed.
4477-
*/
4478-
if (last_notified<latest_boundary_seg-1)
4479-
XLogCtl->lastNotifiedSeg=latest_boundary_seg-1;
4480-
4481-
if (keep_latest)
4482-
{
4483-
XLogCtl->earliestSegBoundary=XLogCtl->latestSegBoundary;
4484-
XLogCtl->earliestSegBoundaryEndPtr=XLogCtl->latestSegBoundaryEndPtr;
4485-
}
4486-
else
4487-
{
4488-
XLogCtl->earliestSegBoundary=MaxXLogSegNo;
4489-
XLogCtl->earliestSegBoundaryEndPtr=InvalidXLogRecPtr;
4490-
}
4491-
4492-
XLogCtl->latestSegBoundary=MaxXLogSegNo;
4493-
XLogCtl->latestSegBoundaryEndPtr=InvalidXLogRecPtr;
4494-
4495-
SpinLockRelease(&XLogCtl->segtrack_lck);
4496-
4497-
/*
4498-
* Notify archiver about segments that are ready for archival (by creating
4499-
* the corresponding .ready files).
4500-
*/
4501-
for (seg=last_notified+1;seg<latest_boundary_seg;seg++)
4502-
XLogArchiveNotifySeg(seg, false);
4503-
4504-
PgArchWakeup();
4505-
}
4506-
45074331
/*
45084332
* Remove previous backup history files. This also retries creation of
45094333
* .ready files for any backup history files for which XLogArchiveNotify
@@ -5406,17 +5230,9 @@ XLOGShmemInit(void)
54065230

54075231
SpinLockInit(&XLogCtl->Insert.insertpos_lck);
54085232
SpinLockInit(&XLogCtl->info_lck);
5409-
SpinLockInit(&XLogCtl->segtrack_lck);
54105233
SpinLockInit(&XLogCtl->ulsn_lck);
54115234
InitSharedLatch(&XLogCtl->recoveryWakeupLatch);
54125235
ConditionVariableInit(&XLogCtl->recoveryNotPausedCV);
5413-
5414-
/* Initialize stuff for marking segments as ready for archival. */
5415-
XLogCtl->lastNotifiedSeg=MaxXLogSegNo;
5416-
XLogCtl->earliestSegBoundary=MaxXLogSegNo;
5417-
XLogCtl->earliestSegBoundaryEndPtr=InvalidXLogRecPtr;
5418-
XLogCtl->latestSegBoundary=MaxXLogSegNo;
5419-
XLogCtl->latestSegBoundaryEndPtr=InvalidXLogRecPtr;
54205236
}
54215237

54225238
/*
@@ -8057,20 +7873,6 @@ StartupXLOG(void)
80577873
XLogCtl->LogwrtRqst.Write=EndOfLog;
80587874
XLogCtl->LogwrtRqst.Flush=EndOfLog;
80597875

8060-
/*
8061-
* Initialize XLogCtl->lastNotifiedSeg to the previous WAL file.
8062-
*/
8063-
if (XLogArchivingActive())
8064-
{
8065-
XLogSegNoEndOfLogSeg;
8066-
8067-
XLByteToSeg(EndOfLog,EndOfLogSeg,wal_segment_size);
8068-
8069-
SpinLockAcquire(&XLogCtl->segtrack_lck);
8070-
XLogCtl->lastNotifiedSeg=EndOfLogSeg-1;
8071-
SpinLockRelease(&XLogCtl->segtrack_lck);
8072-
}
8073-
80747876
/*
80757877
* Update full_page_writes in shared memory and write an XLOG_FPW_CHANGE
80767878
* record before resource manager writes cleanup WAL records or checkpoint
@@ -8198,7 +8000,7 @@ StartupXLOG(void)
81988000
XLogArchiveCleanup(partialfname);
81998001

82008002
durable_rename(origpath,partialpath,ERROR);
8201-
XLogArchiveNotify(partialfname, true);
8003+
XLogArchiveNotify(partialfname);
82028004
}
82038005
}
82048006
}

‎src/backend/access/transam/xlogarchive.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ KeepFileRestoredFromArchive(const char *path, const char *xlogfname)
433433
if (XLogArchiveMode!=ARCHIVE_MODE_ALWAYS)
434434
XLogArchiveForceDone(xlogfname);
435435
else
436-
XLogArchiveNotify(xlogfname, true);
436+
XLogArchiveNotify(xlogfname);
437437

438438
/*
439439
* If the existing file was replaced, since walsenders might have it open,
@@ -462,12 +462,9 @@ KeepFileRestoredFromArchive(const char *path, const char *xlogfname)
462462
* by the archiver, e.g. we write 0000000100000001000000C6.ready
463463
* and the archiver then knows to archive XLOGDIR/0000000100000001000000C6,
464464
* then when complete, rename it to 0000000100000001000000C6.done
465-
*
466-
* Optionally, nudge the archiver process so that it'll notice the file we
467-
* create.
468465
*/
469466
void
470-
XLogArchiveNotify(constchar*xlog,boolnudge)
467+
XLogArchiveNotify(constchar*xlog)
471468
{
472469
chararchiveStatusPath[MAXPGPATH];
473470
FILE*fd;
@@ -492,21 +489,21 @@ XLogArchiveNotify(const char *xlog, bool nudge)
492489
return;
493490
}
494491

495-
/*If caller requested, letarchiverknow it's gotwork to do */
496-
if (nudge)
492+
/*Notifyarchiverthat it's gotsomething to do */
493+
if (IsUnderPostmaster)
497494
PgArchWakeup();
498495
}
499496

500497
/*
501498
* Convenience routine to notify using segment number representation of filename
502499
*/
503500
void
504-
XLogArchiveNotifySeg(XLogSegNosegno,boolnudge)
501+
XLogArchiveNotifySeg(XLogSegNosegno)
505502
{
506503
charxlog[MAXFNAMELEN];
507504

508505
XLogFileName(xlog,ThisTimeLineID,segno,wal_segment_size);
509-
XLogArchiveNotify(xlog,nudge);
506+
XLogArchiveNotify(xlog);
510507
}
511508

512509
/*
@@ -611,7 +608,7 @@ XLogArchiveCheckDone(const char *xlog)
611608
return true;
612609

613610
/* Retry creation of the .ready file */
614-
XLogArchiveNotify(xlog, true);
611+
XLogArchiveNotify(xlog);
615612
return false;
616613
}
617614

‎src/backend/postmaster/walwriter.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -248,13 +248,6 @@ WalWriterMain(void)
248248
/* Process any signals received recently */
249249
HandleWalWriterInterrupts();
250250

251-
/*
252-
* Notify the archiver of any WAL segments that are ready. We do this
253-
* here to handle a race condition where WAL is flushed to disk prior
254-
* to registering the segment boundary.
255-
*/
256-
NotifySegmentsReadyForArchive(GetFlushRecPtr());
257-
258251
/*
259252
* Do what we're here for; then, if XLogBackgroundFlush() found useful
260253
* work to do, reset hibernation counter.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp