mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
etcdserver: autodetect v0.4 WALs and upgrade them to v0.5 automatically
This commit is contained in:
parent
aca195f3ad
commit
78ea3335bf
@ -36,6 +36,7 @@ import (
|
|||||||
"github.com/coreos/etcd/etcdserver/etcdhttp/httptypes"
|
"github.com/coreos/etcd/etcdserver/etcdhttp/httptypes"
|
||||||
pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
|
pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
|
||||||
"github.com/coreos/etcd/etcdserver/stats"
|
"github.com/coreos/etcd/etcdserver/stats"
|
||||||
|
"github.com/coreos/etcd/migrate"
|
||||||
"github.com/coreos/etcd/pkg/pbutil"
|
"github.com/coreos/etcd/pkg/pbutil"
|
||||||
"github.com/coreos/etcd/pkg/types"
|
"github.com/coreos/etcd/pkg/types"
|
||||||
"github.com/coreos/etcd/pkg/wait"
|
"github.com/coreos/etcd/pkg/wait"
|
||||||
@ -190,18 +191,39 @@ type EtcdServer struct {
|
|||||||
raftLead uint64
|
raftLead uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpgradeWAL converts an older version of the EtcdServer data to the newest version.
|
||||||
|
// It must ensure that, after upgrading, the most recent version is present.
|
||||||
|
func UpgradeWAL(cfg *ServerConfig, ver wal.WalVersion) {
|
||||||
|
if ver == wal.WALv0_4 {
|
||||||
|
err := migrate.Migrate4To5(cfg.DataDir, cfg.Name)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed migrating data-dir: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NewServer creates a new EtcdServer from the supplied configuration. The
|
// NewServer creates a new EtcdServer from the supplied configuration. The
|
||||||
// configuration is considered static for the lifetime of the EtcdServer.
|
// configuration is considered static for the lifetime of the EtcdServer.
|
||||||
func NewServer(cfg *ServerConfig) (*EtcdServer, error) {
|
func NewServer(cfg *ServerConfig) (*EtcdServer, error) {
|
||||||
if err := os.MkdirAll(cfg.SnapDir(), privateDirMode); err != nil {
|
|
||||||
return nil, fmt.Errorf("cannot create snapshot directory: %v", err)
|
|
||||||
}
|
|
||||||
ss := snap.New(cfg.SnapDir())
|
|
||||||
st := store.New()
|
st := store.New()
|
||||||
var w *wal.WAL
|
var w *wal.WAL
|
||||||
var n raft.Node
|
var n raft.Node
|
||||||
var id types.ID
|
var id types.ID
|
||||||
haveWAL := wal.Exist(cfg.WALDir())
|
walVersion := wal.DetectVersion(cfg.DataDir)
|
||||||
|
if walVersion == wal.UnknownWAL {
|
||||||
|
return nil, fmt.Errorf("unknown wal version in data dir %s", cfg.DataDir)
|
||||||
|
}
|
||||||
|
haveWAL := walVersion != wal.NoWAL
|
||||||
|
|
||||||
|
if haveWAL && walVersion != wal.WALv0_5 {
|
||||||
|
UpgradeWAL(cfg, walVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.MkdirAll(cfg.SnapDir(), privateDirMode); err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot create snapshot directory: %v", err)
|
||||||
|
}
|
||||||
|
ss := snap.New(cfg.SnapDir())
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case !haveWAL && !cfg.NewCluster:
|
case !haveWAL && !cfg.NewCluster:
|
||||||
us := getOtherPeerURLs(cfg.Cluster, cfg.Name)
|
us := getOtherPeerURLs(cfg.Cluster, cfg.Name)
|
||||||
|
47
wal/util.go
47
wal/util.go
@ -20,8 +20,55 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type StringSlice []string
|
||||||
|
|
||||||
|
func containsStrings(source, target []string) bool {
|
||||||
|
for _, t := range target {
|
||||||
|
ok := false
|
||||||
|
for _, s := range source {
|
||||||
|
if t == s {
|
||||||
|
ok = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// WalVersion is an enum for versions of etcd logs.
|
||||||
|
type WalVersion string
|
||||||
|
|
||||||
|
const (
|
||||||
|
UnknownWAL WalVersion = "Unknown WAL"
|
||||||
|
NoWAL WalVersion = "No WAL"
|
||||||
|
WALv0_4 WalVersion = "0.4.x"
|
||||||
|
WALv0_5 WalVersion = "0.5.x"
|
||||||
|
)
|
||||||
|
|
||||||
|
func DetectVersion(dirpath string) WalVersion {
|
||||||
|
names, err := readDir(dirpath)
|
||||||
|
if err != nil || len(names) == 0 {
|
||||||
|
return NoWAL
|
||||||
|
}
|
||||||
|
if containsStrings(names, []string{"snap", "wal"}) {
|
||||||
|
// .../wal cannot be empty to exist.
|
||||||
|
if Exist(path.Join(dirpath, "wal")) {
|
||||||
|
return WALv0_5
|
||||||
|
}
|
||||||
|
return NoWAL
|
||||||
|
}
|
||||||
|
if containsStrings(names, []string{"snapshot", "conf", "log"}) {
|
||||||
|
return WALv0_4
|
||||||
|
}
|
||||||
|
|
||||||
|
return UnknownWAL
|
||||||
|
}
|
||||||
|
|
||||||
func Exist(dirpath string) bool {
|
func Exist(dirpath string) bool {
|
||||||
names, err := readDir(dirpath)
|
names, err := readDir(dirpath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user