Merge pull request #13972 from ahrtr/simplify_etcdctl_backup

Simply etcdutl backup command to cleanup v2 related implementation
This commit is contained in:
Piotr Tabor 2022-04-29 10:11:32 +02:00 committed by GitHub
commit e74c72ef4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -61,7 +61,7 @@ func NewBackupCommand() *cobra.Command {
cmd.Flags().StringVar(&walDir, "wal-dir", "", "Path to the etcd wal dir")
cmd.Flags().StringVar(&backupDir, "backup-dir", "", "Path to the backup dir")
cmd.Flags().StringVar(&backupWalDir, "backup-wal-dir", "", "Path to the backup wal dir")
cmd.Flags().BoolVar(&withV3, "with-v3", true, "Backup v3 backend data")
cmd.Flags().BoolVar(&withV3, "with-v3", true, "Backup v3 backend data. Note -with-v3=false is not supported since etcd v3.6. Please use v3.5.x client as the last supporting this deprecated functionality.")
cmd.MarkFlagRequired("data-dir")
cmd.MarkFlagRequired("backup-dir")
cmd.MarkFlagDirname("data-dir")
@ -107,6 +107,11 @@ func newDesiredCluster() desiredCluster {
func HandleBackup(withV3 bool, srcDir string, destDir string, srcWAL string, destWAL string) error {
lg := GetLogger()
if !withV3 {
lg.Warn("-with-v3=false is not supported since etcd v3.6. Please use v3.5.x client as the last supporting this deprecated functionality.")
return nil
}
srcSnap := datadir.ToSnapDir(srcDir)
destSnap := datadir.ToSnapDir(destDir)
@ -127,8 +132,8 @@ func HandleBackup(withV3 bool, srcDir string, destDir string, srcWAL string, des
desired := newDesiredCluster()
walsnap := saveSnap(lg, destSnap, srcSnap, &desired)
metadata, state, ents := translateWAL(lg, srcWAL, walsnap, withV3)
saveDB(lg, destDbPath, srcDbPath, state.Commit, state.Term, &desired, withV3)
metadata, state, ents := translateWAL(lg, srcWAL, walsnap)
saveDB(lg, destDbPath, srcDbPath, state.Commit, state.Term, &desired)
neww, err := wal.Create(lg, destWAL, pbutil.MustMarshal(&metadata))
if err != nil {
@ -189,7 +194,7 @@ func mustTranslateV2store(lg *zap.Logger, storeData []byte, desired *desiredClus
return outputData
}
func translateWAL(lg *zap.Logger, srcWAL string, walsnap walpb.Snapshot, v3 bool) (etcdserverpb.Metadata, raftpb.HardState, []raftpb.Entry) {
func translateWAL(lg *zap.Logger, srcWAL string, walsnap walpb.Snapshot) (etcdserverpb.Metadata, raftpb.HardState, []raftpb.Entry) {
w, err := wal.OpenForRead(lg, srcWAL, walsnap)
if err != nil {
lg.Fatal("wal.OpenForRead failed", zap.Error(err))
@ -239,22 +244,13 @@ func translateWAL(lg *zap.Logger, srcWAL string, walsnap walpb.Snapshot, v3 bool
continue
}
if v2Req != nil {
lg.Debug("preserving log entry", zap.Stringer("entry", &ents[i]))
}
if raftReq.ClusterMemberAttrSet != nil {
lg.Info("ignoring cluster_member_attr_set")
raftEntryToNoOp(&ents[i])
continue
}
if v3 || raftReq.Header == nil {
lg.Debug("preserving log entry", zap.Stringer("entry", &ents[i]))
continue
}
lg.Info("ignoring v3 raft entry")
raftEntryToNoOp(&ents[i])
}
var metadata etcdserverpb.Metadata
pbutil.MustUnmarshal(&metadata, wmetadata)
@ -269,10 +265,8 @@ func raftEntryToNoOp(entry *raftpb.Entry) {
}
// saveDB copies the v3 backend and strips cluster information.
func saveDB(lg *zap.Logger, destDB, srcDB string, idx uint64, term uint64, desired *desiredCluster, v3 bool) {
func saveDB(lg *zap.Logger, destDB, srcDB string, idx uint64, term uint64, desired *desiredCluster) {
// open src db to safely copy db state
if v3 {
var src *bolt.DB
ch := make(chan *bolt.DB, 1)
go func() {
@ -306,8 +300,8 @@ func saveDB(lg *zap.Logger, destDB, srcDB string, idx uint64, term uint64, desir
if err := tx.Rollback(); err != nil {
lg.Fatal("bbolt tx.Rollback failed", zap.String("dest", destDB), zap.Error(err))
}
}
// trim membership info
be := backend.NewDefaultBackend(lg, destDB)
defer be.Close()
ms := schema.NewMembershipBackend(lg, be)
@ -319,16 +313,4 @@ func saveDB(lg *zap.Logger, destDB, srcDB string, idx uint64, term uint64, desir
raftCluster.SetID(desired.nodeId, desired.clusterId)
raftCluster.SetBackend(ms)
raftCluster.PushMembershipToStorage()
if !v3 {
tx := be.BatchTx()
tx.LockOutsideApply()
defer tx.Unlock()
schema.UnsafeCreateMetaBucket(tx)
schema.UnsafeUpdateConsistentIndexForce(tx, idx, term)
} else {
// Thanks to translateWAL not moving entries, but just replacing them with
// 'empty', there is no need to update the consistency index.
}
}