Re: Injection point locking

Noah Misch <noah@leadboat.com>

From: Noah Misch <noah@leadboat.com>
To: Michael Paquier <michael@paquier.xyz>
Cc: Heikki Linnakangas <hlinnaka@iki.fi>, pgsql-hackers <pgsql-hackers@postgresql.org>
Date: 2024-06-25T16:10:06Z
Lists: pgsql-hackers
On Tue, Jun 25, 2024 at 11:14:57AM +0900, Michael Paquier wrote:
> On Mon, Jun 24, 2024 at 01:29:38PM +0300, Heikki Linnakangas wrote:
> > InjectionPointRun() acquires InjectionPointLock, looks up the hash entry,
> > and releases the lock:
> > 
> > > 	LWLockAcquire(InjectionPointLock, LW_SHARED);
> > > 	entry_by_name = (InjectionPointEntry *)
> > > 		hash_search(InjectionPointHash, name,
> > > 					HASH_FIND, &found);
> > > 	LWLockRelease(InjectionPointLock);
> > 
> > Later, it reads fields from the entry it looked up:
> > 
> > > 		/* not found in local cache, so load and register */
> > > 		snprintf(path, MAXPGPATH, "%s/%s%s", pkglib_path,
> > > 				 entry_by_name->library, DLSUFFIX);
> > 
> > Isn't that a straightforward race condition, if the injection point is
> > detached in between?
> 
> This is a feature, not a bug :)
> 
> Jokes apart, this is a behavior that Noah was looking for so as it is
> possible to detach a point to emulate what a debugger would do with a
> breakpoint for some of his tests with concurrent DDL bugs, so not
> taking a lock while running a point is important.  It's true, though,
> that we could always delay the LWLock release once the local cache is
> loaded, but would it really matter?

I think your last sentence is what Heikki is saying should happen, and I
agree.  Yes, it matters.  As written, InjectionPointRun() could cache an
entry_by_name->function belonging to a different injection point.



Commits

  1. Improve locking around InjectionPointRun()