Re: Contention preventing locking

From: Konstantin Knizhnik <k(dot)knizhnik(at)postgrespro(dot)ru>
To: Simon Riggs <simon(at)2ndquadrant(dot)com>
Cc: PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Contention preventing locking
Date: 2018-02-20 13:19:18
Message-ID: 07099802-30af-e988-c9db-dc3e5ef54140@postgrespro.ru
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 20.02.2018 14:26, Simon Riggs wrote:
> On 15 February 2018 at 16:00, Konstantin Knizhnik
> <k(dot)knizhnik(at)postgrespro(dot)ru> wrote:
>
>> 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).
> What about the tuple lock? You are saying that is ineffective?
>
> src/backend/access/heap/README.tuplock

In my last mail ni this thread I have mentioned that update of tuple
cause setting of three heavy weight locks:

1. Locking of SnapshotDirty.xmax transaction (XactLockTableWait) in
EvalPlanQualFetch
2. Tuple lock (heap_acquire_tuplock) in heap_tuple_update
3. Transaction lock (XactLockTableWait) in heap_tuple_update

So what I see in debugger and monitoring pg_locks, is that under high
contention there are a lot transactions waiting for SnapshotDirty.xmax.
This lock is obtained before tuple lock, so tuple lock can not help in
this case.

>
>
>> My idea was that we can avoid such performance degradation if we somehow
>> queue competing transactions so that they will get control one-by-one,
>> without doing useless work.
>> First of all I tried to replace TID lock with PK (primary key) lock. Unlike
>> TID, PK of record is not changed during hot update. The second idea is that
>> instead immediate releasing lock after update we can hold it until the end
>> of transaction. And this optimization really provides improve of performance
>> - it corresponds to pg_f1_opt configuration at the attached diagram.
>> For some workloads it provides up to two times improvement comparing with
>> vanilla Postgres. But there are many problems with correct (non-prototype)
>> implementation of this approach:
>> handling different types of PK, including compound keys, PK updates,...
> Try locking the root tid rather than the TID, that is at least unique
> per page for a chain of tuples, just harder to locate.
>

But locking primary key is more efficient, isn't it?
The problem with primary key is that it doesn't always exists or can be
compound, but if it exists and has integer type, then get be obtained
easily than root tid.
For pgrw benchmark primary key lock provides even better results than
transaction lock chaining:

https://docs.google.com/spreadsheets/d/1QOYfUehy8U3sdasMjGnPGQJY8JiRfZmlS64YRBM0YTo/edit?usp=sharing

But for YCSB benchmark xlock optimization is more efficient:

https://docs.google.com/spreadsheets/d/136BfsABXEbzrleZHYoli7XAyDFUAxAXZDHl5EvJR_0Q/edit?usp=sharing

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

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Simon Riggs 2018-02-20 13:42:31 Re: Contention preventing locking
Previous Message Petr Jelinek 2018-02-20 13:03:58 Re: ALTER TABLE ADD COLUMN fast default