On Thu, Jan 09, 2025 at 11:39:53AM +0200, Heikki Linnakangas wrote: > On 07/01/2025 23:56, Noah Misch wrote: > > On Tue, Dec 24, 2024 at 12:18:09AM +0200, Heikki Linnakangas wrote: > > > I'm thinking of the attached to fix this. It changes the strategy for > > > detecting concurrent cache invalidations. Instead of the "recheck" > > > mechanism > > > that was introduced in commit ad98fb1422, keep a stack of "build > > > in-progress" entries, and CatCacheInvalidate() invalidate those > > > "in-progress" entries in addition to the actual CatCTup and CatCList > > > entries. > > > > > > My first attempt was to insert the CatCTup or CatCList entry to the > > > catcache > > > before starting to build it, marked with a flag to indicate that the entry > > > isn't fully built yet. But when I started to write that it got pretty > > > invasive, and it felt easier to add another structure to hold the > > > in-progress entries instead. > > > > That's similar to how relcache has been doing it (in_progress_list). I see > > no > > problem applying that technique here. > > Oh thanks, I didn't notice that in relcache.c. I adjusted the naming and > comments in the new catcache.c code to be a little closer to the relcache.c > version, just to make it a bit more consistent. > > The main difference is that relcache.c uses an array and an end-of-xact > callback to reset the array on error, while my implementation uses a linked > list of entries allocated on stack and PG_TRY-CATCH for error cleanup. I > considered adopting relcache.c's approach for the sake of consistency, but > decided to keep my original approach in the end. Some of the code in > catcache.c already had a suitable PG_TRY-CATCH block and I didn't want to > add a new end-of-xact callback just for this.
That difference is reasonable. catcache will add PG_TRY overhead only in the HEAP_HASEXTERNAL case, which is not a normal benchmark situation. If relcache were to adopt the PG_TRY approach, it would be harder to rule out the significance of the overhead. So a long-term state of using both designs is reasonable. It's not a mere historical accident. > > gcc 4.8.5 warns: > > > > catcache.c: In function ‘CatalogCacheCreateEntry’: > > catcache.c:2159:29: warning: ‘dtp’ may be used uninitialized in this > > function [-Wmaybe-uninitialized] > > ct->tuple.t_tableOid = dtp->t_tableOid; > > > > I remember some commit of a gcc 4.x warning fix in a recent year, and we do > > have buildfarm representation. Consider silencing it. > > Hmm, I guess the compiler doesn't see that it's initialized with all the > PG_TRY()/CATCH() stuff. I initialized it to NULL to silence the warning. It's warning-free now. > @@ -697,9 +725,14 @@ CreateCacheMemoryContext(void) > * > * This is not very efficient if the target cache is nearly empty. > * However, it shouldn't need to be efficient; we don't invoke it often. > + * > + * If 'debug_discard' is true, we are being called as part of > + * debug_discard_caches. In that case, the cache not reset for correctness, s/cache not/cache is not/ or similar > + PG_TRY(); > { > - matches = equalTuple(before, ntp); > - heap_freetuple(before); > + dtp = toast_flatten_tuple(ntp, > cache->cc_tupdesc); > } > - if (!matches || !systable_recheck_tuple(scandesc, ntp)) > + PG_FINALLY(); > { > - heap_freetuple(dtp); Is this an intentional removal of the heap_freetuple(dtp) before return NULL? > - return NULL; > + Assert(catcache_in_progress_stack == > &in_progress_ent); > + catcache_in_progress_stack = save_in_progress; > } > + PG_END_TRY(); > + > + if (in_progress_ent.dead) > + return NULL; ... > +$node->append_conf( > + 'postgresql.conf', qq{ > +debug_discard_caches=1 > +}); I'd drop this debug_discard_caches. debug_discard_caches buildfarm runs will still test it, so let's have normal runs test the normal case.