github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/keys/keys.go (about) 1 // Copyright 2015 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 keys 12 13 import ( 14 "bytes" 15 "fmt" 16 17 "github.com/cockroachdb/cockroach/pkg/roachpb" 18 "github.com/cockroachdb/cockroach/pkg/util/encoding" 19 "github.com/cockroachdb/cockroach/pkg/util/uuid" 20 "github.com/cockroachdb/errors" 21 ) 22 23 func makeKey(keys ...[]byte) []byte { 24 return bytes.Join(keys, nil) 25 } 26 27 // MakeStoreKey creates a store-local key based on the metadata key 28 // suffix, and optional detail. 29 func MakeStoreKey(suffix, detail roachpb.RKey) roachpb.Key { 30 key := make(roachpb.Key, 0, len(localStorePrefix)+len(suffix)+len(detail)) 31 key = append(key, localStorePrefix...) 32 key = append(key, suffix...) 33 key = append(key, detail...) 34 return key 35 } 36 37 // DecodeStoreKey returns the suffix and detail portions of a local 38 // store key. 39 func DecodeStoreKey(key roachpb.Key) (suffix, detail roachpb.RKey, err error) { 40 if !bytes.HasPrefix(key, localStorePrefix) { 41 return nil, nil, errors.Errorf("key %s does not have %s prefix", key, localStorePrefix) 42 } 43 // Cut the prefix, the Range ID, and the infix specifier. 44 key = key[len(localStorePrefix):] 45 if len(key) < localSuffixLength { 46 return nil, nil, errors.Errorf("malformed key does not contain local store suffix") 47 } 48 suffix = roachpb.RKey(key[:localSuffixLength]) 49 detail = roachpb.RKey(key[localSuffixLength:]) 50 return suffix, detail, nil 51 } 52 53 // StoreIdentKey returns a store-local key for the store metadata. 54 func StoreIdentKey() roachpb.Key { 55 return MakeStoreKey(localStoreIdentSuffix, nil) 56 } 57 58 // StoreGossipKey returns a store-local key for the gossip bootstrap metadata. 59 func StoreGossipKey() roachpb.Key { 60 return MakeStoreKey(localStoreGossipSuffix, nil) 61 } 62 63 // StoreClusterVersionKey returns a store-local key for the cluster version. 64 func StoreClusterVersionKey() roachpb.Key { 65 return MakeStoreKey(localStoreClusterVersionSuffix, nil) 66 } 67 68 // StoreLastUpKey returns the key for the store's "last up" timestamp. 69 func StoreLastUpKey() roachpb.Key { 70 return MakeStoreKey(localStoreLastUpSuffix, nil) 71 } 72 73 // StoreHLCUpperBoundKey returns the store-local key for storing an upper bound 74 // to the wall time used by HLC. 75 func StoreHLCUpperBoundKey() roachpb.Key { 76 return MakeStoreKey(localStoreHLCUpperBoundSuffix, nil) 77 } 78 79 // StoreSuggestedCompactionKey returns a store-local key for a 80 // suggested compaction. It combines the specified start and end keys. 81 func StoreSuggestedCompactionKey(start, end roachpb.Key) roachpb.Key { 82 var detail roachpb.RKey 83 detail = encoding.EncodeBytesAscending(detail, start) 84 detail = encoding.EncodeBytesAscending(detail, end) 85 return MakeStoreKey(localStoreSuggestedCompactionSuffix, detail) 86 } 87 88 // DecodeStoreSuggestedCompactionKey returns the start and end keys of 89 // the suggested compaction's span. 90 func DecodeStoreSuggestedCompactionKey(key roachpb.Key) (start, end roachpb.Key, err error) { 91 var suffix, detail roachpb.RKey 92 suffix, detail, err = DecodeStoreKey(key) 93 if err != nil { 94 return nil, nil, err 95 } 96 if !suffix.Equal(localStoreSuggestedCompactionSuffix) { 97 return nil, nil, errors.Errorf("key with suffix %q != %q", suffix, localStoreSuggestedCompactionSuffix) 98 } 99 detail, start, err = encoding.DecodeBytesAscending(detail, nil) 100 if err != nil { 101 return nil, nil, err 102 } 103 detail, end, err = encoding.DecodeBytesAscending(detail, nil) 104 if err != nil { 105 return nil, nil, err 106 } 107 if len(detail) != 0 { 108 return nil, nil, errors.Errorf("invalid key has trailing garbage: %q", detail) 109 } 110 return start, end, nil 111 } 112 113 // NodeLivenessKey returns the key for the node liveness record. 114 func NodeLivenessKey(nodeID roachpb.NodeID) roachpb.Key { 115 key := make(roachpb.Key, 0, len(NodeLivenessPrefix)+9) 116 key = append(key, NodeLivenessPrefix...) 117 key = encoding.EncodeUvarintAscending(key, uint64(nodeID)) 118 return key 119 } 120 121 // NodeStatusKey returns the key for accessing the node status for the 122 // specified node ID. 123 func NodeStatusKey(nodeID roachpb.NodeID) roachpb.Key { 124 key := make(roachpb.Key, 0, len(StatusNodePrefix)+9) 125 key = append(key, StatusNodePrefix...) 126 key = encoding.EncodeUvarintAscending(key, uint64(nodeID)) 127 return key 128 } 129 130 func makePrefixWithRangeID(prefix []byte, rangeID roachpb.RangeID, infix roachpb.RKey) roachpb.Key { 131 // Size the key buffer so that it is large enough for most callers. 132 key := make(roachpb.Key, 0, 32) 133 key = append(key, prefix...) 134 key = encoding.EncodeUvarintAscending(key, uint64(rangeID)) 135 key = append(key, infix...) 136 return key 137 } 138 139 // MakeRangeIDPrefix creates a range-local key prefix from 140 // rangeID for both replicated and unreplicated data. 141 func MakeRangeIDPrefix(rangeID roachpb.RangeID) roachpb.Key { 142 return makePrefixWithRangeID(LocalRangeIDPrefix, rangeID, nil) 143 } 144 145 // MakeRangeIDReplicatedPrefix creates a range-local key prefix from 146 // rangeID for all Raft replicated data. 147 func MakeRangeIDReplicatedPrefix(rangeID roachpb.RangeID) roachpb.Key { 148 return makePrefixWithRangeID(LocalRangeIDPrefix, rangeID, LocalRangeIDReplicatedInfix) 149 } 150 151 // makeRangeIDReplicatedKey creates a range-local key based on the range's 152 // Range ID, metadata key suffix, and optional detail. 153 func makeRangeIDReplicatedKey(rangeID roachpb.RangeID, suffix, detail roachpb.RKey) roachpb.Key { 154 if len(suffix) != localSuffixLength { 155 panic(fmt.Sprintf("suffix len(%q) != %d", suffix, localSuffixLength)) 156 } 157 158 key := MakeRangeIDReplicatedPrefix(rangeID) 159 key = append(key, suffix...) 160 key = append(key, detail...) 161 return key 162 } 163 164 // DecodeRangeIDKey parses a local range ID key into range ID, infix, 165 // suffix, and detail. 166 func DecodeRangeIDKey( 167 key roachpb.Key, 168 ) (rangeID roachpb.RangeID, infix, suffix, detail roachpb.Key, err error) { 169 if !bytes.HasPrefix(key, LocalRangeIDPrefix) { 170 return 0, nil, nil, nil, errors.Errorf("key %s does not have %s prefix", key, LocalRangeIDPrefix) 171 } 172 // Cut the prefix, the Range ID, and the infix specifier. 173 b := key[len(LocalRangeIDPrefix):] 174 b, rangeInt, err := encoding.DecodeUvarintAscending(b) 175 if err != nil { 176 return 0, nil, nil, nil, err 177 } 178 if len(b) < localSuffixLength+1 { 179 return 0, nil, nil, nil, errors.Errorf("malformed key does not contain range ID infix and suffix") 180 } 181 infix = b[:1] 182 b = b[1:] 183 suffix = b[:localSuffixLength] 184 b = b[localSuffixLength:] 185 186 return roachpb.RangeID(rangeInt), infix, suffix, b, nil 187 } 188 189 // AbortSpanKey returns a range-local key by Range ID for an 190 // AbortSpan entry, with detail specified by encoding the 191 // supplied transaction ID. 192 func AbortSpanKey(rangeID roachpb.RangeID, txnID uuid.UUID) roachpb.Key { 193 return MakeRangeIDPrefixBuf(rangeID).AbortSpanKey(txnID) 194 } 195 196 // DecodeAbortSpanKey decodes the provided AbortSpan entry, 197 // returning the transaction ID. 198 func DecodeAbortSpanKey(key roachpb.Key, dest []byte) (uuid.UUID, error) { 199 _, _, suffix, detail, err := DecodeRangeIDKey(key) 200 if err != nil { 201 return uuid.UUID{}, err 202 } 203 if !bytes.Equal(suffix, LocalAbortSpanSuffix) { 204 return uuid.UUID{}, errors.Errorf("key %s does not contain the AbortSpan suffix %s", 205 key, LocalAbortSpanSuffix) 206 } 207 // Decode the id. 208 detail, idBytes, err := encoding.DecodeBytesAscending(detail, dest) 209 if err != nil { 210 return uuid.UUID{}, err 211 } 212 if len(detail) > 0 { 213 return uuid.UUID{}, errors.Errorf("key %q has leftover bytes after decode: %s; indicates corrupt key", key, detail) 214 } 215 txnID, err := uuid.FromBytes(idBytes) 216 return txnID, err 217 } 218 219 // RangeAppliedStateKey returns a system-local key for the range applied state key. 220 // This key has subsumed the responsibility of the following three keys: 221 // - RaftAppliedIndexLegacyKey 222 // - LeaseAppliedIndexLegacyKey 223 // - RangeStatsLegacyKey 224 func RangeAppliedStateKey(rangeID roachpb.RangeID) roachpb.Key { 225 return MakeRangeIDPrefixBuf(rangeID).RangeAppliedStateKey() 226 } 227 228 // RaftAppliedIndexLegacyKey returns a system-local key for a raft applied index. 229 // The key is no longer written to. Its responsibility has been subsumed by the 230 // RangeAppliedStateKey. 231 func RaftAppliedIndexLegacyKey(rangeID roachpb.RangeID) roachpb.Key { 232 return MakeRangeIDPrefixBuf(rangeID).RaftAppliedIndexLegacyKey() 233 } 234 235 // LeaseAppliedIndexLegacyKey returns a system-local key for a lease applied index. 236 // The key is no longer written to. Its responsibility has been subsumed by the 237 // RangeAppliedStateKey. 238 func LeaseAppliedIndexLegacyKey(rangeID roachpb.RangeID) roachpb.Key { 239 return MakeRangeIDPrefixBuf(rangeID).LeaseAppliedIndexLegacyKey() 240 } 241 242 // RaftTruncatedStateLegacyKey returns a system-local key for a RaftTruncatedState. 243 // See VersionUnreplicatedRaftTruncatedState. 244 func RaftTruncatedStateLegacyKey(rangeID roachpb.RangeID) roachpb.Key { 245 return MakeRangeIDPrefixBuf(rangeID).RaftTruncatedStateLegacyKey() 246 } 247 248 // RangeLeaseKey returns a system-local key for a range lease. 249 func RangeLeaseKey(rangeID roachpb.RangeID) roachpb.Key { 250 return MakeRangeIDPrefixBuf(rangeID).RangeLeaseKey() 251 } 252 253 // RangeStatsLegacyKey returns the key for accessing the MVCCStats struct for 254 // the specified Range ID. The key is no longer written to. Its responsibility 255 // has been subsumed by the RangeAppliedStateKey. 256 func RangeStatsLegacyKey(rangeID roachpb.RangeID) roachpb.Key { 257 return MakeRangeIDPrefixBuf(rangeID).RangeStatsLegacyKey() 258 } 259 260 // RangeLastGCKey returns a system-local key for last used GC threshold on the 261 // user keyspace. Reads and writes <= this timestamp will not be served. 262 // 263 // TODO(tschottdorf): should be renamed to RangeGCThresholdKey. 264 func RangeLastGCKey(rangeID roachpb.RangeID) roachpb.Key { 265 return MakeRangeIDPrefixBuf(rangeID).RangeLastGCKey() 266 } 267 268 // MakeRangeIDUnreplicatedPrefix creates a range-local key prefix from 269 // rangeID for all unreplicated data. 270 func MakeRangeIDUnreplicatedPrefix(rangeID roachpb.RangeID) roachpb.Key { 271 return makePrefixWithRangeID(LocalRangeIDPrefix, rangeID, localRangeIDUnreplicatedInfix) 272 } 273 274 // makeRangeIDUnreplicatedKey creates a range-local unreplicated key based 275 // on the range's Range ID, metadata key suffix, and optional detail. 276 func makeRangeIDUnreplicatedKey( 277 rangeID roachpb.RangeID, suffix roachpb.RKey, detail roachpb.RKey, 278 ) roachpb.Key { 279 if len(suffix) != localSuffixLength { 280 panic(fmt.Sprintf("suffix len(%q) != %d", suffix, localSuffixLength)) 281 } 282 283 key := MakeRangeIDUnreplicatedPrefix(rangeID) 284 key = append(key, suffix...) 285 key = append(key, detail...) 286 return key 287 } 288 289 // RangeTombstoneKey returns a system-local key for a range tombstone. 290 func RangeTombstoneKey(rangeID roachpb.RangeID) roachpb.Key { 291 return MakeRangeIDPrefixBuf(rangeID).RangeTombstoneKey() 292 } 293 294 // RaftTruncatedStateKey returns a system-local key for a RaftTruncatedState. 295 func RaftTruncatedStateKey(rangeID roachpb.RangeID) roachpb.Key { 296 return MakeRangeIDPrefixBuf(rangeID).RaftTruncatedStateKey() 297 } 298 299 // RaftHardStateKey returns a system-local key for a Raft HardState. 300 func RaftHardStateKey(rangeID roachpb.RangeID) roachpb.Key { 301 return MakeRangeIDPrefixBuf(rangeID).RaftHardStateKey() 302 } 303 304 // RaftLogPrefix returns the system-local prefix shared by all Entries 305 // in a Raft log. 306 func RaftLogPrefix(rangeID roachpb.RangeID) roachpb.Key { 307 return MakeRangeIDPrefixBuf(rangeID).RaftLogPrefix() 308 } 309 310 // RaftLogKey returns a system-local key for a Raft log entry. 311 func RaftLogKey(rangeID roachpb.RangeID, logIndex uint64) roachpb.Key { 312 return MakeRangeIDPrefixBuf(rangeID).RaftLogKey(logIndex) 313 } 314 315 // RangeLastReplicaGCTimestampKey returns a range-local key for 316 // the range's last replica GC timestamp. 317 func RangeLastReplicaGCTimestampKey(rangeID roachpb.RangeID) roachpb.Key { 318 return MakeRangeIDPrefixBuf(rangeID).RangeLastReplicaGCTimestampKey() 319 } 320 321 // MakeRangeKey creates a range-local key based on the range 322 // start key, metadata key suffix, and optional detail (e.g. the 323 // transaction ID for a txn record, etc.). 324 func MakeRangeKey(key, suffix, detail roachpb.RKey) roachpb.Key { 325 if len(suffix) != localSuffixLength { 326 panic(fmt.Sprintf("suffix len(%q) != %d", suffix, localSuffixLength)) 327 } 328 buf := MakeRangeKeyPrefix(key) 329 buf = append(buf, suffix...) 330 buf = append(buf, detail...) 331 return buf 332 } 333 334 // MakeRangeKeyPrefix creates a key prefix under which all range-local keys 335 // can be found. 336 func MakeRangeKeyPrefix(key roachpb.RKey) roachpb.Key { 337 buf := make(roachpb.Key, 0, len(LocalRangePrefix)+len(key)+1) 338 buf = append(buf, LocalRangePrefix...) 339 buf = encoding.EncodeBytesAscending(buf, key) 340 return buf 341 } 342 343 // DecodeRangeKey decodes the range key into range start key, 344 // suffix and optional detail (may be nil). 345 func DecodeRangeKey(key roachpb.Key) (startKey, suffix, detail roachpb.Key, err error) { 346 if !bytes.HasPrefix(key, LocalRangePrefix) { 347 return nil, nil, nil, errors.Errorf("key %q does not have %q prefix", 348 key, LocalRangePrefix) 349 } 350 // Cut the prefix and the Range ID. 351 b := key[len(LocalRangePrefix):] 352 b, startKey, err = encoding.DecodeBytesAscending(b, nil) 353 if err != nil { 354 return nil, nil, nil, err 355 } 356 if len(b) < localSuffixLength { 357 return nil, nil, nil, errors.Errorf("key %q does not have suffix of length %d", 358 key, localSuffixLength) 359 } 360 // Cut the suffix. 361 suffix = b[:localSuffixLength] 362 detail = b[localSuffixLength:] 363 return 364 } 365 366 // RangeDescriptorKey returns a range-local key for the descriptor 367 // for the range with specified key. 368 func RangeDescriptorKey(key roachpb.RKey) roachpb.Key { 369 return MakeRangeKey(key, LocalRangeDescriptorSuffix, nil) 370 } 371 372 // RangeDescriptorJointKey returns a range-local key for the "joint descriptor" 373 // for the range with specified key. This key is not versioned and it is set if 374 // and only if the range is in a joint configuration that it yet has to transition 375 // out of. 376 func RangeDescriptorJointKey(key roachpb.RKey) roachpb.Key { 377 return MakeRangeKey(key, LocalRangeDescriptorJointSuffix, nil) 378 } 379 380 var _ = RangeDescriptorJointKey // silence unused check 381 382 // TransactionKey returns a transaction key based on the provided 383 // transaction key and ID. The base key is encoded in order to 384 // guarantee that all transaction records for a range sort together. 385 func TransactionKey(key roachpb.Key, txnID uuid.UUID) roachpb.Key { 386 rk, err := Addr(key) 387 if err != nil { 388 panic(err) 389 } 390 return MakeRangeKey(rk, LocalTransactionSuffix, roachpb.RKey(txnID.GetBytes())) 391 } 392 393 // QueueLastProcessedKey returns a range-local key for last processed 394 // timestamps for the named queue. These keys represent per-range last 395 // processed times. 396 func QueueLastProcessedKey(key roachpb.RKey, queue string) roachpb.Key { 397 return MakeRangeKey(key, LocalQueueLastProcessedSuffix, roachpb.RKey(queue)) 398 } 399 400 // IsLocal performs a cheap check that returns true iff a range-local key is 401 // passed, that is, a key for which `Addr` would return a non-identical RKey 402 // (or a decoding error). 403 // 404 // TODO(tschottdorf): we need a better name for these keys as only some of 405 // them are local and it's been identified as an area that is not understood 406 // by many of the team's developers. An obvious suggestion is "system" (as 407 // opposed to "user") keys, but unfortunately that name has already been 408 // claimed by a related (but not identical) concept. 409 func IsLocal(k roachpb.Key) bool { 410 return bytes.HasPrefix(k, localPrefix) 411 } 412 413 // Addr returns the address for the key, used to lookup the range containing the 414 // key. In the normal case, this is simply the key's value. However, for local 415 // keys, such as transaction records, the address is the inner encoded key, with 416 // the local key prefix and the suffix and optional detail removed. This address 417 // unwrapping is performed repeatedly in the case of doubly-local keys. In this 418 // way, local keys address to the same range as non-local keys, but are stored 419 // separately so that they don't collide with user-space or global system keys. 420 // 421 // Logically, the keys are arranged as follows: 422 // 423 // k1 /local/k1/KeyMin ... /local/k1/KeyMax k1\x00 /local/k1/x00/KeyMin ... 424 // 425 // However, not all local keys are addressable in the global map. Only range 426 // local keys incorporating a range key (start key or transaction key) are 427 // addressable (e.g. range metadata and txn records). Range local keys 428 // incorporating the Range ID are not (e.g. AbortSpan Entries, and range 429 // stats). 430 // 431 // See AddrUpperBound which is to be used when `k` is the EndKey of an interval. 432 func Addr(k roachpb.Key) (roachpb.RKey, error) { 433 if !IsLocal(k) { 434 return roachpb.RKey(k), nil 435 } 436 437 for { 438 if bytes.HasPrefix(k, localStorePrefix) { 439 return nil, errors.Errorf("store-local key %q is not addressable", k) 440 } 441 if bytes.HasPrefix(k, LocalRangeIDPrefix) { 442 return nil, errors.Errorf("local range ID key %q is not addressable", k) 443 } 444 if !bytes.HasPrefix(k, LocalRangePrefix) { 445 return nil, errors.Errorf("local key %q malformed; should contain prefix %q", 446 k, LocalRangePrefix) 447 } 448 k = k[len(LocalRangePrefix):] 449 var err error 450 // Decode the encoded key, throw away the suffix and detail. 451 if _, k, err = encoding.DecodeBytesAscending(k, nil); err != nil { 452 return nil, err 453 } 454 if !IsLocal(k) { 455 break 456 } 457 } 458 return roachpb.RKey(k), nil 459 } 460 461 // MustAddr calls Addr and panics on errors. 462 func MustAddr(k roachpb.Key) roachpb.RKey { 463 rk, err := Addr(k) 464 if err != nil { 465 panic(errors.Wrapf(err, "could not take address of '%s'", k)) 466 } 467 return rk 468 } 469 470 // AddrUpperBound returns the address of an (exclusive) EndKey, used to lookup 471 // ranges containing the keys strictly smaller than that key. However, unlike 472 // Addr, it will return the following key that local range keys address to. This 473 // is necessary because range-local keys exist conceptually in the space between 474 // regular keys. Addr() returns the regular key that is just to the left of a 475 // range-local key, which is guaranteed to be located on the same range. 476 // AddrUpperBound() returns the regular key that is just to the right, which may 477 // not be on the same range but is suitable for use as the EndKey of a span 478 // involving a range-local key. 479 // 480 // Logically, the keys are arranged as follows: 481 // 482 // k1 /local/k1/KeyMin ... /local/k1/KeyMax k1\x00 /local/k1/x00/KeyMin ... 483 // 484 // and so any end key /local/k1/x corresponds to an address-resolved end key of 485 // k1\x00. 486 func AddrUpperBound(k roachpb.Key) (roachpb.RKey, error) { 487 rk, err := Addr(k) 488 if err != nil { 489 return rk, err 490 } 491 if IsLocal(k) { 492 // The upper bound for a range-local key that addresses to key k 493 // is the key directly after k. 494 rk = rk.Next() 495 } 496 return rk, nil 497 } 498 499 // RangeMetaKey returns a range metadata (meta1, meta2) indexing key for the 500 // given key. 501 // 502 // - For RKeyMin, KeyMin is returned. 503 // - For a meta1 key, KeyMin is returned. 504 // - For a meta2 key, a meta1 key is returned. 505 // - For an ordinary key, a meta2 key is returned. 506 func RangeMetaKey(key roachpb.RKey) roachpb.RKey { 507 if len(key) == 0 { // key.Equal(roachpb.RKeyMin) 508 return roachpb.RKeyMin 509 } 510 var prefix roachpb.Key 511 switch key[0] { 512 case meta1PrefixByte: 513 return roachpb.RKeyMin 514 case meta2PrefixByte: 515 prefix = Meta1Prefix 516 key = key[len(Meta2Prefix):] 517 default: 518 prefix = Meta2Prefix 519 } 520 521 buf := make(roachpb.RKey, 0, len(prefix)+len(key)) 522 buf = append(buf, prefix...) 523 buf = append(buf, key...) 524 return buf 525 } 526 527 // UserKey returns an ordinary key for the given range metadata (meta1, meta2) 528 // indexing key. 529 // 530 // - For RKeyMin, Meta1Prefix is returned. 531 // - For a meta1 key, a meta2 key is returned. 532 // - For a meta2 key, an ordinary key is returned. 533 // - For an ordinary key, the input key is returned. 534 func UserKey(key roachpb.RKey) roachpb.RKey { 535 if len(key) == 0 { // key.Equal(roachpb.RKeyMin) 536 return roachpb.RKey(Meta1Prefix) 537 } 538 var prefix roachpb.Key 539 switch key[0] { 540 case meta1PrefixByte: 541 prefix = Meta2Prefix 542 key = key[len(Meta1Prefix):] 543 case meta2PrefixByte: 544 key = key[len(Meta2Prefix):] 545 } 546 547 buf := make(roachpb.RKey, 0, len(prefix)+len(key)) 548 buf = append(buf, prefix...) 549 buf = append(buf, key...) 550 return buf 551 } 552 553 // validateRangeMetaKey validates that the given key is a valid Range Metadata 554 // key. This checks only the constraints common to forward and backwards scans: 555 // correct prefix and not exceeding KeyMax. 556 func validateRangeMetaKey(key roachpb.RKey) error { 557 // KeyMin is a valid key. 558 if key.Equal(roachpb.RKeyMin) { 559 return nil 560 } 561 // Key must be at least as long as Meta1Prefix. 562 if len(key) < len(Meta1Prefix) { 563 return NewInvalidRangeMetaKeyError("too short", key) 564 } 565 566 prefix, body := key[:len(Meta1Prefix)], key[len(Meta1Prefix):] 567 if !prefix.Equal(Meta2Prefix) && !prefix.Equal(Meta1Prefix) { 568 return NewInvalidRangeMetaKeyError("not a meta key", key) 569 } 570 571 if roachpb.RKeyMax.Less(body) { 572 return NewInvalidRangeMetaKeyError("body of meta key range lookup is > KeyMax", key) 573 } 574 return nil 575 } 576 577 // MetaScanBounds returns the range [start,end) within which the desired meta 578 // record can be found by means of an engine scan. The given key must be a 579 // valid RangeMetaKey as defined by validateRangeMetaKey. 580 // TODO(tschottdorf): a lot of casting going on inside. 581 func MetaScanBounds(key roachpb.RKey) (roachpb.RSpan, error) { 582 if err := validateRangeMetaKey(key); err != nil { 583 return roachpb.RSpan{}, err 584 } 585 586 if key.Equal(Meta2KeyMax) { 587 return roachpb.RSpan{}, 588 NewInvalidRangeMetaKeyError("Meta2KeyMax can't be used as the key of scan", key) 589 } 590 591 if key.Equal(roachpb.RKeyMin) { 592 // Special case KeyMin: find the first entry in meta1. 593 return roachpb.RSpan{ 594 Key: roachpb.RKey(Meta1Prefix), 595 EndKey: roachpb.RKey(Meta1Prefix.PrefixEnd()), 596 }, nil 597 } 598 if key.Equal(Meta1KeyMax) { 599 // Special case Meta1KeyMax: this is the last key in Meta1, we don't want 600 // to start at Next(). 601 return roachpb.RSpan{ 602 Key: roachpb.RKey(Meta1KeyMax), 603 EndKey: roachpb.RKey(Meta1Prefix.PrefixEnd()), 604 }, nil 605 } 606 607 // Otherwise find the first entry greater than the given key in the same meta prefix. 608 start := key.Next() 609 end := key[:len(Meta1Prefix)].PrefixEnd() 610 return roachpb.RSpan{Key: start, EndKey: end}, nil 611 } 612 613 // MetaReverseScanBounds returns the range [start,end) within which the desired 614 // meta record can be found by means of a reverse engine scan. The given key 615 // must be a valid RangeMetaKey as defined by validateRangeMetaKey. 616 func MetaReverseScanBounds(key roachpb.RKey) (roachpb.RSpan, error) { 617 if err := validateRangeMetaKey(key); err != nil { 618 return roachpb.RSpan{}, err 619 } 620 621 if key.Equal(roachpb.RKeyMin) || key.Equal(Meta1Prefix) { 622 return roachpb.RSpan{}, 623 NewInvalidRangeMetaKeyError("KeyMin and Meta1Prefix can't be used as the key of reverse scan", key) 624 } 625 if key.Equal(Meta2Prefix) { 626 // Special case Meta2Prefix: this is the first key in Meta2, and the scan 627 // interval covers all of Meta1. 628 return roachpb.RSpan{ 629 Key: roachpb.RKey(Meta1Prefix), 630 EndKey: roachpb.RKey(key.Next().AsRawKey()), 631 }, nil 632 } 633 634 // Otherwise find the first entry greater than the given key and find the last entry 635 // in the same prefix. For MVCCReverseScan the endKey is exclusive, if we want to find 636 // the range descriptor the given key specified,we need to set the key.Next() as the 637 // MVCCReverseScan`s endKey. For example: 638 // If we have ranges [a,f) and [f,z), then we'll have corresponding meta records 639 // at f and z. If you're looking for the meta record for key f, then you want the 640 // second record (exclusive in MVCCReverseScan), hence key.Next() below. 641 start := key[:len(Meta1Prefix)] 642 end := key.Next() 643 return roachpb.RSpan{Key: start, EndKey: end}, nil 644 } 645 646 // MakeTableIDIndexID returns the key for the table id and index id by appending 647 // to the passed key. The key must already contain a tenant id. 648 func MakeTableIDIndexID(key []byte, tableID uint32, indexID uint32) []byte { 649 key = encoding.EncodeUvarintAscending(key, uint64(tableID)) 650 key = encoding.EncodeUvarintAscending(key, uint64(indexID)) 651 return key 652 } 653 654 // MakeFamilyKey returns the key for the family in the given row by appending to 655 // the passed key. 656 func MakeFamilyKey(key []byte, famID uint32) []byte { 657 if famID == 0 { 658 // As an optimization, family 0 is encoded without a length suffix. 659 return encoding.EncodeUvarintAscending(key, 0) 660 } 661 size := len(key) 662 key = encoding.EncodeUvarintAscending(key, uint64(famID)) 663 // Note that we assume that `len(key)-size` will always be encoded to a 664 // single byte by EncodeUvarint. This is currently always true because the 665 // varint encoding will encode 1-9 bytes. 666 return encoding.EncodeUvarintAscending(key, uint64(len(key)-size)) 667 } 668 669 // DecodeTableIDIndexID decodes a table id followed by an index id from the 670 // provided key. The input key must already have its tenant id removed. 671 func DecodeTableIDIndexID(key []byte) ([]byte, uint32, uint32, error) { 672 var tableID uint64 673 var indexID uint64 674 var err error 675 676 key, tableID, err = encoding.DecodeUvarintAscending(key) 677 if err != nil { 678 return nil, 0, 0, err 679 } 680 key, indexID, err = encoding.DecodeUvarintAscending(key) 681 if err != nil { 682 return nil, 0, 0, err 683 } 684 return key, uint32(tableID), uint32(indexID), nil 685 } 686 687 // GetRowPrefixLength returns the length of the row prefix of the key. A table 688 // key's row prefix is defined as the maximal prefix of the key that is also a 689 // prefix of every key for the same row. (Any key with this maximal prefix is 690 // also guaranteed to be part of the input key's row.) 691 // For secondary index keys, the row prefix is defined as the entire key. 692 func GetRowPrefixLength(key roachpb.Key) (int, error) { 693 n := len(key) 694 695 // Strip tenant ID prefix to get a "SQL key" starting with a table ID. 696 sqlKey, _, err := DecodeTenantPrefix(key) 697 if err != nil { 698 return 0, errors.Errorf("%s: not a valid table key", key) 699 } 700 sqlN := len(sqlKey) 701 702 if encoding.PeekType(sqlKey) != encoding.Int { 703 // Not a table key, so the row prefix is the entire key. 704 return n, nil 705 } 706 // The column family ID length is encoded as a varint and we take advantage 707 // of the fact that the column family ID itself will be encoded in 0-9 bytes 708 // and thus the length of the column family ID data will fit in a single 709 // byte. 710 colFamIDLenByte := sqlKey[sqlN-1:] 711 if encoding.PeekType(colFamIDLenByte) != encoding.Int { 712 // The last byte is not a valid column family ID suffix. 713 return 0, errors.Errorf("%s: not a valid table key", key) 714 } 715 716 // Strip off the column family ID suffix from the buf. The last byte of the 717 // buf contains the length of the column family ID suffix, which might be 0 718 // if the buf does not contain a column ID suffix or if the column family is 719 // 0 (see the optimization in MakeFamilyKey). 720 _, colFamIDLen, err := encoding.DecodeUvarintAscending(colFamIDLenByte) 721 if err != nil { 722 return 0, err 723 } 724 // Note how this next comparison (and by extension the code after it) is 725 // overflow-safe. There are more intuitive ways of writing this that aren't 726 // as safe. See #18628. 727 if colFamIDLen > uint64(sqlN-1) { 728 // The column family ID length was impossible. colFamIDLen is the length 729 // of the encoded column family ID suffix. We add 1 to account for the 730 // byte holding the length of the encoded column family ID and if that 731 // total (colFamIDLen+1) is greater than the key suffix (sqlN == 732 // len(sqlKey)) then we bail. Note that we don't consider this an error 733 // because EnsureSafeSplitKey can be called on keys that look like table 734 // keys but which do not have a column family ID length suffix (e.g by 735 // SystemConfig.ComputeSplitKey). 736 return 0, errors.Errorf("%s: malformed table key", key) 737 } 738 return n - int(colFamIDLen) - 1, nil 739 } 740 741 // EnsureSafeSplitKey transforms an SQL table key such that it is a valid split key 742 // (i.e. does not occur in the middle of a row). 743 func EnsureSafeSplitKey(key roachpb.Key) (roachpb.Key, error) { 744 // The row prefix for a key is unique to keys in its row - no key without the 745 // row prefix will be in the key's row. Therefore, we can be certain that 746 // using the row prefix for a key as a split key is safe: it doesn't occur in 747 // the middle of a row. 748 idx, err := GetRowPrefixLength(key) 749 if err != nil { 750 return nil, err 751 } 752 return key[:idx], nil 753 } 754 755 // Range returns a key range encompassing the key ranges of all requests. 756 func Range(reqs []roachpb.RequestUnion) (roachpb.RSpan, error) { 757 from := roachpb.RKeyMax 758 to := roachpb.RKeyMin 759 for _, arg := range reqs { 760 req := arg.GetInner() 761 h := req.Header() 762 if !roachpb.IsRange(req) && len(h.EndKey) != 0 { 763 return roachpb.RSpan{}, errors.Errorf("end key specified for non-range operation: %s", req) 764 } 765 766 key, err := Addr(h.Key) 767 if err != nil { 768 return roachpb.RSpan{}, err 769 } 770 if key.Less(from) { 771 // Key is smaller than `from`. 772 from = key 773 } 774 if !key.Less(to) { 775 // Key.Next() is larger than `to`. 776 if bytes.Compare(key, roachpb.RKeyMax) > 0 { 777 return roachpb.RSpan{}, errors.Errorf("%s must be less than KeyMax", key) 778 } 779 to = key.Next() 780 } 781 782 if len(h.EndKey) == 0 { 783 continue 784 } 785 endKey, err := AddrUpperBound(h.EndKey) 786 if err != nil { 787 return roachpb.RSpan{}, err 788 } 789 if bytes.Compare(roachpb.RKeyMax, endKey) < 0 { 790 return roachpb.RSpan{}, errors.Errorf("%s must be less than or equal to KeyMax", endKey) 791 } 792 if to.Less(endKey) { 793 // EndKey is larger than `to`. 794 to = endKey 795 } 796 } 797 return roachpb.RSpan{Key: from, EndKey: to}, nil 798 } 799 800 // RangeIDPrefixBuf provides methods for generating range ID local keys while 801 // avoiding an allocation on every key generated. The generated keys are only 802 // valid until the next call to one of the key generation methods. 803 type RangeIDPrefixBuf roachpb.Key 804 805 // MakeRangeIDPrefixBuf creates a new range ID prefix buf suitable for 806 // generating the various range ID local keys. 807 func MakeRangeIDPrefixBuf(rangeID roachpb.RangeID) RangeIDPrefixBuf { 808 return RangeIDPrefixBuf(MakeRangeIDPrefix(rangeID)) 809 } 810 811 func (b RangeIDPrefixBuf) replicatedPrefix() roachpb.Key { 812 return append(roachpb.Key(b), LocalRangeIDReplicatedInfix...) 813 } 814 815 func (b RangeIDPrefixBuf) unreplicatedPrefix() roachpb.Key { 816 return append(roachpb.Key(b), localRangeIDUnreplicatedInfix...) 817 } 818 819 // AbortSpanKey returns a range-local key by Range ID for an AbortSpan 820 // entry, with detail specified by encoding the supplied transaction ID. 821 func (b RangeIDPrefixBuf) AbortSpanKey(txnID uuid.UUID) roachpb.Key { 822 key := append(b.replicatedPrefix(), LocalAbortSpanSuffix...) 823 return encoding.EncodeBytesAscending(key, txnID.GetBytes()) 824 } 825 826 // RangeAppliedStateKey returns a system-local key for the range applied state key. 827 // See comment on RangeAppliedStateKey function. 828 func (b RangeIDPrefixBuf) RangeAppliedStateKey() roachpb.Key { 829 return append(b.replicatedPrefix(), LocalRangeAppliedStateSuffix...) 830 } 831 832 // RaftAppliedIndexLegacyKey returns a system-local key for a raft applied index. 833 // See comment on RaftAppliedIndexLegacyKey function. 834 func (b RangeIDPrefixBuf) RaftAppliedIndexLegacyKey() roachpb.Key { 835 return append(b.replicatedPrefix(), LocalRaftAppliedIndexLegacySuffix...) 836 } 837 838 // LeaseAppliedIndexLegacyKey returns a system-local key for a lease applied index. 839 // See comment on LeaseAppliedIndexLegacyKey function. 840 func (b RangeIDPrefixBuf) LeaseAppliedIndexLegacyKey() roachpb.Key { 841 return append(b.replicatedPrefix(), LocalLeaseAppliedIndexLegacySuffix...) 842 } 843 844 // RaftTruncatedStateLegacyKey returns a system-local key for a RaftTruncatedState. 845 func (b RangeIDPrefixBuf) RaftTruncatedStateLegacyKey() roachpb.Key { 846 return append(b.replicatedPrefix(), LocalRaftTruncatedStateLegacySuffix...) 847 } 848 849 // RangeLeaseKey returns a system-local key for a range lease. 850 func (b RangeIDPrefixBuf) RangeLeaseKey() roachpb.Key { 851 return append(b.replicatedPrefix(), LocalRangeLeaseSuffix...) 852 } 853 854 // RangeStatsLegacyKey returns the key for accessing the MVCCStats struct 855 // for the specified Range ID. 856 // See comment on RangeStatsLegacyKey function. 857 func (b RangeIDPrefixBuf) RangeStatsLegacyKey() roachpb.Key { 858 return append(b.replicatedPrefix(), LocalRangeStatsLegacySuffix...) 859 } 860 861 // RangeLastGCKey returns a system-local key for the last GC. 862 func (b RangeIDPrefixBuf) RangeLastGCKey() roachpb.Key { 863 return append(b.replicatedPrefix(), LocalRangeLastGCSuffix...) 864 } 865 866 // RangeTombstoneKey returns a system-local key for a range tombstone. 867 func (b RangeIDPrefixBuf) RangeTombstoneKey() roachpb.Key { 868 return append(b.unreplicatedPrefix(), LocalRangeTombstoneSuffix...) 869 } 870 871 // RaftTruncatedStateKey returns a system-local key for a RaftTruncatedState. 872 func (b RangeIDPrefixBuf) RaftTruncatedStateKey() roachpb.Key { 873 return append(b.unreplicatedPrefix(), LocalRaftTruncatedStateLegacySuffix...) 874 } 875 876 // RaftHardStateKey returns a system-local key for a Raft HardState. 877 func (b RangeIDPrefixBuf) RaftHardStateKey() roachpb.Key { 878 return append(b.unreplicatedPrefix(), LocalRaftHardStateSuffix...) 879 } 880 881 // RaftLogPrefix returns the system-local prefix shared by all Entries 882 // in a Raft log. 883 func (b RangeIDPrefixBuf) RaftLogPrefix() roachpb.Key { 884 return append(b.unreplicatedPrefix(), LocalRaftLogSuffix...) 885 } 886 887 // RaftLogKey returns a system-local key for a Raft log entry. 888 func (b RangeIDPrefixBuf) RaftLogKey(logIndex uint64) roachpb.Key { 889 return encoding.EncodeUint64Ascending(b.RaftLogPrefix(), logIndex) 890 } 891 892 // RangeLastReplicaGCTimestampKey returns a range-local key for 893 // the range's last replica GC timestamp. 894 func (b RangeIDPrefixBuf) RangeLastReplicaGCTimestampKey() roachpb.Key { 895 return append(b.unreplicatedPrefix(), LocalRangeLastReplicaGCTimestampSuffix...) 896 }