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

Commit9ba0361

Browse files
committed
Update minimum recovery point on truncation.
If a file is truncated, we must update minRecoveryPoint. Once a file istruncated, there's no going back; it would not be safe to stop recoveryat a point earlier than that anymore.Per report from Kyotaro HORIGUCHI. Backpatch to 8.4. Before that,minRecoveryPoint was not updated during recovery at all.
1 parent8bc8f70 commit9ba0361

File tree

2 files changed

+50
-11
lines changed

2 files changed

+50
-11
lines changed

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

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4544,25 +4544,46 @@ xact_redo_commit(xl_xact_commit *xlrec, TransactionId xid, XLogRecPtr lsn)
45444544
}
45454545

45464546
/* Make sure files supposed to be dropped are dropped */
4547-
for (i=0;i<xlrec->nrels;i++)
4547+
if (xlrec->nrels>0)
45484548
{
4549-
SMgrRelationsrel=smgropen(xlrec->xnodes[i],InvalidBackendId);
4550-
ForkNumberfork;
4549+
/*
4550+
* First update minimum recovery point to cover this WAL record. Once
4551+
* a relation is deleted, there's no going back. The buffer manager
4552+
* enforces the WAL-first rule for normal updates to relation files,
4553+
* so that the minimum recovery point is always updated before the
4554+
* corresponding change in the data file is flushed to disk, but we
4555+
* have to do the same here since we're bypassing the buffer manager.
4556+
*
4557+
* Doing this before deleting the files means that if a deletion fails
4558+
* for some reason, you cannot start up the system even after restart,
4559+
* until you fix the underlying situation so that the deletion will
4560+
* succeed. Alternatively, we could update the minimum recovery point
4561+
* after deletion, but that would leave a small window where the
4562+
* WAL-first rule would be violated.
4563+
*/
4564+
XLogFlush(lsn);
45514565

4552-
for (fork=0;fork <=MAX_FORKNUM;fork++)
4566+
for (i=0;i<xlrec->nrels;i++)
45534567
{
4554-
XLogDropRelation(xlrec->xnodes[i],fork);
4555-
smgrdounlink(srel,fork, true);
4568+
SMgrRelationsrel=smgropen(xlrec->xnodes[i],InvalidBackendId);
4569+
ForkNumberfork;
4570+
4571+
for (fork=0;fork <=MAX_FORKNUM;fork++)
4572+
{
4573+
XLogDropRelation(xlrec->xnodes[i],fork);
4574+
smgrdounlink(srel,fork, true);
4575+
}
4576+
smgrclose(srel);
45564577
}
4557-
smgrclose(srel);
45584578
}
45594579

45604580
/*
45614581
* We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
4562-
* in normal operation. For example, in DROP DATABASE, we delete all the
4563-
* files belonging to the database, and then commit the transaction. If we
4564-
* crash after all the files have been deleted but before the commit, you
4565-
* have an entry in pg_database without any files. To minimize the window
4582+
* in normal operation. For example, in CREATE DATABASE, we copy all files
4583+
* from the template database, and then commit the transaction. If we
4584+
* crash after all the files have been copied but before the commit, you
4585+
* have files in the data directory without an entry in pg_database. To
4586+
* minimize the window
45664587
* for that, we use ForceSyncCommit() to rush the commit record to disk as
45674588
* quick as possible. We have the same window during recovery, and forcing
45684589
* an XLogFlush() (which updates minRecoveryPoint during recovery) helps

‎src/backend/catalog/storage.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,24 @@ smgr_redo(XLogRecPtr lsn, XLogRecord *record)
508508
*/
509509
smgrcreate(reln,MAIN_FORKNUM, true);
510510

511+
/*
512+
* Before we perform the truncation, update minimum recovery point
513+
* to cover this WAL record. Once the relation is truncated, there's
514+
* no going back. The buffer manager enforces the WAL-first rule
515+
* for normal updates to relation files, so that the minimum recovery
516+
* point is always updated before the corresponding change in the
517+
* data file is flushed to disk. We have to do the same manually
518+
* here.
519+
*
520+
* Doing this before the truncation means that if the truncation fails
521+
* for some reason, you cannot start up the system even after restart,
522+
* until you fix the underlying situation so that the truncation will
523+
* succeed. Alternatively, we could update the minimum recovery point
524+
* after truncation, but that would leave a small window where the
525+
* WAL-first rule could be violated.
526+
*/
527+
XLogFlush(lsn);
528+
511529
smgrtruncate(reln,MAIN_FORKNUM,xlrec->blkno);
512530

513531
/* Also tell xlogutils.c about it */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp