Skip to content

Commit 991962a

Browse files
authored
Merge pull request #1102 from percona/PBM-1512-fix-node-validation-mixed-deploy
PBM-1512: Unable to take physical backup in mixed deployments
2 parents 4aca65b + 27754a5 commit 991962a

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

pbm/topo/cluster.go

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package topo
22

33
import (
44
"context"
5+
"fmt"
56
"strings"
67

78
"go.mongodb.org/mongo-driver/bson"
@@ -120,6 +121,7 @@ func ClusterMembers(ctx context.Context, m *mongo.Client) ([]Shard, error) {
120121
return nil, errors.Wrap(err, "define cluster state")
121122
}
122123

124+
// sharded cluster topo
123125
var shards []Shard
124126
if inf.IsMongos() || inf.IsSharded() {
125127
members, err := getShardMapImpl(ctx, m)
@@ -135,10 +137,15 @@ func ClusterMembers(ctx context.Context, m *mongo.Client) ([]Shard, error) {
135137
return shards, nil
136138
}
137139

140+
// RS topo
141+
hosts, err := GetReplsetHosts(ctx, m)
142+
if err != nil {
143+
return nil, errors.Wrap(err, "get all hosts for RS")
144+
}
138145
shards = []Shard{{
139146
ID: inf.SetName,
140147
RS: inf.SetName,
141-
Host: inf.SetName + "/" + strings.Join(inf.Hosts, ","),
148+
Host: fmt.Sprintf("%s/%s", inf.SetName, strings.Join(hosts, ",")),
142149
}}
143150
return shards, nil
144151
}
@@ -153,18 +160,44 @@ func getShardMapImpl(ctx context.Context, m *mongo.Client) (map[ReplsetName]Shar
153160
// if shard name is not set, mongodb will provide unique name for it
154161
// (e.g. the replset name of the shard)
155162
// for configsvr, key name is "config"
156-
var shardMap struct{ Map map[string]string }
163+
// hosts field is used to discover hidden members, which are not present in map field
164+
var shardMap struct {
165+
Map map[string]string
166+
Hosts map[string]string
167+
}
157168
if err := res.Decode(&shardMap); err != nil {
158169
return nil, errors.Wrap(err, "decode")
159170
}
160171

172+
// Example of the hosts field from command output:
173+
// hosts: {
174+
// 'rs103:27017': 'rs1',
175+
// 'rs101:27017': 'rs1',
176+
// 'cfg02:27017': 'config',
177+
// ...
178+
// }
179+
// hostsByShard will contain even hidden RS members
180+
hostsByShard := map[string][]string{}
181+
for host, shardID := range shardMap.Hosts {
182+
hostsByShard[shardID] = append(hostsByShard[shardID], host)
183+
}
184+
185+
// for PSMDB 6 and below, config srv is not reported within hosts field
186+
if len(hostsByShard["config"]) == 0 {
187+
cfgHostgs, err := GetReplsetHosts(ctx, m)
188+
if err != nil {
189+
return nil, errors.Wrap(err, "get all hosts for config RS")
190+
}
191+
hostsByShard["config"] = cfgHostgs
192+
}
193+
161194
shards := make(map[string]Shard, len(shardMap.Map))
162195
for id, host := range shardMap.Map {
163196
rs, _, _ := strings.Cut(host, "/")
164197
shards[rs] = Shard{
165198
ID: id,
166199
RS: rs,
167-
Host: host,
200+
Host: fmt.Sprintf("%s/%s", rs, strings.Join(hostsByShard[id], ",")),
168201
}
169202
}
170203

pbm/topo/topo.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ func collectTopoCheckErrors(
110110
anyAvail := false
111111
for _, host := range hosts {
112112
a, ok := agents[host]
113-
if !ok || a.Arbiter || a.Passive {
113+
if !ok || a.Arbiter {
114114
continue
115115
}
116116

@@ -195,6 +195,21 @@ func GetReplsetStatus(ctx context.Context, m *mongo.Client) (*ReplsetStatus, err
195195
return status, nil
196196
}
197197

198+
// GetReplsetHosts returns host names for all RS members.
199+
// It includes also hidden and passive RS members.
200+
func GetReplsetHosts(ctx context.Context, m *mongo.Client) ([]string, error) {
201+
s, err := GetReplsetStatus(ctx, m)
202+
if err != nil {
203+
return nil, errors.Wrap(err, "get replset status")
204+
}
205+
206+
hosts := []string{}
207+
for _, m := range s.Members {
208+
hosts = append(hosts, m.Name)
209+
}
210+
return hosts, nil
211+
}
212+
198213
func GetNodeStatus(ctx context.Context, m *mongo.Client, name string) (*NodeStatus, error) {
199214
s, err := GetReplsetStatus(ctx, m)
200215
if err != nil {

0 commit comments

Comments
 (0)