Andres Freund wrote:
> On 2013-11-22 12:04:31 -0300, Alvaro Herrera wrote:
> Yes, somewhat: <9.3 GetMultiXactIdMembers() didn't do any work if the
> multixact was old enough:
> if (MultiXactIdPrecedes(multi, OldestVisibleMXactId[MyBackendId]))
> {
> debug_elog2(DEBUG2, "GetMembers: it's too old");
> *xids = NULL;
> return -1;
> }
> so, in OLTP style workloads, doing a heap_lock_tuple() often didn't have
> to perform any IO when locking a tuple that previously had been locked
> using a multixact. We knew that none of the members could still be
> running and thus didn't have to ask the SLRU for them since a
> not-running member cannot still have a row locked.
Right.
> Now, fkey locks changed that because for !HEAP_XMAX_LOCK_ONLY mxacts, we
> need to look up the members to get the update xid and check whether it
> has committed or aborted, even if we know that it isn't currently
> running anymore due do OldestVisibleMXactId. But there's absolutely no
> need to do that for HEAP_XMAX_LOCK_ONLY mxacts, the old reasoning for
> not looking up the members if old is just fine.
Correct. The only difficulty here is that we would need to pass down
the fact that we know for certain that this is only a locking Multixact.
There are some callers that go to it indirectly via MultiXactIdWait or
MultiXactIdExpand, but now that I look I think it's fine for those to
pass false (i.e. assume there might be an update and disable the
optimization), since those aren't hot compared to the other cases.
This patch implements this idea, but I haven't tested it much beyond
compiling and ensuring it passes the existing tests.
Regarding the outdated comment, I had a rewritten version of that
somewhere which I evidently forgot to push :-( I noticed it was
outdated a couple of weeks after I pushed the main patch.
--
Álvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services