Skip to content

Commit 9710b26

Browse files
martinmrdna2github
authored andcommitted
Avoid assigning duplicate RAFT IDs to new nodes. (hypermodeinc#5571)
Currently, zero uses the MaxRaftId to assign RAFT IDs to new nodes. However, the MaxRaftId value is not immediately updated and the lock is released in between creating the proposal and sending the proposal to the RAFT node. This can lead to situations where more than one new node is assigned the same ID. To solve this, this change introduces a new field to generate the IDs that is updated immediately, thus preventing multiple nodes from being assigned the same ID. Fixes hypermodeinc#5436
1 parent 3949708 commit 9710b26

File tree

2 files changed

+11
-1
lines changed

2 files changed

+11
-1
lines changed

dgraph/cmd/zero/raft.go

+1
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ func (n *node) applyProposal(e raftpb.Entry) (string, error) {
324324
return p.Key, errInvalidProposal
325325
}
326326
state.MaxRaftId = p.MaxRaftId
327+
n.server.nextRaftId = x.Max(n.server.nextRaftId, p.MaxRaftId+1)
327328
}
328329
if p.SnapshotTs != nil {
329330
for gid, ts := range p.SnapshotTs {

dgraph/cmd/zero/zero.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ type Server struct {
5656

5757
NumReplicas int
5858
state *pb.MembershipState
59+
nextRaftId uint64
5960

6061
nextLeaseId uint64
6162
nextTxnTs uint64
@@ -83,6 +84,7 @@ func (s *Server) Init() {
8384
Groups: make(map[uint32]*pb.Group),
8485
Zeros: make(map[uint64]*pb.Member),
8586
}
87+
s.nextRaftId = 1
8688
s.nextLeaseId = 1
8789
s.nextTxnTs = 1
8890
s.nextGroup = 1
@@ -217,7 +219,10 @@ func (s *Server) hasLeader(gid uint32) bool {
217219
func (s *Server) SetMembershipState(state *pb.MembershipState) {
218220
s.Lock()
219221
defer s.Unlock()
222+
220223
s.state = state
224+
s.nextRaftId = x.Max(s.nextRaftId, s.state.MaxRaftId+1)
225+
221226
if state.Zeros == nil {
222227
state.Zeros = make(map[uint64]*pb.Member)
223228
}
@@ -491,7 +496,11 @@ func (s *Server) Connect(ctx context.Context,
491496
}
492497
}
493498
if m.Id == 0 {
494-
m.Id = s.state.MaxRaftId + 1
499+
// In certain situations, the proposal can be sent and return with an error.
500+
// However, Dgraph will keep retrying the proposal. To avoid assigning duplicating
501+
// IDs, the couter is incremented every time a proposal is created.
502+
m.Id = s.nextRaftId
503+
s.nextRaftId += 1
495504
proposal.MaxRaftId = m.Id
496505
}
497506

0 commit comments

Comments
 (0)