@@ -106,10 +106,7 @@ static char const* const messageText[] =
106
106
"HANDSHAKE" ,
107
107
"READY" ,
108
108
"PREPARE" ,
109
- "COMMIT" ,
110
- "ABORT" ,
111
109
"PREPARED" ,
112
- "COMMITTED" ,
113
110
"ABORTED" ,
114
111
"STATUS"
115
112
};
@@ -456,8 +453,10 @@ static void MtmAppendBuffer(MtmBuffer* txBuffer, TransactionId xid, int node, Mt
456
453
buf -> used = 0 ;
457
454
}
458
455
MTM_TRACE ("Send %s message CSN=%ld to node %d from node %d for global transaction %d/local transaction %d\n" ,
459
- ts -> status == TRANSACTION_STATUS_ABORTED ? "abort" : "commit" , ts -> csn , node + 1 , MtmNodeId , ts -> gtid .xid , ts -> xid );
460
- buf -> data [buf -> used ].code = ts -> status == TRANSACTION_STATUS_ABORTED ? MSG_ABORTED : MSG_PREPARED ;
456
+ messageText [ts -> cmd ], ts -> csn , node + 1 , MtmNodeId , ts -> gtid .xid , ts -> xid );
457
+
458
+ Assert (ts -> cmd != MSG_INVALID );
459
+ buf -> data [buf -> used ].code = ts -> cmd ;
461
460
buf -> data [buf -> used ].dxid = xid ;
462
461
buf -> data [buf -> used ].sxid = ts -> xid ;
463
462
buf -> data [buf -> used ].csn = ts -> csn ;
@@ -466,6 +465,22 @@ static void MtmAppendBuffer(MtmBuffer* txBuffer, TransactionId xid, int node, Mt
466
465
buf -> used += 1 ;
467
466
}
468
467
468
+ static void MtmBroadcastMessage (MtmBuffer * txBuffer , MtmTransState * ts )
469
+ {
470
+ int i ;
471
+ int n = 1 ;
472
+ for (i = 0 ; i < MtmNodes ; i ++ )
473
+ {
474
+ if (TransactionIdIsValid (ts -> xids [i ])) {
475
+ Assert (i + 1 != MtmNodeId );
476
+ MtmAppendBuffer (txBuffer , ts -> xids [i ], i , ts );
477
+ n += 1 ;
478
+ }
479
+ }
480
+ Assert (n == ds -> nNodes );
481
+ }
482
+
483
+
469
484
static void MtmTransSender (Datum arg )
470
485
{
471
486
int nNodes = MtmNodes ;
@@ -492,7 +507,11 @@ static void MtmTransSender(Datum arg)
492
507
MtmLock (LW_SHARED );
493
508
494
509
for (ts = ds -> votingTransactions ; ts != NULL ; ts = ts -> nextVoting ) {
495
- MtmAppendBuffer (txBuffer , ts -> gtid .xid , ts -> gtid .node - 1 , ts );
510
+ if (MtmIsCoordinator (ts )) {
511
+ MtmBroadcastMessage (txBuffer , ts );
512
+ } else {
513
+ MtmAppendBuffer (txBuffer , ts -> gtid .xid , ts -> gtid .node - 1 , ts );
514
+ }
496
515
}
497
516
ds -> votingTransactions = NULL ;
498
517
@@ -510,6 +529,7 @@ static void MtmTransSender(Datum arg)
510
529
static void MtmWakeUpBackend (MtmTransState * ts )
511
530
{
512
531
MTM_TRACE ("Wakeup backed procno=%d, pid=%d\n" , ts -> procno , ProcGlobal -> allProcs [ts -> procno ].pid );
532
+ ts -> votingCompleted = true;
513
533
SetLatch (& ProcGlobal -> allProcs [ts -> procno ].procLatch );
514
534
}
515
535
@@ -565,6 +585,9 @@ static void MtmTransReceiver(Datum arg)
565
585
#if USE_EPOLL
566
586
n = epoll_wait (epollfd , events , nNodes , MtmKeepaliveTimeout /1000 );
567
587
if (n < 0 ) {
588
+ if (errno == EINTR ) {
589
+ continue ;
590
+ }
568
591
elog (ERROR , "Arbiter failed to poll sockets: %d" , errno );
569
592
}
570
593
for (j = 0 ; j < n ; j ++ ) {
@@ -581,7 +604,9 @@ static void MtmTransReceiver(Datum arg)
581
604
events = inset ;
582
605
tv .tv_sec = MtmKeepaliveTimeout /USEC ;
583
606
tv .tv_usec = MtmKeepaliveTimeout %USEC ;
584
- n = select (max_fd + 1 , & events , NULL , NULL , & tv );
607
+ do {
608
+ n = select (max_fd + 1 , & events , NULL , NULL , & tv );
609
+ } while (n < 0 && errno == ENINTR );
585
610
} while (n < 0 && MtmRecovery ());
586
611
587
612
if (rc < 0 ) {
@@ -612,31 +637,62 @@ static void MtmTransReceiver(Datum arg)
612
637
MtmTransState * ts = (MtmTransState * )hash_search (MtmXid2State , & msg -> dxid , HASH_FIND , NULL );
613
638
Assert (ts != NULL );
614
639
Assert (msg -> node > 0 && msg -> node <= nNodes && msg -> node != MtmNodeId );
615
- Assert (MtmIsCoordinator (ts ));
616
- switch (msg -> code ) {
617
- case MSG_PREPARED :
618
- if (ts -> status != TRANSACTION_STATUS_ABORTED ) {
619
- Assert (ts -> status == TRANSACTION_STATUS_IN_PROGRESS || ts -> status == TRANSACTION_STATUS_UNKNOWN );
620
- if (msg -> csn > ts -> csn ) {
621
- ts -> csn = msg -> csn ;
622
- MtmSyncClock (ts -> csn );
623
- }
624
- if (++ ts -> nVotes == ds -> nNodes ) {
625
- MtmWakeUpBackend (ts );
640
+ if (MtmIsCoordinator (ts )) {
641
+ switch (msg -> code ) {
642
+ case MSG_READY :
643
+ Assert (ts -> nVotes < ds -> nNodes );
644
+ ds -> nodeTransDelay [msg -> node - 1 ] += MtmGetCurrentTime () - ts -> csn ;
645
+ ts -> xids [msg -> node - 1 ] = msg -> sxid ;
646
+ if (++ ts -> nVotes == ds -> nNodes ) {
647
+ /* All nodes are finished their transactions */
648
+ if (ts -> status == TRANSACTION_STATUS_IN_PROGRESS ) {
649
+ ts -> nVotes = 1 ; /* I voted myself */
650
+ MtmSendNotificationMessage (ts , MSG_PREPARE );
651
+ } else {
652
+ Assert (ts -> status == TRANSACTION_STATUS_ABORTED );
653
+ MtmWakeUpBackend (ts );
626
654
}
627
655
}
628
- break ;
629
- case MSG_ABORTED :
656
+ break ;
657
+ case MSG_ABORTED :
658
+ Assert (ts -> nVotes < ds -> nNodes );
630
659
if (ts -> status != TRANSACTION_STATUS_ABORTED ) {
631
- Assert (ts -> status == TRANSACTION_STATUS_IN_PROGRESS || ts -> status == TRANSACTION_STATUS_UNKNOWN );
660
+ Assert (ts -> status == TRANSACTION_STATUS_IN_PROGRESS );
632
661
ts -> status = TRANSACTION_STATUS_ABORTED ;
633
662
MtmAdjustSubtransactions (ts );
663
+ }
664
+ if (++ ts -> nVotes == ds -> nNodes ) {
634
665
MtmWakeUpBackend (ts );
635
666
}
636
667
break ;
637
- default :
668
+ case MSG_PREPARED :
669
+ Assert (ts -> status == TRANSACTION_STATUS_IN_PROGRESS );
670
+ Assert (ts -> nVotes < ds -> nNodes );
671
+ if (msg -> csn > ts -> csn ) {
672
+ ts -> csn = msg -> csn ;
673
+ MtmSyncClock (ts -> csn );
674
+ }
675
+ if (++ ts -> nVotes == ds -> nNodes ) {
676
+ ts -> csn = MtmAssignCSN ();
677
+ ts -> status = TRANSACTION_STATUS_UNKNOWN ;
678
+ MtmWakeUpBackend (ts );
679
+ }
680
+ default :
681
+ Assert (false);
682
+ }
683
+ } else {
684
+ switch (msg -> code ) {
685
+ case MSG_PREPARE :
686
+ Assert (ts -> status == TRANSACTION_STATUS_IN_PROGRESS );
687
+ ts -> status = TRANSACTION_STATUS_UNKNOWN ;
688
+ ts -> csn = MtmAssignCSN ();
689
+ MtmAdjustSubtransactions (ts );
690
+ MtmSendNotificationMessage (ts , MSG_PREPARED );
691
+ break ;
692
+ default :
638
693
Assert (false);
639
- }
694
+ }
695
+ }
640
696
}
641
697
MtmUnlock ();
642
698
0 commit comments