diff --git a/dgraph/cmd/zero/raft.go b/dgraph/cmd/zero/raft.go index 86b0aea302d..395c80189ed 100644 --- a/dgraph/cmd/zero/raft.go +++ b/dgraph/cmd/zero/raft.go @@ -324,6 +324,7 @@ func (n *node) applyProposal(e raftpb.Entry) (string, error) { return p.Key, errInvalidProposal } state.MaxRaftId = p.MaxRaftId + n.server.nextRaftId = x.Max(n.server.nextRaftId, p.MaxRaftId+1) } if p.SnapshotTs != nil { for gid, ts := range p.SnapshotTs { diff --git a/dgraph/cmd/zero/zero.go b/dgraph/cmd/zero/zero.go index 0e5cd5cad60..d1da1cefde4 100644 --- a/dgraph/cmd/zero/zero.go +++ b/dgraph/cmd/zero/zero.go @@ -56,6 +56,7 @@ type Server struct { NumReplicas int state *pb.MembershipState + nextRaftId uint64 nextLeaseId uint64 nextTxnTs uint64 @@ -83,6 +84,7 @@ func (s *Server) Init() { Groups: make(map[uint32]*pb.Group), Zeros: make(map[uint64]*pb.Member), } + s.nextRaftId = 1 s.nextLeaseId = 1 s.nextTxnTs = 1 s.nextGroup = 1 @@ -217,7 +219,10 @@ func (s *Server) hasLeader(gid uint32) bool { func (s *Server) SetMembershipState(state *pb.MembershipState) { s.Lock() defer s.Unlock() + s.state = state + s.nextRaftId = x.Max(s.nextRaftId, s.state.MaxRaftId+1) + if state.Zeros == nil { state.Zeros = make(map[uint64]*pb.Member) } @@ -491,7 +496,11 @@ func (s *Server) Connect(ctx context.Context, } } if m.Id == 0 { - m.Id = s.state.MaxRaftId + 1 + // In certain situations, the proposal can be sent and return with an error. + // However, Dgraph will keep retrying the proposal. To avoid assigning duplicating + // IDs, the couter is incremented every time a proposal is created. + m.Id = s.nextRaftId + s.nextRaftId += 1 proposal.MaxRaftId = m.Id }