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

Commit133d2fa

Browse files
committed
Fix bug in cancellation of non-exclusive backup to avoid assertion failure.
Previously an assertion failure occurred when pg_stop_backup() fornon-exclusive backup was aborted while it's waiting for WAL files tobe archived. This assertion failure happened in do_pg_abort_backup()which was called when a non-exclusive backup was canceled.do_pg_abort_backup() assumes that there is at least one non-exclusivebackup running when it's called. But pg_stop_backup() can be canceledeven after it marks the end of non-exclusive backup (e.g.,during waiting for WAL archiving). This broke the assumption thatdo_pg_abort_backup() relies on, and which caused an assertion failure.This commit changes do_pg_abort_backup() so that it does nothingwhen non-exclusive backup has been already marked as completed.That is, the asssumption is also changed, and do_pg_abort_backup()now can handle even the case where it's called when there isno running backup.Backpatch to 9.6 where SQL-callable non-exclusive backup was added.Author: Masahiko Sawada and Michael PaquierReviewed-By: Robert Haas and Fujii MasaoDiscussion:https://www.postgresql.org/message-id/CAD21AoD2L1Fu2c==gnVASMyFAAaq3y-AQ2uEVj-zTCGFFjvmDg@mail.gmail.com
1 parentb70ea4c commit133d2fa

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed

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

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10609,13 +10609,20 @@ do_pg_start_backup(const char *backupidstr, bool fast, TimeLineID *starttli_p,
1060910609
/*
1061010610
* Mark that start phase has correctly finished for an exclusive backup.
1061110611
* Session-level locks are updated as well to reflect that state.
10612+
*
10613+
* Note that CHECK_FOR_INTERRUPTS() must not occur while updating
10614+
* backup counters and session-level lock. Otherwise they can be
10615+
* updated inconsistently, and which might cause do_pg_abort_backup()
10616+
* to fail.
1061210617
*/
1061310618
if (exclusive)
1061410619
{
1061510620
WALInsertLockAcquireExclusive();
1061610621
XLogCtl->Insert.exclusiveBackupState=EXCLUSIVE_BACKUP_IN_PROGRESS;
10617-
WALInsertLockRelease();
10622+
10623+
/* Set session-level lock */
1061810624
sessionBackupState=SESSION_BACKUP_EXCLUSIVE;
10625+
WALInsertLockRelease();
1061910626
}
1062010627
else
1062110628
sessionBackupState=SESSION_BACKUP_NON_EXCLUSIVE;
@@ -10819,7 +10826,11 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
1081910826
}
1082010827

1082110828
/*
10822-
* OK to update backup counters and forcePageWrites
10829+
* OK to update backup counters, forcePageWrites and session-level lock.
10830+
*
10831+
* Note that CHECK_FOR_INTERRUPTS() must not occur while updating them.
10832+
* Otherwise they can be updated inconsistently, and which might cause
10833+
* do_pg_abort_backup() to fail.
1082310834
*/
1082410835
WALInsertLockAcquireExclusive();
1082510836
if (exclusive)
@@ -10843,11 +10854,20 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
1084310854
{
1084410855
XLogCtl->Insert.forcePageWrites= false;
1084510856
}
10846-
WALInsertLockRelease();
1084710857

10848-
/* Clean up session-level lock */
10858+
/*
10859+
* Clean up session-level lock.
10860+
*
10861+
* You might think that WALInsertLockRelease() can be called
10862+
* before cleaning up session-level lock because session-level
10863+
* lock doesn't need to be protected with WAL insertion lock.
10864+
* But since CHECK_FOR_INTERRUPTS() can occur in it,
10865+
* session-level lock must be cleaned up before it.
10866+
*/
1084910867
sessionBackupState=SESSION_BACKUP_NONE;
1085010868

10869+
WALInsertLockRelease();
10870+
1085110871
/*
1085210872
* Read and parse the START WAL LOCATION line (this code is pretty crude,
1085310873
* but we are not expecting any variability in the file format).
@@ -11085,8 +11105,16 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
1108511105
void
1108611106
do_pg_abort_backup(void)
1108711107
{
11108+
/*
11109+
* Quick exit if session is not keeping around a non-exclusive backup
11110+
* already started.
11111+
*/
11112+
if (sessionBackupState==SESSION_BACKUP_NONE)
11113+
return;
11114+
1108811115
WALInsertLockAcquireExclusive();
1108911116
Assert(XLogCtl->Insert.nonExclusiveBackups>0);
11117+
Assert(sessionBackupState==SESSION_BACKUP_NON_EXCLUSIVE);
1109011118
XLogCtl->Insert.nonExclusiveBackups--;
1109111119

1109211120
if (XLogCtl->Insert.exclusiveBackupState==EXCLUSIVE_BACKUP_NONE&&

‎src/backend/replication/basebackup.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
211211
* Once do_pg_start_backup has been called, ensure that any failure causes
212212
* us to abort the backup so we don't "leak" a backup counter. For this
213213
* reason, *all* functionality between do_pg_start_backup() and
214-
* do_pg_stop_backup() should be inside the error cleanup block!
214+
*the end ofdo_pg_stop_backup() should be inside the error cleanup block!
215215
*/
216216

217217
PG_ENSURE_ERROR_CLEANUP(base_backup_cleanup, (Datum)0);
@@ -320,10 +320,11 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
320320
else
321321
pq_putemptymessage('c');/* CopyDone */
322322
}
323+
324+
endptr=do_pg_stop_backup(labelfile->data, !opt->nowait,&endtli);
323325
}
324326
PG_END_ENSURE_ERROR_CLEANUP(base_backup_cleanup, (Datum)0);
325327

326-
endptr=do_pg_stop_backup(labelfile->data, !opt->nowait,&endtli);
327328

328329
if (opt->includewal)
329330
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp