Skip to content

Commit

Permalink
[release-20.0] Tablet picker: Handle the case where a primary tablet …
Browse files Browse the repository at this point in the history
…is not setup for a shard (#17573) (#17575)

Signed-off-by: Rohit Nayak <rohit@planetscale.com>
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Rohit Nayak <rohit@planetscale.com>
  • Loading branch information
vitess-bot[bot] and rohit-nayak-ps authored Jan 19, 2025
1 parent be08a65 commit 30e7c9e
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 2 deletions.
12 changes: 10 additions & 2 deletions go/vt/discovery/tablet_picker.go
Original file line number Diff line number Diff line change
Expand Up @@ -388,8 +388,13 @@ func (tp *TabletPicker) GetMatchingTablets(ctx context.Context) []*topo.TabletIn
log.Errorf("Error getting shard %s/%s: %v", tp.keyspace, tp.shard, err)
return nil
}
if _, ignore := tp.ignoreTablets[si.PrimaryAlias.String()]; !ignore {
aliases = append(aliases, si.PrimaryAlias)

// It is possible that there is a cluster event (ERS/PRS, for example) due to which
// there is no primary elected for the shard at the moment.
if si.PrimaryAlias != nil {
if _, ignore := tp.ignoreTablets[si.PrimaryAlias.String()]; !ignore {
aliases = append(aliases, si.PrimaryAlias)
}
}
} else {
actualCells := make([]string, 0)
Expand Down Expand Up @@ -426,6 +431,9 @@ func (tp *TabletPicker) GetMatchingTablets(ctx context.Context) []*topo.TabletIn
continue
}
for _, node := range sri.Nodes {
if node.TabletAlias == nil {
continue
}
if _, ignore := tp.ignoreTablets[node.TabletAlias.String()]; !ignore {
aliases = append(aliases, node.TabletAlias)
}
Expand Down
23 changes: 23 additions & 0 deletions go/vt/discovery/tablet_picker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,29 @@ func TestPickPrimary(t *testing.T) {
assert.True(t, proto.Equal(want, tablet), "Pick: %v, want %v", tablet, want)
}

// TestPickNoPrimary confirms that if the picker was setup only for primary tablets but
// there is no primary setup for the shard we correctly return an error.
func TestPickNoPrimary(t *testing.T) {
defer utils.EnsureNoLeaks(t)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

te := newPickerTestEnv(t, ctx, []string{"cell", "otherCell"})
want := addTablet(ctx, te, 100, topodatapb.TabletType_PRIMARY, "cell", true, true)
defer deleteTablet(t, te, want)
_, err := te.topoServ.UpdateShardFields(ctx, te.keyspace, te.shard, func(si *topo.ShardInfo) error {
si.PrimaryAlias = nil // force a missing primary
return nil
})
require.NoError(t, err)

tp, err := NewTabletPicker(ctx, te.topoServ, []string{"otherCell"}, "cell", te.keyspace, te.shard, "primary", TabletPickerOptions{})
require.NoError(t, err)

_, err = tp.PickForStreaming(ctx)
require.Errorf(t, err, "No healthy serving tablet")
}

func TestPickLocalPreferences(t *testing.T) {
defer utils.EnsureNoLeaks(t)
type tablet struct {
Expand Down
3 changes: 3 additions & 0 deletions go/vt/topo/tablet.go
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,9 @@ func (ts *Server) GetTabletMap(ctx context.Context, tabletAliases []*topodatapb.
var sem = semaphore.NewWeighted(int64(concurrency))

for _, tabletAlias := range tabletAliases {
if tabletAlias == nil {
return nil, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "nil tablet alias in list")
}
wg.Add(1)
go func(tabletAlias *topodatapb.TabletAlias) {
defer wg.Done()
Expand Down

0 comments on commit 30e7c9e

Please sign in to comment.