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

Commitcbc55da

Browse files
committed
Rework order of end-of-recovery actions to delay timeline history write
A critical failure in some of the end-of-recovery actions before theend-of-recovery record is written can cause PostgreSQL to reactinconsistently with the rest of the cluster in the event of a crashbefore the final record is written. Two such failures are for examplean error while processing a two-phase state files or when operating onrecovery.conf. With this commit, the failures are still consideredFATAL, but the write of the timeline history file is delayed as much aspossible so as the window between the moment the file is written and theend-of-recovery record is generated gets minimized. This way, in theevent of a crash or a failure, the new timeline decided at promotionwill not seem taken by other nodes in the cluster. It is not reallypossible to reduce to zero this window, hence one could still seefailures if a crash happens between the history file write and theend-of-recovery record, so any future code should be careful whenadding new end-of-recovery actions. The original report from MagnusHagander mentioned a renamed recovery.conf as original end-of-recoveryfailure which caused a timeline to be seen as taken but the subsequentprocessing on the now-missing recovery.conf cause the startup process toissue stop on FATAL, which at follow-up startup made the systeminconsistent because of on-disk changes which already happened.Processing of two-phase state files still needs some work as corruptedentries are simply ignored now. This is left as a future item and thiscommit fixes the original complain.Reported-by: Magnus HaganderAuthor: Heikki LinnakangasReviewed-by: Alexander Korotkov, Michael Paquier, David SteeleDiscussion:https://postgr.es/m/CABUevEz09XY2EevA2dLjPCY-C5UO4Hq=XxmXLmF6ipNFecbShQ@mail.gmail.com
1 parenta45adc7 commitcbc55da

File tree

1 file changed

+25
-12
lines changed
  • src/backend/access/transam

1 file changed

+25
-12
lines changed

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

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7494,6 +7494,13 @@ StartupXLOG(void)
74947494
}
74957495
}
74967496

7497+
/*
7498+
* Pre-scan prepared transactions to find out the range of XIDs present.
7499+
* This information is not quite needed yet, but it is positioned here so
7500+
* as potential problems are detected before any on-disk change is done.
7501+
*/
7502+
oldestActiveXID=PrescanPreparedTransactions(NULL,NULL);
7503+
74977504
/*
74987505
* Consider whether we need to assign a new timeline ID.
74997506
*
@@ -7548,6 +7555,24 @@ StartupXLOG(void)
75487555
else
75497556
snprintf(reason,sizeof(reason),"no recovery target specified");
75507557

7558+
/*
7559+
* We are now done reading the old WAL. Turn off archive fetching if
7560+
* it was active, and make a writable copy of the last WAL segment.
7561+
* (Note that we also have a copy of the last block of the old WAL in
7562+
* readBuf; we will use that below.)
7563+
*/
7564+
exitArchiveRecovery(EndOfLogTLI,EndOfLog);
7565+
7566+
/*
7567+
* Write the timeline history file, and have it archived. After this
7568+
* point (or rather, as soon as the file is archived), the timeline
7569+
* will appear as "taken" in the WAL archive and to any standby
7570+
* servers. If we crash before actually switching to the new
7571+
* timeline, standby servers will nevertheless think that we switched
7572+
* to the new timeline, and will try to connect to the new timeline.
7573+
* To minimize the window for that, try to do as little as possible
7574+
* between here and writing the end-of-recovery record.
7575+
*/
75517576
writeTimeLineHistory(ThisTimeLineID,recoveryTargetTLI,
75527577
EndRecPtr,reason);
75537578
}
@@ -7556,15 +7581,6 @@ StartupXLOG(void)
75567581
XLogCtl->ThisTimeLineID=ThisTimeLineID;
75577582
XLogCtl->PrevTimeLineID=PrevTimeLineID;
75587583

7559-
/*
7560-
* We are now done reading the old WAL. Turn off archive fetching if it
7561-
* was active, and make a writable copy of the last WAL segment. (Note
7562-
* that we also have a copy of the last block of the old WAL in readBuf;
7563-
* we will use that below.)
7564-
*/
7565-
if (ArchiveRecoveryRequested)
7566-
exitArchiveRecovery(EndOfLogTLI,EndOfLog);
7567-
75687584
/*
75697585
* Prepare to write WAL starting at EndOfLog location, and init xlog
75707586
* buffer cache using the block containing the last record from the
@@ -7617,9 +7633,6 @@ StartupXLOG(void)
76177633
XLogCtl->LogwrtRqst.Write=EndOfLog;
76187634
XLogCtl->LogwrtRqst.Flush=EndOfLog;
76197635

7620-
/* Pre-scan prepared transactions to find out the range of XIDs present */
7621-
oldestActiveXID=PrescanPreparedTransactions(NULL,NULL);
7622-
76237636
/*
76247637
* Update full_page_writes in shared memory and write an XLOG_FPW_CHANGE
76257638
* record before resource manager writes cleanup WAL records or checkpoint

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp