Обсуждение: COMMIT
Hi,
while on the redolog, I've came across a little detail I'm in
doubt about. Currently it seems, that the 'C' response to the
frontend is sent before the transaction get's really
committed in the backend. So there is a little chance that
the backend dies between this response and the
CommitTransaction() call.
Isn't that the wrong order? As a programmer I would assume,
that if I have positive response to COMMIT, I can forget my
local data because it made it safely into the database.
Jan
--
#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me. #
#======================================== jwieck@debis.com (Jan Wieck) #
Jan Wieck wrote: > > Hi, > > while on the redolog, I've came across a little detail I'm in > doubt about. Currently it seems, that the 'C' response to the > frontend is sent before the transaction get's really > committed in the backend. So there is a little chance that > the backend dies between this response and the > CommitTransaction() call. > > Isn't that the wrong order? As a programmer I would assume, > that if I have positive response to COMMIT, I can forget my > local data because it made it safely into the database. Yes, this should be fixed... Vadim
Vadim Mikheev <vadim@krs.ru> writes:
> Jan Wieck wrote:
>> while on the redolog, I've came across a little detail I'm in
>> doubt about. Currently it seems, that the 'C' response to the
>> frontend is sent before the transaction get's really
>> committed in the backend. So there is a little chance that
>> the backend dies between this response and the
>> CommitTransaction() call.
> Yes, this should be fixed...
I don't think it's practical to fix this without changing the semantics
of queries. Maybe we are willing to do that, but we should think twice
about the implications.
The reason it acts this way is that the command response is generated
at the end of a command execution subroutine (for COMMIT, it happens
at the bottom of ProcessUtility), whereas StartTransactionCommand and
CommitTransactionCommand are called from the outer loop in postgres.c.
We can't very reasonably move command-response sending to the outer
loop, since if the query string contains several commands we need to
send several responses.
We could take the start/commit calls out of postgres.c and put them
into the command execution subroutines. For example, ProcessUtility
would then look likeStartTransactionCommand();big switch statementCommitTransactionCommand();EndCommand(commandTag,
dest);// this sends the command response
However there are two disadvantages to that:
1. If you forget to put the start/commit calls into *all* the possible
execution paths, you have a problem. Having them only one place, in
the outer loop, is much more reliable.
2. This changes the semantics of a query string that contains multiple
commands. Right now, such commands are executed within a single
transaction. If we change the code as above, each one will get its own
transaction, so a failure in a later one will not rollback earlier ones.
In the 6.4 FE/BE protocol there is another answer. The terminating
"Z" (ReadyForQuery) message does not get sent until after the commit
has occurred successfully. So, if you believe the command has completed
when you get the "Z" message, and not just when you get the "C" message,
then this concern does not arise.
And, in fact, that's how libpq currently works, at least if you are using
PQexec() and not the lower-level routines --- it won't come back until
it gets "Z".
So my inclination is to leave well enough alone. There might be some
documentation effort called for here ... but I don't see a problem that
justifies changing the behavior of queries in a way that could break
some applications.
regards, tom lane
> Jan Wieck wrote: > > > > Hi, > > > > while on the redolog, I've came across a little detail I'm in > > doubt about. Currently it seems, that the 'C' response to the > > frontend is sent before the transaction get's really > > committed in the backend. So there is a little chance that > > the backend dies between this response and the > > CommitTransaction() call. > > > > Isn't that the wrong order? As a programmer I would assume, > > that if I have positive response to COMMIT, I can forget my > > local data because it made it safely into the database. > > Yes, this should be fixed... Added to TODO: * 'C' response returned to fontend before actual data committed -- Bruce Momjian | http://www.op.net/~candle maillist@candle.pha.pa.us | (610) 853-3000+ If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania19026
Bruce Momjian <maillist@candle.pha.pa.us> writes:
> Added to TODO:
> * 'C' response returned to fontend before actual data committed
See my followup to that thread --- there is already a solution (wait for
'Z' instead of 'C') and changing the backend's behavior would break
applications that rely on the current semantics of multiple commands in
a single query string. So I think we should leave well enough alone.
regards, tom lane
> Bruce Momjian <maillist@candle.pha.pa.us> writes: > > Added to TODO: > > * 'C' response returned to fontend before actual data committed > > See my followup to that thread --- there is already a solution (wait for > 'Z' instead of 'C') and changing the backend's behavior would break > applications that rely on the current semantics of multiple commands in > a single query string. So I think we should leave well enough alone. > > regards, tom lane > Removed from TODO list. -- Bruce Momjian | http://www.op.net/~candle maillist@candle.pha.pa.us | (610) 853-3000+ If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania19026