diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c new file mode 100644 index 8c9ebe0..e49464c *** a/src/backend/utils/cache/relcache.c --- b/src/backend/utils/cache/relcache.c *************** static long relcacheInvalsReceived = 0L; *** 136,145 **** */ static List *initFileRelationIds = NIL; ! /* ! * This flag lets us optimize away work in AtEO(Sub)Xact_RelationCache(). */ ! static bool need_eoxact_work = false; /* --- 136,160 ---- */ static List *initFileRelationIds = NIL; ! /* ! * To avoid the need to inspect the entire hash table in ! * AtEO(Sub)Xact_RelationCache(), keep a small list of ! * relations that may need work. If it overflows, then ! * revert to inspecting the entire hash table. If ! * n_eoxact_list == -1, then no work can be necessary. ! * If the same entry shows up in the list more than once, ! * no harm is done as the processing is idempotent. */ ! #define MAX_EOXACT_LIST 10 ! static Oid eoxact_list[MAX_EOXACT_LIST]; ! static int n_eoxact_list=-1; ! ! #define EOXactListAdd(rel) \ ! do { \ ! if (n_eoxact_list < MAX_EOXACT_LIST) \ ! if (++n_eoxact_list < MAX_EOXACT_LIST) \ ! eoxact_list[n_eoxact_list]=rel->rd_id; \ ! } while (0) /* *************** static void RelationClearRelation(Relati *** 204,209 **** --- 219,225 ---- static void RelationReloadIndexInfo(Relation relation); static void RelationFlushRelation(Relation relation); + static void AtEOXact_release(bool isCommit, RelIdCacheEnt *idhentry); static bool load_relcache_init_file(bool shared); static void write_relcache_init_file(bool shared); static void write_item(const void *data, Size len, FILE *fp); *************** AtEOXact_RelationCache(bool isCommit) *** 2246,2269 **** * To speed up transaction exit, we want to avoid scanning the relcache * unless there is actually something for this routine to do. Other than * the debug-only Assert checks, most transactions don't create any work ! * for us to do here, so we keep a static flag that gets set if there is * anything to do. (Currently, this means either a relation is created in * the current xact, or one is given a new relfilenode, or an index list ! * is forced.) For simplicity, the flag remains set till end of top-level * transaction, even though we could clear it at subtransaction end in ! * some cases. */ ! if (!need_eoxact_work #ifdef USE_ASSERT_CHECKING && !assert_enabled #endif ) - return; - - hash_seq_init(&status, RelationIdCache); - - while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL) { Relation relation = idhentry->reldesc; /* --- 2262,2303 ---- * To speed up transaction exit, we want to avoid scanning the relcache * unless there is actually something for this routine to do. Other than * the debug-only Assert checks, most transactions don't create any work ! * for us to do here, so we keep a small static list that gets pushed onto if there is * anything to do. (Currently, this means either a relation is created in * the current xact, or one is given a new relfilenode, or an index list ! * is forced.) For simplicity, the list remains set till end of top-level * transaction, even though we could clear it at subtransaction end in ! * some cases, or remove relations from it if they are cleared for other reasons. */ ! ! if (n_eoxact_list < MAX_EOXACT_LIST #ifdef USE_ASSERT_CHECKING && !assert_enabled #endif ) { + for ( ; n_eoxact_list>=0; n_eoxact_list--) { + idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, + (void *) &(eoxact_list[n_eoxact_list]), + HASH_FIND, NULL); + if (idhentry) + AtEOXact_release(isCommit, idhentry); + } + } + else + { + hash_seq_init(&status, RelationIdCache); + while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL) + { + AtEOXact_release(isCommit, idhentry); + } + } + n_eoxact_list = -1; + } + + void + AtEOXact_release(bool isCommit, RelIdCacheEnt *idhentry) + { Relation relation = idhentry->reldesc; /* *************** AtEOXact_RelationCache(bool isCommit) *** 2301,2307 **** else { RelationClearRelation(relation, false); ! continue; } } --- 2335,2341 ---- else { RelationClearRelation(relation, false); ! return; } } *************** AtEOXact_RelationCache(bool isCommit) *** 2320,2329 **** relation->rd_oidindex = InvalidOid; relation->rd_indexvalid = 0; } - } - - /* Once done with the transaction, we can reset need_eoxact_work */ - need_eoxact_work = false; } /* --- 2354,2359 ---- *************** AtEOSubXact_RelationCache(bool isCommit, *** 2344,2350 **** * Skip the relcache scan if nothing to do --- see notes for * AtEOXact_RelationCache. */ ! if (!need_eoxact_work) return; hash_seq_init(&status, RelationIdCache); --- 2374,2380 ---- * Skip the relcache scan if nothing to do --- see notes for * AtEOXact_RelationCache. */ ! if (n_eoxact_list == -1) return; hash_seq_init(&status, RelationIdCache); *************** RelationBuildLocalRelation(const char *r *** 2482,2489 **** rel->rd_createSubid = GetCurrentSubTransactionId(); rel->rd_newRelfilenodeSubid = InvalidSubTransactionId; - /* must flag that we have rels created in this transaction */ - need_eoxact_work = true; /* * create a new tuple descriptor from the one passed in. We do this --- 2512,2517 ---- *************** RelationBuildLocalRelation(const char *r *** 2568,2575 **** RelationInitPhysicalAddr(rel); /* ! * Okay to insert into the relcache hash tables. */ RelationCacheInsert(rel); /* --- 2596,2604 ---- RelationInitPhysicalAddr(rel); /* ! * Okay to insert into the relcache hash tables. Must flag that we have rels created in this transaction */ + EOXactListAdd(rel); RelationCacheInsert(rel); /* *************** RelationSetNewRelfilenode(Relation relat *** 2696,2702 **** */ relation->rd_newRelfilenodeSubid = GetCurrentSubTransactionId(); /* ... and now we have eoxact cleanup work to do */ ! need_eoxact_work = true; } --- 2725,2731 ---- */ relation->rd_newRelfilenodeSubid = GetCurrentSubTransactionId(); /* ... and now we have eoxact cleanup work to do */ ! EOXactListAdd(relation); } *************** RelationSetIndexList(Relation relation, *** 3469,3475 **** relation->rd_oidindex = oidIndex; relation->rd_indexvalid = 2; /* mark list as forced */ /* must flag that we have a forced index list */ ! need_eoxact_work = true; } /* --- 3498,3504 ---- relation->rd_oidindex = oidIndex; relation->rd_indexvalid = 2; /* mark list as forced */ /* must flag that we have a forced index list */ ! EOXactListAdd(relation); } /*