Applying logical replication changes by more than one process

From: Konstantin Knizhnik <k(dot)knizhnik(at)postgrespro(dot)ru>
To: PostgreSQL Developers <pgsql-hackers(at)postgreSQL(dot)org>
Subject: Applying logical replication changes by more than one process
Date: 2016-03-19 10:46:00
Message-ID: 56ED2DE8.1080707@postgrespro.ru
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

I am trying to use logical replication mechanism in implementation of PostgreSQL multimaster and faced with one conceptual problem.
Originally logical replication was intended to support asynchronous replication. In this case applying changes by single process should not be a bottleneck.
But if we are using distributed transaction manager to provide global consistency, then applying transaction by one worker leads to very bad performance and what is worser: cause unintended serialization of transactions, which is not taken in account by
distributed deadlock detection algorithm and so can cause
undetected deadlocks.

So I have implemented pool of background workers which can apply transactions concurrently.
It works and shows acceptable performance. But now I am thinking about HA and tracking origin LSNs which are needed to correctly specify slot position in case of recovery. And there is a problem: as far as I understand to correctly record origin LSN in WAL
and advance slot position it is necessary to setup session
using replorigin_session_setup. It is not so convenient in case of using pool of background workers, because we have to setup session for each commit.
But the main problem is that for each slot session can be associated only with one process:

else if (curstate->acquired_by != 0)
{
ereport(ERROR,
(errcode(ERRCODE_OBJECT_IN_USE),
errmsg("replication identifier %d is already active for PID %d",
curstate->roident, curstate->acquired_by)));
}

Which once again means that there can be only one process applying changes.

To provide correct state of replication node it is necessary to enforce that each logical replication record is replayed exactly once: we should not loose some change or try to apply it twice. So operation of recording original LSN position in WAL and
adjusting slot should be atomic. And during recovery we should restore slot current position based on the origin values extracted from WAL. I wonder if it can be done using current logical replication mechanism when changes of each slot are applied by
more than one process? Or the only alternative is to write/read origin LSNs in WAL myself, for example using custom WAL records?

Thanks in advance!

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

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Amit Kapila 2016-03-19 11:14:49 Re: Performance degradation in commit ac1d794
Previous Message Amit Kapila 2016-03-19 10:13:27 Re: Performance degradation in commit ac1d794