Skip to content

Commit f22016c

Browse files
knizhnikkelvich
authored andcommitted
Do not set XMAX_INVALID for transaction which are in progress
1 parent 990b7c0 commit f22016c

File tree

1 file changed

+17
-11
lines changed

1 file changed

+17
-11
lines changed

multimaster.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
typedef struct {
7474
TransactionId xid; /* local transaction ID */
7575
GlobalTransactionId gtid; /* global transaction ID assigned by coordinator of transaction */
76+
bool isTwoPhase; /* user level 2PC */
7677
bool isReplicated; /* transaction on replica */
7778
bool isDistributed; /* transaction performed INSERT/UPDATE/DELETE and has to be replicated to other nodes */
7879
bool isPrepared; /* transaction is perpared at first stage of 2PC */
@@ -719,6 +720,7 @@ MtmResetTransaction()
719720
x->gtid.xid = InvalidTransactionId;
720721
x->isDistributed = false;
721722
x->isPrepared = false;
723+
x->isTwoPhase = false;
722724
x->status = TRANSACTION_STATUS_UNKNOWN;
723725
}
724726

@@ -746,6 +748,7 @@ MtmBeginTransaction(MtmCurrentTrans* x)
746748
x->isReplicated = MtmIsLogicalReceiver;
747749
x->isDistributed = MtmIsUserTransaction();
748750
x->isPrepared = false;
751+
x->isTwoPhase = false;
749752
x->isTransactionBlock = IsTransactionBlock();
750753
/* Application name can be changed usnig PGAPPNAME environment variable */
751754
if (x->isDistributed && Mtm->status != MTM_ONLINE && strcmp(application_name, MULTIMASTER_ADMIN) != 0) {
@@ -906,8 +909,7 @@ MtmPostPrepareTransaction(MtmCurrentTrans* x)
906909
Assert(ts != NULL);
907910
//if (x->gid[0]) MTM_LOG1("Preparing transaction %d (%s) at %ld", x->xid, x->gid, MtmGetCurrentTime());
908911
if (!MtmIsCoordinator(ts) || Mtm->status == MTM_RECOVERY) {
909-
bool found;
910-
MtmTransMap* tm = (MtmTransMap*)hash_search(MtmGid2State, x->gid, HASH_ENTER, &found);
912+
MtmTransMap* tm = (MtmTransMap*)hash_search(MtmGid2State, x->gid, HASH_ENTER, NULL);
911913
Assert(x->gid[0]);
912914
tm->state = ts;
913915
ts->votingCompleted = true;
@@ -925,8 +927,13 @@ MtmPostPrepareTransaction(MtmCurrentTrans* x)
925927
time_t transTimeout = Max(MSEC_TO_USEC(Mtm2PCMinTimeout), (ts->csn - ts->snapshot)*Mtm2PCPrepareRatio/100);
926928
int result = 0;
927929
int nConfigChanges = Mtm->nConfigChanges;
928-
929930
timestamp_t start = MtmGetSystemTime();
931+
932+
if (x->isTwoPhase) {
933+
MtmTransMap* tm = (MtmTransMap*)hash_search(MtmGid2State, x->gid, HASH_ENTER, NULL);
934+
tm->state = ts;
935+
}
936+
930937
/* Wait votes from all nodes until: */
931938
while (!ts->votingCompleted /* all nodes voted */
932939
&& nConfigChanges == Mtm->nConfigChanges /* configarion is changed */
@@ -982,7 +989,7 @@ MtmAbortPreparedTransaction(MtmCurrentTrans* x)
982989
MtmLock(LW_EXCLUSIVE);
983990
tm = (MtmTransMap*)hash_search(MtmGid2State, x->gid, HASH_REMOVE, NULL);
984991
if (tm == NULL) {
985-
elog(WARNING, "Global transaciton ID %s is not found", x->gid);
992+
elog(WARNING, "Global transaciton ID '%s' is not found", x->gid);
986993
} else {
987994
Assert(tm->state != NULL);
988995
MTM_LOG1("Abort prepared transaction %d with gid='%s'", x->xid, x->gid);
@@ -1265,7 +1272,7 @@ void MtmAbortTransaction(MtmTransState* ts)
12651272
Assert(MtmLockCount != 0); /* should be invoked with exclsuive lock */
12661273
if (ts->status != TRANSACTION_STATUS_ABORTED) {
12671274
if (ts->status == TRANSACTION_STATUS_COMMITTED) {
1268-
elog(WARNING, "Attempt to rollback already committed transaction %d (%s)", ts->xid, ts->gid);
1275+
elog(LOG, "Attempt to rollback already committed transaction %d (%s)", ts->xid, ts->gid);
12691276
} else {
12701277
MTM_LOG1("Rollback active transaction %d:%d (local xid %d) status %d", ts->gtid.node, ts->gtid.xid, ts->xid, ts->status);
12711278
ts->status = TRANSACTION_STATUS_ABORTED;
@@ -3798,11 +3805,10 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
37983805
}
37993806
break;
38003807
case TRANS_STMT_PREPARE:
3801-
elog(ERROR, "Two phase commit is not supported by multimaster");
3802-
break;
38033808
case TRANS_STMT_COMMIT_PREPARED:
38043809
case TRANS_STMT_ROLLBACK_PREPARED:
3805-
skipCommand = true;
3810+
MtmTx.isTwoPhase = true;
3811+
strcpy(MtmTx.gid, stmt->gid);
38063812
break;
38073813
default:
38083814
break;
@@ -3960,8 +3966,8 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
39603966
standard_ProcessUtility(parsetree, queryString, context,
39613967
params, dest, completionTag);
39623968
}
3963-
3964-
if (MtmTx.isDistributed && XactIsoLevel != XACT_REPEATABLE_READ && !MtmVolksWagenMode) {
3969+
3970+
if (!MtmVolksWagenMode && MtmTx.isDistributed && XactIsoLevel != XACT_REPEATABLE_READ) {
39653971
elog(ERROR, "Isolation level %s is not supported by multimaster", isoLevelStr[XactIsoLevel]);
39663972
}
39673973

@@ -4147,7 +4153,7 @@ MtmDetectGlobalDeadLockFortXid(TransactionId xid)
41474153
}
41484154
MtmGetGtid(xid, &gtid);
41494155
hasDeadlock = MtmGraphFindLoop(&graph, &gtid);
4150-
elog(WARNING, "Distributed deadlock check by backend %d for %u:%u = %d", MyProcPid, gtid.node, gtid.xid, hasDeadlock);
4156+
elog(LOG, "Distributed deadlock check by backend %d for %u:%u = %d", MyProcPid, gtid.node, gtid.xid, hasDeadlock);
41514157
if (!hasDeadlock) {
41524158
/* There is no deadlock loop in graph, but deadlock can be caused by lack of apply workers: if all of them are busy, then some transactions
41534159
* can not be appied just because there are no vacant workers and it cause additional dependency between transactions which is not

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy