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

Commit172d067

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 parent0dfbb64 commit172d067

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
@@ -4489,25 +4489,46 @@ xact_redo_commit(xl_xact_commit *xlrec, TransactionId xid, XLogRecPtr lsn)
44894489
}
44904490

44914491
/* Make sure files supposed to be dropped are dropped */
4492-
for (i=0;i<xlrec->nrels;i++)
4492+
if (xlrec->nrels>0)
44934493
{
4494-
SMgrRelationsrel=smgropen(xlrec->xnodes[i]);
4495-
ForkNumberfork;
4494+
/*
4495+
* First update minimum recovery point to cover this WAL record. Once
4496+
* a relation is deleted, there's no going back. The buffer manager
4497+
* enforces the WAL-first rule for normal updates to relation files,
4498+
* so that the minimum recovery point is always updated before the
4499+
* corresponding change in the data file is flushed to disk, but we
4500+
* have to do the same here since we're bypassing the buffer manager.
4501+
*
4502+
* Doing this before deleting the files means that if a deletion fails
4503+
* for some reason, you cannot start up the system even after restart,
4504+
* until you fix the underlying situation so that the deletion will
4505+
* succeed. Alternatively, we could update the minimum recovery point
4506+
* after deletion, but that would leave a small window where the
4507+
* WAL-first rule would be violated.
4508+
*/
4509+
XLogFlush(lsn);
44964510

4497-
for (fork=0;fork <=MAX_FORKNUM;fork++)
4511+
for (i=0;i<xlrec->nrels;i++)
44984512
{
4499-
XLogDropRelation(xlrec->xnodes[i],fork);
4500-
smgrdounlink(srel,fork, false, true);
4513+
SMgrRelationsrel=smgropen(xlrec->xnodes[i]);
4514+
ForkNumberfork;
4515+
4516+
for (fork=0;fork <=MAX_FORKNUM;fork++)
4517+
{
4518+
XLogDropRelation(xlrec->xnodes[i],fork);
4519+
smgrdounlink(srel,fork, false, true);
4520+
}
4521+
smgrclose(srel);
45014522
}
4502-
smgrclose(srel);
45034523
}
45044524

45054525
/*
45064526
* We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
4507-
* in normal operation. For example, in DROP DATABASE, we delete all the
4508-
* files belonging to the database, and then commit the transaction. If we
4509-
* crash after all the files have been deleted but before the commit, you
4510-
* have an entry in pg_database without any files. To minimize the window
4527+
* in normal operation. For example, in CREATE DATABASE, we copy all files
4528+
* from the template database, and then commit the transaction. If we
4529+
* crash after all the files have been copied but before the commit, you
4530+
* have files in the data directory without an entry in pg_database. To
4531+
* minimize the window
45114532
* for that, we use ForceSyncCommit() to rush the commit record to disk as
45124533
* quick as possible. We have the same window during recovery, and forcing
45134534
* 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
@@ -474,6 +474,24 @@ smgr_redo(XLogRecPtr lsn, XLogRecord *record)
474474
*/
475475
smgrcreate(reln,MAIN_FORKNUM, true);
476476

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

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

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp