// Copyright 2024 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package mvcc import ( "encoding/binary" "encoding/json" "github.com/coreos/go-semver/semver" "go.etcd.io/etcd/mvcc/backend" "go.etcd.io/etcd/raft/raftpb" "go.etcd.io/etcd/version" "go.uber.org/zap" ) var ( // meta bucket keys since 3.5 confStateKeyName = []byte("confState") termKeyName = []byte("term") // meta bucket keys since 3.6 storageVersionKeyName = []byte("storageVersion") ) // unsafeDowngradeMetaBucket delete 3.5 specific keys to make backend fully compatible with 3.4 func unsafeDowngradeMetaBucket(lg *zap.Logger, tx backend.BatchTx) { if lg != nil { lg.Info( "downgrade meta bucket", zap.ByteStrings("remove-keys", [][]byte{confStateKeyName, termKeyName}), ) } else { plog.Printf("downgrade meta bucket: remove keys [%s, %s]", string(confStateKeyName), string(termKeyName)) } tx.UnsafeDelete(metaBucketName, confStateKeyName) tx.UnsafeDelete(metaBucketName, termKeyName) } // unsafeReadStorageVersion loads storage version from given backend transaction. // Populated since v3.6 func unsafeReadStorageVersion(tx backend.ReadTx) *semver.Version { _, vs := tx.UnsafeRange(metaBucketName, storageVersionKeyName, nil, 0) if len(vs) == 0 { return nil } v, err := semver.NewVersion(string(vs[0])) if err != nil { return nil } return v } // unsafeReadTerm loads term from given transaction. // returns 0 if the data are not found. // Term is persisted since v3.5. func unsafeReadTerm(tx backend.ReadTx) uint64 { _, ts := tx.UnsafeRange(metaBucketName, termKeyName, nil, 0) if len(ts) == 0 { return 0 } return binary.BigEndian.Uint64(ts[0]) } // unsafeConfStateFromBackend retrieves ConfState from the backend. // Returns nil if confState in backend is not persisted (e.g. backend writen by