Reducing relation locking overhead - Mailing list pgsql-hackers
From | Tom Lane |
---|---|
Subject | Reducing relation locking overhead |
Date | |
Msg-id | 20841.1133491067@sss.pgh.pa.us Whole thread Raw |
Responses |
Re: Reducing relation locking overhead
Re: Reducing relation locking overhead |
List | pgsql-hackers |
In looking at the current pgbench results, I notice that one considerable contribution to LWLock contention is access to the heavyweight-lock manager. Almost all of that comes from taking relation-level locks, so we could cut down the contention if we could reduce the number of distinct locks taken. (The lmgr code already avoids touching shared memory again if, say, you request another AccessShareLock on a relation you've already AccessShareLocked in the current transaction.) I see several places where we might possibly make this kind of savings: 1. In an UPDATE or DELETE query, we take RowExclusiveLock on the target relation, and also take AccessShareLock in the scan node that reads the relation. It wouldn't take much extra code to make the scan nodes avoid taking AccessShareLock if the relation is already opened as the query result relation. AFAICS there is no downside to this; any lock that would conflict with AccessShareLock will also conflict with RowExclusiveLock, so there's no real need to hold both lock types. (Moreover, we already make a similar kind of optimization when accessing system catalogs: those routines only take one lock not two.) Does anyone have an objection to it? 2. In the same way, an index that is used to scan the target relation will be locked in both RowExclusiveLock and AccessShareLock modes (corresponding to its roles as both source and update target). We could avoid taking both lock types, but this would require some restructuring because the code responsible for locking the indexes doesn't currently have access to the EState to find out whether an index belongs to a target relation. What I'm thinking here is that maybe there's no point in maintaining the read versus write distinction at all for indexes --- we could just take AccessShareLock in both cases. Any thoughts on the pros and cons there? 3. We could also save some trips to the lock manager if we adopt the same position for user indexes as we do for user tables, namely that locks once taken are held till end of transaction. Any thoughts about that? 4. The only reason we need to take relation-level locks on indexes at all is to make the world safe for REINDEX being done concurrently with read-only accesses to the table (that don't use the index being reindexed). If we went back to requiring exclusive lock for reindex we could forget all about both #2 and #3. Particularly for updates of relations with lots of indexes, this could be a pretty significant win. However we'd definitely be giving up something that was seen as a feature at one point, so I'm not sold on this idea ... unless someone can see a way to reduce the overhead without giving up concurrent REINDEX. regards, tom lane
pgsql-hackers by date: