Skip to content

Commit 3396000

Browse files
committed
Rethink the way FSM truncation works. Instead of WAL-logging FSM
truncations in FSM code, call FreeSpaceMapTruncateRel from smgr_redo. To make that cleaner from modularity point of view, move the WAL-logging one level up to RelationTruncate, and move RelationTruncate and all the related WAL-logging to new src/backend/catalog/storage.c file. Introduce new RelationCreateStorage and RelationDropStorage functions that are used instead of calling smgrcreate/smgrscheduleunlink directly. Move the pending rel deletion stuff from smgrcreate/smgrscheduleunlink to the new functions. This leaves smgr.c as a thin wrapper around md.c; all the transactional stuff is now in storage.c. This will make it easier to add new forks with similar truncation logic, like the visibility map.
1 parent 26e6c89 commit 3396000

30 files changed

+675
-794
lines changed

src/backend/access/gin/gininsert.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/gin/gininsert.c,v 1.16 2008/11/13 17:42:09 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/gin/gininsert.c,v 1.17 2008/11/19 10:34:50 heikki Exp $
1212
*-------------------------------------------------------------------------
1313
*/
1414

@@ -284,9 +284,6 @@ ginbuild(PG_FUNCTION_ARGS)
284284
elog(ERROR, "index \"%s\" already contains data",
285285
RelationGetRelationName(index));
286286

287-
/* Initialize FSM */
288-
InitIndexFreeSpaceMap(index);
289-
290287
initGinState(&buildstate.ginstate, index);
291288

292289
/* initialize the root page */

src/backend/access/gin/ginvacuum.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/gin/ginvacuum.c,v 1.25 2008/11/03 20:47:48 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/gin/ginvacuum.c,v 1.26 2008/11/19 10:34:50 heikki Exp $
1212
*-------------------------------------------------------------------------
1313
*/
1414

1515
#include "postgres.h"
1616

1717
#include "access/genam.h"
1818
#include "access/gin.h"
19+
#include "catalog/storage.h"
1920
#include "commands/vacuum.h"
2021
#include "miscadmin.h"
2122
#include "storage/bufmgr.h"
@@ -757,7 +758,6 @@ ginvacuumcleanup(PG_FUNCTION_ARGS)
757758
if (info->vacuum_full && lastBlock > lastFilledBlock)
758759
{
759760
/* try to truncate index */
760-
FreeSpaceMapTruncateRel(index, lastFilledBlock + 1);
761761
RelationTruncate(index, lastFilledBlock + 1);
762762

763763
stats->pages_removed = lastBlock - lastFilledBlock;

src/backend/access/gist/gist.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.154 2008/11/13 17:42:09 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.155 2008/11/19 10:34:50 heikki Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -103,9 +103,6 @@ gistbuild(PG_FUNCTION_ARGS)
103103
elog(ERROR, "index \"%s\" already contains data",
104104
RelationGetRelationName(index));
105105

106-
/* Initialize FSM */
107-
InitIndexFreeSpaceMap(index);
108-
109106
/* no locking is needed */
110107
initGISTstate(&buildstate.giststate, index);
111108

src/backend/access/gist/gistvacuum.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/gist/gistvacuum.c,v 1.40 2008/11/03 20:47:48 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/gist/gistvacuum.c,v 1.41 2008/11/19 10:34:50 heikki Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
1515
#include "postgres.h"
1616

1717
#include "access/genam.h"
1818
#include "access/gist_private.h"
19+
#include "catalog/storage.h"
1920
#include "commands/vacuum.h"
2021
#include "miscadmin.h"
2122
#include "storage/bufmgr.h"
@@ -603,7 +604,6 @@ gistvacuumcleanup(PG_FUNCTION_ARGS)
603604

604605
if (info->vacuum_full && lastFilledBlock < lastBlock)
605606
{ /* try to truncate index */
606-
FreeSpaceMapTruncateRel(rel, lastFilledBlock + 1);
607607
RelationTruncate(rel, lastFilledBlock + 1);
608608

609609
stats->std.pages_removed = lastBlock - lastFilledBlock;

src/backend/access/heap/heapam.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.269 2008/11/06 20:51:14 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.270 2008/11/19 10:34:50 heikki Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -4863,8 +4863,7 @@ heap_sync(Relation rel)
48634863
/* FlushRelationBuffers will have opened rd_smgr */
48644864
smgrimmedsync(rel->rd_smgr, MAIN_FORKNUM);
48654865

4866-
/* sync FSM as well */
4867-
smgrimmedsync(rel->rd_smgr, FSM_FORKNUM);
4866+
/* FSM is not critical, don't bother syncing it */
48684867

48694868
/* toast heap, if any */
48704869
if (OidIsValid(rel->rd_rel->reltoastrelid))
@@ -4874,7 +4873,6 @@ heap_sync(Relation rel)
48744873
toastrel = heap_open(rel->rd_rel->reltoastrelid, AccessShareLock);
48754874
FlushRelationBuffers(toastrel);
48764875
smgrimmedsync(toastrel->rd_smgr, MAIN_FORKNUM);
4877-
smgrimmedsync(toastrel->rd_smgr, FSM_FORKNUM);
48784876
heap_close(toastrel, AccessShareLock);
48794877
}
48804878
}

