From: | Heikki Linnakangas <heikki(dot)linnakangas(at)enterprisedb(dot)com> |
---|---|
To: | Dimitri Fontaine <dfontaine(at)hi-media(dot)com> |
Cc: | Simon Riggs <simon(at)2ndQuadrant(dot)com>, Fujii Masao <masao(dot)fujii(at)gmail(dot)com>, Robert Haas <robertmhaas(at)gmail(dot)com>, David Fetter <david(at)fetter(dot)org>, Heikki Linnakangas <heikki(at)postgresql(dot)org>, pgsql-hackers(at)postgresql(dot)org |
Subject: | Re: Configuring synchronous replication |
Date: | 2010-09-17 09:30:19 |
Message-ID: | 4C93352B.7000503@enterprisedb.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-committers pgsql-hackers |
On 17/09/10 12:10, Dimitri Fontaine wrote:
> Heikki Linnakangas<heikki(dot)linnakangas(at)enterprisedb(dot)com> writes:
>> * Support multiple standbys with various synchronization levels.
>>
>> * What happens if a synchronous standby isn't connected at the moment?
>> Return immediately vs. wait forever.
>>
>> * Per-transaction control. Some transactions are important, others are not.
>>
>> * Quorum commit. Wait until n standbys acknowledge. n=1 and n=all servers
>> can be seen as important special cases of this.
>>
>> * async, recv, fsync and replay levels of synchronization.
>>
>> So what should the user interface be like? Given the 1st and 2nd
>> requirement, we need standby registration. If some standbys are important
>> and others are not, the master needs to distinguish between them to be able
>> to determine that a transaction is safely delivered to the important
>> standbys.
>
> Well the 1st point can be handled in a distributed fashion, where the
> sync level is setup at the slave.
If the synchronicity is configured in the standby, how does the master
know that there's a synchronous slave out there that it should wait for,
if that slave isn't connected at the moment?
>> OTOH, if we do want fine-grained per-transaction control, a simple boolean
>> or even an enum GUC doesn't really cut it. For truly fine-grained control
>> you want to be able to specify exceptions like "wait until this is replayed
>> in slave named 'reporting'" or 'don't wait for acknowledgment from slave
>> named 'uk-server'". With standby registration, we can invent a syntax for
>> specifying overriding rules in the transaction. Something like SET
>> replication_exceptions = 'reporting=replay, uk-server=async'.
>
> Then you want to be able to have more than one reporting server and need
> only one of them at the "replay" level, but you don't need to know which
> it is. Or on the contrary you have a failover server and you want to be
> sure this one is at the replay level whatever happens.
>
> Then you want topology flexibility: you need to be able to replace a
> reporting server with another, ditto for the failover one.
>
> Did I tell you my current thinking on how to tackle that yet? :) Using a
> distributed setup, where each slave has a weight (several votes per
> transaction) and a level offering would allow that I think.
Yeah, the quorum stuff. That's all good, but doesn't change the way you
would do per-transaction control. By specifying overrides on a
per-transaction basis, you can have as fine-grained control as you
possibly can. Anything you can specify in a configuration file can then
also be specified per-transaction with overrides. The syntax just needs
to be flexible enough.
If we buy into the concept of per-transaction exceptions, we can put
that issue aside for the moment, and just consider how to configure
things in a config file. Anything you can express in the config file can
also be expressed per-transaction with the exceptions GUC.
> Now something similar to your idea that I can see a need for is being
> able to have a multi-part quorum target: when you currently say that you
> want 2 votes for sync, you would be able to say you want 2 votes for
> recv, 2 for fsync and 1 for replay. Remember that any slave is setup to
> offer only one level of synchronicity but can offer multiple votes.
>
> How this would look like in the setup? Best would be to register the
> different service levels your application need. Time to bikeshed a
> little?
>
> sync_rep_services = {critical: recv=2, fsync=2, replay=1;
> important: fsync=3;
> reporting: recv=2, apply=1}
>
> Well you get the idea, it could maybe get stored on a catalog somewhere
> with nice SQL commands etc. The goal is then to be able to handle a much
> simpler GUC in the application, sync_rep_service = important for
> example. Reserved label would be off, the default value
So ignoring the quorum stuff for a moment, the general idea is that you
have predefined sets of configurations (or exceptions to the general
config) specified in a config file, and in the application you just
choose among those with "sync_rep_service=XXX". Yeah, I like that, it
allows you to isolate the details of the topology from the application.
> If you add a weight to each slave then a quorum commit, you don't change
> the implementation complexity and you offer lot of setup flexibility. If
> the slave sync-level and weight are SIGHUP, then it even become rather
> easy to switch roles online or to add new servers or to organise a
> maintenance window — the quorum to reach is a per-transaction GUC on the
> master, too, right?
I haven't bought into the quorum idea yet, but yeah, if we have quorum
support, then it would be configurable on a per-transaction basis too
with the above mechanism.
--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com
From | Date | Subject | |
---|---|---|---|
Next Message | Simon Riggs | 2010-09-17 09:49:29 | Re: Configuring synchronous replication |
Previous Message | Simon Riggs | 2010-09-17 09:19:58 | Re: Configuring synchronous replication |
From | Date | Subject | |
---|---|---|---|
Next Message | Simon Riggs | 2010-09-17 09:49:29 | Re: Configuring synchronous replication |
Previous Message | Fujii Masao | 2010-09-17 09:22:27 | libpq changes for synchronous replication |