mirror of https://github.com/citusdata/citus.git
Don't wait for statement completion when aborting coordinated transaction.
Previously we used ForgetResults() in StartRemoteTransactionAbort() - that's problematic because there might still be an ongoing statement, and this causes us to wait for its completion. That e.g. happens when a statement running on the coordinator is cancelled.pull/1473/head
parent
0d791f6740
commit
3461244539
|
@ -276,16 +276,21 @@ StartRemoteTransactionAbort(MultiConnection *connection)
|
||||||
Assert(transaction->transactionState != REMOTE_TRANS_INVALID);
|
Assert(transaction->transactionState != REMOTE_TRANS_INVALID);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear previous results, so we have a better chance to send
|
* Clear previous results, so we have a better chance to send ROLLBACK
|
||||||
* ROLLBACK [PREPARED];
|
* [PREPARED]. If we've previously sent a PREPARE TRANSACTION, we always
|
||||||
|
* want to wait for that result, as that shouldn't take long and will
|
||||||
|
* reserve resources. But if there's another query running, we don't want
|
||||||
|
* to wait, because a longrunning statement may be running, force it to be
|
||||||
|
* killed in that case.
|
||||||
*/
|
*/
|
||||||
ForgetResults(connection);
|
|
||||||
|
|
||||||
if (transaction->transactionState == REMOTE_TRANS_PREPARING ||
|
if (transaction->transactionState == REMOTE_TRANS_PREPARING ||
|
||||||
transaction->transactionState == REMOTE_TRANS_PREPARED)
|
transaction->transactionState == REMOTE_TRANS_PREPARED)
|
||||||
{
|
{
|
||||||
StringInfoData command;
|
StringInfoData command;
|
||||||
|
|
||||||
|
/* await PREPARE TRANSACTION results, closing the connection would leave it dangling */
|
||||||
|
ForgetResults(connection);
|
||||||
|
|
||||||
initStringInfo(&command);
|
initStringInfo(&command);
|
||||||
appendStringInfo(&command, "ROLLBACK PREPARED '%s'",
|
appendStringInfo(&command, "ROLLBACK PREPARED '%s'",
|
||||||
transaction->preparedName);
|
transaction->preparedName);
|
||||||
|
@ -304,6 +309,14 @@ StartRemoteTransactionAbort(MultiConnection *connection)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (!NonblockingForgetResults(connection))
|
||||||
|
{
|
||||||
|
ShutdownConnection(connection);
|
||||||
|
|
||||||
|
/* FinishRemoteTransactionAbort will emit warning */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!SendRemoteCommand(connection, "ROLLBACK"))
|
if (!SendRemoteCommand(connection, "ROLLBACK"))
|
||||||
{
|
{
|
||||||
/* no point in reporting a likely redundant message */
|
/* no point in reporting a likely redundant message */
|
||||||
|
@ -336,17 +349,17 @@ FinishRemoteTransactionAbort(MultiConnection *connection)
|
||||||
ReportResultError(connection, result, WARNING);
|
ReportResultError(connection, result, WARNING);
|
||||||
MarkRemoteTransactionFailed(connection, dontRaiseErrors);
|
MarkRemoteTransactionFailed(connection, dontRaiseErrors);
|
||||||
|
|
||||||
if (transaction->transactionState == REMOTE_TRANS_1PC_ABORTING)
|
if (transaction->transactionState == REMOTE_TRANS_2PC_ABORTING)
|
||||||
|
{
|
||||||
|
WarnAboutLeakedPreparedTransaction(connection, isNotCommit);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
ereport(WARNING,
|
ereport(WARNING,
|
||||||
(errmsg("failed to abort 1PC transaction \"%s\" on %s:%d",
|
(errmsg("failed to abort 1PC transaction \"%s\" on %s:%d",
|
||||||
transaction->preparedName, connection->hostname,
|
transaction->preparedName, connection->hostname,
|
||||||
connection->port)));
|
connection->port)));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
WarnAboutLeakedPreparedTransaction(connection, isNotCommit);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PQclear(result);
|
PQclear(result);
|
||||||
|
|
Loading…
Reference in New Issue