Re: POC: Sharing record typmods between backends
Andres Freund <andres@anarazel.de>
On 2017-08-21 11:02:52 +1200, Thomas Munro wrote:
> 2. Andres didn't like what I did to DecrTupleDescRefCount, namely
> allowing to run when there is no ResourceOwner. I now see that this
> is probably an indication of a different problem; even if there were a
> worker ResourceOwner as he suggested (or perhaps a session-scoped one,
> which a worker would reset before being reused), it wouldn't be the
> one that was active when the TupleDesc was created. I think I have
> failed to understand the contracts here and will think/read about it
> some more.
Maybe I'm missing something, but isn't the issue here that using
DecrTupleDescRefCount() simply is wrong, because we're not actually
necessarily tracking the TupleDesc via the resowner mechanism?
If you look at the code, in the case it's a previously unknown tupledesc
it's registered with:
entDesc = CreateTupleDescCopy(tupDesc);
...
/* mark it as a reference-counted tupdesc */
entDesc->tdrefcount = 1;
...
RecordCacheArray[newtypmod] = entDesc;
...
Note that there's no PinTupleDesc(), IncrTupleDescRefCount() or
ResourceOwnerRememberTupleDesc() managing the reference from the
array. Nor was there one before.
We have other code managing TupleDesc lifetimes similarly, and look at
how they're freeing it:
/* Delete tupdesc if we have it */
if (typentry->tupDesc != NULL)
{
/*
* Release our refcount, and free the tupdesc if none remain.
* (Can't use DecrTupleDescRefCount because this reference is not
* logged in current resource owner.)
*/
Assert(typentry->tupDesc->tdrefcount > 0);
if (--typentry->tupDesc->tdrefcount == 0)
FreeTupleDesc(typentry->tupDesc);
typentry->tupDesc = NULL;
}
This also made me think about how we're managing the lookup from the
shared array:
/*
* Our local array can now point directly to the TupleDesc
* in shared memory.
*/
RecordCacheArray[typmod] = tupdesc;
Uhm. Isn't that highly highly problematic? E.g. tdrefcount manipulations
which are done by all lookups (cf. lookup_rowtype_tupdesc()) would in
that case manipulate shared memory in a concurrency unsafe manner.
Greetings,
Andres Freund
Commits
-
Remove TupleDesc remapping logic from tqueue.c.
- 6b65a7fe62e1 11.0 landed
-
Add support for coordinating record typmods among parallel workers.
- cc5f81366c36 11.0 landed
-
Improve division of labor between execParallel.c and nodeGather[Merge].c.
- 51daa7bdb39e 11.0 cited
-
Add minimal regression test for blessed record type transfer.
- d36f7efb39e1 11.0 landed
-
Consolidate the function pointer types used by dshash.c.
- d7694fc14870 11.0 landed
-
Fix unlikely shared memory leak after failure in dshash_create().
- 4569715bd6fa 11.0 landed
-
Refactor typcache.c's record typmod hash table.
- 35ea75632a56 11.0 landed
-
Add a hash_combine function for mixing hash values.
- 0052a0243d9c 11.0 landed
-
Backpatch introduction of TupleDescAttr(tupdesc, i).
- 8cda1fadd25b 9.2.23 landed
- 5b286cae3cc1 9.3.19 landed
- 3d58994eccb7 9.4.14 landed
- d778a77d38be 9.5.9 landed
- 6c036d01089c 9.6.5 landed
- d34a74dd064a 10.0 landed
-
Partially flatten struct tupleDesc so that it can be used in DSM.
- c6293249dc17 11.0 landed
-
Change tupledesc->attrs[n] to TupleDescAttr(tupledesc, n).
- 2cd708452400 11.0 landed