github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/kv/kvserver/addressing.go (about) 1 // Copyright 2014 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package kvserver 12 13 import ( 14 "bytes" 15 16 "github.com/cockroachdb/cockroach/pkg/keys" 17 "github.com/cockroachdb/cockroach/pkg/kv" 18 "github.com/cockroachdb/cockroach/pkg/roachpb" 19 "github.com/cockroachdb/errors" 20 ) 21 22 type metaAction func(*kv.Batch, roachpb.Key, *roachpb.RangeDescriptor) 23 24 func putMeta(b *kv.Batch, key roachpb.Key, desc *roachpb.RangeDescriptor) { 25 b.Put(key, desc) 26 } 27 28 func delMeta(b *kv.Batch, key roachpb.Key, desc *roachpb.RangeDescriptor) { 29 b.Del(key) 30 } 31 32 // splitRangeAddressing creates (or overwrites if necessary) the meta1 33 // and meta2 range addressing records for the left and right ranges 34 // caused by a split. 35 func splitRangeAddressing(b *kv.Batch, left, right *roachpb.RangeDescriptor) error { 36 if err := rangeAddressing(b, left, putMeta); err != nil { 37 return err 38 } 39 return rangeAddressing(b, right, putMeta) 40 } 41 42 // mergeRangeAddressing removes subsumed meta1 and meta2 range 43 // addressing records caused by merging and updates the records for 44 // the new merged range. Left is the range descriptor for the "left" 45 // range before merging and merged describes the left to right merge. 46 func mergeRangeAddressing(b *kv.Batch, left, merged *roachpb.RangeDescriptor) error { 47 if err := rangeAddressing(b, left, delMeta); err != nil { 48 return err 49 } 50 return rangeAddressing(b, merged, putMeta) 51 } 52 53 // updateRangeAddressing overwrites the meta1 and meta2 range addressing 54 // records for the descriptor. 55 func updateRangeAddressing(b *kv.Batch, desc *roachpb.RangeDescriptor) error { 56 return rangeAddressing(b, desc, putMeta) 57 } 58 59 // rangeAddressing updates or deletes the range addressing metadata 60 // for the range specified by desc. The action to take is specified by 61 // the supplied metaAction function. 62 // 63 // The rules for meta1 and meta2 records are as follows: 64 // 65 // 1. If desc.StartKey or desc.EndKey is meta1: 66 // - ERROR 67 // 2. If desc.EndKey is meta2: 68 // - meta1(desc.EndKey) 69 // 3. If desc.EndKey is normal user key: 70 // - meta2(desc.EndKey) 71 // 3a. If desc.StartKey is not normal user key: 72 // - meta1(KeyMax) 73 func rangeAddressing(b *kv.Batch, desc *roachpb.RangeDescriptor, action metaAction) error { 74 // 1. handle illegal case of start or end key being meta1. 75 if bytes.HasPrefix(desc.EndKey, keys.Meta1Prefix) || 76 bytes.HasPrefix(desc.StartKey, keys.Meta1Prefix) { 77 return errors.Errorf("meta1 addressing records cannot be split: %+v", desc) 78 } 79 80 // Note that both cases 2 and 3 are handled by keys.RangeMetaKey. 81 // 82 // 2. the case of the range ending with a meta2 prefix. This means 83 // the range is full of meta2. We must update the relevant meta1 84 // entry pointing to the end of this range. 85 // 86 // 3. the range ends with a normal user key, so we must update the 87 // relevant meta2 entry pointing to the end of this range. 88 action(b, keys.RangeMetaKey(desc.EndKey).AsRawKey(), desc) 89 90 if bytes.Compare(desc.StartKey, keys.MetaMax) < 0 && 91 bytes.Compare(desc.EndKey, keys.MetaMax) >= 0 { 92 // 3a. the range spans meta2 and user keys, update the meta1 93 // entry for KeyMax. We do this to prevent the 3 levels of 94 // descriptor indirection described in #18998. 95 action(b, keys.Meta1KeyMax, desc) 96 } 97 return nil 98 }