Thread: Reporting the commit LSN at commit time

Reporting the commit LSN at commit time

From
Craig Ringer
Date:
Hi all

To support transparent client-side failover in BDR, it's necessary to
know what the LSN of a node was at the time a transaction committed and
keep track of that in the client/proxy.

I'm thinking about adding a new message type in the protocol that gets
sent immediately before CommandComplete, containing the LSN of the
commit. Clients would need to enable the sending of this message with a
GUC that they set when they connect, so it doesn't confuse clients that
aren't expecting it or aware of it.

Is this something you can see being useful for other non-BDR purposes?
Are there any obvious issues with this?


Clients can always follow up with a second query to get the xlog
position, after commit, but that's potentially slow and has a race that
might cause a client to wait longer than it has to after fail-over to a
different node. That's why having the server report it automatically
seems useful.

-- Craig Ringer                   http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training & Services



Re: Reporting the commit LSN at commit time

From
Ants Aasma
Date:
On Thu, Aug 7, 2014 at 4:15 AM, Craig Ringer <craig@2ndquadrant.com> wrote:
> I'm thinking about adding a new message type in the protocol that gets
> sent immediately before CommandComplete, containing the LSN of the
> commit. Clients would need to enable the sending of this message with a
> GUC that they set when they connect, so it doesn't confuse clients that
> aren't expecting it or aware of it.
>
> Is this something you can see being useful for other non-BDR purposes?

I have been thinking about something similar.

For regular streaming replication you could keep track of the commit
LSN on a per client basis and automatically redirect read queries to a
standby if standby apply location is larger than the commit LSN of
this particular client. This can be done mostly transparently for the
application while not running into the issue that recent modifications
disappear for a while after commit.

Regards,
Ants Aasma
--
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt
Web: http://www.postgresql-support.de



Re: Reporting the commit LSN at commit time

From
Robert Haas
Date:
On Wed, Aug 6, 2014 at 9:15 PM, Craig Ringer <craig@2ndquadrant.com> wrote:
> To support transparent client-side failover in BDR, it's necessary to
> know what the LSN of a node was at the time a transaction committed and
> keep track of that in the client/proxy.

I doubt whether it makes sense to do this without a broader
understanding of how the client-side failover mechanism would work.
If we're going to add something like this, it should include libpq
support for actually doing something useful with it.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company



Re: Reporting the commit LSN at commit time

From
Tom Lane
Date:
Craig Ringer <craig@2ndquadrant.com> writes:
> Hi all
> To support transparent client-side failover in BDR, it's necessary to
> know what the LSN of a node was at the time a transaction committed and
> keep track of that in the client/proxy.

> I'm thinking about adding a new message type in the protocol that gets
> sent immediately before CommandComplete, containing the LSN of the
> commit. Clients would need to enable the sending of this message with a
> GUC that they set when they connect, so it doesn't confuse clients that
> aren't expecting it or aware of it.

FWIW, I think it's a seriously bad idea to expose LSNs in the protocol
at all.   What happens five years from now when we switch to some other
implementation that doesn't have LSNs?

I don't mind if you expose some other way to inquire about LSNs, but
let's *not* embed it into the wire protocol.  Not even as an option.

This position also obviates the need to complain about having a GUC
that changes the protocol-level behavior, which is also a seriously
bad idea.
        regards, tom lane



Re: Reporting the commit LSN at commit time

From
Craig Ringer
Date:
On 08/08/2014 03:54 AM, Tom Lane wrote:
> Craig Ringer <craig@2ndquadrant.com> writes:
>> Hi all
>> To support transparent client-side failover in BDR, it's necessary to
>> know what the LSN of a node was at the time a transaction committed and
>> keep track of that in the client/proxy.
> 
>> I'm thinking about adding a new message type in the protocol that gets
>> sent immediately before CommandComplete, containing the LSN of the
>> commit. Clients would need to enable the sending of this message with a
>> GUC that they set when they connect, so it doesn't confuse clients that
>> aren't expecting it or aware of it.
> 
> FWIW, I think it's a seriously bad idea to expose LSNs in the protocol
> at all.   What happens five years from now when we switch to some other
> implementation that doesn't have LSNs?

Everyone who's relying on them already via pg_stat_replication, etc, breaks.

They're _already_ exposed to users. That ship has sailed.

That's not to say I'm stuck to LSNs as the way to do this, just that I
don't think that particular argument is relevant.

> I don't mind if you expose some other way to inquire about LSNs, but
> let's *not* embed it into the wire protocol.  Not even as an option.

Well, the underlying need here is to have the client able to keep track
of what point in the server's time-line it must see on a replica before
it proceeds to use that replica.

So if the client does some work on server A, then for some reason needs
to / must use server B, it can ask server B "are you replayed up to the
last transaction I performed on server A yet?" and wait until it is.

That's useful for streaming replication (to permit consistent queries
against read replicas) but it's much more so for BDR, where it's
necessary to avoid a variety of multi-master replication anomalies and
conflicts.

I considered LSNs to be the logical mechanism for this as they're
already user-visible, exposed in pg_stat_replication, they can already
be used for just this purpose by hand (just with an extra round-trip), etc.

An obvious alternative is to merge the commit timestamp work, then
expose the timestamp of the last commit replayed in pg_stat_replication.
Then all the client needs to keep track of is the server time of the
last commit.

> This position also obviates the need to complain about having a GUC
> that changes the protocol-level behavior, which is also a seriously
> bad idea.

Well, I'd prefer to be able to negotiate with the server and establish
requirements during the protocol handshake.

As far as I know there isn't an explicit protocol negotiation with
capabilities fields (just a plain version field), but we do have the
startup packet's 'options' field. So I was thinking that requesting the
setting of a PGC_BACKEND GUC in the startup packet would be a logical
way for the client to request use of a protocol extension.

Looking at ProcessStartupPacket(...) in postmaster.c I see that there's
room for special-casing options. Do you think it would be more
appropriate to add a new connection option that's sent by a client to
request reporting of commit timestamps / LSNs / whatever by the server
at commit time?

If not, do you have an alternative suggestion? I can't imagine that
extending the CommandComplete message is a desirable option.

It seems like it'd be useful to expose this as a read-only GUC anyway,
so I don't really see why a PGC_BACKEND GUC isn't exactly the right
thing to use for this, but I'm happy to listen to suggestions.

-- Craig Ringer                   http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training & Services



Re: Reporting the commit LSN at commit time

From
Tom Lane
Date:
Craig Ringer <craig@2ndquadrant.com> writes:
> On 08/08/2014 03:54 AM, Tom Lane wrote:
>> FWIW, I think it's a seriously bad idea to expose LSNs in the protocol
>> at all.   What happens five years from now when we switch to some other
>> implementation that doesn't have LSNs?

> Everyone who's relying on them already via pg_stat_replication, etc, breaks.
> They're _already_ exposed to users. That ship has sailed.

They're exposed to replication tools, yeah, but embedding them in the
wire protocol would be moving the goalposts a long way past that.  As an
example of something that doubtless seemed like a good idea at the time,
consider the business about how an INSERT command completion tag includes
the OID of the inserted row.  We're stuck with that obsolete idea
*forever* because it's embedded in the protocol for all clients.

>> This position also obviates the need to complain about having a GUC
>> that changes the protocol-level behavior, which is also a seriously
>> bad idea.

> Well, I'd prefer to be able to negotiate with the server and establish
> requirements during the protocol handshake.

Sure, but a GUC is not that.  The problem with a GUC for changing
wire-level behavior is that it might be set by code far removed from
the wire, possibly breaking lower code levels that expected different
behavior.  The multitude of ways that we offer for setting GUCs is
an active evil in this particular context.
        regards, tom lane



Re: Reporting the commit LSN at commit time

From
Craig Ringer
Date:
On 08/07/2014 11:42 PM, Robert Haas wrote:
> I doubt whether it makes sense to do this without a broader
> understanding of how the client-side failover mechanism would work.
> If we're going to add something like this, it should include libpq
> support for actually doing something useful with it.

I'm currently interested in targeting PgBouncer and PgJDBC, not libpq,
though I can see that exposing helpers for it in libpq could be useful.

The goal here is to permit a client to safely switch from one server to
another - either in a multimaster async replication system like BDR, or
routing read-only queries to hot standbys with streaming replication -
and know for sure that its last commit is visible on the server it is
now connected to.

For hot standby that means it can avoid running queries that won't see
the latest work it did if the standby is lagging - deciding to run them
on the upstream instead, or wait, as appropriate.

For BDR it'll permit the client to safely perform transparent failover
to another node and resume write operations without risking conflicts
with its own prior transactions . (I wrote some explanations about this
on -general in the thread here:
http://www.postgresql.org/message-id/84184AEF-887D-49DF-8F47-6377B1D6EE9F@gmail.com
).


Broadly, what I'm thinking of is:

* Whenever a client issues a transaction that gets a txid assigned, and
that tx commits, the server reports the LSN that includes the commit.

* The client keeps track of which server it is connected to using the
server's (sysid, timelineid, databaseoid) or a similar identifier -
probably specific to the replication protocol in use, unless something
generic proves practical.

* When the client has to switch to a new server or chooses to do so, it
checks pg_stat_replication or pg_replication_slots, finds the server it
was previously connected to, and checks to see if the new server has
replayed up to the last write transaction this client performed on the
previous server. If not, it can make a policy-driven decision: wait
until replay catchup, wait for a while then bail out, etc.

This is admittedly all a bit hand-wavey. I'm looking at ways to do it,
not a firm implementation plan.

Notably, the LSN (and timelineID) aren't the only way to keep track of
the replay progress of a server and check it from another server. If the
commit timestamps work is merged and the timestamp of the last replayed
commit record is exposed in pg_replication_slots, the client could use
the server-reported commit timestamp to the same effect.


In the above you'll note that the client has to make some choices. The
client might be picking different servers for failover, read load
spreading, or other things I haven't thought of. It might be retaining
the old connection and making new ones it wants to be consistent up to a
certain point on the old connection (read spreading), or it might be
dropping the old connection and making a new one (failover). If the new
server to connect to isn't caught up yet it might want to wait
indefinitely, wait a short while, or bail out immediately and try a
different server. There's a lot of client/application specific policy
going to be involved here, so I'm not sure it makes sense to try to make
it transparent in libpq. I can see it being useful to expose some tools
in libpq for it, without a doubt, so clients can do these sorts of
things usefully.

(There's also another whole new question: how do you pick which
alternative server to connect to? But that's not really within the scope
of this.)

-- Craig Ringer                   http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training & Services



Re: Reporting the commit LSN at commit time

From
Craig Ringer
Date:
On 08/08/2014 09:02 AM, Tom Lane wrote:
> Craig Ringer <craig@2ndquadrant.com> writes:
>> On 08/08/2014 03:54 AM, Tom Lane wrote:
>>> FWIW, I think it's a seriously bad idea to expose LSNs in the protocol
>>> at all.   What happens five years from now when we switch to some other
>>> implementation that doesn't have LSNs?
> 
>> Everyone who's relying on them already via pg_stat_replication, etc, breaks.
>> They're _already_ exposed to users. That ship has sailed.
> 
> They're exposed to replication tools, yeah, but embedding them in the
> wire protocol would be moving the goalposts a long way past that.  As an
> example of something that doubtless seemed like a good idea at the time,
> consider the business about how an INSERT command completion tag includes
> the OID of the inserted row.  We're stuck with that obsolete idea
> *forever* because it's embedded in the protocol for all clients.

That makes sense.


>> Well, I'd prefer to be able to negotiate with the server and establish
>> requirements during the protocol handshake.
> 
> Sure, but a GUC is not that.  The problem with a GUC for changing
> wire-level behavior is that it might be set by code far removed from
> the wire, possibly breaking lower code levels that expected different
> behavior.  The multitude of ways that we offer for setting GUCs is
> an active evil in this particular context.

I'd value your input and suggestions then.

I thought this is what PGC_BACKEND GUCs were for - set them in the
startup packet and you can't mess with them afterwards. I can see that
the ability of someone to cause that to be set in (e.g.) PGOPTIONS could
be a problem though.

AFAIK we don't _have_ a fancy negotiation system in the protocol, with
back-and-forth exchanges of capabilities information.

So is the appropriate thing to do here to set a non-GUC 'options' field
in the startup packet?

-- Craig Ringer                   http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training & Services



Re: Reporting the commit LSN at commit time

From
Tom Lane
Date:
Craig Ringer <craig@2ndquadrant.com> writes:
> On 08/08/2014 09:02 AM, Tom Lane wrote:
>> Craig Ringer <craig@2ndquadrant.com> writes:
>>> Well, I'd prefer to be able to negotiate with the server and establish
>>> requirements during the protocol handshake.

>> Sure, but a GUC is not that.  The problem with a GUC for changing
>> wire-level behavior is that it might be set by code far removed from
>> the wire, possibly breaking lower code levels that expected different
>> behavior.  The multitude of ways that we offer for setting GUCs is
>> an active evil in this particular context.

> I thought this is what PGC_BACKEND GUCs were for - set them in the
> startup packet and you can't mess with them afterwards. I can see that
> the ability of someone to cause that to be set in (e.g.) PGOPTIONS could
> be a problem though.

Right.  AFAICS it's mostly irrelevant whether or not the setting can be
changed intrasession; what *is* important is that it not be turned on
if the lowest level(s) of the client software stack can't handle it.
It's not beyond the realm of credibility that there could be
security-grade bugs arising from client software receiving messages it
didn't understand.  And what that means is that anything that is
accessible to higher levels of the stack is suspect.  We've provided
enough pass-through behaviors that I'm not sure anything in the current
connection options API would be safe.

> AFAIK we don't _have_ a fancy negotiation system in the protocol, with
> back-and-forth exchanges of capabilities information.

Maybe it's time to invent that.  It would be positively foolish to
create any such behavior without a protocol version bump anyway.

Although as I said, I don't think embedding knowledge of LSNs at the
protocol level is a good thing to begin with.  Is it really necessary that
this information be pushed to the client on every commit, as opposed to
the client asking for it occasionally?
        regards, tom lane



Re: Reporting the commit LSN at commit time

From
Fujii Masao
Date:
On Fri, Aug 8, 2014 at 9:50 AM, Craig Ringer <craig@2ndquadrant.com> wrote:
> On 08/08/2014 03:54 AM, Tom Lane wrote:
>> Craig Ringer <craig@2ndquadrant.com> writes:
>>> Hi all
>>> To support transparent client-side failover in BDR, it's necessary to
>>> know what the LSN of a node was at the time a transaction committed and
>>> keep track of that in the client/proxy.
>>
>>> I'm thinking about adding a new message type in the protocol that gets
>>> sent immediately before CommandComplete, containing the LSN of the
>>> commit. Clients would need to enable the sending of this message with a
>>> GUC that they set when they connect, so it doesn't confuse clients that
>>> aren't expecting it or aware of it.
>>
>> FWIW, I think it's a seriously bad idea to expose LSNs in the protocol
>> at all.   What happens five years from now when we switch to some other
>> implementation that doesn't have LSNs?
>
> Everyone who's relying on them already via pg_stat_replication, etc, breaks.
>
> They're _already_ exposed to users. That ship has sailed.
>
> That's not to say I'm stuck to LSNs as the way to do this, just that I
> don't think that particular argument is relevant.
>
>> I don't mind if you expose some other way to inquire about LSNs, but
>> let's *not* embed it into the wire protocol.  Not even as an option.
>
> Well, the underlying need here is to have the client able to keep track
> of what point in the server's time-line it must see on a replica before
> it proceeds to use that replica.
>
> So if the client does some work on server A, then for some reason needs
> to / must use server B, it can ask server B "are you replayed up to the
> last transaction I performed on server A yet?" and wait until it is.

ISTM that the proper solution to that problem is the introduction of
new synchronous replication mode which makes the transaction wait for
its WAL to be replayed by the standby. If this mode is used, a client
doesn't need to track the LSN of each transaction and check whether
the committed transaction has already replayed by the standby or not.

Regards,

-- 
Fujii Masao



Re: Reporting the commit LSN at commit time

From
Craig Ringer
Date:
On 08/08/2014 10:58 AM, Fujii Masao wrote:
> ISTM that the proper solution to that problem is the introduction of
> new synchronous replication mode which makes the transaction wait for
> its WAL to be replayed by the standby. If this mode is used, a client
> doesn't need to track the LSN of each transaction and check whether
> the committed transaction has already replayed by the standby or not.

I'm not convinced of that.

That pushes the penalty onto the writer - which now has to wait until
replicas catch up. It has to pay this for every commit, even if actually
failing over to another node is unlikely.

It'd be better to just enable sync rep instead, or it would if we had
all-nodes sync rep.

IMO any waiting needs to be done on the other side, i.e. "Wait until I
am caught up before proceeding" rather than "wait for the other end to
catch up before returning".

Doing it the way you describe would make it nearly useless for enabling
client-side failover in BDR, where half the point is that it can deal
with high latency or intermittently available links to downstream replicas.

-- Craig Ringer                   http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training & Services



Re: Reporting the commit LSN at commit time

From
Michael Paquier
Date:
On Fri, Aug 8, 2014 at 11:58 AM, Fujii Masao <masao.fujii@gmail.com> wrote:
> On Fri, Aug 8, 2014 at 9:50 AM, Craig Ringer <craig@2ndquadrant.com> wrote:
> ISTM that the proper solution to that problem is the introduction of
> new synchronous replication mode which makes the transaction wait for
> its WAL to be replayed by the standby. If this mode is used, a client
> doesn't need to track the LSN of each transaction and check whether
> the committed transaction has already replayed by the standby or not.
Don't you need to combine that with the possibility to wait for N
targets instead of 1 in synchronous_standby_names? You may want to be
sure that the commit is done on a series of standbys before
considering any further operations after this transaction commit.
-- 
Michael



Re: Reporting the commit LSN at commit time

From
Craig Ringer
Date:
On 08/08/2014 09:51 AM, Tom Lane wrote:

>> AFAIK we don't _have_ a fancy negotiation system in the protocol, with
>> back-and-forth exchanges of capabilities information.
> 
> Maybe it's time to invent that.  It would be positively foolish to
> create any such behavior without a protocol version bump anyway.

I was hoping it'd be easier to sneak a new message type in without a
full protocol bump. As you can imagine that makes it a ... rather larger
job.

Still, if it's unsafe to do it that way...

> Although as I said, I don't think embedding knowledge of LSNs at the
> protocol level is a good thing to begin with. 

As I said upthread, it need not necessarily be an LSN. A commit
timestamp would do the job too, if information about the last-replayed
commit timestamp was accessible on the downstream node.

It needs to be a sequence identifier that can be matched against
pg_replication_slots / pg_stat_replication or passed to a function on
the downstream end to say "wait until we're replayed to this point".

For streaming replication there's only one upstream, so there's no need
to identify it. For BDR you'd also have to identify the upstream node of
interest - probably by slot ID, or by (sysid, tlid, dboid) tuple.

In the end, it can be an opaque magic cookie. It really doesn't matter,
so long as what the client receives is a value it can pass to another Pg
instance and say "wait until you've replayed up to this, please" or
"have you replayed up to this yet?".

> Is it really necessary that this information be pushed to the client
on every commit, as opposed to the client asking for it occasionally?

I think so, yes, though I'd be glad to be proved wrong.

For the purpose of transparent failover (BDR) at least, the server
currently being written to can go away at any moment, and you should
know exactly what you're up to in order to make it safe to continue on
another server.



Consider, for a multi-master configuration where two servers replicate
to each other:

On a connection to server1:

INSERT INTO bird(id, parrot)
VALUES (1, 'African Grey');

[client grabs magic cookie for server replay state]

INSERT INTO bird(id, parrot)
VALUES (2, 'Lorikkeet');

[server1 sends changes to server2, which is behind on replayand still working on catching up]

[server1 dies abruptly]

[client drops connection to server1, connects to server2]

-- Correct spelling
UPDATE bird
SET parrot = 'Lorikeet'
WHERE id = 2;


If the INSERT from server1 hasn't replayed on server2 yet this will
fail. Other anomalies can be worse and cause lost updates, etc.

To protect against this the client needs a way to wait, after connecting
to server2, until it's caught up with the state of server1. That's what
I'm talking about here. In this case, if you used a periodic progress
indicator requested by the client, you'd still get the same error,
because you'd wait until the first INSERT but not the second.

So yes, the client needs this info at every commit.

That means that enabling client-side fail-over won't be free, especially
for lots of small transactions. It'll be cheaper if Pg can push the info
with the commit confirmation instead of the client having to request it
afterwards though.


(Note that the client risks waiting forever if server1 didn't send the
required commits before it died, but that's where application policy
decisions come in).



-- Craig Ringer                   http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training & Services



Re: Reporting the commit LSN at commit time

From
Andres Freund
Date:
On 2014-08-07 21:02:54 -0400, Tom Lane wrote:
> Craig Ringer <craig@2ndquadrant.com> writes:
> > On 08/08/2014 03:54 AM, Tom Lane wrote:
> >> FWIW, I think it's a seriously bad idea to expose LSNs in the protocol
> >> at all.   What happens five years from now when we switch to some other
> >> implementation that doesn't have LSNs?
> 
> > Everyone who's relying on them already via pg_stat_replication, etc, breaks.
> > They're _already_ exposed to users. That ship has sailed.
> 
> They're exposed to replication tools, yeah, but embedding them in the
> wire protocol would be moving the goalposts a long way past that.  As an
> example of something that doubtless seemed like a good idea at the time,
> consider the business about how an INSERT command completion tag includes
> the OID of the inserted row.  We're stuck with that obsolete idea
> *forever* because it's embedded in the protocol for all clients.

I don't think we really need to embed it at that level. And it doesn't
have to be always on - only clients that ask for it need to get the
answer. Something like COMMIT WITH (report_commit_lsn ON); or similar
might do the trick?

Greetings,

Andres Freund

-- Andres Freund                       http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training &
Services



Re: Reporting the commit LSN at commit time

From
Craig Ringer
Date:
On 08/10/2014 12:54 AM, Andres Freund wrote:
> On 2014-08-07 21:02:54 -0400, Tom Lane wrote:
>> Craig Ringer <craig@2ndquadrant.com> writes:
>>> On 08/08/2014 03:54 AM, Tom Lane wrote:
>>>> FWIW, I think it's a seriously bad idea to expose LSNs in the protocol
>>>> at all.   What happens five years from now when we switch to some other
>>>> implementation that doesn't have LSNs?
>>
>>> Everyone who's relying on them already via pg_stat_replication, etc, breaks.
>>> They're _already_ exposed to users. That ship has sailed.
>>
>> They're exposed to replication tools, yeah, but embedding them in the
>> wire protocol would be moving the goalposts a long way past that.  As an
>> example of something that doubtless seemed like a good idea at the time,
>> consider the business about how an INSERT command completion tag includes
>> the OID of the inserted row.  We're stuck with that obsolete idea
>> *forever* because it's embedded in the protocol for all clients.
> 
> I don't think we really need to embed it at that level. And it doesn't
> have to be always on - only clients that ask for it need to get the
> answer. Something like COMMIT WITH (report_commit_lsn ON); or similar
> might do the trick?

Wouldn't that force client drivers - libpq, psqlODBC, PgJDBC, etc - to
all watch for explicit "COMMIT"s sent by the application and rewrite them?

Applications could also then request the commit option via a driver that
couldn't cope with it - which I think was one of Tom's concerns re using
a GUC, too.

-- Craig Ringer                   http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training & Services



Re: Reporting the commit LSN at commit time

From
Andres Freund
Date:
On 2014-08-10 08:50:58 +0800, Craig Ringer wrote:
> On 08/10/2014 12:54 AM, Andres Freund wrote:
> > On 2014-08-07 21:02:54 -0400, Tom Lane wrote:
> >> Craig Ringer <craig@2ndquadrant.com> writes:
> >>> On 08/08/2014 03:54 AM, Tom Lane wrote:
> >>>> FWIW, I think it's a seriously bad idea to expose LSNs in the protocol
> >>>> at all.   What happens five years from now when we switch to some other
> >>>> implementation that doesn't have LSNs?
> >>
> >>> Everyone who's relying on them already via pg_stat_replication, etc, breaks.
> >>> They're _already_ exposed to users. That ship has sailed.
> >>
> >> They're exposed to replication tools, yeah, but embedding them in the
> >> wire protocol would be moving the goalposts a long way past that.  As an
> >> example of something that doubtless seemed like a good idea at the time,
> >> consider the business about how an INSERT command completion tag includes
> >> the OID of the inserted row.  We're stuck with that obsolete idea
> >> *forever* because it's embedded in the protocol for all clients.
> > 
> > I don't think we really need to embed it at that level. And it doesn't
> > have to be always on - only clients that ask for it need to get the
> > answer. Something like COMMIT WITH (report_commit_lsn ON); or similar
> > might do the trick?
> 
> Wouldn't that force client drivers - libpq, psqlODBC, PgJDBC, etc - to
> all watch for explicit "COMMIT"s sent by the application and rewrite them?

Any application doing such "transparent" failover would need to have a
driver that's aware of all that anyway. They need to learn about the
transaction boundaries, the commit command and such. I personally think
this should mean that that feature requires an explicit API call for
transaction control.

Greetings,

Andres Freund

-- Andres Freund                       http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training &
Services



Re: Reporting the commit LSN at commit time

From
Robert Haas
Date:
On Sat, Aug 9, 2014 at 12:54 PM, Andres Freund <andres@2ndquadrant.com> wrote:
> On 2014-08-07 21:02:54 -0400, Tom Lane wrote:
>> Craig Ringer <craig@2ndquadrant.com> writes:
>> > On 08/08/2014 03:54 AM, Tom Lane wrote:
>> >> FWIW, I think it's a seriously bad idea to expose LSNs in the protocol
>> >> at all.   What happens five years from now when we switch to some other
>> >> implementation that doesn't have LSNs?
>>
>> > Everyone who's relying on them already via pg_stat_replication, etc, breaks.
>> > They're _already_ exposed to users. That ship has sailed.
>>
>> They're exposed to replication tools, yeah, but embedding them in the
>> wire protocol would be moving the goalposts a long way past that.  As an
>> example of something that doubtless seemed like a good idea at the time,
>> consider the business about how an INSERT command completion tag includes
>> the OID of the inserted row.  We're stuck with that obsolete idea
>> *forever* because it's embedded in the protocol for all clients.
>
> I don't think we really need to embed it at that level. And it doesn't
> have to be always on - only clients that ask for it need to get the
> answer. Something like COMMIT WITH (report_commit_lsn ON); or similar
> might do the trick?

And what does that actually do?  Send back a result-set, or a new
protocol message?

I don't have a very clear idea whether this is a good idea in any form
because I can't quite imagine how this is going to be used by the
client without adding an unwarranted amount of complexity there.
However, based on my experiences at EnterpriseDB, I would be extremely
wary of extending the wire protocol.  As soon as we do that, it
requires updates to a really phenomenal amount of other software.
Software using libpq may be more or less able to ignore the
difference, as long as they have a new-enough version of libpq (which
is a significant proviso).  But any driver that has its own
implementation of the wire protocol (and I think there is at least one
and maybe several important ones that do) needs updating, and anything
that acts as middleware (pgpool, pgbouncer) does too.  And it's not
just a matter of the maintainers making the appropriate changes
(though that does need to happen); it's also about everyone who is
using the new server version getting new versions of that other
software also.

So, even accepting for the moment the premise that the basic idea here
is good, I think the benefits would have to be monumental to convince
me that a protocol change is a good idea.  If we do anything like
that, we'll be hearing about the downstream damage for years.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company



Re: Reporting the commit LSN at commit time

From
Craig Ringer
Date:
On 08/15/2014 12:21 AM, Robert Haas wrote:
> On Sat, Aug 9, 2014 at 12:54 PM, Andres Freund <andres@2ndquadrant.com> wrote:

> I don't have a very clear idea whether this is a good idea in any form
> because I can't quite imagine how this is going to be used by the
> client without adding an unwarranted amount of complexity there.

Full automatic transparent failover _will_ be complex on the client. No
denying that. The hard parts are picking which node to connect to when
one goes away, the decision making around what to do when the new node
fails to catch up to the last committed state on the old node, and
tracking session state.

There are some quite simple uses too though. The main one of interest to
me is an app that routes read-only queries to an async read-replica and
wants to guarantee that some of them see a state consistent with the
last commit on the master.

It's the first thing many people have asked me about BDR, though. "How
does client-side failover work".  This is a priority for a lot of people.

As far as I can see, if you have client-side failover with asynchronous
replication of any form, the client _must_ have some way to reliably
connect to a new node and ask it "are you caught up to the state of the
last node I was connected to yet?". Or "Please wait until the last
transaction I committed elsewhere is visible here".

The client must keep track of some kind of information that indicates
the last node it talked to and identifies the last transaction it
committed. ("Client" could mean "proxy" in the case of a failover-aware
pgbouncer.)

> So, even accepting for the moment the premise that the basic idea here
> is good, I think the benefits would have to be monumental to convince
> me that a protocol change is a good idea.  If we do anything like
> that, we'll be hearing about the downstream damage for years.

Yes, that's a real concern.

PgJDBC and psqlODBC both implement the wire protocol themselves. PgJDBC
does because it's a type 4 JDBC driver (pure Java, no native code, no
recompile required). I don't understand why psqlODBC goes its own way
instead of using libpq, but it does.

There are also numerous language-specific pure-language bindings, though
half of them seem pretty close to unmaintained.

That's why I proposed a new protocol message carrying extra info, that
clients can optionally request only if they understand it. Nobody else
needs to care or notice that anything's new.

The v2 to v3 protocol switch has only now reached the point where it's
realistic to to drop v2 support from clients. I'm hardly keen to do
another protocol rev, especially for something as minor as this.


-- Craig Ringer                   http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training & Services



Re: Reporting the commit LSN at commit time

From
Josh Berkus
Date:
On 08/14/2014 05:45 PM, Craig Ringer wrote:

> Wouldn't that force client drivers - libpq, psqlODBC, PgJDBC, etc - to
> all watch for explicit "COMMIT"s sent by the application and rewrite them?

Realistically, users are going to need new drivers to take advantage of
any automated connection failover anyway.

> Full automatic transparent failover _will_ be complex on the client. No
> denying that. The hard parts are picking which node to connect to when
> one goes away, the decision making around what to do when the new node
> fails to catch up to the last committed state on the old node, and
> tracking session state.

Frankly, I'd love to see just the simplest version of this implemented
in libpq as a start: the ability for client drivers to take a list of
hosts instead of a singe hostaddr (this was discussed at the 2013
clustering meeting).

> There are some quite simple uses too though. The main one of interest to
> me is an app that routes read-only queries to an async read-replica and
> wants to guarantee that some of them see a state consistent with the
> last commit on the master.
> 
> It's the first thing many people have asked me about BDR, though. "How
> does client-side failover work".  This is a priority for a lot of people.

> As far as I can see, if you have client-side failover with asynchronous
> replication of any form, the client _must_ have some way to reliably
> connect to a new node and ask it "are you caught up to the state of the
> last node I was connected to yet?". Or "Please wait until the last
> transaction I committed elsewhere is visible here".

There are quite a few use-cases where this information isn't required;
even for BDR, I'd love to see the ability to disable this check.

There's also cases where it's not adequate; the user may not have
committed anything on the master, but they still don't want to connect
to a replica which is hours behind the last node they queried.

There's also use-cases for which automated connection failover without a
managed proxy is a Seriously Bad Idea.  For one thing, you're setting up
a strong risk of split-brain.

-- 
Josh Berkus
PostgreSQL Experts Inc.
http://pgexperts.com



Re: Reporting the commit LSN at commit time

From
Andres Freund
Date:
On 2014-08-14 12:21:38 -0400, Robert Haas wrote:
> On Sat, Aug 9, 2014 at 12:54 PM, Andres Freund <andres@2ndquadrant.com> wrote:
> > I don't think we really need to embed it at that level. And it doesn't
> > have to be always on - only clients that ask for it need to get the
> > answer. Something like COMMIT WITH (report_commit_lsn ON); or similar
> > might do the trick?
> 
> And what does that actually do?  Send back a result-set, or a new
> protocol message?

What I was thinking of was to return "COMMIT X/X" instead of
"COMMIT". Since that's only sent when COMMIT WITH (report_commit_lsn ON)
was set it won't break clients/libraries that don't need it.

Greetings,

Andres Freund

-- Andres Freund                       http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training &
Services



Re: Reporting the commit LSN at commit time

From
Tom Lane
Date:
Andres Freund <andres@2ndquadrant.com> writes:
> On 2014-08-14 12:21:38 -0400, Robert Haas wrote:
>> And what does that actually do?  Send back a result-set, or a new
>> protocol message?

> What I was thinking of was to return "COMMIT X/X" instead of
> "COMMIT". Since that's only sent when COMMIT WITH (report_commit_lsn ON)
> was set it won't break clients/libraries that don't need it.

Au contraire: it will break any piece of code that is expecting a COMMIT
command tag to look like exactly "COMMIT" and not "COMMIT something".
If you think there isn't any such, a look into libpq should disabuse you
of that notion.  (Admittedly, libpq's instance is only in the protocol-V2
code paths, but I'm sure that similar code exists elsewhere client-side.)

The risk still remains, therefore, that one layer of the client-side
software stack might try to enable this feature even though another
layer is not prepared for it.  Changing the command tag might actually
be *more* dangerous than a new protocol message, rather than less so,
because command tags are usually exposed at multiple layers of the stack
--- libpq for instance happily returns them up to its caller.  So it
will be somewhere between difficult and impossible to be sure that one
has fixed everything that needs fixing.

And, again, I think that controlling this via something as widely
changeable as a GUC is sheer folly, potentially even reaching the point
of being a security bug.  (Applications that fail to recognize when
their transactions have committed would be broken in very nasty ways.)
        regards, tom lane



Re: Reporting the commit LSN at commit time

From
Andres Freund
Date:
On 2014-08-15 09:54:01 -0400, Tom Lane wrote:
> Andres Freund <andres@2ndquadrant.com> writes:
> > On 2014-08-14 12:21:38 -0400, Robert Haas wrote:
> >> And what does that actually do?  Send back a result-set, or a new
> >> protocol message?
> 
> > What I was thinking of was to return "COMMIT X/X" instead of
> > "COMMIT". Since that's only sent when COMMIT WITH (report_commit_lsn ON)
> > was set it won't break clients/libraries that don't need it.
> 
> Au contraire: it will break any piece of code that is expecting a COMMIT
> command tag to look like exactly "COMMIT" and not "COMMIT something".

Well, if your code doesn't support it. Don't use it.

> The risk still remains, therefore, that one layer of the client-side
> software stack might try to enable this feature even though another
> layer is not prepared for it.

Well, then the user will have to fix that. It's not like the feature
will magically start to be used by itself.

One alternative would be to expose a pg_get_last_commit_lsn(); function
that'd return the the last commit's lsn stored in a static variable if
set. That'll increase the window in which the connection can break, but
that window already exists.

> And, again, I think that controlling this via something as widely
> changeable as a GUC is sheer folly, potentially even reaching the point
> of being a security bug.  (Applications that fail to recognize when
> their transactions have committed would be broken in very nasty ways.)

*I*'ve never suggested making this depend on a guc. I think that'd a
major PITA.

Greetings,

Andres Freund

-- Andres Freund                       http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training &
Services



Re: Reporting the commit LSN at commit time

From
Robert Haas
Date:
On Fri, Aug 15, 2014 at 9:54 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Andres Freund <andres@2ndquadrant.com> writes:
>> On 2014-08-14 12:21:38 -0400, Robert Haas wrote:
>>> And what does that actually do?  Send back a result-set, or a new
>>> protocol message?
>
>> What I was thinking of was to return "COMMIT X/X" instead of
>> "COMMIT". Since that's only sent when COMMIT WITH (report_commit_lsn ON)
>> was set it won't break clients/libraries that don't need it.
>
> Au contraire: it will break any piece of code that is expecting a COMMIT
> command tag to look like exactly "COMMIT" and not "COMMIT something".
> If you think there isn't any such, a look into libpq should disabuse you
> of that notion.  (Admittedly, libpq's instance is only in the protocol-V2
> code paths, but I'm sure that similar code exists elsewhere client-side.)

Well, I remember debating this with you once before, when we were
deciding whether to make SELECT INTO and CREATE TABLE AS return row
counts in the command tag.  That change went into 9.0 and, while I
think we may have gotten maybe one complaint about it, on the whole I
believe it went pretty smoothly.  If we're going to expose this
information, I believe that exposing it through the command tag is
about an order of magnitude safer than trying to return it through a
new protocol message or a result-set.  I *have* seen code that parses
command tags and cares about their exact contents, but I think nearly
all code passes them through as uninterpreted strings.  Contrariwise,
there is a whole LOT of code that cares whether PQresultStatus()
returns PGRES_COMMAND_OK vs. PGRES_TUPLES_OK; if we made the latter
happen for some commits, a huge amount of stuff would break.  And
adding a new protocol message is a disaster for middleware, but most
if not all of that middleware will happily pass on a revised command
tag without batting an eyelash.

All that having been said, I'm not convinced that we should do this at
all unless we've got a libpq implementation of client-side failover so
that people can actually use this without having to put all of the
logic in their application.  But if we are going to do it, the command
tag seems like the least-risky option of those proposed thus far by a
considerable margin.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company



Re: Reporting the commit LSN at commit time

From
Tom Lane
Date:
Robert Haas <robertmhaas@gmail.com> writes:
> On Fri, Aug 15, 2014 at 9:54 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> Au contraire: it will break any piece of code that is expecting a COMMIT
>> command tag to look like exactly "COMMIT" and not "COMMIT something".

> Well, I remember debating this with you once before, when we were
> deciding whether to make SELECT INTO and CREATE TABLE AS return row
> counts in the command tag.  That change went into 9.0 and, while I
> think we may have gotten maybe one complaint about it, on the whole I
> believe it went pretty smoothly.

I think it's a serious, serious mistake to equate the number of clients
that deal with COMMIT specially with the number that have special logic
for (or even use at all) SELECT INTO/CREATE TABLE AS.  So I don't find
that argument to have any merit.

The precedent that seems more relevant to me is our disastrous attempt to
put in server-side autocommit behavior, back in 7.3.  We thought that that
wouldn't break too much client code; we were wrong.  And IMO a large part
of the reason we were wrong was that we exposed the switch as a GUC,
whereby anybody could twiddle it regardless of whether the relevant
client-side layer(s) would cope.

> All that having been said, I'm not convinced that we should do this at
> all unless we've got a libpq implementation of client-side failover so
> that people can actually use this without having to put all of the
> logic in their application.

There's that, too.  The whole proposal is a solution in search of a
problem at the moment, or maybe better to say that it's 1% of a solution
with no clear path to getting the other 99% done.
        regards, tom lane



Re: Reporting the commit LSN at commit time

From
Robert Haas
Date:
On Mon, Aug 18, 2014 at 12:49 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Robert Haas <robertmhaas@gmail.com> writes:
>> On Fri, Aug 15, 2014 at 9:54 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>>> Au contraire: it will break any piece of code that is expecting a COMMIT
>>> command tag to look like exactly "COMMIT" and not "COMMIT something".
>
>> Well, I remember debating this with you once before, when we were
>> deciding whether to make SELECT INTO and CREATE TABLE AS return row
>> counts in the command tag.  That change went into 9.0 and, while I
>> think we may have gotten maybe one complaint about it, on the whole I
>> believe it went pretty smoothly.
>
> I think it's a serious, serious mistake to equate the number of clients
> that deal with COMMIT specially with the number that have special logic
> for (or even use at all) SELECT INTO/CREATE TABLE AS.  So I don't find
> that argument to have any merit.
>
> The precedent that seems more relevant to me is our disastrous attempt to
> put in server-side autocommit behavior, back in 7.3.  We thought that that
> wouldn't break too much client code; we were wrong.  And IMO a large part
> of the reason we were wrong was that we exposed the switch as a GUC,
> whereby anybody could twiddle it regardless of whether the relevant
> client-side layer(s) would cope.

1. That seems like a false parallel, because that sounds like it was
an actual behavior change, not just a reporting change.

2. I agree that it's not good to have this get controlled by a GUC.
If the behavior change is big enough that it's going to break clients,
adding a GUC isn't a sufficient remedy.  If it's not, adding a GUC is
unnecessary.

3. I really doubt people are relying on the COMMIT command tag to know
the transaction status.  Surely the right way to get that information
is from the transaction state code in the ReadyForQuery message; isn't
the whole point of having that there that it avoids the need for
fine-grained knowledge of what other protocol messages mean?
Moreover, even if somebody is (rather oddly, IMV) checking for
command_tag == "COMMIT", it's not going to be a difficult change to
check for command_tag == "COMMIT" or substr(command_tag,0,7) ==
"COMMIT ".  That's a level of incompatibility that would certainly
deserve mention in the release notes, but it doesn't seem worth
worrying more about than that.

>> All that having been said, I'm not convinced that we should do this at
>> all unless we've got a libpq implementation of client-side failover so
>> that people can actually use this without having to put all of the
>> logic in their application.
>
> There's that, too.  The whole proposal is a solution in search of a
> problem at the moment, or maybe better to say that it's 1% of a solution
> with no clear path to getting the other 99% done.

Yeah, and I think that's the much more worrying problem.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company



Re: Reporting the commit LSN at commit time

From
Alvaro Herrera
Date:
Robert Haas wrote:

> Moreover, even if somebody is (rather oddly, IMV) checking for
> command_tag == "COMMIT", it's not going to be a difficult change to
> check for command_tag == "COMMIT" or substr(command_tag,0,7) ==
> "COMMIT ".  That's a level of incompatibility that would certainly
> deserve mention in the release notes, but it doesn't seem worth
> worrying more about than that.

I agree.  If an application fails its test for a new major PG release
because the received command tag is no longer identical to "COMMIT",
it's not going to be a subtle failure --- people are going to notice
pretty much immediately, I expect.

-- 
Álvaro Herrera                http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services



Re: Reporting the commit LSN at commit time

From
Greg Stark
Date:
<p dir="ltr"><br /> On 15 Aug 2014 14:54, "Tom Lane" <<a href="mailto:tgl@sss.pgh.pa.us">tgl@sss.pgh.pa.us</a>>
wrote:<br/> ><br /> > Andres Freund <<a href="mailto:andres@2ndquadrant.com">andres@2ndquadrant.com</a>>
writes:<br/> > > On 2014-08-14 12:21:38 -0400, Robert Haas wrote:<br /> > >> And what does that actually
do? Send back a result-set, or a new<br /> > >> protocol message?<br /> ><br /> > > What I was
thinkingof was to return "COMMIT X/X" instead of<br /> > > "COMMIT". Since that's only sent when COMMIT WITH
(report_commit_lsnON)<br /> > > was set it won't break clients/libraries that don't need it.<br /> ><br />
>Au contraire: it will break any piece of code that is expecting a COMMIT<br /> > command tag to look like
exactly"COMMIT" and not "COMMIT something".<p dir="ltr">Two comments. Firstly, we can't freeze everything forever. This
seemslike it would be the least of people's issues to deal with for an upgrade. We should search for the cleanest
solution,not bolt on features for fear that integrating them where they make the most sense might break someone's code
somewhere.<pdir="ltr">I fear putting out anywhere but in the commit message would have race conditions. Having it in
thecommit message guarantees the client never has to deal with strange states like " I know this transaction committed
butI  know when" which would make clients vastly simpler.<p dir="ltr">But secondly there will *always* be race
conditionsin this.  This is the same problem as our hokey synchronous commit which commits transactions but then hides
themfrom the client. All it does is move the uncertainty around.<p dir="ltr">The long term solution will be something
morelike 2PC. At the beginning of your transaction you get an identifier for the transaction and store that in a
transactionmanager. The transaction manager knows how to determine which transcribe are committed on which nodes and
howto resolve conflicts.<br /> 

Re: Reporting the commit LSN at commit time

From
Greg Stark
Date:
<p dir="ltr"><br /> On 18 Aug 2014 20:05, "Greg Stark" <<a href="mailto:stark@mit.edu">stark@mit.edu</a>>
wrote:<br/> >Having it in the commit message guarantees the client never has to deal with strange states like " I
knowthis transaction committed but I  know when"<p dir="ltr">Sigh. Typing on the phone. "But I *don't* know when" 

Re: Reporting the commit LSN at commit time

From
Craig Ringer
Date:
On 08/19/2014 01:03 AM, Robert Haas wrote:
> 2. I agree that it's not good to have this get controlled by a GUC.
> If the behavior change is big enough that it's going to break clients,
> adding a GUC isn't a sufficient remedy.  If it's not, adding a GUC is
> unnecessary.

There's plenty of agreement on "not a GUC" - but what about alternatives?

I mentioned setting an option in the startup packet, to be processed
directly not set as a GUC like some of the other startup packet options
already are, but didn't see any real response there.

I presume the concern there is that, while it's not a GUC as far as the
server is concerned, libpq at least will still send a value for it in
the startup packet if it's defined in
   PGOPTIONS='-c protocol_affecting_option_here=on'

so while it isn't a GUC to the server, clients can still twiddle it w/o
making specific new API calls.


I'm not entirely sure why the answer isn't what we excuse other
problematic or potential user-foot-gun behaviour with: "Well, don't do
that".

> 3. I really doubt people are relying on the COMMIT command tag to know
> the transaction status.  Surely the right way to get that information
> is from the transaction state code in the ReadyForQuery message; isn't
> the whole point of having that there that it avoids the need for
> fine-grained knowledge of what other protocol messages mean?

I wouldn't assume anything about how people are using the protocol,
after some of the things I've seen in client code and client drivers
recently. Especially where I've fixed version detection code.

If it can be done badly, it's going to be done badly.

> Moreover, even if somebody is (rather oddly, IMV) checking for
> command_tag == "COMMIT", it's not going to be a difficult change to
> check for command_tag == "COMMIT" or substr(command_tag,0,7) ==
> "COMMIT ".  That's a level of incompatibility that would certainly
> deserve mention in the release notes, but it doesn't seem worth
> worrying more about than that.

I'm not convinced the relnotes get read by a lot of users. They're very
important for professional and/or serious admins an devs, but the number
of questions I see about stuff that's already highlighted in the
relnotes for a version suggests that it's not somewhere Joe Average goes
to find out what's going on.

Unfortunately.

As for whether relnoting it would be enough - that depends a great deal
on how exactly different clients failed. With the number of direct
protocol implementations out there, that's pretty hard to determine.

I'm somewhat confused by why messing with the commit command tag for all
clients is more acceptable than adding a new protocol message, enabled
only by clients that explicitly request it - and no, not by a GUC, I got
that message.

>> There's that, too.  The whole proposal is a solution in search of a
>> problem at the moment, or maybe better to say that it's 1% of a solution
>> with no clear path to getting the other 99% done.
> 
> Yeah, and I think that's the much more worrying problem.

It was just an RFC, and I certainly got the C, which I appreciate.

OTOH, knowing if/how inter-node catchup can be requested by a client is
a pre-req for designing anything else useful in this area IMO.

That part of the discussion has Tom's input to the effect that LSNs
shouldn't be exposed, but I don't think anybody's made any suggestions
about what could be acceptable or could work instead.

Server-reported timestamps would work if commit timestamp tracking is
merged.

As for being 1% of the problem, I disagree. I've already outlined some
simple use cases where having this information reported already provides
the client with all it needs. It'd only be a tiny part of fully
transparent client side failover, sure, but that's not something it's
realistic to aim for right from the start. Reporting of a position
indicator that can be used to see if replicas have replayed up to that
position is useful for simpler things too, and to allow clients
themselves to provide failover as part of application logic.

-- Craig Ringer                   http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training & Services



Re: Reporting the commit LSN at commit time

From
Greg Stark
Date:
On Tue, Aug 19, 2014 at 1:21 AM, Craig Ringer <craig@2ndquadrant.com> wrote:
> There's plenty of agreement on "not a GUC" - but what about alternatives?

It could be a new protocol message. Currently there are no transaction
oriented protocol messages (other than the "transaction status" in
ReadyForQuery). But would it not make sense to have TransactionBegin,
TransactionCommit, and TransactionAbort in the protocol? Would that
make it easier for the client-side failover to keep track of what
transactions are pending or committed and need to be verified after a
failover?


-- 
greg



Re: Reporting the commit LSN at commit time

From
Andres Freund
Date:
On 2014-08-19 08:21:10 +0800, Craig Ringer wrote:
> On 08/19/2014 01:03 AM, Robert Haas wrote:
> > 2. I agree that it's not good to have this get controlled by a GUC.
> > If the behavior change is big enough that it's going to break clients,
> > adding a GUC isn't a sufficient remedy.  If it's not, adding a GUC is
> > unnecessary.
> 
> There's plenty of agreement on "not a GUC" - but what about alternatives?

What's the problem with the COMMIT WITH (report_lsn on) I've proposed?
Reporting the LSN in the command tag? Anything doing transparent
failover needs to be aware of transaction boundaries anyway. 

Greetings,

Andres Freund

-- Andres Freund                       http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training &
Services



Re: Reporting the commit LSN at commit time

From
Fujii Masao
Date:
On Tue, Aug 19, 2014 at 7:21 PM, Andres Freund <andres@2ndquadrant.com> wrote:
> On 2014-08-19 08:21:10 +0800, Craig Ringer wrote:
>> On 08/19/2014 01:03 AM, Robert Haas wrote:
>> > 2. I agree that it's not good to have this get controlled by a GUC.
>> > If the behavior change is big enough that it's going to break clients,
>> > adding a GUC isn't a sufficient remedy.  If it's not, adding a GUC is
>> > unnecessary.
>>
>> There's plenty of agreement on "not a GUC" - but what about alternatives?
>
> What's the problem with the COMMIT WITH (report_lsn on) I've proposed?
> Reporting the LSN in the command tag? Anything doing transparent
> failover needs to be aware of transaction boundaries anyway.

So something like transparent failover doesn't work when a client is
working in auto commit mode? That sounds not good.

Just idea. What about using NoticeResponse message to report LSN?
It can be sent basically anytime and this idea doesn't break current
wire protocol.

Regards,

-- 
Fujii Masao



Re: Reporting the commit LSN at commit time

From
Andres Freund
Date:
On 2014-08-19 19:59:51 +0900, Fujii Masao wrote:
> On Tue, Aug 19, 2014 at 7:21 PM, Andres Freund <andres@2ndquadrant.com> wrote:
> > On 2014-08-19 08:21:10 +0800, Craig Ringer wrote:
> >> On 08/19/2014 01:03 AM, Robert Haas wrote:
> >> > 2. I agree that it's not good to have this get controlled by a GUC.
> >> > If the behavior change is big enough that it's going to break clients,
> >> > adding a GUC isn't a sufficient remedy.  If it's not, adding a GUC is
> >> > unnecessary.
> >>
> >> There's plenty of agreement on "not a GUC" - but what about alternatives?
> >
> > What's the problem with the COMMIT WITH (report_lsn on) I've proposed?
> > Reporting the LSN in the command tag? Anything doing transparent
> > failover needs to be aware of transaction boundaries anyway.
> 
> So something like transparent failover doesn't work when a client is
> working in auto commit mode? That sounds not good.

I don't think transparent failover + autocommit is a sensible
combination.

> Just idea. What about using NoticeResponse message to report LSN?
> It can be sent basically anytime and this idea doesn't break current
> wire protocol.

I think that'd be horrible from multiple perspectives: a) how to discern
them from regular notice messages b) It's not sent in the same protocol
level message as the COMMIT message. Thus there's scenarios where you
only have the commit, but not the LSN.

Greetings,

Andres Freund

-- Andres Freund                       http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training &
Services



Re: Reporting the commit LSN at commit time

From
Fujii Masao
Date:
On Tue, Aug 19, 2014 at 8:22 PM, Andres Freund <andres@2ndquadrant.com> wrote:
> On 2014-08-19 19:59:51 +0900, Fujii Masao wrote:
>> On Tue, Aug 19, 2014 at 7:21 PM, Andres Freund <andres@2ndquadrant.com> wrote:
>> > On 2014-08-19 08:21:10 +0800, Craig Ringer wrote:
>> >> On 08/19/2014 01:03 AM, Robert Haas wrote:
>> >> > 2. I agree that it's not good to have this get controlled by a GUC.
>> >> > If the behavior change is big enough that it's going to break clients,
>> >> > adding a GUC isn't a sufficient remedy.  If it's not, adding a GUC is
>> >> > unnecessary.
>> >>
>> >> There's plenty of agreement on "not a GUC" - but what about alternatives?
>> >
>> > What's the problem with the COMMIT WITH (report_lsn on) I've proposed?
>> > Reporting the LSN in the command tag? Anything doing transparent
>> > failover needs to be aware of transaction boundaries anyway.
>>
>> So something like transparent failover doesn't work when a client is
>> working in auto commit mode? That sounds not good.
>
> I don't think transparent failover + autocommit is a sensible
> combination.
>
>> Just idea. What about using NoticeResponse message to report LSN?
>> It can be sent basically anytime and this idea doesn't break current
>> wire protocol.
>
> I think that'd be horrible from multiple perspectives: a) how to discern
> them from regular notice messages

You can implement your own protocol upon existing messages like
replication is done.
b) It's not sent in the same protocol
> level message as the COMMIT message. Thus there's scenarios where you
> only have the commit, but not the LSN.

Hmm.. you can change the code so that the message with LSN is sent
as soon as COMMIT message is sent, if required.

Regards,

-- 
Fujii Masao



Re: Reporting the commit LSN at commit time

From
Craig Ringer
Date:
On 08/19/2014 06:21 PM, Andres Freund wrote:
> What's the problem with the COMMIT WITH (report_lsn on) I've proposed?
> Reporting the LSN in the command tag? Anything doing transparent
> failover needs to be aware of transaction boundaries anyway. 

Tom's objection to a GUC applies there too - a client app can send that
when the underlying driver doesn't expect to get the results.

I'm not completely convinced that's a problem - oh dear, the app breaks.
The answer to so many other things in Pg is "well, don't do that then"
that I don't see this as overly different.

However, granting that it is a problem, the same objection to a GUC
applies to this too.
-- Craig Ringer                   http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training & Services



Re: Reporting the commit LSN at commit time

From
Andres Freund
Date:
On 2014-08-19 21:47:26 +0800, Craig Ringer wrote:
> On 08/19/2014 06:21 PM, Andres Freund wrote:
> > What's the problem with the COMMIT WITH (report_lsn on) I've proposed?
> > Reporting the LSN in the command tag? Anything doing transparent
> > failover needs to be aware of transaction boundaries anyway. 
> 
> Tom's objection to a GUC applies there too - a client app can send that
> when the underlying driver doesn't expect to get the results.

I don't really think this is true. With a GUC it's set for the whole
session or even users. With such a option to COMMIT it'd only set when
issued by something that actually does transparent failover (i.e. the
underlying driver).

Greetings,

Andres Freund

-- Andres Freund                       http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training &
Services