diff --git a/src/backend/access/transam/subtrans.c b/src/backend/access/transam/subtrans.c index 88e8bc5f8ef..a793ab61209 100644 --- a/src/backend/access/transam/subtrans.c +++ b/src/backend/access/transam/subtrans.c @@ -55,6 +55,8 @@ #define TransactionIdToEntry(xid) ((xid) % (uint32) SUBTRANS_XACTS_PER_PAGE) +subtransaction_id_hook_type subtransaction_id_hook = NULL; + /* * Link to shared-memory data structures for SUBTRANS control */ diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index 12ad9fa2af0..aa97834787c 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -26,6 +26,7 @@ #include "access/tableam.h" #include "access/toast_internals.h" #include "access/transam.h" +#include "access/subtrans.h" #include "access/xact.h" #include "access/xlog.h" #include "catalog/catalog.h" @@ -1255,6 +1256,12 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class, rel2->rd_newRelfilenodeSubid = rel1->rd_newRelfilenodeSubid; rel2->rd_firstRelfilenodeSubid = rel1->rd_firstRelfilenodeSubid; RelationAssumeNewRelfilenode(rel1); + + if (subtransaction_id_hook) + { + subtransaction_id_hook(rel2); + } + relation_close(rel1, NoLock); relation_close(rel2, NoLock); } diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 90007981298..b462bb7c497 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -25,6 +25,7 @@ #include "access/nbtree.h" #include "access/reloptions.h" #include "access/relscan.h" +#include "access/subtrans.h" #include "access/sysattr.h" #include "access/tableam.h" #include "access/toast_compression.h" @@ -10099,6 +10100,12 @@ ATExecAddIndex(AlteredTableInfo *tab, Relation rel, irel->rd_createSubid = stmt->oldCreateSubid; irel->rd_firstRelfilenodeSubid = stmt->oldFirstRelfilenodeSubid; + + if (subtransaction_id_hook) + { + subtransaction_id_hook(irel); + } + RelationPreserveStorage(irel->rd_node, true); index_close(irel, NoLock); } diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index f133bc038eb..fb623e503f4 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -38,6 +38,7 @@ #include "access/nbtree.h" #include "access/parallel.h" #include "access/reloptions.h" +#include "access/subtrans.h" #include "access/sysattr.h" #include "access/table.h" #include "access/tableam.h" @@ -1425,6 +1426,11 @@ RelationInitPhysicalAddr(Relation relation) relation->rd_firstRelfilenodeSubid = TopSubTransactionId; else relation->rd_firstRelfilenodeSubid = InvalidSubTransactionId; + + if (subtransaction_id_hook) + { + subtransaction_id_hook(relation); + } } } @@ -2924,6 +2930,11 @@ RelationForgetRelation(Oid rid) * transaction, we could opt to destroy the entry.) */ relation->rd_droppedSubid = GetCurrentSubTransactionId(); + + if (subtransaction_id_hook) + { + subtransaction_id_hook(relation); + } } RelationClearRelation(relation, false); @@ -3642,6 +3653,11 @@ RelationBuildLocalRelation(const char *relname, rel->rd_firstRelfilenodeSubid = InvalidSubTransactionId; rel->rd_droppedSubid = InvalidSubTransactionId; + if (subtransaction_id_hook) + { + subtransaction_id_hook(rel); + } + /* * create a new tuple descriptor from the one passed in. We do this * partly to copy it into the cache context, and partly because the new @@ -4007,6 +4023,11 @@ RelationAssumeNewRelfilenode(Relation relation) if (relation->rd_firstRelfilenodeSubid == InvalidSubTransactionId) relation->rd_firstRelfilenodeSubid = relation->rd_newRelfilenodeSubid; + if (subtransaction_id_hook) + { + subtransaction_id_hook(relation); + } + /* Flag relation as needing eoxact cleanup (to clear these fields) */ EOXactListAdd(relation); } diff --git a/src/include/access/subtrans.h b/src/include/access/subtrans.h index 9ad1ecc31b9..7b0ae420592 100644 --- a/src/include/access/subtrans.h +++ b/src/include/access/subtrans.h @@ -11,6 +11,8 @@ #ifndef SUBTRANS_H #define SUBTRANS_H +#include "utils/rel.h" + /* Number of SLRU buffers to use for subtrans */ #define NUM_SUBTRANS_BUFFERS 32 @@ -23,6 +25,10 @@ typedef struct SubTransData struct SlruCtlData; typedef struct SlruCtlData *SlruCtl; +/* Hook for subtransaction id */ +typedef void (*subtransaction_id_hook_type) (Relation rel); +extern PGDLLIMPORT subtransaction_id_hook_type subtransaction_id_hook; + extern void SubTransSetParent(TransactionId xid, TransactionId parent); extern TransactionId SubTransGetParent(TransactionId xid); extern TransactionId SubTransGetTopmostTransaction(TransactionId xid);