diff --git a/pkg/storage/mvcc.go b/pkg/storage/mvcc.go index 153fddab0174..f01d9a69540b 100644 --- a/pkg/storage/mvcc.go +++ b/pkg/storage/mvcc.go @@ -5496,10 +5496,16 @@ func mvccMinSplitKey(it MVCCIterator, startKey roachpb.Key) (roachpb.Key, error) // 4. Not in between the start and end of a row for table ranges. // // The returned split key is NOT guaranteed to be outside a no-split span, such -// as Meta1, Meta2Max or Node Liveness. +// as Meta2Max or Node Liveness. func MVCCFirstSplitKey( _ context.Context, reader Reader, desiredSplitKey, startKey, endKey roachpb.RKey, ) (roachpb.Key, error) { + // If the start key of the range is within the meta1 key space, the range + // cannot be split. + if startKey.Less(roachpb.RKey(keys.LocalMax)) { + return nil, nil + } + it := reader.NewMVCCIterator(MVCCKeyAndIntentsIterKind, IterOptions{UpperBound: endKey.AsRawKey()}) defer it.Close() diff --git a/pkg/storage/mvcc_test.go b/pkg/storage/mvcc_test.go index 102d578a6e47..427a4cd0cb7a 100644 --- a/pkg/storage/mvcc_test.go +++ b/pkg/storage/mvcc_test.go @@ -4530,6 +4530,25 @@ func TestMVCCFirstSplitKey(t *testing.T) { {desired: roachpb.Key("z"), expected: nil}, }, }, + { + // meta1 cannot be split. Previously, this test would cause a panic in + // mvccMinSplitKey, called by MVCCFirstSplitKey. The iterator is + // initialized with a global key constraint from the endKey + // ("\x02\xff\xff"), but we seekGE the start key (MinKey="") which is + // local because it is before LocalMax (0x02). + keys: []roachpb.Key{ + roachpb.Key("\x02"), + roachpb.Key("\x02\x00"), + roachpb.Key("\x02\xff"), + }, + startKey: keys.MinKey, + endKey: keys.Meta1KeyMax, + splits: []splitExpect{ + {desired: keys.MinKey, expected: nil}, + {desired: roachpb.Key("\x02"), expected: nil}, + {desired: roachpb.Key("\x02\x00"), expected: nil}, + }, + }, { // All keys are outside the range, no keys to spit at so expect no // splits. @@ -4581,6 +4600,7 @@ func TestMVCCFirstSplitKey(t *testing.T) { {desired: roachpb.Key("0"), expected: roachpb.Key("c")}, {desired: roachpb.Key("b"), expected: roachpb.Key("c")}, {desired: roachpb.Key("c"), expected: roachpb.Key("c")}, + {desired: keys.MinKey, expected: roachpb.Key("c")}, // Desired split key is after the last key in the range (c), shouldn't // split. {desired: roachpb.Key("d"), expected: nil},