Skip to content

Commit 536c6e3

Browse files
authored
Fix a race condition in node registration. (#847)
Without this fix, we could register first a node that is not meant to be a primary. The node then is assigned REPORT_LSN, but there is no primary in the group yet, and now, all the other nodes fail to register because there is already a node registered, but there is no primary...
1 parent 51a3e11 commit 536c6e3

1 file changed

Lines changed: 10 additions & 4 deletions

File tree

src/monitor/node_active_protocol.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,6 @@ register_node(PG_FUNCTION_ARGS)
194194
sysIdentifier,
195195
nodeCluster,
196196
&currentNodeState);
197-
LockNodeGroup(formationId, currentNodeState.groupId, ExclusiveLock);
198197

199198
AutoFailoverNode *pgAutoFailoverNode = GetAutoFailoverNode(nodeHost, nodePort);
200199
if (pgAutoFailoverNode == NULL)
@@ -536,12 +535,18 @@ JoinAutoFailoverFormation(AutoFailoverFormation *formation,
536535
groupId = currentNodeState->groupId = 0;
537536
}
538537

539-
/* a group number was asked for in the registration call */
538+
/* either a Citus groupId was asked for, or we're in group 0 for pgsql */
540539
if (currentNodeState->groupId >= 0)
541540
{
542-
/* the node prefers a particular group */
543541
groupId = currentNodeState->groupId;
544542

543+
/*
544+
* Now that we have a groupId, take an exclusive lock to avoid race
545+
* conditions during registration, as the initial target state depends
546+
* on the other nodes in the same group.
547+
*/
548+
LockNodeGroup(formation->formationId, groupId, ExclusiveLock);
549+
545550
List *groupNodeList =
546551
AutoFailoverNodeGroup(formation->formationId, groupId);
547552

@@ -550,7 +555,8 @@ JoinAutoFailoverFormation(AutoFailoverFormation *formation,
550555
* in a group, we only ever accept a primary node first. Then, any
551556
* other node in the same group should be a standby. That's easy.
552557
*/
553-
if (list_length(groupNodeList) == 0)
558+
if (list_length(groupNodeList) == 0 &&
559+
currentNodeState->candidatePriority > 0)
554560
{
555561
initialState = REPLICATION_STATE_SINGLE;
556562
}

0 commit comments

Comments
 (0)