Skip to content

Commit 7228b8b

Browse files
authored
Merge pull request #1311 from jcechace/PBM-1675-incompatible-bcps
PBM-1675 Fix backup compatibility checks
2 parents e0f1b99 + 94893e7 commit 7228b8b

4 files changed

Lines changed: 83 additions & 53 deletions

File tree

cmd/pbm/backup.go

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -577,25 +577,50 @@ func bcpsMatchCluster(
577577
ver string,
578578
fcv string,
579579
shards []topo.Shard,
580-
confsrv string,
581580
rsMap map[string]string,
582581
) {
583-
sh := make(map[string]bool, len(shards))
584-
for _, s := range shards {
585-
sh[s.RS] = s.RS == confsrv
586-
}
582+
sh := backupRequiredRSMap(shards)
587583

588584
mapRS, mapRevRS := util.MakeRSMapFunc(rsMap), util.MakeReverseRSMapFunc(rsMap)
589585
for i := 0; i < len(bcps); i++ {
590586
bcpMatchCluster(&bcps[i], ver, fcv, sh, mapRS, mapRevRS)
591587
}
592588
}
593589

590+
// backupRequiredRSMap marks the RS whose absence makes the backup incompatible:
591+
// the config RS for sharded clusters, or the sole RS otherwise.
592+
func backupRequiredRSMap(shards []topo.Shard) map[string]bool {
593+
sh := make(map[string]bool, len(shards))
594+
requiredRS := backupRequiredRSName(shards)
595+
596+
for _, s := range shards {
597+
sh[s.RS] = s.RS == requiredRS
598+
}
599+
600+
return sh
601+
}
602+
603+
// backupRequiredRSName returns the RS whose absence makes the backup incompatible:
604+
// the config RS for sharded clusters, or the sole RS otherwise.
605+
func backupRequiredRSName(shards []topo.Shard) string {
606+
if len(shards) == 1 {
607+
return shards[0].RS
608+
}
609+
610+
for _, s := range shards {
611+
if s.ID == "config" {
612+
return s.RS
613+
}
614+
}
615+
616+
return ""
617+
}
618+
594619
func bcpMatchCluster(
595620
bcp *backup.BackupMeta,
596621
ver string,
597622
fcv string,
598-
shards map[string]bool,
623+
rs map[string]bool,
599624
mapRS util.RSMapFunc,
600625
mapRevRS util.RSMapFunc,
601626
) {
@@ -618,26 +643,26 @@ func bcpMatchCluster(
618643
}
619644

620645
var nomatch []string
621-
hasconfsrv := false
646+
hasMandatoryRS := false
622647
for i := range bcp.Replsets {
623648
name := mapRS(bcp.Replsets[i].Name)
624649

625-
isconfsrv, ok := shards[name]
650+
isMandatoryRS, ok := rs[name]
626651
if !ok {
627652
nomatch = append(nomatch, name)
628653
} else if mapRevRS(name) != bcp.Replsets[i].Name {
629654
nomatch = append(nomatch, name)
630655
}
631656

632-
if isconfsrv {
633-
hasconfsrv = true
657+
if isMandatoryRS {
658+
hasMandatoryRS = true
634659
}
635660
}
636661

637-
if len(nomatch) != 0 || !hasconfsrv {
662+
if len(nomatch) != 0 || !hasMandatoryRS {
638663
names := make([]string, len(nomatch))
639664
copy(names, nomatch)
640-
bcp.SetRuntimeError(missedReplsetsError{names: names, configsrv: !hasconfsrv})
665+
bcp.SetRuntimeError(missedReplsetsError{names: names, configsrv: !hasMandatoryRS})
641666
}
642667
}
643668

cmd/pbm/backup_test.go

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,12 @@ func TestBcpMatchCluster(t *testing.T) {
2020
expect defs.Status
2121
}
2222
cases := []struct {
23-
confsrv string
24-
shards []topo.Shard
25-
bcps []bcase
23+
shards []topo.Shard
24+
bcps []bcase
2625
}{
2726
{
28-
confsrv: "config",
2927
shards: []topo.Shard{
30-
{RS: "config"},
28+
{ID: "config", RS: "config"},
3129
{RS: "rs1"},
3230
{RS: "rs2"},
3331
},
@@ -104,7 +102,6 @@ func TestBcpMatchCluster(t *testing.T) {
104102
},
105103
},
106104
{
107-
confsrv: "rs1",
108105
shards: []topo.Shard{
109106
{RS: "rs1"},
110107
},
@@ -171,7 +168,7 @@ func TestBcpMatchCluster(t *testing.T) {
171168
b.meta.Status = defs.StatusDone
172169
m = append(m, b.meta)
173170
}
174-
bcpsMatchCluster(m, "", "", c.shards, c.confsrv, nil)
171+
bcpsMatchCluster(m, "", "", c.shards, nil)
175172
for i := 0; i < len(c.bcps); i++ {
176173
if c.bcps[i].expect != m[i].Status {
177174
t.Errorf("wrong status for %s, expect %s, got %s", m[i].Name, c.bcps[i].expect, m[i].Status)
@@ -316,6 +313,31 @@ func TestBcpMatchRemappedCluster(t *testing.T) {
316313
}
317314
}
318315

316+
func TestBackupRequiredRSMap(t *testing.T) {
317+
t.Run("sharded cluster uses config shard rs", func(t *testing.T) {
318+
sh := backupRequiredRSMap([]topo.Shard{
319+
{ID: "config", RS: "cfg"},
320+
{ID: "rs1", RS: "rs1"},
321+
{ID: "rs2", RS: "rs2"},
322+
})
323+
324+
if !sh["cfg"] {
325+
t.Fatal("expected config RS to be marked as required")
326+
}
327+
if sh["rs1"] || sh["rs2"] {
328+
t.Fatal("expected only config RS to be marked as required")
329+
}
330+
})
331+
332+
t.Run("sole rs cluster uses only replset", func(t *testing.T) {
333+
sh := backupRequiredRSMap([]topo.Shard{{RS: "rs1"}})
334+
335+
if !sh["rs1"] {
336+
t.Fatal("expected sole RS to be marked as required")
337+
}
338+
})
339+
}
340+
319341
func checkBcpMatchClusterError(err, target error) string {
320342
if err == nil && target == nil {
321343
return ""
@@ -354,7 +376,7 @@ func checkBcpMatchClusterError(err, target error) string {
354376

355377
func BenchmarkBcpMatchCluster3x10(b *testing.B) {
356378
shards := []topo.Shard{
357-
{RS: "config"},
379+
{ID: "config", RS: "config"},
358380
{RS: "rs1"},
359381
{RS: "rs2"},
360382
}
@@ -374,13 +396,13 @@ func BenchmarkBcpMatchCluster3x10(b *testing.B) {
374396
}
375397
b.ResetTimer()
376398
for i := 0; i < b.N; i++ {
377-
bcpsMatchCluster(bcps, "", "", shards, "config", nil)
399+
bcpsMatchCluster(bcps, "", "", shards, nil)
378400
}
379401
}
380402

381403
func BenchmarkBcpMatchCluster3x100(b *testing.B) {
382404
shards := []topo.Shard{
383-
{RS: "config"},
405+
{ID: "config", RS: "config"},
384406
{RS: "rs1"},
385407
{RS: "rs2"},
386408
}
@@ -400,13 +422,13 @@ func BenchmarkBcpMatchCluster3x100(b *testing.B) {
400422
}
401423
b.ResetTimer()
402424
for i := 0; i < b.N; i++ {
403-
bcpsMatchCluster(bcps, "", "", shards, "config", nil)
425+
bcpsMatchCluster(bcps, "", "", shards, nil)
404426
}
405427
}
406428

407429
func BenchmarkBcpMatchCluster17x100(b *testing.B) {
408430
shards := []topo.Shard{
409-
{RS: "config"},
431+
{ID: "config", RS: "config"},
410432
{RS: "rs1"},
411433
{RS: "rs12"},
412434
{RS: "rs112"},
@@ -454,13 +476,13 @@ func BenchmarkBcpMatchCluster17x100(b *testing.B) {
454476
}
455477
b.ResetTimer()
456478
for i := 0; i < b.N; i++ {
457-
bcpsMatchCluster(bcps, "", "", shards, "config", nil)
479+
bcpsMatchCluster(bcps, "", "", shards, nil)
458480
}
459481
}
460482

461483
func BenchmarkBcpMatchCluster3x1000(b *testing.B) {
462484
shards := []topo.Shard{
463-
{RS: "config"},
485+
{ID: "config", RS: "config"},
464486
{RS: "rs1"},
465487
{RS: "rs2"},
466488
}
@@ -480,12 +502,12 @@ func BenchmarkBcpMatchCluster3x1000(b *testing.B) {
480502
}
481503
b.ResetTimer()
482504
for i := 0; i < b.N; i++ {
483-
bcpsMatchCluster(bcps, "", "", shards, "config", nil)
505+
bcpsMatchCluster(bcps, "", "", shards, nil)
484506
}
485507
}
486508

487509
func BenchmarkBcpMatchCluster1000x1000(b *testing.B) {
488-
shards := []topo.Shard{{RS: "config"}}
510+
shards := []topo.Shard{{ID: "config", RS: "config"}}
489511
rss := []backup.BackupReplset{{Name: "config"}}
490512

491513
for i := 0; i < 1000; i++ {
@@ -503,13 +525,13 @@ func BenchmarkBcpMatchCluster1000x1000(b *testing.B) {
503525
}
504526
b.ResetTimer()
505527
for i := 0; i < b.N; i++ {
506-
bcpsMatchCluster(bcps, "", "", shards, "config", nil)
528+
bcpsMatchCluster(bcps, "", "", shards, nil)
507529
}
508530
}
509531

510532
func BenchmarkBcpMatchCluster3x10Err(b *testing.B) {
511533
shards := []topo.Shard{
512-
{RS: "config"},
534+
{ID: "config", RS: "config"},
513535
{RS: "rs2"},
514536
}
515537

@@ -543,12 +565,12 @@ func BenchmarkBcpMatchCluster3x10Err(b *testing.B) {
543565
})
544566
}
545567
for i := 0; i < b.N; i++ {
546-
bcpsMatchCluster(bcps, "", "", shards, "config", nil)
568+
bcpsMatchCluster(bcps, "", "", shards, nil)
547569
}
548570
}
549571

550572
func BenchmarkBcpMatchCluster1000x1000Err(b *testing.B) {
551-
shards := []topo.Shard{{RS: "config"}}
573+
shards := []topo.Shard{{ID: "config", RS: "config"}}
552574
rss := []backup.BackupReplset{{Name: "config"}}
553575

554576
for i := 0; i < 1000; i++ {
@@ -567,6 +589,6 @@ func BenchmarkBcpMatchCluster1000x1000Err(b *testing.B) {
567589
}
568590
b.ResetTimer()
569591
for i := 0; i < b.N; i++ {
570-
bcpsMatchCluster(bcps, "", "", shards, "config", nil)
592+
bcpsMatchCluster(bcps, "", "", shards, nil)
571593
}
572594
}

cmd/pbm/list.go

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -338,11 +338,6 @@ func getSnapshotList(
338338
return nil, errors.Wrap(err, "get cluster members")
339339
}
340340

341-
inf, err := topo.GetNodeInfoExt(ctx, conn.MongoClient())
342-
if err != nil {
343-
return nil, errors.Wrap(err, "define cluster state")
344-
}
345-
346341
ver, err := version.GetMongoVersion(ctx, conn.MongoClient())
347342
if err != nil {
348343
return nil, errors.Wrap(err, "get mongo version")
@@ -352,9 +347,7 @@ func getSnapshotList(
352347
return nil, errors.Wrap(err, "get featureCompatibilityVersion")
353348
}
354349

355-
// PBM agent is always connected either to config server or to the sole (hence main) RS
356-
// which the `confsrv` param in `bcpMatchCluster` is all about
357-
bcpsMatchCluster(bcps, ver.VersionString, fcv, shards, inf.SetName, rsMap)
350+
bcpsMatchCluster(bcps, ver.VersionString, fcv, shards, rsMap)
358351

359352
var s []snapshotStat
360353
for i := len(bcps) - 1; i >= 0; i-- {
@@ -389,11 +382,6 @@ func getPitrList(
389382
unbacked bool,
390383
rsMap map[string]string,
391384
) ([]pitrRange, map[string][]pitrRange, error) {
392-
inf, err := topo.GetNodeInfoExt(ctx, conn.MongoClient())
393-
if err != nil {
394-
return nil, nil, errors.Wrap(err, "define cluster state")
395-
}
396-
397385
shards, err := topo.ClusterMembers(ctx, conn.MongoClient())
398386
if err != nil {
399387
return nil, nil, errors.Wrap(err, "get cluster members")
@@ -431,10 +419,7 @@ func getPitrList(
431419
rstlines = append(rstlines, tlns)
432420
}
433421

434-
sh := make(map[string]bool, len(shards))
435-
for _, s := range shards {
436-
sh[s.RS] = s.RS == inf.SetName
437-
}
422+
sh := backupRequiredRSMap(shards)
438423

439424
ranges := []pitrRange{}
440425
for _, tl := range oplog.MergeTimelines(rstlines...) {

cmd/pbm/status.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -601,9 +601,7 @@ func getStorageStat(
601601
return s, errors.Wrap(err, "get cluster members")
602602
}
603603

604-
// pbm.PBM is always connected either to config server or to the sole (hence main) RS
605-
// which the `confsrv` param in `bcpMatchCluster` is all about
606-
bcpsMatchCluster(bcps, ver.VersionString, fcv, shards, inf.SetName, rsMap)
604+
bcpsMatchCluster(bcps, ver.VersionString, fcv, shards, rsMap)
607605

608606
stg, err := util.GetStorage(ctx, conn, inf.Me,
609607
log.FromContext(ctx).NewEvent("", "", "", primitive.Timestamp{}))

0 commit comments

Comments
 (0)