On 26.02.2018 17:00, Amit Kapila wrote:
On Thu, Feb 15, 2018 at 9:30 PM, Konstantin Knizhnik
<k.knizh...@postgrespro.ru> wrote:
Hi,

PostgreSQL performance degrades signficantly in case of high contention.
You can look at the attached YCSB results (ycsb-zipf-pool.png) to estimate
the level of this degradation.

Postgres is acquiring two kind of heavy weight locks during update: it locks
TID of the updated tuple and XID of transaction created this version.
In debugger I see the following picture: if several transactions are trying
to update the same record, then first of all they compete for
SnapshotDirty.xmax transaction lock in EvalPlanQualFetch.
Then in heap_tuple_update they are trying to lock TID of the updated tuple:
heap_acquire_tuplock in heapam.c

There is no function named heap_tuple_update.  Do you mean to say heap_update?

Yes, sorry. I mean heap_update.


After that transactions wait completion of the transaction updated the
tuple: XactLockTableWait in heapam.c

So in heap_acquire_tuplock all competing transactions are waiting for TID of
the updated version. When transaction which changed this tuple is committed,
one of the competitors will grant this lock and proceed, creating new
version of the tuple. Then all other competitors will be awaken and ... find
out that locked tuple is not the last version any more.
Then they will locate new version and try to lock it... The more competitors
we have, then more attempts they all have to perform (quadratic complexity).

The attempts are controlled by marking the tuple as locked by me after
waiting on SnapshotDirty.xmax.  So, the backend which marks the tuple
as locked must get the tuple to update and I think it is ensured in
code that only one backend will be allowed to do so.  I can see some
serialization in this logic, but I think we should first try to get
the theory behind the contention problem you are seeing before trying
to find the solution for it.


Sorry, I could not say, that I completely understand logic of locking updated tuples in Postgres, although  I have spent some time inspecting this code. It seems to be strange and quite inefficient to me that updating one tuple requires obtaining three heavy-weight locks.
Did you read this thread:

https://www.postgresql.org/message-id/CANP8%2BjKoMAyXvMO2hUqFzHX8fYSFc82q9MEse2zAEOC8vxwDfA%40mail.gmail.com


In any, the summary of all my last experiments with locking is the following:

1. My proposal with transaction lock chaining can reduce performance degradation with increasing number of competing transactions. But degradation still takes place. Moreover, my recent experiments shows that lock chaining can cause deadlocks. It seems to me that I know the reason of such deadlocks,
but right now have no idea how to fix them.
2.  Replacing tuple TID locks with tuple PK lock has positive effect only if lock is hold until end of transaction. Certainly we can not lock all updated tuples (it will cause lock hash overflow). But we can keep until end of transaction just some small number of tuple locks. Unfortunately it is not the only problem with this solution: it is relatively simple to implement in case of integer primary key, but handling all kind of PKs, including compound keys requires more efforts. Also there can be no PK at all... 3. Alternative to PK lock is root tuple lock (head of  hot update chain). Unfortunately there is no efficient way (at least I do not know one) of locating root tuple. Scanning the whole page seems to be too inefficient. If we perform index scan, than we actually start with root tuple, so it is possible to somehow propagate it. But it doesn't work in case of heap scan. And I suspect that as in case of PK lock, it can increase performance only of lock is hold until end of transaction.

So the problem with lock contention really exist. It can be quite easily reproduced at the computer with large number of core with either pgbench with zipf distribution, either with YCSB benchmark, either with my pgrw benchmark... But how to fix it is unclear.


--
Konstantin Knizhnik
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company


Reply via email to