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

Commitfbe285a

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 parent6cb8c60 commitfbe285a

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
@@ -4637,23 +4637,44 @@ xact_redo_commit_internal(TransactionId xid, XLogRecPtr lsn,
46374637
}
46384638

46394639
/* Make sure files supposed to be dropped are dropped */
4640-
for (i=0;i<nrels;i++)
4640+
if (nrels>0)
46414641
{
4642-
SMgrRelationsrel=smgropen(xnodes[i],InvalidBackendId);
4643-
ForkNumberfork;
4642+
/*
4643+
* First update minimum recovery point to cover this WAL record. Once
4644+
* a relation is deleted, there's no going back. The buffer manager
4645+
* enforces the WAL-first rule for normal updates to relation files,
4646+
* so that the minimum recovery point is always updated before the
4647+
* corresponding change in the data file is flushed to disk, but we
4648+
* have to do the same here since we're bypassing the buffer manager.
4649+
*
4650+
* Doing this before deleting the files means that if a deletion fails
4651+
* for some reason, you cannot start up the system even after restart,
4652+
* until you fix the underlying situation so that the deletion will
4653+
* succeed. Alternatively, we could update the minimum recovery point
4654+
* after deletion, but that would leave a small window where the
4655+
* WAL-first rule would be violated.
4656+
*/
4657+
XLogFlush(lsn);
46444658

4645-
for (fork=0;fork <=MAX_FORKNUM;fork++)
4646-
XLogDropRelation(xnodes[i],fork);
4647-
smgrdounlink(srel, true);
4648-
smgrclose(srel);
4659+
for (i=0;i<nrels;i++)
4660+
{
4661+
SMgrRelationsrel=smgropen(xnodes[i],InvalidBackendId);
4662+
ForkNumberfork;
4663+
4664+
for (fork=0;fork <=MAX_FORKNUM;fork++)
4665+
XLogDropRelation(xnodes[i],fork);
4666+
smgrdounlink(srel, true);
4667+
smgrclose(srel);
4668+
}
46494669
}
46504670

46514671
/*
46524672
* We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
4653-
* in normal operation. For example, in DROP DATABASE, we delete all the
4654-
* files belonging to the database, and then commit the transaction. If we
4655-
* crash after all the files have been deleted but before the commit, you
4656-
* have an entry in pg_database without any files. To minimize the window
4673+
* in normal operation. For example, in CREATE DATABASE, we copy all files
4674+
* from the template database, and then commit the transaction. If we
4675+
* crash after all the files have been copied but before the commit, you
4676+
* have files in the data directory without an entry in pg_database. To
4677+
* minimize the window
46574678
* for that, we use ForceSyncCommit() to rush the commit record to disk as
46584679
* quick as possible. We have the same window during recovery, and forcing
46594680
* 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
@@ -505,6 +505,24 @@ smgr_redo(XLogRecPtr lsn, XLogRecord *record)
505505
*/
506506
smgrcreate(reln,MAIN_FORKNUM, true);
507507

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

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

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp