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

Commit7bffc9b

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 parent6be7996 commit7bffc9b

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
@@ -4617,23 +4617,44 @@ xact_redo_commit_internal(TransactionId xid, XLogRecPtr lsn,
46174617
}
46184618

46194619
/* Make sure files supposed to be dropped are dropped */
4620-
for (i=0;i<nrels;i++)
4620+
if (nrels>0)
46214621
{
4622-
SMgrRelationsrel=smgropen(xnodes[i],InvalidBackendId);
4623-
ForkNumberfork;
4622+
/*
4623+
* First update minimum recovery point to cover this WAL record. Once
4624+
* a relation is deleted, there's no going back. The buffer manager
4625+
* enforces the WAL-first rule for normal updates to relation files,
4626+
* so that the minimum recovery point is always updated before the
4627+
* corresponding change in the data file is flushed to disk, but we
4628+
* have to do the same here since we're bypassing the buffer manager.
4629+
*
4630+
* Doing this before deleting the files means that if a deletion fails
4631+
* for some reason, you cannot start up the system even after restart,
4632+
* until you fix the underlying situation so that the deletion will
4633+
* succeed. Alternatively, we could update the minimum recovery point
4634+
* after deletion, but that would leave a small window where the
4635+
* WAL-first rule would be violated.
4636+
*/
4637+
XLogFlush(lsn);
46244638

4625-
for (fork=0;fork <=MAX_FORKNUM;fork++)
4626-
XLogDropRelation(xnodes[i],fork);
4627-
smgrdounlink(srel, true);
4628-
smgrclose(srel);
4639+
for (i=0;i<nrels;i++)
4640+
{
4641+
SMgrRelationsrel=smgropen(xnodes[i],InvalidBackendId);
4642+
ForkNumberfork;
4643+
4644+
for (fork=0;fork <=MAX_FORKNUM;fork++)
4645+
XLogDropRelation(xnodes[i],fork);
4646+
smgrdounlink(srel, true);
4647+
smgrclose(srel);
4648+
}
46294649
}
46304650

46314651
/*
46324652
* We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
4633-
* in normal operation. For example, in DROP DATABASE, we delete all the
4634-
* files belonging to the database, and then commit the transaction. If we
4635-
* crash after all the files have been deleted but before the commit, you
4636-
* have an entry in pg_database without any files. To minimize the window
4653+
* in normal operation. For example, in CREATE DATABASE, we copy all files
4654+
* from the template database, and then commit the transaction. If we
4655+
* crash after all the files have been copied but before the commit, you
4656+
* have files in the data directory without an entry in pg_database. To
4657+
* minimize the window
46374658
* for that, we use ForceSyncCommit() to rush the commit record to disk as
46384659
* quick as possible. We have the same window during recovery, and forcing
46394660
* 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
@@ -482,6 +482,24 @@ smgr_redo(XLogRecPtr lsn, XLogRecord *record)
482482
*/
483483
smgrcreate(reln,MAIN_FORKNUM, true);
484484

485+
/*
486+
* Before we perform the truncation, update minimum recovery point
487+
* to cover this WAL record. Once the relation is truncated, there's
488+
* no going back. The buffer manager enforces the WAL-first rule
489+
* for normal updates to relation files, so that the minimum recovery
490+
* point is always updated before the corresponding change in the
491+
* data file is flushed to disk. We have to do the same manually
492+
* here.
493+
*
494+
* Doing this before the truncation means that if the truncation fails
495+
* for some reason, you cannot start up the system even after restart,
496+
* until you fix the underlying situation so that the truncation will
497+
* succeed. Alternatively, we could update the minimum recovery point
498+
* after truncation, but that would leave a small window where the
499+
* WAL-first rule could be violated.
500+
*/
501+
XLogFlush(lsn);
502+
485503
smgrtruncate(reln,MAIN_FORKNUM,xlrec->blkno);
486504

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

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp