Header And Logo

PostgreSQL
| The world's most advanced open source database.

Typedefs | Functions

inval.h File Reference

#include "access/htup.h"
#include "storage/relfilenode.h"
#include "utils/relcache.h"
Include dependency graph for inval.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef void(* SyscacheCallbackFunction )(Datum arg, int cacheid, uint32 hashvalue)
typedef void(* RelcacheCallbackFunction )(Datum arg, Oid relid)

Functions

void AcceptInvalidationMessages (void)
void AtStart_Inval (void)
void AtSubStart_Inval (void)
void AtEOXact_Inval (bool isCommit)
void AtEOSubXact_Inval (bool isCommit)
void AtPrepare_Inval (void)
void PostPrepare_Inval (void)
void CommandEndInvalidationMessages (void)
void CacheInvalidateHeapTuple (Relation relation, HeapTuple tuple, HeapTuple newtuple)
void CacheInvalidateCatalog (Oid catalogId)
void CacheInvalidateRelcache (Relation relation)
void CacheInvalidateRelcacheByTuple (HeapTuple classTuple)
void CacheInvalidateRelcacheByRelid (Oid relid)
void CacheInvalidateSmgr (RelFileNodeBackend rnode)
void CacheInvalidateRelmap (Oid databaseId)
void CacheRegisterSyscacheCallback (int cacheid, SyscacheCallbackFunction func, Datum arg)
void CacheRegisterRelcacheCallback (RelcacheCallbackFunction func, Datum arg)
void CallSyscacheCallbacks (int cacheid, uint32 hashvalue)
void inval_twophase_postcommit (TransactionId xid, uint16 info, void *recdata, uint32 len)

Typedef Documentation

typedef void(* RelcacheCallbackFunction)(Datum arg, Oid relid)

Definition at line 23 of file inval.h.

typedef void(* SyscacheCallbackFunction)(Datum arg, int cacheid, uint32 hashvalue)

Definition at line 22 of file inval.h.


Function Documentation

void AcceptInvalidationMessages ( void   ) 

Definition at line 588 of file inval.c.

References InvalidateSystemCaches(), LocalExecuteInvalidationMessage(), and ReceiveSharedInvalidMessages().

Referenced by AtStart_Cache(), ConditionalLockRelation(), ConditionalLockRelationOid(), LockDatabaseObject(), LockRelation(), LockRelationOid(), LockSharedObject(), ProcessCatchupEvent(), RangeVarGetRelidExtended(), relation_openrv(), relation_openrv_extended(), RemoveRelations(), and write_relcache_init_file().

{
    ReceiveSharedInvalidMessages(LocalExecuteInvalidationMessage,
                                 InvalidateSystemCaches);

    /*
     * Test code to force cache flushes anytime a flush could happen.
     *
     * If used with CLOBBER_FREED_MEMORY, CLOBBER_CACHE_ALWAYS provides a
     * fairly thorough test that the system contains no cache-flush hazards.
     * However, it also makes the system unbelievably slow --- the regression
     * tests take about 100 times longer than normal.
     *
     * If you're a glutton for punishment, try CLOBBER_CACHE_RECURSIVELY. This
     * slows things by at least a factor of 10000, so I wouldn't suggest
     * trying to run the entire regression tests that way.  It's useful to try
     * a few simple tests, to make sure that cache reload isn't subject to
     * internal cache-flush hazards, but after you've done a few thousand
     * recursive reloads it's unlikely you'll learn more.
     */
#if defined(CLOBBER_CACHE_ALWAYS)
    {
        static bool in_recursion = false;

        if (!in_recursion)
        {
            in_recursion = true;
            InvalidateSystemCaches();
            in_recursion = false;
        }
    }
#elif defined(CLOBBER_CACHE_RECURSIVELY)
    InvalidateSystemCaches();
#endif
}

void AtEOSubXact_Inval ( bool  isCommit  ) 

Definition at line 890 of file inval.c.

References AppendInvalidationMessages(), Assert, CommandEndInvalidationMessages(), GetCurrentTransactionNestLevel(), LocalExecuteInvalidationMessage(), TransInvalidationInfo::my_level, NULL, TransInvalidationInfo::parent, pfree(), TransInvalidationInfo::PriorCmdInvalidMsgs, ProcessInvalidationMessages(), and TransInvalidationInfo::RelcacheInitFileInval.

Referenced by AbortSubTransaction(), and CommitSubTransaction().

{
    int         my_level = GetCurrentTransactionNestLevel();
    TransInvalidationInfo *myInfo = transInvalInfo;

    if (isCommit)
    {
        /* Must be at non-top of stack */
        Assert(myInfo != NULL && myInfo->parent != NULL);
        Assert(myInfo->my_level == my_level);

        /* If CurrentCmdInvalidMsgs still has anything, fix it */
        CommandEndInvalidationMessages();

        /* Pass up my inval messages to parent */
        AppendInvalidationMessages(&myInfo->parent->PriorCmdInvalidMsgs,
                                   &myInfo->PriorCmdInvalidMsgs);

        /* Pending relcache inval becomes parent's problem too */
        if (myInfo->RelcacheInitFileInval)
            myInfo->parent->RelcacheInitFileInval = true;

        /* Pop the transaction state stack */
        transInvalInfo = myInfo->parent;

        /* Need not free anything else explicitly */
        pfree(myInfo);
    }
    else if (myInfo != NULL && myInfo->my_level == my_level)
    {
        /* Must be at non-top of stack */
        Assert(myInfo->parent != NULL);

        ProcessInvalidationMessages(&myInfo->PriorCmdInvalidMsgs,
                                    LocalExecuteInvalidationMessage);

        /* Pop the transaction state stack */
        transInvalInfo = myInfo->parent;

        /* Need not free anything else explicitly */
        pfree(myInfo);
    }
}

void AtEOXact_Inval ( bool  isCommit  ) 
void AtPrepare_Inval ( void   ) 
void AtStart_Inval ( void   ) 
void AtSubStart_Inval ( void   ) 
void CacheInvalidateCatalog ( Oid  catalogId  ) 

Definition at line 1082 of file inval.c.

References IsSharedRelation(), MyDatabaseId, and RegisterCatalogInvalidation().

Referenced by finish_heap_swap().

{
    Oid         databaseId;

    if (IsSharedRelation(catalogId))
        databaseId = InvalidOid;
    else
        databaseId = MyDatabaseId;

    RegisterCatalogInvalidation(databaseId, catalogId);
}

void CacheInvalidateHeapTuple ( Relation  relation,
HeapTuple  tuple,
HeapTuple  newtuple 
)

Definition at line 979 of file inval.c.

References AttributeRelationId, GETSTRUCT, HeapTupleGetOid, IndexRelationId, IsBootstrapProcessingMode, IsSystemRelation(), IsToastRelation(), MyDatabaseId, PrepareToInvalidateCacheTuple(), RegisterCatcacheInvalidation(), RegisterRelcacheInvalidation(), RelationGetRelid, and RelationRelationId.

Referenced by heap_delete(), heap_inplace_update(), heap_insert(), heap_multi_insert(), and heap_update().

{
    Oid         tupleRelId;
    Oid         databaseId;
    Oid         relationId;

    /* Do nothing during bootstrap */
    if (IsBootstrapProcessingMode())
        return;

    /*
     * We only need to worry about invalidation for tuples that are in system
     * relations; user-relation tuples are never in catcaches and can't affect
     * the relcache either.
     */
    if (!IsSystemRelation(relation))
        return;

    /*
     * TOAST tuples can likewise be ignored here. Note that TOAST tables are
     * considered system relations so they are not filtered by the above test.
     */
    if (IsToastRelation(relation))
        return;

    /*
     * First let the catcache do its thing
     */
    PrepareToInvalidateCacheTuple(relation, tuple, newtuple,
                                  RegisterCatcacheInvalidation);

    /*
     * Now, is this tuple one of the primary definers of a relcache entry?
     *
     * Note we ignore newtuple here; we assume an update cannot move a tuple
     * from being part of one relcache entry to being part of another.
     */
    tupleRelId = RelationGetRelid(relation);

    if (tupleRelId == RelationRelationId)
    {
        Form_pg_class classtup = (Form_pg_class) GETSTRUCT(tuple);

        relationId = HeapTupleGetOid(tuple);
        if (classtup->relisshared)
            databaseId = InvalidOid;
        else
            databaseId = MyDatabaseId;
    }
    else if (tupleRelId == AttributeRelationId)
    {
        Form_pg_attribute atttup = (Form_pg_attribute) GETSTRUCT(tuple);

        relationId = atttup->attrelid;

        /*
         * KLUGE ALERT: we always send the relcache event with MyDatabaseId,
         * even if the rel in question is shared (which we can't easily tell).
         * This essentially means that only backends in this same database
         * will react to the relcache flush request.  This is in fact
         * appropriate, since only those backends could see our pg_attribute
         * change anyway.  It looks a bit ugly though.  (In practice, shared
         * relations can't have schema changes after bootstrap, so we should
         * never come here for a shared rel anyway.)
         */
        databaseId = MyDatabaseId;
    }
    else if (tupleRelId == IndexRelationId)
    {
        Form_pg_index indextup = (Form_pg_index) GETSTRUCT(tuple);

        /*
         * When a pg_index row is updated, we should send out a relcache inval
         * for the index relation.  As above, we don't know the shared status
         * of the index, but in practice it doesn't matter since indexes of
         * shared catalogs can't have such updates.
         */
        relationId = indextup->indexrelid;
        databaseId = MyDatabaseId;
    }
    else
        return;

    /*
     * Yes.  We need to register a relcache invalidation event.
     */
    RegisterRelcacheInvalidation(databaseId, relationId);
}

