@@ -725,18 +725,6 @@ typedef struct XLogCtlData
725
725
XLogRecPtr lastFpwDisableRecPtr ;
726
726
727
727
slock_t info_lck ; /* locks shared variables shown above */
728
-
729
- /*
730
- * Variables used to track segment-boundary-crossing WAL records. See
731
- * RegisterSegmentBoundary. Protected by segtrack_lck.
732
- */
733
- XLogSegNo lastNotifiedSeg ;
734
- XLogSegNo earliestSegBoundary ;
735
- XLogRecPtr earliestSegBoundaryEndPtr ;
736
- XLogSegNo latestSegBoundary ;
737
- XLogRecPtr latestSegBoundaryEndPtr ;
738
-
739
- slock_t segtrack_lck ; /* locks shared variables shown above */
740
728
} XLogCtlData ;
741
729
742
730
static XLogCtlData * XLogCtl = NULL ;
@@ -933,7 +921,6 @@ static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecP
933
921
static void RemoveXlogFile (const char * segname , XLogRecPtr lastredoptr , XLogRecPtr endptr );
934
922
static void UpdateLastRemovedPtr (char * filename );
935
923
static void ValidateXLOGDirectoryStructure (void );
936
- static void RegisterSegmentBoundary (XLogSegNo seg , XLogRecPtr pos );
937
924
static void CleanupBackupHistory (void );
938
925
static void UpdateMinRecoveryPoint (XLogRecPtr lsn , bool force );
939
926
static XLogRecord * ReadRecord (XLogReaderState * xlogreader ,
@@ -1167,56 +1154,23 @@ XLogInsertRecord(XLogRecData *rdata,
1167
1154
END_CRIT_SECTION ();
1168
1155
1169
1156
/*
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.
1172
1158
*/
1173
1159
if (StartPos / XLOG_BLCKSZ != EndPos / XLOG_BLCKSZ )
1174
1160
{
1175
- XLogSegNo StartSeg ;
1176
- XLogSegNo EndSeg ;
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
- */
1199
1161
SpinLockAcquire (& XLogCtl -> info_lck );
1162
+ /* advance global request to include new block(s) */
1200
1163
if (XLogCtl -> LogwrtRqst .Write < EndPos )
1201
1164
XLogCtl -> LogwrtRqst .Write = EndPos ;
1202
1165
/* update local result copy while I have the chance */
1203
1166
LogwrtResult = XLogCtl -> LogwrtResult ;
1204
1167
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 );
1215
1168
}
1216
1169
1217
1170
/*
1218
1171
* 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).
1220
1174
*/
1221
1175
if (isLogSwitch )
1222
1176
{
@@ -2468,7 +2422,6 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
2468
2422
2469
2423
/* We should always be inside a critical section here */
2470
2424
Assert (CritSectionCount > 0 );
2471
- Assert (LWLockHeldByMe (WALWriteLock ));
2472
2425
2473
2426
/*
2474
2427
* Update local LogwrtResult (caller probably did this already, but...)
@@ -2614,12 +2567,11 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
2614
2567
* later. Doing it here ensures that one and only one backend will
2615
2568
* perform this fsync.
2616
2569
*
2617
- * If WAL archiving is active, we attempt to notify the archiver
2618
- * of any segments that are now ready for archival.
2619
- *
2620
- * This is also the right place to update the timer for
2621
- * archive_timeout and to signal for a checkpoint if too many
2622
- * logfile segments have been used since the last checkpoint.
2570
+ * This is also the right place to notify the Archiver that the
2571
+ * segment is ready to copy to archival storage, and to update the
2572
+ * timer for archive_timeout, and to signal for a checkpoint if
2573
+ * too many logfile segments have been used since the last
2574
+ * checkpoint.
2623
2575
*/
2624
2576
if (finishing_seg )
2625
2577
{
@@ -2631,7 +2583,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
2631
2583
LogwrtResult .Flush = LogwrtResult .Write ; /* end of page */
2632
2584
2633
2585
if (XLogArchivingActive ())
2634
- NotifySegmentsReadyForArchive ( LogwrtResult . Flush );
2586
+ XLogArchiveNotifySeg ( openLogSegNo );
2635
2587
2636
2588
XLogCtl -> lastSegSwitchTime = (pg_time_t ) time (NULL );
2637
2589
XLogCtl -> lastSegSwitchLSN = LogwrtResult .Flush ;
@@ -2719,9 +2671,6 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
2719
2671
XLogCtl -> LogwrtRqst .Flush = LogwrtResult .Flush ;
2720
2672
SpinLockRelease (& XLogCtl -> info_lck );
2721
2673
}
2722
-
2723
- if (XLogArchivingActive ())
2724
- NotifySegmentsReadyForArchive (LogwrtResult .Flush );
2725
2674
}
2726
2675
2727
2676
/*
@@ -4331,129 +4280,6 @@ ValidateXLOGDirectoryStructure(void)
4331
4280
}
4332
4281
}
4333
4282
4334
- /*
4335
- * RegisterSegmentBoundary
4336
- *
4337
- * WAL records that are split across a segment boundary require special
4338
- * treatment for archiving: the initial segment must not be archived until
4339
- * the end segment has been flushed, in case we crash before we have
4340
- * the chance to flush the end segment (because after recovery we would
4341
- * overwrite that WAL record with a different one, and so the file we
4342
- * archived no longer represents truth.) This also applies to streaming
4343
- * physical replication.
4344
- *
4345
- * To handle this, we keep track of the LSN of WAL records that cross
4346
- * segment boundaries. Two such are sufficient: the ones with the
4347
- * earliest and the latest end pointers we know about, since the flush
4348
- * position advances monotonically. WAL record writers register
4349
- * boundary-crossing records here, which is used by .ready file creation
4350
- * to delay until the end segment is known flushed.
4351
- */
4352
- static void
4353
- RegisterSegmentBoundary (XLogSegNo seg , XLogRecPtr endpos )
4354
- {
4355
- XLogSegNo segno PG_USED_FOR_ASSERTS_ONLY ;
4356
-
4357
- /* verify caller computed segment number correctly */
4358
- AssertArg ((XLByteToSeg (endpos , segno , wal_segment_size ), segno == seg ));
4359
-
4360
- SpinLockAcquire (& XLogCtl -> segtrack_lck );
4361
-
4362
- /*
4363
- * If no segment boundaries are registered, store the new segment boundary
4364
- * in earliestSegBoundary. Otherwise, store the greater segment
4365
- * boundaries in latestSegBoundary.
4366
- */
4367
- if (XLogCtl -> earliestSegBoundary == MaxXLogSegNo )
4368
- {
4369
- XLogCtl -> earliestSegBoundary = seg ;
4370
- XLogCtl -> earliestSegBoundaryEndPtr = endpos ;
4371
- }
4372
- else if (seg > XLogCtl -> earliestSegBoundary &&
4373
- (XLogCtl -> latestSegBoundary == MaxXLogSegNo ||
4374
- seg > XLogCtl -> latestSegBoundary ))
4375
- {
4376
- XLogCtl -> latestSegBoundary = seg ;
4377
- XLogCtl -> latestSegBoundaryEndPtr = endpos ;
4378
- }
4379
-
4380
- SpinLockRelease (& XLogCtl -> segtrack_lck );
4381
- }
4382
-
4383
- /*
4384
- * NotifySegmentsReadyForArchive
4385
- *
4386
- * Mark segments as ready for archival, given that it is safe to do so.
4387
- * This function is idempotent.
4388
- */
4389
- void
4390
- NotifySegmentsReadyForArchive (XLogRecPtr flushRecPtr )
4391
- {
4392
- XLogSegNo latest_boundary_seg ;
4393
- XLogSegNo last_notified ;
4394
- XLogSegNo flushed_seg ;
4395
- XLogSegNo seg ;
4396
- bool keep_latest ;
4397
-
4398
- XLByteToSeg (flushRecPtr , flushed_seg , wal_segment_size );
4399
-
4400
- SpinLockAcquire (& XLogCtl -> segtrack_lck );
4401
-
4402
- if (XLogCtl -> latestSegBoundary <= flushed_seg &&
4403
- XLogCtl -> latestSegBoundaryEndPtr <= flushRecPtr )
4404
- {
4405
- latest_boundary_seg = XLogCtl -> latestSegBoundary ;
4406
- keep_latest = false;
4407
- }
4408
- else if (XLogCtl -> earliestSegBoundary <= flushed_seg &&
4409
- XLogCtl -> earliestSegBoundaryEndPtr <= flushRecPtr )
4410
- {
4411
- latest_boundary_seg = XLogCtl -> earliestSegBoundary ;
4412
- keep_latest = true;
4413
- }
4414
- else
4415
- {
4416
- SpinLockRelease (& XLogCtl -> segtrack_lck );
4417
- return ;
4418
- }
4419
-
4420
- last_notified = XLogCtl -> lastNotifiedSeg ;
4421
-
4422
- /*
4423
- * Update shared memory and discard segment boundaries that are no longer
4424
- * needed.
4425
- *
4426
- * It is safe to update shared memory before we attempt to create the
4427
- * .ready files. If our calls to XLogArchiveNotifySeg() fail,
4428
- * RemoveOldXlogFiles() will retry it as needed.
4429
- */
4430
- if (last_notified < latest_boundary_seg - 1 )
4431
- XLogCtl -> lastNotifiedSeg = latest_boundary_seg - 1 ;
4432
-
4433
- if (keep_latest )
4434
- {
4435
- XLogCtl -> earliestSegBoundary = XLogCtl -> latestSegBoundary ;
4436
- XLogCtl -> earliestSegBoundaryEndPtr = XLogCtl -> latestSegBoundaryEndPtr ;
4437
- }
4438
- else
4439
- {
4440
- XLogCtl -> earliestSegBoundary = MaxXLogSegNo ;
4441
- XLogCtl -> earliestSegBoundaryEndPtr = InvalidXLogRecPtr ;
4442
- }
4443
-
4444
- XLogCtl -> latestSegBoundary = MaxXLogSegNo ;
4445
- XLogCtl -> latestSegBoundaryEndPtr = InvalidXLogRecPtr ;
4446
-
4447
- SpinLockRelease (& XLogCtl -> segtrack_lck );
4448
-
4449
- /*
4450
- * Notify archiver about segments that are ready for archival (by creating
4451
- * the corresponding .ready files).
4452
- */
4453
- for (seg = last_notified + 1 ; seg < latest_boundary_seg ; seg ++ )
4454
- XLogArchiveNotifySeg (seg );
4455
- }
4456
-
4457
4283
/*
4458
4284
* Remove previous backup history files. This also retries creation of
4459
4285
* .ready files for any backup history files for which XLogArchiveNotify
@@ -5355,16 +5181,8 @@ XLOGShmemInit(void)
5355
5181
5356
5182
SpinLockInit (& XLogCtl -> Insert .insertpos_lck );
5357
5183
SpinLockInit (& XLogCtl -> info_lck );
5358
- SpinLockInit (& XLogCtl -> segtrack_lck );
5359
5184
SpinLockInit (& XLogCtl -> ulsn_lck );
5360
5185
InitSharedLatch (& XLogCtl -> recoveryWakeupLatch );
5361
-
5362
- /* Initialize stuff for marking segments as ready for archival. */
5363
- XLogCtl -> lastNotifiedSeg = MaxXLogSegNo ;
5364
- XLogCtl -> earliestSegBoundary = MaxXLogSegNo ;
5365
- XLogCtl -> earliestSegBoundaryEndPtr = InvalidXLogRecPtr ;
5366
- XLogCtl -> latestSegBoundary = MaxXLogSegNo ;
5367
- XLogCtl -> latestSegBoundaryEndPtr = InvalidXLogRecPtr ;
5368
5186
}
5369
5187
5370
5188
/*
@@ -7888,20 +7706,6 @@ StartupXLOG(void)
7888
7706
XLogCtl -> LogwrtRqst .Write = EndOfLog ;
7889
7707
XLogCtl -> LogwrtRqst .Flush = EndOfLog ;
7890
7708
7891
- /*
7892
- * Initialize XLogCtl->lastNotifiedSeg to the previous WAL file.
7893
- */
7894
- if (XLogArchivingActive ())
7895
- {
7896
- XLogSegNo EndOfLogSeg ;
7897
-
7898
- XLByteToSeg (EndOfLog , EndOfLogSeg , wal_segment_size );
7899
-
7900
- SpinLockAcquire (& XLogCtl -> segtrack_lck );
7901
- XLogCtl -> lastNotifiedSeg = EndOfLogSeg - 1 ;
7902
- SpinLockRelease (& XLogCtl -> segtrack_lck );
7903
- }
7904
-
7905
7709
/*
7906
7710
* Update full_page_writes in shared memory and write an XLOG_FPW_CHANGE
7907
7711
* record before resource manager writes cleanup WAL records or checkpoint
0 commit comments