Обсуждение: Proposal: New LWLockmode LW_OWNER
Currently there are two modes of LWLock : SHARED and EXCLUSIVE Mostly you need to have EXCLUSIVE lock mode to make any changes, add, delete and SHARED if you are just reading it. Multiple backends can grab SHARED mode simultaneously while only one Backend can grab EXCLUSIVE at a time. There are situations when there are opportunities that certain values are typically changed by the same backend also in such cases when multiple backend wants to change similarly values that they themselves typically change there is no lockmode which allows simultaneous updates in such cases and the result is sequential changes to the values which can be done simultaneously New Lock Mode Proposed: LW_EX_OWNER (input on better name will be appreciated). So now there will be three modes SHARED, EXCLUSIVE, EX_OWNER They will still be all mutually exclusive in the sense at any given time there can be only one mode active. However there is a marked difference while values of SHARED can be 0..N and EXCLUSIVE can be 0..1, the new lock mode EX_OWNER can be again 0..N. This is primarily important so that we can carry out tasks of updates which not necessarily will be modified by any other backend.. Protection is guranteed since mostly old code will still have EXCLUSIVE lock so they will still need to work as guranteed. However advantage is for certain operations where we can still allow others to write into their own "area" with this EX_OWNER lock mode which allows multiple backend into shared area that they own. The area is not guaranteed by the lock mode but the procedure themselves and lock framework need not worry about that. I wrote a prototype which needs changes in lwlock.h and lwlock.c and modifies lwlock.c which also awakes all SHARED together and if the first waiter is EX_OWNER it awakes all EX_OWNER together and if it EXCLUSIVE then just wakes the EXCLUSIVE waiter.. The potential for this new lock mode can be used in various scenarios though it will need separate proposals on how to handle them since all bases are not covered yet but just as examples here: 1. Proc array structure: Many times specific proc array structure is modified by the same backend. 2. WAL Buffers themselves: One way to make wal_buffer scalable is to have areas defined and have certain backend go against such areas rather than get the whole buffer lock. EXCLUSIVE is still used for most of them except certain identified parts.. 3. Many other not identified yet. Right now this proposal is only for the new Lock mode. Since thats a Lock framework enhancements which can give rise to multiple uses later Regards, Jignesh
"Jignesh K. Shah" <J.K.Shah@Sun.COM> writes: > New Lock Mode Proposed: LW_EX_OWNER (input on better name will be > appreciated). This seems rather crazy, and you haven't actually given a single convincing use-case. Shouldn't you be trying to break down a lock into multiple locks instead of inventing new lock semantics that nobody really understands? regards, tom lane
Tom Lane wrote: > "Jignesh K. Shah" <J.K.Shah@Sun.COM> writes: > >> New Lock Mode Proposed: LW_EX_OWNER (input on better name will be >> appreciated). >> > > This seems rather crazy, and you haven't actually given a single > convincing use-case. Shouldn't you be trying to break down a lock > into multiple locks instead of inventing new lock semantics that > nobody really understands? > > One area that I find it useful is where it will be useful is in ProcArrayEndTransaction where it uses exclusive to update proc array structure where right now it uses EXCLUSIVE and most commit transactions are updating their own proc array structure this lock semantic can be useful.. However I havent figured out on the last line where it updates ShmemVariableCache->latestCompletedXid which might require still an EXCLUSIVE lock and hence did not propose the use case. http://doxygen.postgresql.org/procarray_8c-source.html#l00231 The whole concept of a single Exclusive lock to me is more flawed than the proposed idea. Single Exclusive locks are artificial bottlenecks in PostgreSQL and thats why a new lock semantic is helpful in opening people's mind beyond exclusive lock and suddenly people will start doing more parallel work where possible and LW_EX_OWNER allows that to work. Which infact will allow somebody else to innovate on ProcArrayEndTransaction and solve the problem that I could not figure regarding latestCompletedXid. In my sample test where putting LW_EX_OWNER or LW_OWNER as I have it my code in ProcArrayEndTransaction the throughput of HEAD CVS went from 200,000 transactions per minute to 300,000 transactions per minute but though in my case latestCompletedXid is unsafe. If thats solved, there is a potential upswing in scalability in PostgreSQL core. Once that function is implemented correctly, it will highlight other places where such lock semantics could prove to be useful.. (My money on WALInsertLock) -Jignesh
Tom Lane wrote: > "Jignesh K. Shah" <J.K.Shah@Sun.COM> writes: > > New Lock Mode Proposed: LW_EX_OWNER (input on better name will be > > appreciated). > > This seems rather crazy, and you haven't actually given a single > convincing use-case. Shouldn't you be trying to break down a lock > into multiple locks instead of inventing new lock semantics that > nobody really understands? We do something like this in the sinval code -- see SIGetDataEntry. We use LW_SHARED for it. Obviously it has the implication that a backend can never grab only SHARED and examine the status of other backends, but that's not needed in this code. Perhaps the other pieces of code that Jignesh wants to improve can be treated similarly? -- Alvaro Herrera http://www.CommandPrompt.com/ The PostgreSQL Company - Command Prompt, Inc.
"Jignesh K. Shah" <J.K.Shah@Sun.COM> writes: > Tom Lane wrote: >> This seems rather crazy, and you haven't actually given a single >> convincing use-case. > One area that I find it useful is where it will be useful is in > ProcArrayEndTransaction where it uses exclusive to update proc array > structure where right now it uses EXCLUSIVE and most commit transactions > are updating their own proc array structure this lock semantic can be > useful.. That is exactly a place where you CAN'T use this, because it will break transactional semantics, specifically serialization of commits relative to snapshots. See all the discussions around the last refactoring of ProcArray locking, and particularly the summary in src/backend/access/transam/README. regards, tom lane
Alvaro Herrera <alvherre@commandprompt.com> writes: > Tom Lane wrote: >> "Jignesh K. Shah" <J.K.Shah@Sun.COM> writes: >>> New Lock Mode Proposed: LW_EX_OWNER (input on better name will be >>> appreciated). > We do something like this in the sinval code -- see SIGetDataEntry. Yeah, that analogy occurred to me later --- EX_OWNER would be a close match to what sinval is doing. However, adding a third mode to LWLocks would certainly introduce extra cycles into what is already a hotspot, and one use-case that is already working fine without it doesn't seem like much of an argument. (ProcArray isn't a use-case because of the commit interlock problem, and I didn't see any other proposed uses that weren't mere hand-waving.) regards, tom lane
On Fri, 2008-06-06 at 12:39 -0400, Tom Lane wrote: > "Jignesh K. Shah" <J.K.Shah@Sun.COM> writes: > > New Lock Mode Proposed: LW_EX_OWNER (input on better name will be > > appreciated). > > This seems rather crazy, and you haven't actually given a single > convincing use-case. Shouldn't you be trying to break down a lock > into multiple locks instead of inventing new lock semantics that > nobody really understands? I understand why Jignesh has approached it this way, having talked some at PGCon about this. Splitting ProcArray into multiple pieces is likely to slow down access to the ProcArray for everyone, since shared accessors want the whole thing, but we should try that also as you suggest. Allowing a lock mode where the individual pieces are accessible as a whole or individually does make some sense. This is a different situation than buffer and lock table access, where there was no common workload that needed access to all partitions. So I think its a reasonable idea, with a complex sounding name. The main issue is proving it helps the target workload, and doesn't hinder other workloads. We should do that before we think of a better name. There are other possibilities as well, but my feeling is that we should explore them all - so lets give this idea enough space to show its worth, if any. Personally, I don't see it being applicable to WAL buffers though. That is a different situation again and we have a couple of workable ideas on the table already. That doesn't detract from this idea's possible worth. Unique and important situations need unique solutions. So, please can we see some perf results? Big gains justify extra code. -- Simon Riggs www.2ndQuadrant.comPostgreSQL Training, Services and Support
Tom Lane wrote: > "Jignesh K. Shah" <J.K.Shah@Sun.COM> writes: > >> Tom Lane wrote: >> >>> This seems rather crazy, and you haven't actually given a single >>> convincing use-case. >>> > > >> One area that I find it useful is where it will be useful is in >> ProcArrayEndTransaction where it uses exclusive to update proc array >> structure where right now it uses EXCLUSIVE and most commit transactions >> are updating their own proc array structure this lock semantic can be >> useful.. >> > > That is exactly a place where you CAN'T use this, because it will break > transactional semantics, specifically serialization of commits relative > to snapshots. See all the discussions around the last refactoring of > ProcArray locking, and particularly the summary in > src/backend/access/transam/README. > > > Quoting from the README that you mentioned: Formally, the correctness requirement is "if a snapshot A considers transaction X as committed, and any of transaction X's snapshots considered transaction Y as committed, then snapshot A must consider transaction Y as committed". What we actually enforce is strict serialization of commits and rollbacks with snapshot-taking: we do not allow any transaction to exit the set of running transactions while a snapshot is being taken. (This rule is stronger than necessary for consistency, but is relatively simple to enforce, and it assists with some other issues as explained below.) The implementation of this is that GetSnapshotData takes the ProcArrayLock in shared mode (so that multiple backends can take snapshots in parallel), but ProcArrayEndTransaction must take the ProcArrayLock in exclusive mode while clearing MyProc->xid at transaction end (either commit or abort). ProcArrayEndTransaction also holds the lock while advancing the shared latestCompletedXid variable. This allows GetSnapshotData to use latestCompletedXid + 1 as xmax for its snapshot: there can be no transaction >= this xid value that the snapshot needs to consider as completed. Quote End What I understand is the rule of serializations comes into play when Snapshot is being taken... Snapshot is being taken only when SHARED lock has already been acquired. If EX_OWNER is being used in this scenario, it still works as designed. If EX_OWNER has been acquired, NOBODY can get SHARED Lock which means the rule is still satisfied. Of course I am still worried about latestCompletedXid being written at the same time (maybe use some atomic compare and swap function for it to solve the problem) but I dont understand why you think that this is the place where it cannot be used? Simon, Scalability increases 50% from what I see (throughput increases from 200k tpm to 300k tpm and system utilization went from 50% to 80% or so) and is a step forward in overall performance and system utilization. Also response time on high loads also falls drastically to something similar to low load response times. Regards, Jignesh