Обсуждение: 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