@@ -192,7 +192,7 @@ CheckpointStatsData CheckpointStats;
192
192
* ThisTimeLineID will be same in all backends --- it identifies current
193
193
* WAL timeline for the database system.
194
194
*/
195
- TimeLineID ThisTimeLineID = 0 ;
195
+ static TimeLineID ThisTimeLineID = 0 ;
196
196
197
197
static XLogRecPtr LastRec ;
198
198
@@ -917,7 +917,8 @@ static void AdvanceXLInsertBuffer(XLogRecPtr upto, bool opportunistic);
917
917
static bool XLogCheckpointNeeded (XLogSegNo new_segno );
918
918
static void XLogWrite (XLogwrtRqst WriteRqst , bool flexible );
919
919
static bool InstallXLogFileSegment (XLogSegNo * segno , char * tmppath ,
920
- bool find_free , XLogSegNo max_segno );
920
+ bool find_free , XLogSegNo max_segno ,
921
+ TimeLineID tli );
921
922
static int XLogFileRead (XLogSegNo segno , int emode , TimeLineID tli ,
922
923
XLogSource source , bool notfoundOk );
923
924
static int XLogFileReadAnyTLI (XLogSegNo segno , int emode , XLogSource source );
@@ -2518,7 +2519,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
2518
2519
wal_segment_size );
2519
2520
2520
2521
/* create/use new log file */
2521
- openLogFile = XLogFileInit (openLogSegNo );
2522
+ openLogFile = XLogFileInit (openLogSegNo , ThisTimeLineID );
2522
2523
ReserveExternalFD ();
2523
2524
}
2524
2525
@@ -2633,15 +2634,15 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
2633
2634
*/
2634
2635
if (finishing_seg )
2635
2636
{
2636
- issue_xlog_fsync (openLogFile , openLogSegNo );
2637
+ issue_xlog_fsync (openLogFile , openLogSegNo , ThisTimeLineID );
2637
2638
2638
2639
/* signal that we need to wakeup walsenders later */
2639
2640
WalSndWakeupRequest ();
2640
2641
2641
2642
LogwrtResult .Flush = LogwrtResult .Write ; /* end of page */
2642
2643
2643
2644
if (XLogArchivingActive ())
2644
- XLogArchiveNotifySeg (openLogSegNo );
2645
+ XLogArchiveNotifySeg (openLogSegNo , ThisTimeLineID );
2645
2646
2646
2647
XLogCtl -> lastSegSwitchTime = (pg_time_t ) time (NULL );
2647
2648
XLogCtl -> lastSegSwitchLSN = LogwrtResult .Flush ;
@@ -2704,7 +2705,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
2704
2705
ReserveExternalFD ();
2705
2706
}
2706
2707
2707
- issue_xlog_fsync (openLogFile , openLogSegNo );
2708
+ issue_xlog_fsync (openLogFile , openLogSegNo , ThisTimeLineID );
2708
2709
}
2709
2710
2710
2711
/* signal that we need to wakeup walsenders later */
@@ -3296,7 +3297,8 @@ XLogNeedsFlush(XLogRecPtr record)
3296
3297
* succeed. (This is weird, but it's efficient for the callers.)
3297
3298
*/
3298
3299
static int
3299
- XLogFileInitInternal (XLogSegNo logsegno , bool * added , char * path )
3300
+ XLogFileInitInternal (XLogSegNo logsegno , TimeLineID logtli ,
3301
+ bool * added , char * path )
3300
3302
{
3301
3303
char tmppath [MAXPGPATH ];
3302
3304
PGAlignedXLogBlock zbuffer ;
@@ -3305,7 +3307,9 @@ XLogFileInitInternal(XLogSegNo logsegno, bool *added, char *path)
3305
3307
int fd ;
3306
3308
int save_errno ;
3307
3309
3308
- XLogFilePath (path , ThisTimeLineID , logsegno , wal_segment_size );
3310
+ Assert (logtli != 0 );
3311
+
3312
+ XLogFilePath (path , logtli , logsegno , wal_segment_size );
3309
3313
3310
3314
/*
3311
3315
* Try to use existent file (checkpoint maker may have created it already)
@@ -3449,7 +3453,8 @@ XLogFileInitInternal(XLogSegNo logsegno, bool *added, char *path)
3449
3453
* CheckPointSegments.
3450
3454
*/
3451
3455
max_segno = logsegno + CheckPointSegments ;
3452
- if (InstallXLogFileSegment (& installed_segno , tmppath , true, max_segno ))
3456
+ if (InstallXLogFileSegment (& installed_segno , tmppath , true, max_segno ,
3457
+ logtli ))
3453
3458
{
3454
3459
* added = true;
3455
3460
elog (DEBUG2 , "done creating and filling new WAL file" );
@@ -3481,13 +3486,15 @@ XLogFileInitInternal(XLogSegNo logsegno, bool *added, char *path)
3481
3486
* in a critical section.
3482
3487
*/
3483
3488
int
3484
- XLogFileInit (XLogSegNo logsegno )
3489
+ XLogFileInit (XLogSegNo logsegno , TimeLineID logtli )
3485
3490
{
3486
3491
bool ignore_added ;
3487
3492
char path [MAXPGPATH ];
3488
3493
int fd ;
3489
3494
3490
- fd = XLogFileInitInternal (logsegno , & ignore_added , path );
3495
+ Assert (logtli != 0 );
3496
+
3497
+ fd = XLogFileInitInternal (logsegno , logtli , & ignore_added , path );
3491
3498
if (fd >= 0 )
3492
3499
return fd ;
3493
3500
@@ -3629,7 +3636,7 @@ XLogFileCopy(XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno,
3629
3636
/*
3630
3637
* Now move the segment into place with its final name.
3631
3638
*/
3632
- if (!InstallXLogFileSegment (& destsegno , tmppath , false, 0 ))
3639
+ if (!InstallXLogFileSegment (& destsegno , tmppath , false, 0 , ThisTimeLineID ))
3633
3640
elog (ERROR , "InstallXLogFileSegment should not have failed" );
3634
3641
}
3635
3642
@@ -3653,18 +3660,22 @@ XLogFileCopy(XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno,
3653
3660
* free slot is found between *segno and max_segno. (Ignored when find_free
3654
3661
* is false.)
3655
3662
*
3663
+ * tli: The timeline on which the new segment should be installed.
3664
+ *
3656
3665
* Returns true if the file was installed successfully. false indicates that
3657
3666
* max_segno limit was exceeded, the startup process has disabled this
3658
3667
* function for now, or an error occurred while renaming the file into place.
3659
3668
*/
3660
3669
static bool
3661
3670
InstallXLogFileSegment (XLogSegNo * segno , char * tmppath ,
3662
- bool find_free , XLogSegNo max_segno )
3671
+ bool find_free , XLogSegNo max_segno , TimeLineID tli )
3663
3672
{
3664
3673
char path [MAXPGPATH ];
3665
3674
struct stat stat_buf ;
3666
3675
3667
- XLogFilePath (path , ThisTimeLineID , * segno , wal_segment_size );
3676
+ Assert (tli != 0 );
3677
+
3678
+ XLogFilePath (path , tli , * segno , wal_segment_size );
3668
3679
3669
3680
LWLockAcquire (ControlFileLock , LW_EXCLUSIVE );
3670
3681
if (!XLogCtl -> InstallXLogFileSegmentActive )
@@ -3690,7 +3701,7 @@ InstallXLogFileSegment(XLogSegNo *segno, char *tmppath,
3690
3701
return false;
3691
3702
}
3692
3703
(* segno )++ ;
3693
- XLogFilePath (path , ThisTimeLineID , * segno , wal_segment_size );
3704
+ XLogFilePath (path , tli , * segno , wal_segment_size );
3694
3705
}
3695
3706
}
3696
3707
@@ -3987,7 +3998,7 @@ PreallocXlogFiles(XLogRecPtr endptr)
3987
3998
if (offset >= (uint32 ) (0.75 * wal_segment_size ))
3988
3999
{
3989
4000
_logSegNo ++ ;
3990
- lf = XLogFileInitInternal (_logSegNo , & added , path );
4001
+ lf = XLogFileInitInternal (_logSegNo , ThisTimeLineID , & added , path );
3991
4002
if (lf >= 0 )
3992
4003
close (lf );
3993
4004
if (added )
@@ -4266,7 +4277,7 @@ RemoveXlogFile(const char *segname, XLogSegNo recycleSegNo,
4266
4277
XLogCtl -> InstallXLogFileSegmentActive && /* callee rechecks this */
4267
4278
lstat (path , & statbuf ) == 0 && S_ISREG (statbuf .st_mode ) &&
4268
4279
InstallXLogFileSegment (endlogSegNo , path ,
4269
- true, recycleSegNo ))
4280
+ true, recycleSegNo , ThisTimeLineID ))
4270
4281
{
4271
4282
ereport (DEBUG2 ,
4272
4283
(errmsg_internal ("recycled write-ahead log file \"%s\"" ,
@@ -5401,7 +5412,7 @@ BootStrapXLOG(void)
5401
5412
record -> xl_crc = crc ;
5402
5413
5403
5414
/* Create first XLOG segment file */
5404
- openLogFile = XLogFileInit (1 );
5415
+ openLogFile = XLogFileInit (1 , ThisTimeLineID );
5405
5416
5406
5417
/*
5407
5418
* We needn't bother with Reserve/ReleaseExternalFD here, since we'll
@@ -5709,7 +5720,7 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
5709
5720
*/
5710
5721
int fd ;
5711
5722
5712
- fd = XLogFileInit (startLogSegNo );
5723
+ fd = XLogFileInit (startLogSegNo , ThisTimeLineID );
5713
5724
5714
5725
if (close (fd ) != 0 )
5715
5726
{
@@ -8706,15 +8717,35 @@ GetInsertRecPtr(void)
8706
8717
* position known to be fsync'd to disk.
8707
8718
*/
8708
8719
XLogRecPtr
8709
- GetFlushRecPtr (void )
8720
+ GetFlushRecPtr (TimeLineID * insertTLI )
8710
8721
{
8711
8722
SpinLockAcquire (& XLogCtl -> info_lck );
8712
8723
LogwrtResult = XLogCtl -> LogwrtResult ;
8713
8724
SpinLockRelease (& XLogCtl -> info_lck );
8714
8725
8726
+ /*
8727
+ * If we're writing and flushing WAL, the time line can't be changing,
8728
+ * so no lock is required.
8729
+ */
8730
+ if (insertTLI )
8731
+ * insertTLI = XLogCtl -> ThisTimeLineID ;
8732
+
8715
8733
return LogwrtResult .Flush ;
8716
8734
}
8717
8735
8736
+ /*
8737
+ * GetWALInsertionTimeLine -- Returns the current timeline of a system that
8738
+ * is not in recovery.
8739
+ */
8740
+ TimeLineID
8741
+ GetWALInsertionTimeLine (void )
8742
+ {
8743
+ Assert (XLogCtl -> SharedRecoveryState == RECOVERY_STATE_DONE );
8744
+
8745
+ /* Since the value can't be changing, no lock is required. */
8746
+ return XLogCtl -> ThisTimeLineID ;
8747
+ }
8748
+
8718
8749
/*
8719
8750
* GetLastImportantRecPtr -- Returns the LSN of the last important record
8720
8751
* inserted. All records not explicitly marked as unimportant are considered
@@ -10849,11 +10880,13 @@ assign_xlog_sync_method(int new_sync_method, void *extra)
10849
10880
* 'segno' is for error reporting purposes.
10850
10881
*/
10851
10882
void
10852
- issue_xlog_fsync (int fd , XLogSegNo segno )
10883
+ issue_xlog_fsync (int fd , XLogSegNo segno , TimeLineID tli )
10853
10884
{
10854
10885
char * msg = NULL ;
10855
10886
instr_time start ;
10856
10887
10888
+ Assert (tli != 0 );
10889
+
10857
10890
/*
10858
10891
* Quick exit if fsync is disabled or write() has already synced the WAL
10859
10892
* file.
@@ -10902,8 +10935,7 @@ issue_xlog_fsync(int fd, XLogSegNo segno)
10902
10935
char xlogfname [MAXFNAMELEN ];
10903
10936
int save_errno = errno ;
10904
10937
10905
- XLogFileName (xlogfname , ThisTimeLineID , segno ,
10906
- wal_segment_size );
10938
+ XLogFileName (xlogfname , tli , segno , wal_segment_size );
10907
10939
errno = save_errno ;
10908
10940
ereport (PANIC ,
10909
10941
(errcode_for_file_access (),
0 commit comments