Skip to content

Commit f004f79

Browse files
vitess-bot[bot]Jun Wangajm188
authored
[release-18.0] increase vtctlclient backupShard command success rate (#14604) (#14639)
Signed-off-by: Jun Wang <jun.wang@demonware.net> Signed-off-by: jwangace <121262788+jwangace@users.noreply.github.com> Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Jun Wang <jun.wang@demonware.net> Co-authored-by: Andrew Mason <amason@hey.com>
1 parent a37b7dd commit f004f79

File tree

3 files changed

+121
-1
lines changed

3 files changed

+121
-1
lines changed

go/vt/vtctl/grpcvtctldserver/server.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,8 +431,14 @@ func (s *VtctldServer) BackupShard(req *vtctldatapb.BackupShardRequest, stream v
431431
span.Annotate("incremental_from_pos", req.IncrementalFromPos)
432432

433433
tablets, stats, err := reparentutil.ShardReplicationStatuses(ctx, s.ts, s.tmc, req.Keyspace, req.Shard)
434+
435+
// Instead of return on err directly, only return err when no tablets for backup at all
434436
if err != nil {
435-
return err
437+
tablets = reparentutil.GetBackupCandidates(tablets, stats)
438+
// Only return err when no usable tablet
439+
if len(tablets) == 0 {
440+
return err
441+
}
436442
}
437443

438444
var (

go/vt/vtctl/reparentutil/util.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,3 +343,15 @@ func waitForCatchUp(
343343
}
344344
return nil
345345
}
346+
347+
// GetBackupCandidates is used to get a list of healthy tablets for backup
348+
func GetBackupCandidates(tablets []*topo.TabletInfo, stats []*replicationdatapb.Status) (res []*topo.TabletInfo) {
349+
for i, stat := range stats {
350+
// shardTablets[i] and stats[i] is 1:1 mapping
351+
// Always include TabletType_PRIMARY. Healthy shardTablets[i] will be added to tablets
352+
if tablets[i].Type == topodatapb.TabletType_PRIMARY || stat != nil {
353+
res = append(res, tablets[i])
354+
}
355+
}
356+
return res
357+
}

go/vt/vtctl/reparentutil/util_test.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,3 +1218,105 @@ func Test_getTabletsWithPromotionRules(t *testing.T) {
12181218
})
12191219
}
12201220
}
1221+
1222+
func TestGetBackupCandidates(t *testing.T) {
1223+
var (
1224+
primaryTablet = &topo.TabletInfo{
1225+
Tablet: &topodatapb.Tablet{
1226+
Alias: &topodatapb.TabletAlias{
1227+
Cell: "zone1",
1228+
Uid: 1,
1229+
},
1230+
Type: topodatapb.TabletType_PRIMARY,
1231+
},
1232+
}
1233+
replicaTablet = &topo.TabletInfo{
1234+
Tablet: &topodatapb.Tablet{
1235+
Alias: &topodatapb.TabletAlias{
1236+
Cell: "zone1",
1237+
Uid: 2,
1238+
},
1239+
Type: topodatapb.TabletType_REPLICA,
1240+
},
1241+
}
1242+
rdonlyTablet = &topo.TabletInfo{
1243+
Tablet: &topodatapb.Tablet{
1244+
Alias: &topodatapb.TabletAlias{
1245+
Cell: "zone1",
1246+
Uid: 3,
1247+
},
1248+
Type: topodatapb.TabletType_RDONLY,
1249+
},
1250+
}
1251+
spareTablet = &topo.TabletInfo{
1252+
Tablet: &topodatapb.Tablet{
1253+
Alias: &topodatapb.TabletAlias{
1254+
Cell: "zone1",
1255+
Uid: 4,
1256+
},
1257+
Type: topodatapb.TabletType_SPARE,
1258+
},
1259+
}
1260+
)
1261+
tests := []struct {
1262+
name string
1263+
in []*topo.TabletInfo
1264+
expected []*topo.TabletInfo
1265+
status []*replicationdatapb.Status
1266+
}{
1267+
{
1268+
name: "one primary tablet with status",
1269+
in: []*topo.TabletInfo{primaryTablet},
1270+
expected: []*topo.TabletInfo{primaryTablet},
1271+
status: []*replicationdatapb.Status{{}},
1272+
},
1273+
{
1274+
name: "one primary tablet with no status",
1275+
in: []*topo.TabletInfo{primaryTablet},
1276+
expected: []*topo.TabletInfo{primaryTablet},
1277+
status: []*replicationdatapb.Status{nil},
1278+
},
1279+
{
1280+
name: "4 tablets with no status",
1281+
in: []*topo.TabletInfo{primaryTablet, replicaTablet, rdonlyTablet, spareTablet},
1282+
expected: []*topo.TabletInfo{primaryTablet},
1283+
status: []*replicationdatapb.Status{nil, nil, nil, nil},
1284+
},
1285+
{
1286+
name: "4 tablets with full status",
1287+
in: []*topo.TabletInfo{primaryTablet, replicaTablet, rdonlyTablet, spareTablet},
1288+
expected: []*topo.TabletInfo{primaryTablet, replicaTablet, rdonlyTablet, spareTablet},
1289+
status: []*replicationdatapb.Status{{}, {}, {}, {}},
1290+
},
1291+
{
1292+
name: "4 tablets with no primaryTablet status",
1293+
in: []*topo.TabletInfo{primaryTablet, replicaTablet, rdonlyTablet, spareTablet},
1294+
expected: []*topo.TabletInfo{primaryTablet, replicaTablet, rdonlyTablet, spareTablet},
1295+
status: []*replicationdatapb.Status{nil, {}, {}, {}},
1296+
},
1297+
{
1298+
name: "4 tablets with no replicaTablet status",
1299+
in: []*topo.TabletInfo{primaryTablet, replicaTablet, rdonlyTablet, spareTablet},
1300+
expected: []*topo.TabletInfo{primaryTablet, rdonlyTablet, spareTablet},
1301+
status: []*replicationdatapb.Status{{}, nil, {}, {}},
1302+
},
1303+
{
1304+
name: "4 tablets with no rdonlyTablet status",
1305+
in: []*topo.TabletInfo{primaryTablet, replicaTablet, rdonlyTablet, spareTablet},
1306+
expected: []*topo.TabletInfo{primaryTablet, replicaTablet, spareTablet},
1307+
status: []*replicationdatapb.Status{{}, {}, nil, {}},
1308+
},
1309+
{
1310+
name: "4 tablets with no spareTablet status",
1311+
in: []*topo.TabletInfo{primaryTablet, replicaTablet, rdonlyTablet, spareTablet},
1312+
expected: []*topo.TabletInfo{primaryTablet, replicaTablet, rdonlyTablet},
1313+
status: []*replicationdatapb.Status{{}, {}, {}, nil},
1314+
},
1315+
}
1316+
for _, tt := range tests {
1317+
t.Run(tt.name, func(t *testing.T) {
1318+
res := GetBackupCandidates(tt.in, tt.status)
1319+
require.EqualValues(t, tt.expected, res)
1320+
})
1321+
}
1322+
}

0 commit comments

Comments
 (0)