88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.163 2004/02/10 03:42:43 tgl Exp $
11+ * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.164 2004/02/11 22:55:24 tgl Exp $
1212 *
1313 * NOTES
1414 *Transaction aborts can now occur two ways:
@@ -519,19 +519,32 @@ RecordTransactionCommit(void)
519519if (MyLastRecPtr .xrecoff != 0 )
520520{
521521/* Need to emit a commit record */
522- XLogRecData rdata ;
522+ XLogRecData rdata [ 2 ] ;
523523xl_xact_commit xlrec ;
524+ int nrels ;
525+ RelFileNode * rptr ;
526+
527+ nrels = smgrGetPendingDeletes (true,& rptr );
524528
525529xlrec .xtime = time (NULL );
526- rdata .buffer = InvalidBuffer ;
527- rdata .data = (char * ) (& xlrec );
528- rdata .len = SizeOfXactCommit ;
529- rdata .next = NULL ;
530+ rdata [0 ].buffer = InvalidBuffer ;
531+ rdata [0 ].data = (char * ) (& xlrec );
532+ rdata [0 ].len = MinSizeOfXactCommit ;
533+ if (nrels > 0 )
534+ {
535+ rdata [0 ].next = & (rdata [1 ]);
536+ rdata [1 ].buffer = InvalidBuffer ;
537+ rdata [1 ].data = (char * )rptr ;
538+ rdata [1 ].len = nrels * sizeof (RelFileNode );
539+ rdata [1 ].next = NULL ;
540+ }
541+ else
542+ rdata [0 ].next = NULL ;
530543
531- /*
532- * XXX SHOULD SAVE ARRAY OF RELFILENODE-s TO DROP
533- */
534- recptr = XLogInsert ( RM_XACT_ID , XLOG_XACT_COMMIT , & rdata );
544+ recptr = XLogInsert ( RM_XACT_ID , XLOG_XACT_COMMIT , rdata );
545+
546+ if ( rptr )
547+ pfree ( rptr );
535548}
536549else
537550{
@@ -689,26 +702,42 @@ RecordTransactionAbort(void)
689702 * We only need to log the abort in XLOG if the transaction made
690703 * any transaction-controlled XLOG entries. (Otherwise, its XID
691704 * appears nowhere in permanent storage, so no one else will ever
692- * care if it committed.) We do not flush XLOG to diskin any
693- *case , since the default assumption after a crash would be that
694- * we aborted, anyway.
705+ * care if it committed.) We do not flush XLOG to diskunless
706+ *deleting files , since the default assumption after a crash
707+ *would be that we aborted, anyway.
695708 */
696709if (MyLastRecPtr .xrecoff != 0 )
697710{
698- XLogRecData rdata ;
711+ XLogRecData rdata [ 2 ] ;
699712xl_xact_abort xlrec ;
713+ int nrels ;
714+ RelFileNode * rptr ;
700715XLogRecPtr recptr ;
701716
717+ nrels = smgrGetPendingDeletes (false,& rptr );
718+
702719xlrec .xtime = time (NULL );
703- rdata .buffer = InvalidBuffer ;
704- rdata .data = (char * ) (& xlrec );
705- rdata .len = SizeOfXactAbort ;
706- rdata .next = NULL ;
720+ rdata [0 ].buffer = InvalidBuffer ;
721+ rdata [0 ].data = (char * ) (& xlrec );
722+ rdata [0 ].len = MinSizeOfXactAbort ;
723+ if (nrels > 0 )
724+ {
725+ rdata [0 ].next = & (rdata [1 ]);
726+ rdata [1 ].buffer = InvalidBuffer ;
727+ rdata [1 ].data = (char * )rptr ;
728+ rdata [1 ].len = nrels * sizeof (RelFileNode );
729+ rdata [1 ].next = NULL ;
730+ }
731+ else
732+ rdata [0 ].next = NULL ;
707733
708- /*
709- * SHOULD SAVE ARRAY OF RELFILENODE-s TO DROP
710- */
711- recptr = XLogInsert (RM_XACT_ID ,XLOG_XACT_ABORT ,& rdata );
734+ recptr = XLogInsert (RM_XACT_ID ,XLOG_XACT_ABORT ,rdata );
735+
736+ if (nrels > 0 )
737+ XLogFlush (recptr );
738+
739+ if (rptr )
740+ pfree (rptr );
712741}
713742
714743/*
@@ -1774,13 +1803,33 @@ xact_redo(XLogRecPtr lsn, XLogRecord *record)
17741803
17751804if (info == XLOG_XACT_COMMIT )
17761805{
1806+ xl_xact_commit * xlrec = (xl_xact_commit * )XLogRecGetData (record );
1807+ int nfiles ;
1808+ int i ;
1809+
17771810TransactionIdCommit (record -> xl_xid );
1778- /* SHOULD REMOVE FILES OF ALL DROPPED RELATIONS */
1811+ /* Make sure files supposed to be dropped are dropped */
1812+ nfiles = (record -> xl_len - MinSizeOfXactCommit ) /sizeof (RelFileNode );
1813+ for (i = 0 ;i < nfiles ;i ++ )
1814+ {
1815+ XLogCloseRelation (xlrec -> xnodes [i ]);
1816+ smgrdounlink (smgropen (xlrec -> xnodes [i ]), false, true);
1817+ }
17791818}
17801819else if (info == XLOG_XACT_ABORT )
17811820{
1821+ xl_xact_abort * xlrec = (xl_xact_abort * )XLogRecGetData (record );
1822+ int nfiles ;
1823+ int i ;
1824+
17821825TransactionIdAbort (record -> xl_xid );
1783- /* SHOULD REMOVE FILES OF ALL FAILED-TO-BE-CREATED RELATIONS */
1826+ /* Make sure files supposed to be dropped are dropped */
1827+ nfiles = (record -> xl_len - MinSizeOfXactAbort ) /sizeof (RelFileNode );
1828+ for (i = 0 ;i < nfiles ;i ++ )
1829+ {
1830+ XLogCloseRelation (xlrec -> xnodes [i ]);
1831+ smgrdounlink (smgropen (xlrec -> xnodes [i ]), false, true);
1832+ }
17841833}
17851834else
17861835elog (PANIC ,"xact_redo: unknown op code %u" ,info );
@@ -1810,6 +1859,7 @@ xact_desc(char *buf, uint8 xl_info, char *rec)
18101859sprintf (buf + strlen (buf ),"commit: %04u-%02u-%02u %02u:%02u:%02u" ,
18111860tm -> tm_year + 1900 ,tm -> tm_mon + 1 ,tm -> tm_mday ,
18121861tm -> tm_hour ,tm -> tm_min ,tm -> tm_sec );
1862+ /* XXX can't show RelFileNodes for lack of access to record length */
18131863}
18141864else if (info == XLOG_XACT_ABORT )
18151865{
@@ -1819,6 +1869,7 @@ xact_desc(char *buf, uint8 xl_info, char *rec)
18191869sprintf (buf + strlen (buf ),"abort: %04u-%02u-%02u %02u:%02u:%02u" ,
18201870tm -> tm_year + 1900 ,tm -> tm_mon + 1 ,tm -> tm_mday ,
18211871tm -> tm_hour ,tm -> tm_min ,tm -> tm_sec );
1872+ /* XXX can't show RelFileNodes for lack of access to record length */
18221873}
18231874else
18241875strcat (buf ,"UNKNOWN" );