Merge pull request #16376 from geetasg/pr6

Update etcdutl restore to create v2 snapshot from v3
This commit is contained in:
Benjamin Wang 2023-08-14 18:33:11 +01:00 committed by GitHub
commit 731048d728
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 9 deletions

View File

@ -38,7 +38,6 @@ import (
"go.etcd.io/etcd/server/v3/etcdserver" "go.etcd.io/etcd/server/v3/etcdserver"
"go.etcd.io/etcd/server/v3/etcdserver/api/membership" "go.etcd.io/etcd/server/v3/etcdserver/api/membership"
"go.etcd.io/etcd/server/v3/etcdserver/api/snap" "go.etcd.io/etcd/server/v3/etcdserver/api/snap"
"go.etcd.io/etcd/server/v3/etcdserver/api/v2store"
"go.etcd.io/etcd/server/v3/etcdserver/cindex" "go.etcd.io/etcd/server/v3/etcdserver/cindex"
"go.etcd.io/etcd/server/v3/storage/backend" "go.etcd.io/etcd/server/v3/storage/backend"
"go.etcd.io/etcd/server/v3/storage/mvcc" "go.etcd.io/etcd/server/v3/storage/mvcc"
@ -472,9 +471,7 @@ func (s *v3Manager) saveWALAndSnap() (*raftpb.HardState, error) {
return nil, err return nil, err
} }
// add members again to persist them to the store we create. // add members again to persist them to the backend we create.
st := v2store.New(etcdserver.StoreClusterPrefix, etcdserver.StoreKeysPrefix)
s.cl.SetStore(st)
be := backend.NewDefaultBackend(s.lg, s.outDbPath()) be := backend.NewDefaultBackend(s.lg, s.outDbPath())
defer be.Close() defer be.Close()
s.cl.SetBackend(schema.NewMembershipBackend(s.lg, be)) s.cl.SetBackend(schema.NewMembershipBackend(s.lg, be))
@ -534,15 +531,11 @@ func (s *v3Manager) saveWALAndSnap() (*raftpb.HardState, error) {
return nil, err return nil, err
} }
b, berr := st.Save()
if berr != nil {
return nil, berr
}
confState := raftpb.ConfState{ confState := raftpb.ConfState{
Voters: nodeIDs, Voters: nodeIDs,
} }
raftSnap := raftpb.Snapshot{ raftSnap := raftpb.Snapshot{
Data: b, Data: etcdserver.GetMembershipInfoInV2Format(s.lg, s.cl),
Metadata: raftpb.SnapshotMetadata{ Metadata: raftpb.SnapshotMetadata{
Index: commit, Index: commit,
Term: term, Term: term,

View File

@ -29,8 +29,12 @@ import (
"go.etcd.io/etcd/api/v3/version" "go.etcd.io/etcd/api/v3/version"
"go.etcd.io/etcd/client/pkg/v3/fileutil" "go.etcd.io/etcd/client/pkg/v3/fileutil"
"go.etcd.io/etcd/client/pkg/v3/types"
clientv3 "go.etcd.io/etcd/client/v3" clientv3 "go.etcd.io/etcd/client/v3"
"go.etcd.io/etcd/server/v3/etcdserver"
"go.etcd.io/etcd/server/v3/etcdserver/api/membership"
"go.etcd.io/etcd/server/v3/etcdserver/api/snap" "go.etcd.io/etcd/server/v3/etcdserver/api/snap"
"go.etcd.io/etcd/server/v3/etcdserver/api/v2store"
"go.etcd.io/etcd/server/v3/storage/datadir" "go.etcd.io/etcd/server/v3/storage/datadir"
"go.etcd.io/etcd/tests/v3/framework/config" "go.etcd.io/etcd/tests/v3/framework/config"
"go.etcd.io/etcd/tests/v3/framework/e2e" "go.etcd.io/etcd/tests/v3/framework/e2e"
@ -293,6 +297,23 @@ func verifySnapshot(t *testing.T, epc *e2e.EtcdProcessCluster) {
t.Logf("All members have a valid snapshot") t.Logf("All members have a valid snapshot")
} }
func verifySnapshotMembers(t *testing.T, epc *e2e.EtcdProcessCluster, expectedMembers *clientv3.MemberListResponse) {
for i := range epc.Procs {
t.Logf("Verifying snapshot for member %d", i)
ss := snap.New(epc.Cfg.Logger, datadir.ToSnapDir(epc.Procs[i].Config().DataDirPath))
snap, err := ss.Load()
st := v2store.New(etcdserver.StoreClusterPrefix, etcdserver.StoreKeysPrefix)
err = st.Recovery(snap.Data)
assert.NoError(t, err)
for _, m := range expectedMembers.Members {
_, err := st.Get(membership.MemberStoreKey(types.ID(m.ID)), true, true)
assert.NoError(t, err)
}
t.Logf("Verifed snapshot for member %d", i)
}
t.Log("All members have a valid snapshot")
}
func getMembersAndKeys(t *testing.T, epc *e2e.EtcdProcessCluster) (*clientv3.MemberListResponse, *clientv3.GetResponse) { func getMembersAndKeys(t *testing.T, epc *e2e.EtcdProcessCluster) (*clientv3.MemberListResponse, *clientv3.GetResponse) {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()

View File

@ -358,6 +358,9 @@ func TestRestoreCompactionRevBump(t *testing.T) {
require.NoError(t, ctl.Put(context.Background(), unsnappedKVs[i].Key, unsnappedKVs[i].Val, config.PutOptions{})) require.NoError(t, ctl.Put(context.Background(), unsnappedKVs[i].Key, unsnappedKVs[i].Val, config.PutOptions{}))
} }
membersBefore, err := ctl.MemberList(context.Background(), false)
require.NoError(t, err)
t.Log("Stopping the original server...") t.Log("Stopping the original server...")
require.NoError(t, epc.Stop()) require.NoError(t, epc.Stop())
@ -380,12 +383,16 @@ func TestRestoreCompactionRevBump(t *testing.T) {
t.Log("(Re)starting the etcd member using the restored snapshot...") t.Log("(Re)starting the etcd member using the restored snapshot...")
epc.Procs[0].Config().DataDirPath = newDataDir epc.Procs[0].Config().DataDirPath = newDataDir
for i := range epc.Procs[0].Config().Args { for i := range epc.Procs[0].Config().Args {
if epc.Procs[0].Config().Args[i] == "--data-dir" { if epc.Procs[0].Config().Args[i] == "--data-dir" {
epc.Procs[0].Config().Args[i+1] = newDataDir epc.Procs[0].Config().Args[i+1] = newDataDir
} }
} }
// Verify that initial snapshot is created by the restore operation
verifySnapshotMembers(t, epc, membersBefore)
require.NoError(t, epc.Restart(context.Background())) require.NoError(t, epc.Restart(context.Background()))
t.Log("Ensuring the restored member has the correct data...") t.Log("Ensuring the restored member has the correct data...")