@@ -230,14 +230,14 @@ bool DtmXidInMVCCSnapshot(TransactionId xid, Snapshot snapshot)
230
230
if (ts != NULL )
231
231
{
232
232
if (ts -> csn > dtmTx .snapshot ) {
233
- DTM_TRACE (( stderr , "%d: tuple with xid=%d(csn=%lld ) is invisibile in snapshot %lld \n" ,
234
- getpid (), xid , ts -> csn , dtmTx .snapshot ) );
233
+ DTM_TUPLE_TRACE ( "%d: tuple with xid=%d(csn=%ld ) is invisibile in snapshot %ld \n" ,
234
+ getpid (), xid , ts -> csn , dtmTx .snapshot );
235
235
LWLockRelease (dtm -> hashLock );
236
236
return true;
237
237
}
238
238
if (ts -> status == TRANSACTION_STATUS_IN_PROGRESS )
239
239
{
240
- DTM_TRACE (( stderr , "%d: wait for in-doubt transaction %u in snapshot %lu\n" , getpid (), xid , dtmTx .snapshot ) );
240
+ DTM_TRACE ("%d: wait for in-doubt transaction %u in snapshot %lu\n" , getpid (), xid , dtmTx .snapshot );
241
241
LWLockRelease (dtm -> hashLock );
242
242
#if TRACE_SLEEP_TIME
243
243
{
@@ -255,7 +255,7 @@ bool DtmXidInMVCCSnapshot(TransactionId xid, Snapshot snapshot)
255
255
if (firstReportTime == 0 ) {
256
256
firstReportTime = now ;
257
257
} else {
258
- fprintf ( stderr , "Snapshot sleep %lu of %lu usec (%f%%), maximum=%lu\n" , totalSleepTime , now - firstReportTime , totalSleepTime * 100.0 /(now - firstReportTime ), maxSleepTime );
258
+ DTM_TRACE ( "Snapshot sleep %lu of %lu usec (%f%%), maximum=%lu\n" , totalSleepTime , now - firstReportTime , totalSleepTime * 100.0 /(now - firstReportTime ), maxSleepTime );
259
259
}
260
260
}
261
261
}
@@ -268,15 +268,15 @@ bool DtmXidInMVCCSnapshot(TransactionId xid, Snapshot snapshot)
268
268
else
269
269
{
270
270
bool invisible = ts -> status != TRANSACTION_STATUS_COMMITTED ;
271
- DTM_TRACE (( stderr , "%d: tuple with xid=%d(csn= %lld ) is %s in snapshot %lld \n" ,
272
- getpid (), xid , ts -> csn , invisible ? "rollbacked" : "committed" , dtmTx .snapshot ) );
271
+ DTM_TUPLE_TRACE ( "%d: tuple with xid=%d(csn= %ld ) is %s in snapshot %ld \n" ,
272
+ getpid (), xid , ts -> csn , invisible ? "rollbacked" : "committed" , dtmTx .snapshot );
273
273
LWLockRelease (dtm -> hashLock );
274
274
return invisible ;
275
275
}
276
276
}
277
277
else
278
278
{
279
- DTM_TRACE (( stderr , "%d: visibility check is skept for transaction %u in snapshot %lu\n" , getpid (), xid , dtmTx .snapshot ) );
279
+ DTM_TUPLE_TRACE ( "%d: visibility check is skept for transaction %u in snapshot %lu\n" , getpid (), xid , dtmTx .snapshot );
280
280
break ;
281
281
}
282
282
}
@@ -342,14 +342,15 @@ DtmAdjustOldestXid(TransactionId xid)
342
342
ts = (DtmTransState * )hash_search (xid2state , & xid , HASH_FIND , NULL );
343
343
if (ts != NULL ) {
344
344
timestamp_t cutoff_time = ts -> csn - DtmVacuumDelay * USEC ;
345
-
345
+ #if 0
346
346
for (ts = dtm -> transListHead ; ts != NULL && ts -> csn < cutoff_time ; prev = ts , ts = ts -> next ) {
347
347
Assert (ts -> status == TRANSACTION_STATUS_COMMITTED || ts -> status == TRANSACTION_STATUS_ABORTED );
348
348
if (prev != NULL ) {
349
349
/* Remove information about too old transactions */
350
350
hash_search (xid2state , & prev -> xid , HASH_REMOVE , NULL );
351
351
}
352
352
}
353
+ #endif
353
354
}
354
355
if (prev != NULL ) {
355
356
dtm -> transListHead = prev ;
@@ -398,7 +399,6 @@ static void DtmInitialize()
398
399
static void
399
400
DtmXactCallback (XactEvent event , void * arg )
400
401
{
401
- //XTM_INFO("%d: DtmXactCallbackevent=%d nextxid=%d\n", getpid(), event, DtmNextXid);
402
402
switch (event )
403
403
{
404
404
case XACT_EVENT_START :
@@ -427,7 +427,7 @@ DtmBeginTransaction(DtmCurrentTrans* x)
427
427
x -> snapshot = dtm_get_csn ();
428
428
x -> gtid .xid = InvalidTransactionId ;
429
429
LWLockRelease (dtm -> hashLock );
430
- DTM_TRACE (( stderr , "DtmLocalTransaction: transaction %u uses local snapshot %lu\n" , x -> xid , x -> snapshot ) );
430
+ DTM_TRACE ("DtmLocalTransaction: transaction %u uses local snapshot %lu\n" , x -> xid , x -> snapshot );
431
431
}
432
432
}
433
433
@@ -438,6 +438,7 @@ DtmBeginTransaction(DtmCurrentTrans* x)
438
438
static void DtmPrepareTransaction (DtmCurrentTrans * x )
439
439
{
440
440
DtmTransState * ts ;
441
+ bool found ;
441
442
int i ;
442
443
443
444
if (!x -> isDistributed ) {
@@ -448,8 +449,9 @@ static void DtmPrepareTransaction(DtmCurrentTrans* x)
448
449
x -> xid = GetCurrentTransactionId ();
449
450
}
450
451
LWLockAcquire (dtm -> hashLock , LW_EXCLUSIVE );
451
- ts = hash_search (xid2state , & x -> xid , HASH_ENTER , NULL );
452
- ts -> snapshot = x -> isReplicated ? x -> snapshot : INVALID_CSN ;
452
+ ts = hash_search (xid2state , & x -> xid , HASH_ENTER , & found );
453
+ Assert (!found );
454
+ ts -> snapshot = x -> isReplicated ? INVALID_CSN : x -> snapshot ;
453
455
ts -> status = TRANSACTION_STATUS_UNKNOWN ;
454
456
ts -> csn = dtm_get_csn ();
455
457
ts -> procno = MyProc -> pgprocno ;
@@ -475,6 +477,24 @@ DtmEndTransaction(DtmCurrentTrans* x)
475
477
x -> gtid .xid = InvalidTransactionId ;
476
478
}
477
479
480
+ static void
481
+ SendNotificationMessage (DtmTransState * ts )
482
+ {
483
+ DtmTransState * votingList ;
484
+
485
+ SpinLockAcquire (& dtm -> votingSpinlock );
486
+ votingList = dtm -> votingTransactions ;
487
+ ts -> nextVoting = votingList ;
488
+ dtm -> votingTransactions = ts ;
489
+ SpinLockRelease (& dtm -> votingSpinlock );
490
+ DTM_TRACE ("Register commit message\n" );
491
+ if (votingList == NULL ) {
492
+ /* singal semaphore only once for the whole list */
493
+ DTM_TRACE ("Signal semaphore\n" );
494
+ PGSemaphoreUnlock (& dtm -> votingSemaphore );
495
+ }
496
+ }
497
+
478
498
static XidStatus
479
499
DtmCommitTransaction (TransactionId xid , int nsubxids , TransactionId * subxids )
480
500
{
@@ -524,12 +544,16 @@ DtmFinishTransaction(TransactionId xid, int nsubxids, TransactionId *subxids, Xi
524
544
525
545
LWLockAcquire (dtm -> hashLock , LW_EXCLUSIVE );
526
546
ts = hash_search (xid2state , & xid , HASH_FIND , NULL );
527
- Assert (ts != NULL ); /* should be created by DtmPrepareTransaction */
528
- ts -> status = status ;
529
- for (i = 0 ; i < nsubxids ; i ++ ) {
530
- ts = ts -> next ;
547
+ if (ts != NULL ) { /* should be created by DtmPrepareTransaction */
531
548
ts -> status = status ;
532
- }
549
+ for (i = 0 ; i < nsubxids ; i ++ ) {
550
+ ts = ts -> next ;
551
+ ts -> status = status ;
552
+ }
553
+ if (dtmTx .isReplicated ) {
554
+ SendNotificationMessage (ts );
555
+ }
556
+ }
533
557
LWLockRelease (dtm -> hashLock );
534
558
}
535
559
@@ -538,19 +562,18 @@ DtmFinishTransaction(TransactionId xid, int nsubxids, TransactionId *subxids, Xi
538
562
static void
539
563
DtmSetTransactionStatus (TransactionId xid , int nsubxids , TransactionId * subxids , XidStatus status , XLogRecPtr lsn )
540
564
{
541
- DTM_INFO ("%d: DtmSetTransactionStatus %u = %u\n" , getpid (), xid , status );
542
- if (dtmTx .isDistributed )
565
+ DTM_TRACE ("%d: DtmSetTransactionStatus %u = %u\n" , getpid (), xid , status );
566
+ if (xid == dtmTx . xid && dtmTx .isDistributed )
543
567
{
544
- Assert (xid == dtmTx .xid );
545
568
if (status == TRANSACTION_STATUS_ABORTED || !dtmTx .containsDML )
546
569
{
547
570
DtmFinishTransaction (xid , nsubxids , subxids , status );
548
- DTM_INFO ("Abort transaction %d\n" , xid );
571
+ DTM_TRACE ("Abort transaction %d\n" , xid );
549
572
}
550
573
else
551
574
{
552
575
if (DtmCommitTransaction (xid , nsubxids , subxids ) == TRANSACTION_STATUS_COMMITTED ) {
553
- DTM_INFO ("Commit transaction %d\n" , xid );
576
+ DTM_TRACE ("Commit transaction %d\n" , xid );
554
577
} else {
555
578
PgTransactionIdSetTreeStatus (xid , nsubxids , subxids , TRANSACTION_STATUS_ABORTED , lsn );
556
579
dtmTx .isDistributed = false;
@@ -643,7 +666,7 @@ _PG_init(void)
643
666
);
644
667
645
668
DefineCustomIntVariable (
646
- "multimaster.arpiter_port " ,
669
+ "multimaster.arbiter_port " ,
647
670
"Base value for assigning arbiter ports" ,
648
671
NULL ,
649
672
& MMArbiterPort ,
@@ -990,42 +1013,29 @@ MMPoolConstructor(void)
990
1013
return & dtm -> pool ;
991
1014
}
992
1015
993
- static void
994
- SendCommitMessage (DtmTransState * ts )
995
- {
996
- DtmTransState * votingList ;
997
-
998
- SpinLockAcquire (& dtm -> votingSpinlock );
999
- votingList = dtm -> votingTransactions ;
1000
- ts -> nextVoting = votingList ;
1001
- dtm -> votingTransactions = ts ;
1002
- SpinLockRelease (& dtm -> votingSpinlock );
1003
-
1004
- if (votingList == NULL ) {
1005
- /* singal semaphreo only once for the whole list */
1006
- PGSemaphoreUnlock (& dtm -> votingSemaphore );
1007
- }
1008
- }
1009
-
1010
1016
static void
1011
1017
MMVoteForTransaction (DtmTransState * ts )
1012
1018
{
1013
1019
LWLockRelease (dtm -> hashLock );
1014
1020
if (ts -> gtid .node == MMNodeId ) {
1015
1021
/* I am coordinator: wait responses from all replicas for transaction replicated using logical decoding */
1022
+ DTM_TRACE ("Coordinator waiting latch...\n" );
1016
1023
WaitLatch (& MyProc -> procLatch , WL_LATCH_SET , -1 );
1017
1024
ResetLatch (& MyProc -> procLatch );
1025
+ DTM_TRACE ("Coordinator receive %d votes\n" , ts -> nVotes );
1018
1026
Assert (ts -> nVotes == dtm -> nNodes );
1019
1027
1020
1028
/* ... and then send notifications to replicas */
1021
- SendCommitMessage (ts );
1029
+ SendNotificationMessage (ts );
1022
1030
} else {
1023
1031
/* I am replica: first notify coordinator... */
1024
1032
ts -> nVotes = dtm -> nNodes - 1 ; /* I just need one confirmation from coordinator */
1025
- SendCommitMessage (ts );
1033
+ SendNotificationMessage (ts );
1026
1034
/* ... and wait response from it */
1035
+ DTM_TRACE ("Node %d waiting latch...\n" , MMNodeId );
1027
1036
WaitLatch (& MyProc -> procLatch , WL_LATCH_SET , -1 );
1028
1037
ResetLatch (& MyProc -> procLatch );
1038
+ DTM_TRACE ("Node %d receive response...\n" , MMNodeId );
1029
1039
}
1030
1040
LWLockAcquire (dtm -> hashLock , LW_EXCLUSIVE );
1031
1041
}
@@ -1034,6 +1044,7 @@ HTAB* MMCreateHash(void)
1034
1044
{
1035
1045
HASHCTL info ;
1036
1046
HTAB * htab ;
1047
+ Assert (MMNodes > 0 );
1037
1048
memset (& info , 0 , sizeof (info ));
1038
1049
info .keysize = sizeof (TransactionId );
1039
1050
info .entrysize = sizeof (DtmTransState ) + (MMNodes - 1 )* sizeof (TransactionId );
0 commit comments