From 5b48de7430193971dea96a9bb71c37935a48708e Mon Sep 17 00:00:00 2001 From: Onder Kalaci Date: Fri, 11 Aug 2017 13:19:53 +0300 Subject: [PATCH] Improve deadlock detection for MX We added a new field to the transaction id that is set to true only for the transactions initialized on the coordinator. This is only useful for MX in order to distinguish the transaction that started the distributed transaction on the coordinator where we could have the same transactions' worker queries on the same node. --- src/backend/distributed/transaction/backend_data.c | 6 ++++++ .../transaction/distributed_deadlock_detection.c | 9 +++++++++ src/include/distributed/transaction_identifier.h | 5 +++++ 3 files changed, 20 insertions(+) diff --git a/src/backend/distributed/transaction/backend_data.c b/src/backend/distributed/transaction/backend_data.c index a1705cf4d..dad7372b5 100644 --- a/src/backend/distributed/transaction/backend_data.c +++ b/src/backend/distributed/transaction/backend_data.c @@ -112,6 +112,7 @@ assign_distributed_transaction_id(PG_FUNCTION_ARGS) MyBackendData->transactionId.initiatorNodeIdentifier = PG_GETARG_INT32(0); MyBackendData->transactionId.transactionNumber = PG_GETARG_INT64(1); MyBackendData->transactionId.timestamp = PG_GETARG_TIMESTAMPTZ(2); + MyBackendData->transactionId.transactionOriginator = false; SpinLockRelease(&MyBackendData->mutex); @@ -413,6 +414,7 @@ InitializeBackendData(void) MyBackendData->databaseId = MyDatabaseId; MyBackendData->transactionId.initiatorNodeIdentifier = 0; + MyBackendData->transactionId.transactionOriginator = false; MyBackendData->transactionId.transactionNumber = 0; MyBackendData->transactionId.timestamp = 0; @@ -436,6 +438,7 @@ UnSetDistributedTransactionId(void) MyBackendData->databaseId = 0; MyBackendData->transactionId.initiatorNodeIdentifier = 0; + MyBackendData->transactionId.transactionOriginator = false; MyBackendData->transactionId.transactionNumber = 0; MyBackendData->transactionId.timestamp = 0; @@ -487,6 +490,8 @@ GetCurrentDistributedTransactionId(void) currentDistributedTransactionId->initiatorNodeIdentifier = MyBackendData->transactionId.initiatorNodeIdentifier; + currentDistributedTransactionId->transactionOriginator = + MyBackendData->transactionId.transactionOriginator; currentDistributedTransactionId->transactionNumber = MyBackendData->transactionId.transactionNumber; currentDistributedTransactionId->timestamp = @@ -521,6 +526,7 @@ AssignDistributedTransactionId(void) MyBackendData->databaseId = MyDatabaseId; MyBackendData->transactionId.initiatorNodeIdentifier = localGroupId; + MyBackendData->transactionId.transactionOriginator = true; MyBackendData->transactionId.transactionNumber = nextTransactionNumber; MyBackendData->transactionId.timestamp = currentTimestamp; diff --git a/src/backend/distributed/transaction/distributed_deadlock_detection.c b/src/backend/distributed/transaction/distributed_deadlock_detection.c index b231da2e0..176a2c60b 100644 --- a/src/backend/distributed/transaction/distributed_deadlock_detection.c +++ b/src/backend/distributed/transaction/distributed_deadlock_detection.c @@ -362,6 +362,12 @@ AssociateDistributedTransactionWithBackendProc(TransactionNode *transactionNode) continue; } + /* we're only interested in transactions started on this node */ + if (!currentTransactionId->transactionOriginator) + { + continue; + } + /* at the point we should only have transactions initiated by this node */ Assert(currentTransactionId->initiatorNodeIdentifier == GetLocalGroupId()); @@ -419,15 +425,18 @@ BuildAdjacencyListsForWaitGraph(WaitGraph *waitGraph) WaitEdge *edge = &waitGraph->edges[edgeIndex]; TransactionNode *waitingTransaction = NULL; TransactionNode *blockingTransaction = NULL; + bool transactionOriginator = false; DistributedTransactionId waitingId = { edge->waitingNodeId, + transactionOriginator, edge->waitingTransactionNum, edge->waitingTransactionStamp }; DistributedTransactionId blockingId = { edge->blockingNodeId, + transactionOriginator, edge->blockingTransactionNum, edge->blockingTransactionStamp }; diff --git a/src/include/distributed/transaction_identifier.h b/src/include/distributed/transaction_identifier.h index 21c6d530e..b2589814e 100644 --- a/src/include/distributed/transaction_identifier.h +++ b/src/include/distributed/transaction_identifier.h @@ -21,6 +21,10 @@ * * - initiatorNodeIdentifier: A unique identifier of the node that initiated * the distributed transaction + * - transactionOriginator: Set to true only for the transactions initialized on + * the coordinator. This is only useful for MX in order to distinguish the transaction + * that started the distributed transaction on the coordinator where we could + * have the same transactions' worker queries on the same node * - transactionNumber: A locally unique identifier assigned for the distributed * transaction on the node that initiated the distributed transaction * - timestamp: The current timestamp of distributed transaction initiation @@ -29,6 +33,7 @@ typedef struct DistributedTransactionId { int initiatorNodeIdentifier; + bool transactionOriginator; uint64 transactionNumber; TimestampTz timestamp; } DistributedTransactionId;