mirror of
https://github.com/gogrlx/nats-server.git
synced 2026-04-02 03:38:42 -07:00
Add in utility to detect and delete any NRG orphans.
Signed-off-by: Derek Collison <derek@nats.io>
This commit is contained in:
@@ -1167,6 +1167,65 @@ func (js *jetStream) checkForOrphans() {
|
||||
}
|
||||
}
|
||||
|
||||
// Check and delete any orphans we may come across.
|
||||
func (s *Server) checkForNRGOrphans() {
|
||||
js, cc := s.getJetStreamCluster()
|
||||
if js == nil || cc == nil || js.isMetaRecovering() {
|
||||
// No cluster means no NRGs. Also return if still recovering.
|
||||
return
|
||||
}
|
||||
|
||||
// Track which assets R>1 should be on this server.
|
||||
nrgMap := make(map[string]struct{})
|
||||
trackGroup := func(rg *raftGroup) {
|
||||
// If R>1 track this as a legit NRG.
|
||||
if rg.node != nil {
|
||||
nrgMap[rg.Name] = struct{}{}
|
||||
}
|
||||
}
|
||||
// Register our meta.
|
||||
js.mu.RLock()
|
||||
meta := cc.meta
|
||||
if meta == nil {
|
||||
js.mu.RUnlock()
|
||||
// Bail with no meta node.
|
||||
return
|
||||
}
|
||||
|
||||
ourID := meta.ID()
|
||||
nrgMap[meta.Group()] = struct{}{}
|
||||
|
||||
// Collect all valid groups from our assignments.
|
||||
for _, asa := range cc.streams {
|
||||
for _, sa := range asa {
|
||||
if sa.Group.isMember(ourID) && sa.Restore == nil {
|
||||
trackGroup(sa.Group)
|
||||
for _, ca := range sa.consumers {
|
||||
if ca.Group.isMember(ourID) {
|
||||
trackGroup(ca.Group)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
js.mu.RUnlock()
|
||||
|
||||
// Check NRGs that are running.
|
||||
var needDelete []RaftNode
|
||||
s.rnMu.RLock()
|
||||
for name, n := range s.raftNodes {
|
||||
if _, ok := nrgMap[name]; !ok {
|
||||
needDelete = append(needDelete, n)
|
||||
}
|
||||
}
|
||||
s.rnMu.RUnlock()
|
||||
|
||||
for _, n := range needDelete {
|
||||
s.Warnf("Detected orphaned NRG %q, will cleanup", n.Group())
|
||||
n.Delete()
|
||||
}
|
||||
}
|
||||
|
||||
func (js *jetStream) monitorCluster() {
|
||||
s, n := js.server(), js.getMetaGroup()
|
||||
qch, rqch, lch, aq := js.clusterQuitC(), n.QuitC(), n.LeadChangeC(), n.ApplyQ()
|
||||
@@ -1197,6 +1256,8 @@ func (js *jetStream) monitorCluster() {
|
||||
if hs := s.healthz(nil); hs.Error != _EMPTY_ {
|
||||
s.Warnf("%v", hs.Error)
|
||||
}
|
||||
// Also check for orphaned NRGs.
|
||||
s.checkForNRGOrphans()
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -1277,7 +1338,6 @@ func (js *jetStream) monitorCluster() {
|
||||
go checkHealth()
|
||||
continue
|
||||
}
|
||||
// FIXME(dlc) - Deal with errors.
|
||||
if didSnap, didStreamRemoval, didConsumerRemoval, err := js.applyMetaEntries(ce.Entries, ru); err == nil {
|
||||
_, nb := n.Applied(ce.Index)
|
||||
if js.hasPeerEntries(ce.Entries) || didStreamRemoval || (didSnap && !isLeader) {
|
||||
@@ -1288,6 +1348,8 @@ func (js *jetStream) monitorCluster() {
|
||||
doSnapshot()
|
||||
}
|
||||
ce.ReturnToPool()
|
||||
} else {
|
||||
s.Warnf("Error applying JetStream cluster entries: %v", err)
|
||||
}
|
||||
}
|
||||
aq.recycle(&ces)
|
||||
@@ -2037,6 +2099,15 @@ func (mset *stream) removeNode() {
|
||||
}
|
||||
}
|
||||
|
||||
func (mset *stream) clearRaftNode() {
|
||||
if mset == nil {
|
||||
return
|
||||
}
|
||||
mset.mu.Lock()
|
||||
defer mset.mu.Unlock()
|
||||
mset.node = nil
|
||||
}
|
||||
|
||||
// Helper function to generate peer info.
|
||||
// lists and sets for old and new.
|
||||
func genPeerInfo(peers []string, split int) (newPeers, oldPeers []string, newPeerSet, oldPeerSet map[string]bool) {
|
||||
|
||||
Reference in New Issue
Block a user