I took a brief look through this patch. I agree with the fundamental idea that we shouldn't need to use the heavyweight lock manager for relation extension, since deadlock is not a concern and no backend should ever need to hold more than one such lock at once. But it feels to me like this particular solution is rather seriously overengineered. I would like to suggest that we do something similar to Robert Haas' excellent hack (daa7527af) for the !HAVE_SPINLOCK case in lmgr/spin.c, that is,
* Create some predetermined number N of LWLocks for relation extension. * When we want to extend some relation R, choose one of those locks (say, R's relfilenode number mod N) and lock it. 1. As long as all backends agree on the relation-to-lock mapping, this provides full security against concurrent extensions of the same relation. 2. Occasionally a backend will be blocked when it doesn't need to be, because of false sharing of a lock between two relations that need to be extended at the same time. But as long as N is large enough (and I doubt that it needs to be very large), that will be a negligible penalty. 3. Aside from being a lot simpler than the proposed extension_lock.c, this approach involves absolutely negligible overhead beyond the raw LWLockAcquire and LWLockRelease calls. I suspect therefore that in typical noncontended cases it will be faster. It also does not require any new resource management overhead, thus eliminating this patch's small but real penalty on transaction exit/cleanup. We'd need to do a bit of performance testing to choose a good value for N. I think that with N comparable to MaxBackends, the odds of false sharing being a problem would be quite negligible ... but it could be that we could get away with a lot less than that. regards, tom lane