Re: Soft deadlocks
Re: Soft deadlocks
От:
Tom Lane <tgl@sss.pgh.pa.us>
Дата:
Gregory Stark writes: > I'm trying to understand what a soft deadlock is as described by deadlock.c. > As best I understand if a process, A, is waiting for a lock and is being > blocked only because someone, B, is ahead of it in the queue but hasn't been > granted the conflicting lock we want to jump A ahead of B. No, we only do that if it breaks a deadlock. In your example there is no reason to move process A ahead of B. A more typical situation is like this: Process A:begin;select * from T where ...;-- now A holds AccessShareLock on T Process B:lock table T;-- wants AccessExclusiveLock on T, blocks waiting for A Process A:lock table T;-- blocks behind B? Fairness would normally demand that A queue behind B for the AccessExclusiveLock, but if we do that we have a deadlock. So we spring A ahead of B and let it have the AccessExclusiveLock out of turn. This is just the base case; you can get into similar situations involving more than one lockable object and more than two processes. I believe that the above case is caught by the test in ProcSleep and A will be granted the lock upgrade without blocking at all; but any more-complex situation will only be discovered when someone runs the deadlock checker. regards, tom lane
Soft deadlocks
От:
Gregory Stark <stark@enterprisedb.com>
Дата:
I'm trying to understand what a soft deadlock is as described by deadlock.c. As best I understand if a process, A, is waiting for a lock and is being blocked only because someone, B, is ahead of it in the queue but hasn't been granted the conflicting lock we want to jump A ahead of B. So if i do something like: process X: --------- select * from x where i=1 for share; ---------------- process B: --------- select * from x where i=1 for update; ---------------- process A: --------- select * from x where i=1 for share; process A will block, but when the deadlock timeout fires it should get jumped ahead of process B. If that's right then, uh, it doesn't seem to be working. Process B: postgres=# select * from x where i = 0 for update; LOG: process 4629 still waiting for ShareLock on transaction 7802 after 5000.149 ms Process A: postgres=# select * from x where i = 0 for share; LOG: process 4631 still waiting for ShareLock on tuple (0,1) of relation 16423 of database 11408 after 5000.151 ms -- Gregory Stark EnterpriseDB http://www.enterprisedb.com