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
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,
141143int nchildren ,
142144TransactionId * children ,
143145int nrels ,
144- RelFileFork * rels );
146+ RelFileNode * rels );
145147static void RecordTransactionAbortPrepared (TransactionId xid ,
146148int nchildren ,
147149TransactionId * children ,
148150int nrels ,
149- RelFileFork * rels );
151+ RelFileNode * rels );
150152static void ProcessRecords (char * bufptr ,TransactionId xid ,
151153const 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)
793795TransactionId xid = gxact -> proc .xid ;
794796TwoPhaseFileHeader hdr ;
795797TransactionId * children ;
796- RelFileFork * commitrels ;
797- RelFileFork * abortrels ;
798+ RelFileNode * commitrels ;
799+ RelFileNode * abortrels ;
798800
799801/* Initialize linked list */
800802records .head = palloc0 (sizeof (XLogRecData ));
@@ -832,12 +834,12 @@ StartPrepare(GlobalTransaction gxact)
832834}
833835if (hdr .ncommitrels > 0 )
834836{
835- save_state_data (commitrels ,hdr .ncommitrels * sizeof (RelFileFork ));
837+ save_state_data (commitrels ,hdr .ncommitrels * sizeof (RelFileNode ));
836838pfree (commitrels );
837839}
838840if (hdr .nabortrels > 0 )
839841{
840- save_state_data (abortrels ,hdr .nabortrels * sizeof (RelFileFork ));
842+ save_state_data (abortrels ,hdr .nabortrels * sizeof (RelFileNode ));
841843pfree (abortrels );
842844}
843845}
@@ -1140,8 +1142,10 @@ FinishPreparedTransaction(const char *gid, bool isCommit)
11401142TwoPhaseFileHeader * hdr ;
11411143TransactionId latestXid ;
11421144TransactionId * children ;
1143- RelFileFork * commitrels ;
1144- RelFileFork * abortrels ;
1145+ RelFileNode * commitrels ;
1146+ RelFileNode * abortrels ;
1147+ RelFileNode * delrels ;
1148+ int ndelrels ;
11451149int i ;
11461150
11471151/*
@@ -1169,10 +1173,10 @@ FinishPreparedTransaction(const char *gid, bool isCommit)
11691173bufptr = buf + MAXALIGN (sizeof (TwoPhaseFileHeader ));
11701174children = (TransactionId * )bufptr ;
11711175bufptr += 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 */
11781182latestXid = TransactionIdLatest (xid ,hdr -> nsubxacts ,children );
@@ -1214,21 +1218,28 @@ FinishPreparedTransaction(const char *gid, bool isCommit)
12141218 */
12151219if (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}
12241224else
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)
16391650bufptr = buf + MAXALIGN (sizeof (TwoPhaseFileHeader ));
16401651subxids = (TransactionId * )bufptr ;
16411652bufptr += 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,
16931704int nchildren ,
16941705TransactionId * children ,
16951706int nrels ,
1696- RelFileFork * rels )
1707+ RelFileNode * rels )
16971708{
16981709XLogRecData rdata [3 ];
16991710int lastrdata = 0 ;
@@ -1718,7 +1729,7 @@ RecordTransactionCommitPrepared(TransactionId xid,
17181729{
17191730rdata [0 ].next = & (rdata [1 ]);
17201731rdata [1 ].data = (char * )rels ;
1721- rdata [1 ].len = nrels * sizeof (RelFileFork );
1732+ rdata [1 ].len = nrels * sizeof (RelFileNode );
17221733rdata [1 ].buffer = InvalidBuffer ;
17231734lastrdata = 1 ;
17241735}
@@ -1766,7 +1777,7 @@ RecordTransactionAbortPrepared(TransactionId xid,
17661777int nchildren ,
17671778TransactionId * children ,
17681779int nrels ,
1769- RelFileFork * rels )
1780+ RelFileNode * rels )
17701781{
17711782XLogRecData rdata [3 ];
17721783int lastrdata = 0 ;
@@ -1796,7 +1807,7 @@ RecordTransactionAbortPrepared(TransactionId xid,
17961807{
17971808rdata [0 ].next = & (rdata [1 ]);
17981809rdata [1 ].data = (char * )rels ;
1799- rdata [1 ].len = nrels * sizeof (RelFileFork );
1810+ rdata [1 ].len = nrels * sizeof (RelFileNode );
18001811rdata [1 ].buffer = InvalidBuffer ;
18011812lastrdata = 1 ;
18021813}