src/backend/access/nbtree/nbtree.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* Portions Copyright (c) 1994, Regents of the University of California
1313
*
1414
* IDENTIFICATION
15-
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.165 2008/11/13 17:42:10 tgl Exp $
15+
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.166 2008/11/19 10:34:50 heikki Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
@@ -22,6 +22,7 @@
2222
#include "access/nbtree.h"
2323
#include "access/relscan.h"
2424
#include "catalog/index.h"
25+
#include "catalog/storage.h"
2526
#include "commands/vacuum.h"
2627
#include "miscadmin.h"
2728
#include "storage/bufmgr.h"
@@ -109,9 +110,6 @@ btbuild(PG_FUNCTION_ARGS)
109110
elog(ERROR, "index \"%s\" already contains data",
110111
RelationGetRelationName(index));
111112

112-
/* Initialize FSM */
113-
InitIndexFreeSpaceMap(index);
114-
115113
buildstate.spool = _bt_spoolinit(index, indexInfo->ii_Unique, false);
116114

117115
/*
@@ -696,7 +694,6 @@ btvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
696694
/*
697695
* Okay to truncate.
698696
*/
699-
FreeSpaceMapTruncateRel(rel, new_pages);
700697
RelationTruncate(rel, new_pages);
701698

702699
/* update statistics */

src/backend/access/transam/rmgr.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* Resource managers definition
55
*
6-
* $PostgreSQL: pgsql/src/backend/access/transam/rmgr.c,v 1.26 2008/09/30 10:52:11 heikki Exp $
6+
* $PostgreSQL: pgsql/src/backend/access/transam/rmgr.c,v 1.27 2008/11/19 10:34:50 heikki Exp $
77
*/
88
#include "postgres.h"
99

@@ -16,11 +16,11 @@
1616
#include "access/nbtree.h"
1717
#include "access/xact.h"
1818
#include "access/xlog_internal.h"
19+
#include "catalog/storage.h"
1920
#include "commands/dbcommands.h"
2021
#include "commands/sequence.h"
2122
#include "commands/tablespace.h"
2223
#include "storage/freespace.h"
23-
#include "storage/smgr.h"
2424

2525

2626
const RmgrData RmgrTable[RM_MAX_ID + 1] = {
@@ -31,7 +31,7 @@ const RmgrData RmgrTable[RM_MAX_ID + 1] = {
3131
{"Database", dbase_redo, dbase_desc, NULL, NULL, NULL},
3232
{"Tablespace", tblspc_redo, tblspc_desc, NULL, NULL, NULL},
3333
{"MultiXact", multixact_redo, multixact_desc, NULL, NULL, NULL},
34-
{"FreeSpaceMap", fsm_redo, fsm_desc, NULL, NULL, NULL},
34+
{"Reserved 7", NULL, NULL, NULL, NULL, NULL},
3535
{"Reserved 8", NULL, NULL, NULL, NULL, NULL},
3636
{"Heap2", heap2_redo, heap2_desc, NULL, NULL, NULL},
3737
{"Heap", heap_redo, heap_desc, NULL, NULL, NULL},

src/backend/access/transam/twophase.c

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.47 2008/11/02 21:24:51 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.48 2008/11/19 10:34:50 heikki Exp $
1111
*
1212
* NOTES
1313
* Each global transaction is associated with a global transaction
@@ -48,7 +48,9 @@
4848
#include "access/twophase.h"
4949
#include "access/twophase_rmgr.h"
5050
#include "access/xact.h"
51+
#include "access/xlogutils.h"
5152
#include "catalog/pg_type.h"
53+
#include "catalog/storage.h"
5254
#include "funcapi.h"
5355
#include "miscadmin.h"
5456
#include "pg_trace.h"
@@ -141,12 +143,12 @@ static void RecordTransactionCommitPrepared(TransactionId xid,
141143
int nchildren,
142144
TransactionId *children,
143145
int nrels,
144-
RelFileFork *rels);
146+
RelFileNode *rels);
145147
static void RecordTransactionAbortPrepared(TransactionId xid,
146148
int nchildren,
147149
TransactionId *children,
148150
int nrels,
149-
RelFileFork *rels);
151+
RelFileNode *rels);
150152
static void ProcessRecords(char *bufptr, TransactionId xid,
151153
const TwoPhaseCallback callbacks[]);
152154

@@ -694,8 +696,8 @@ TwoPhaseGetDummyProc(TransactionId xid)
694696
*
695697
* 1. TwoPhaseFileHeader
696698
* 2. TransactionId[] (subtransactions)
697-
* 3. RelFileFork[] (files to be deleted at commit)
698-
* 4. RelFileFork[] (files to be deleted at abort)
699+
* 3. RelFileNode[] (files to be deleted at commit)
700+
* 4. RelFileNode[] (files to be deleted at abort)
699701
* 5. TwoPhaseRecordOnDisk
700702
* 6. ...
701703
* 7. TwoPhaseRecordOnDisk (end sentinel, rmid == TWOPHASE_RM_END_ID)
@@ -793,8 +795,8 @@ StartPrepare(GlobalTransaction gxact)
793795
TransactionId xid = gxact->proc.xid;
794796
TwoPhaseFileHeader hdr;
795797
TransactionId *children;
796-
RelFileFork *commitrels;
797-
RelFileFork *abortrels;
798+
RelFileNode *commitrels;
799+
RelFileNode *abortrels;
798800

799801
/* Initialize linked list */
800802
records.head = palloc0(sizeof(XLogRecData));
@@ -832,12 +834,12 @@ StartPrepare(GlobalTransaction gxact)
832834
}
833835
if (hdr.ncommitrels > 0)
834836
{
835-
save_state_data(commitrels, hdr.ncommitrels * sizeof(RelFileFork));
837+
save_state_data(commitrels, hdr.ncommitrels * sizeof(RelFileNode));
836838
pfree(commitrels);
837839
}
838840
if (hdr.nabortrels > 0)
839841
{
840-
save_state_data(abortrels, hdr.nabortrels * sizeof(RelFileFork));
842+
save_state_data(abortrels, hdr.nabortrels * sizeof(RelFileNode));
841843
pfree(abortrels);
842844
}
843845
}
@@ -1140,8 +1142,10 @@ FinishPreparedTransaction(const char *gid, bool isCommit)
11401142
TwoPhaseFileHeader *hdr;
11411143
TransactionId latestXid;
11421144
TransactionId *children;
1143-
RelFileFork *commitrels;
1144-
RelFileFork *abortrels;
1145+
RelFileNode *commitrels;
1146+
RelFileNode *abortrels;
1147+
RelFileNode *delrels;
1148+
int ndelrels;
11451149
int i;
11461150

11471151
/*
@@ -1169,10 +1173,10 @@ FinishPreparedTransaction(const char *gid, bool isCommit)
11691173
bufptr = buf + MAXALIGN(sizeof(TwoPhaseFileHeader));
11701174
children = (TransactionId *) bufptr;
11711175
bufptr += MAXALIGN(hdr->nsubxacts * sizeof(TransactionId));
1172-
commitrels = (RelFileFork *) bufptr;
1173-
bufptr += MAXALIGN(hdr->ncommitrels * sizeof(RelFileFork));
1174-
abortrels = (RelFileFork *) bufptr;
1175-
bufptr += MAXALIGN(hdr->nabortrels * sizeof(RelFileFork));
1176+
commitrels = (RelFileNode *) bufptr;
1177+
bufptr += MAXALIGN(hdr->ncommitrels * sizeof(RelFileNode));
1178+
abortrels = (RelFileNode *) bufptr;
1179+
bufptr += MAXALIGN(hdr->nabortrels * sizeof(RelFileNode));
11761180

11771181
/* compute latestXid among all children */
11781182
latestXid = TransactionIdLatest(xid, hdr->nsubxacts, children);
@@ -1214,21 +1218,28 @@ FinishPreparedTransaction(const char *gid, bool isCommit)
12141218
*/
12151219
if (isCommit)
12161220
{
1217-
for (i = 0; i < hdr->ncommitrels; i++)
1218-
{
1219-
SMgrRelation srel = smgropen(commitrels[i].rnode);
1220-
smgrdounlink(srel, commitrels[i].forknum, false, false);
1221-
smgrclose(srel);
1222-
}
1221+
delrels = commitrels;
1222+
ndelrels = hdr->ncommitrels;
12231223
}
12241224
else
12251225
{
1226-
for (i = 0; i < hdr->nabortrels; i++)
1226+
delrels = abortrels;
1227+
ndelrels = hdr->nabortrels;
1228+
}
1229+
for (i = 0; i < ndelrels; i++)
1230+
{
1231+
SMgrRelation srel = smgropen(delrels[i]);
1232+
ForkNumber fork;
1233+
1234+
for (fork = 0; fork <= MAX_FORKNUM; fork++)
12271235
{
1228-
SMgrRelation srel = smgropen(abortrels[i].rnode);
1229-
smgrdounlink(srel, abortrels[i].forknum, false, false);
1230-
smgrclose(srel);
1236+
if (smgrexists(srel, fork))
1237+
{
1238+
XLogDropRelation(delrels[i], fork);
1239+
smgrdounlink(srel, fork, false, true);
1240+
}
12311241
}
1242+
smgrclose(srel);
12321243
}
12331244

12341245
/* And now do the callbacks */
@@ -1639,8 +1650,8 @@ RecoverPreparedTransactions(void)
16391650
bufptr = buf + MAXALIGN(sizeof(TwoPhaseFileHeader));
16401651
subxids = (TransactionId *) bufptr;
16411652
bufptr += MAXALIGN(hdr->nsubxacts * sizeof(TransactionId));
1642-
bufptr += MAXALIGN(hdr->ncommitrels * sizeof(RelFileFork));
1643-
bufptr += MAXALIGN(hdr->nabortrels * sizeof(RelFileFork));
1653+
bufptr += MAXALIGN(hdr->ncommitrels * sizeof(RelFileNode));
1654+
bufptr += MAXALIGN(hdr->nabortrels * sizeof(RelFileNode));
16441655

16451656
/*
16461657
* Reconstruct subtrans state for the transaction --- needed
@@ -1693,7 +1704,7 @@ RecordTransactionCommitPrepared(TransactionId xid,
16931704
int nchildren,
16941705
TransactionId *children,
16951706
int nrels,
1696-
RelFileFork *rels)
1707+
RelFileNode *rels)
16971708
{
16981709
XLogRecData rdata[3];
16991710
int lastrdata = 0;
@@ -1718,7 +1729,7 @@ RecordTransactionCommitPrepared(TransactionId xid,
17181729
{
17191730
rdata[0].next = &(rdata[1]);
17201731
rdata[1].data = (char *) rels;
1721-
rdata[1].len = nrels * sizeof(RelFileFork);
1732+
rdata[1].len = nrels * sizeof(RelFileNode);
17221733
rdata[1].buffer = InvalidBuffer;
17231734
lastrdata = 1;
17241735
}
@@ -1766,7 +1777,7 @@ RecordTransactionAbortPrepared(TransactionId xid,
17661777
int nchildren,
17671778
TransactionId *children,
17681779
int nrels,
1769-
RelFileFork *rels)
1780+
RelFileNode *rels)
17701781
{
17711782
XLogRecData rdata[3];
17721783
int lastrdata = 0;
@@ -1796,7 +1807,7 @@ RecordTransactionAbortPrepared(TransactionId xid,
17961807
{
17971808
rdata[0].next = &(rdata[1]);
17981809
rdata[1].data = (char *) rels;
1799-
rdata[1].len = nrels * sizeof(RelFileFork);
1810+
rdata[1].len = nrels * sizeof(RelFileNode);
18001811
rdata[1].buffer = InvalidBuffer;
18011812
lastrdata = 1;
18021813
}

0 commit comments

Comments
 (0)