@ -1285,6 +1285,8 @@ RecordTransactionCommit(void)
RelFileNode * rels ;
RelFileNode * rels ;
int nchildren ;
int nchildren ;
TransactionId * children ;
TransactionId * children ;
int ndroppedstats = 0 ;
xl_xact_stats_item * droppedstats = NULL ;
int nmsgs = 0 ;
int nmsgs = 0 ;
SharedInvalidationMessage * invalMessages = NULL ;
SharedInvalidationMessage * invalMessages = NULL ;
bool RelcacheInitFileInval = false ;
bool RelcacheInitFileInval = false ;
@ -1303,6 +1305,7 @@ RecordTransactionCommit(void)
/* Get data needed for commit record */
/* Get data needed for commit record */
nrels = smgrGetPendingDeletes ( true , & rels ) ;
nrels = smgrGetPendingDeletes ( true , & rels ) ;
nchildren = xactGetCommittedChildren ( & children ) ;
nchildren = xactGetCommittedChildren ( & children ) ;
ndroppedstats = pgstat_get_transactional_drops ( true , & droppedstats ) ;
if ( XLogStandbyInfoActive ( ) )
if ( XLogStandbyInfoActive ( ) )
nmsgs = xactGetCommittedInvalidationMessages ( & invalMessages ,
nmsgs = xactGetCommittedInvalidationMessages ( & invalMessages ,
& RelcacheInitFileInval ) ;
& RelcacheInitFileInval ) ;
@ -1317,10 +1320,12 @@ RecordTransactionCommit(void)
/*
/*
* We expect that every RelationDropStorage is followed by a catalog
* We expect that every RelationDropStorage is followed by a catalog
* update , and hence XID assignment , so we shouldn ' t get here with any
* update , and hence XID assignment , so we shouldn ' t get here with any
* pending deletes . Use a real test not just an Assert to check this ,
* pending deletes . Same is true for dropping stats .
* since it ' s a bit fragile .
*
* Use a real test not just an Assert to check this , since it ' s a bit
* fragile .
*/
*/
if ( nrels ! = 0 )
if ( nrels ! = 0 | | ndroppedstats ! = 0 )
elog ( ERROR , " cannot commit a transaction that deleted files but has no xid " ) ;
elog ( ERROR , " cannot commit a transaction that deleted files but has no xid " ) ;
/* Can't have child XIDs either; AssignTransactionId enforces this */
/* Can't have child XIDs either; AssignTransactionId enforces this */
@ -1395,6 +1400,7 @@ RecordTransactionCommit(void)
XactLogCommitRecord ( xactStopTimestamp ,
XactLogCommitRecord ( xactStopTimestamp ,
nchildren , children , nrels , rels ,
nchildren , children , nrels , rels ,
ndroppedstats , droppedstats ,
nmsgs , invalMessages ,
nmsgs , invalMessages ,
RelcacheInitFileInval ,
RelcacheInitFileInval ,
MyXactFlags ,
MyXactFlags ,
@ -1518,6 +1524,8 @@ cleanup:
/* Clean up local data */
/* Clean up local data */
if ( rels )
if ( rels )
pfree ( rels ) ;
pfree ( rels ) ;
if ( ndroppedstats )
pfree ( droppedstats ) ;
return latestXid ;
return latestXid ;
}
}
@ -1698,6 +1706,8 @@ RecordTransactionAbort(bool isSubXact)
TransactionId latestXid ;
TransactionId latestXid ;
int nrels ;
int nrels ;
RelFileNode * rels ;
RelFileNode * rels ;
int ndroppedstats = 0 ;
xl_xact_stats_item * droppedstats = NULL ;
int nchildren ;
int nchildren ;
TransactionId * children ;
TransactionId * children ;
TimestampTz xact_time ;
TimestampTz xact_time ;
@ -1734,6 +1744,7 @@ RecordTransactionAbort(bool isSubXact)
/* Fetch the data we need for the abort record */
/* Fetch the data we need for the abort record */
nrels = smgrGetPendingDeletes ( false , & rels ) ;
nrels = smgrGetPendingDeletes ( false , & rels ) ;
nchildren = xactGetCommittedChildren ( & children ) ;
nchildren = xactGetCommittedChildren ( & children ) ;
ndroppedstats = pgstat_get_transactional_drops ( false , & droppedstats ) ;
/* XXX do we really need a critical section here? */
/* XXX do we really need a critical section here? */
START_CRIT_SECTION ( ) ;
START_CRIT_SECTION ( ) ;
@ -1750,6 +1761,7 @@ RecordTransactionAbort(bool isSubXact)
XactLogAbortRecord ( xact_time ,
XactLogAbortRecord ( xact_time ,
nchildren , children ,
nchildren , children ,
nrels , rels ,
nrels , rels ,
ndroppedstats , droppedstats ,
MyXactFlags , InvalidTransactionId ,
MyXactFlags , InvalidTransactionId ,
NULL ) ;
NULL ) ;
@ -1796,6 +1808,8 @@ RecordTransactionAbort(bool isSubXact)
/* And clean up local data */
/* And clean up local data */
if ( rels )
if ( rels )
pfree ( rels ) ;
pfree ( rels ) ;
if ( ndroppedstats )
pfree ( droppedstats ) ;
return latestXid ;
return latestXid ;
}
}
@ -5573,6 +5587,7 @@ XLogRecPtr
XactLogCommitRecord ( TimestampTz commit_time ,
XactLogCommitRecord ( TimestampTz commit_time ,
int nsubxacts , TransactionId * subxacts ,
int nsubxacts , TransactionId * subxacts ,
int nrels , RelFileNode * rels ,
int nrels , RelFileNode * rels ,
int ndroppedstats , xl_xact_stats_item * droppedstats ,
int nmsgs , SharedInvalidationMessage * msgs ,
int nmsgs , SharedInvalidationMessage * msgs ,
bool relcacheInval ,
bool relcacheInval ,
int xactflags , TransactionId twophase_xid ,
int xactflags , TransactionId twophase_xid ,
@ -5583,6 +5598,7 @@ XactLogCommitRecord(TimestampTz commit_time,
xl_xact_dbinfo xl_dbinfo ;
xl_xact_dbinfo xl_dbinfo ;
xl_xact_subxacts xl_subxacts ;
xl_xact_subxacts xl_subxacts ;
xl_xact_relfilenodes xl_relfilenodes ;
xl_xact_relfilenodes xl_relfilenodes ;
xl_xact_stats_items xl_dropped_stats ;
xl_xact_invals xl_invals ;
xl_xact_invals xl_invals ;
xl_xact_twophase xl_twophase ;
xl_xact_twophase xl_twophase ;
xl_xact_origin xl_origin ;
xl_xact_origin xl_origin ;
@ -5640,6 +5656,12 @@ XactLogCommitRecord(TimestampTz commit_time,
info | = XLR_SPECIAL_REL_UPDATE ;
info | = XLR_SPECIAL_REL_UPDATE ;
}
}
if ( ndroppedstats > 0 )
{
xl_xinfo . xinfo | = XACT_XINFO_HAS_DROPPED_STATS ;
xl_dropped_stats . nitems = ndroppedstats ;
}
if ( nmsgs > 0 )
if ( nmsgs > 0 )
{
{
xl_xinfo . xinfo | = XACT_XINFO_HAS_INVALS ;
xl_xinfo . xinfo | = XACT_XINFO_HAS_INVALS ;
@ -5696,6 +5718,14 @@ XactLogCommitRecord(TimestampTz commit_time,
nrels * sizeof ( RelFileNode ) ) ;
nrels * sizeof ( RelFileNode ) ) ;
}
}
if ( xl_xinfo . xinfo & XACT_XINFO_HAS_DROPPED_STATS )
{
XLogRegisterData ( ( char * ) ( & xl_dropped_stats ) ,
MinSizeOfXactStatsItems ) ;
XLogRegisterData ( ( char * ) droppedstats ,
ndroppedstats * sizeof ( xl_xact_stats_item ) ) ;
}
if ( xl_xinfo . xinfo & XACT_XINFO_HAS_INVALS )
if ( xl_xinfo . xinfo & XACT_XINFO_HAS_INVALS )
{
{
XLogRegisterData ( ( char * ) ( & xl_invals ) , MinSizeOfXactInvals ) ;
XLogRegisterData ( ( char * ) ( & xl_invals ) , MinSizeOfXactInvals ) ;
@ -5729,6 +5759,7 @@ XLogRecPtr
XactLogAbortRecord ( TimestampTz abort_time ,
XactLogAbortRecord ( TimestampTz abort_time ,
int nsubxacts , TransactionId * subxacts ,
int nsubxacts , TransactionId * subxacts ,
int nrels , RelFileNode * rels ,
int nrels , RelFileNode * rels ,
int ndroppedstats , xl_xact_stats_item * droppedstats ,
int xactflags , TransactionId twophase_xid ,
int xactflags , TransactionId twophase_xid ,
const char * twophase_gid )
const char * twophase_gid )
{
{
@ -5736,6 +5767,7 @@ XactLogAbortRecord(TimestampTz abort_time,
xl_xact_xinfo xl_xinfo ;
xl_xact_xinfo xl_xinfo ;
xl_xact_subxacts xl_subxacts ;
xl_xact_subxacts xl_subxacts ;
xl_xact_relfilenodes xl_relfilenodes ;
xl_xact_relfilenodes xl_relfilenodes ;
xl_xact_stats_items xl_dropped_stats ;
xl_xact_twophase xl_twophase ;
xl_xact_twophase xl_twophase ;
xl_xact_dbinfo xl_dbinfo ;
xl_xact_dbinfo xl_dbinfo ;
xl_xact_origin xl_origin ;
xl_xact_origin xl_origin ;
@ -5773,6 +5805,12 @@ XactLogAbortRecord(TimestampTz abort_time,
info | = XLR_SPECIAL_REL_UPDATE ;
info | = XLR_SPECIAL_REL_UPDATE ;
}
}
if ( ndroppedstats > 0 )
{
xl_xinfo . xinfo | = XACT_XINFO_HAS_DROPPED_STATS ;
xl_dropped_stats . nitems = ndroppedstats ;
}
if ( TransactionIdIsValid ( twophase_xid ) )
if ( TransactionIdIsValid ( twophase_xid ) )
{
{
xl_xinfo . xinfo | = XACT_XINFO_HAS_TWOPHASE ;
xl_xinfo . xinfo | = XACT_XINFO_HAS_TWOPHASE ;
@ -5834,6 +5872,14 @@ XactLogAbortRecord(TimestampTz abort_time,
nrels * sizeof ( RelFileNode ) ) ;
nrels * sizeof ( RelFileNode ) ) ;
}
}
if ( xl_xinfo . xinfo & XACT_XINFO_HAS_DROPPED_STATS )
{
XLogRegisterData ( ( char * ) ( & xl_dropped_stats ) ,
MinSizeOfXactStatsItems ) ;
XLogRegisterData ( ( char * ) droppedstats ,
ndroppedstats * sizeof ( xl_xact_stats_item ) ) ;
}
if ( xl_xinfo . xinfo & XACT_XINFO_HAS_TWOPHASE )
if ( xl_xinfo . xinfo & XACT_XINFO_HAS_TWOPHASE )
{
{
XLogRegisterData ( ( char * ) ( & xl_twophase ) , sizeof ( xl_xact_twophase ) ) ;
XLogRegisterData ( ( char * ) ( & xl_twophase ) , sizeof ( xl_xact_twophase ) ) ;
@ -5967,6 +6013,14 @@ xact_redo_commit(xl_xact_parsed_commit *parsed,
DropRelationFiles ( parsed - > xnodes , parsed - > nrels , true ) ;
DropRelationFiles ( parsed - > xnodes , parsed - > nrels , true ) ;
}
}
if ( parsed - > nstats > 0 )
{
/* see equivalent call for relations above */
XLogFlush ( lsn ) ;
pgstat_execute_transactional_drops ( parsed - > nstats , parsed - > stats , true ) ;
}
/*
/*
* We issue an XLogFlush ( ) for the same reason we emit ForceSyncCommit ( )
* We issue an XLogFlush ( ) for the same reason we emit ForceSyncCommit ( )
* in normal operation . For example , in CREATE DATABASE , we copy all files
* in normal operation . For example , in CREATE DATABASE , we copy all files
@ -6069,6 +6123,14 @@ xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid,
DropRelationFiles ( parsed - > xnodes , parsed - > nrels , true ) ;
DropRelationFiles ( parsed - > xnodes , parsed - > nrels , true ) ;
}
}
if ( parsed - > nstats > 0 )
{
/* see equivalent call for relations above */
XLogFlush ( lsn ) ;
pgstat_execute_transactional_drops ( parsed - > nstats , parsed - > stats , true ) ;
}
}
}
void
void