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.
pull/1529/head
Onder Kalaci 2017-08-11 13:19:53 +03:00
parent 59133415b0
commit 5b48de7430
3 changed files with 20 additions and 0 deletions

View File

@ -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;

View File

@ -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
};

View File

@ -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;