void CacheInvalidateRelcache ( Relation  relation  ) 
void CacheInvalidateRelcacheByRelid ( Oid  relid  ) 

Definition at line 1144 of file inval.c.

References CacheInvalidateRelcacheByTuple(), elog, ERROR, HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), RELOID, and SearchSysCache1.

Referenced by DefineIndex().

{
    HeapTuple   tup;

    tup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
    if (!HeapTupleIsValid(tup))
        elog(ERROR, "cache lookup failed for relation %u", relid);
    CacheInvalidateRelcacheByTuple(tup);
    ReleaseSysCache(tup);
}

void CacheInvalidateRelcacheByTuple ( HeapTuple  classTuple  ) 

Definition at line 1123 of file inval.c.

References GETSTRUCT, HeapTupleGetOid, MyDatabaseId, and RegisterRelcacheInvalidation().

Referenced by CacheInvalidateRelcacheByRelid(), index_update_stats(), SetRelationHasSubclass(), SetRelationRuleStatus(), and swap_relation_files().

{
    Form_pg_class classtup = (Form_pg_class) GETSTRUCT(classTuple);
    Oid         databaseId;
    Oid         relationId;

    relationId = HeapTupleGetOid(classTuple);
    if (classtup->relisshared)
        databaseId = InvalidOid;
    else
        databaseId = MyDatabaseId;
    RegisterRelcacheInvalidation(databaseId, relationId);
}

void CacheInvalidateRelmap ( Oid  databaseId  ) 

Definition at line 1209 of file inval.c.

References SharedInvalRelmapMsg::dbId, SharedInvalRelmapMsg::id, SharedInvalidationMessage::rm, and SendSharedInvalidMessages().

Referenced by write_relmap_file().

{
    SharedInvalidationMessage msg;

    msg.rm.id = SHAREDINVALRELMAP_ID;
    msg.rm.dbId = databaseId;
    SendSharedInvalidMessages(&msg, 1);
}

void CacheInvalidateSmgr ( RelFileNodeBackend  rnode  ) 
void CacheRegisterRelcacheCallback ( RelcacheCallbackFunction  func,
Datum  arg 
)
void CacheRegisterSyscacheCallback ( int  cacheid,
SyscacheCallbackFunction  func,
Datum  arg 
)
void CallSyscacheCallbacks ( int  cacheid,
uint32  hashvalue 
)

Definition at line 1276 of file inval.c.

References SYSCACHECALLBACK::arg, SYSCACHECALLBACK::function, i, SYSCACHECALLBACK::id, syscache_callback_count, and syscache_callback_list.

Referenced by CatalogCacheFlushCatalog(), and LocalExecuteInvalidationMessage().

{
    int         i;

    for (i = 0; i < syscache_callback_count; i++)
    {
        struct SYSCACHECALLBACK *ccitem = syscache_callback_list + i;

        if (ccitem->id == cacheid)
            (*ccitem->function) (ccitem->arg, cacheid, hashvalue);
    }
}

void CommandEndInvalidationMessages ( void   ) 

Definition at line 950 of file inval.c.

References AppendInvalidationMessages(), TransInvalidationInfo::CurrentCmdInvalidMsgs, LocalExecuteInvalidationMessage(), NULL, TransInvalidationInfo::PriorCmdInvalidMsgs, and ProcessInvalidationMessages().

Referenced by AtCCI_LocalCache(), and AtEOSubXact_Inval().

{
    /*
     * You might think this shouldn't be called outside any transaction, but
     * bootstrap does it, and also ABORT issued when not in a transaction. So
     * just quietly return if no state to work on.
     */
    if (transInvalInfo == NULL)
        return;

    ProcessInvalidationMessages(&transInvalInfo->CurrentCmdInvalidMsgs,
                                LocalExecuteInvalidationMessage);
    AppendInvalidationMessages(&transInvalInfo->PriorCmdInvalidMsgs,
                               &transInvalInfo->CurrentCmdInvalidMsgs);
}

void inval_twophase_postcommit ( TransactionId  xid,
uint16  info,
void *  recdata,
uint32  len 
)
void PostPrepare_Inval ( void   ) 

Definition at line 653 of file inval.c.

References AtEOXact_Inval().

Referenced by PrepareTransaction().

{
    AtEOXact_Inval(false);
}