From ed67f6593fa832e4d551c2f569f1f638bc7278fd Mon Sep 17 00:00:00 2001 From: Ryan Uber Date: Thu, 29 Jan 2015 21:55:11 -0800 Subject: [PATCH 1/4] consul: swap over to raft-boltdb --- consul/server.go | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/consul/server.go b/consul/server.go index f8adba7b97a2..0fe981113ae3 100644 --- a/consul/server.go +++ b/consul/server.go @@ -10,7 +10,6 @@ import ( "os" "path/filepath" "reflect" - "runtime" "strconv" "sync" "time" @@ -18,7 +17,7 @@ import ( "github.com/hashicorp/consul/acl" "github.com/hashicorp/golang-lru" "github.com/hashicorp/raft" - "github.com/hashicorp/raft-mdb" + "github.com/hashicorp/raft-boltdb" "github.com/hashicorp/serf/serf" ) @@ -31,13 +30,11 @@ const ( ) const ( - serfLANSnapshot = "serf/local.snapshot" - serfWANSnapshot = "serf/remote.snapshot" - raftState = "raft/" - tmpStatePath = "tmp/" - snapshotsRetained = 2 - raftDBSize32bit uint64 = 64 * 1024 * 1024 // Limit Raft log to 64MB - raftDBSize64bit uint64 = 8 * 1024 * 1024 * 1024 // Limit Raft log to 8GB + serfLANSnapshot = "serf/local.snapshot" + serfWANSnapshot = "serf/remote.snapshot" + raftState = "raft/" + tmpStatePath = "tmp/" + snapshotsRetained = 2 // serverRPCCache controls how long we keep an idle connection // open to a server @@ -108,7 +105,7 @@ type Server struct { raft *raft.Raft raftLayer *RaftLayer raftPeers raft.PeerStore - raftStore *raftmdb.MDBStore + raftStore *raftboltdb.BoltStore raftTransport *raft.NetworkTransport // reconcileCh is used to pass events from the serf handler @@ -349,22 +346,14 @@ func (s *Server) setupRaft() error { return err } - // Set the maximum raft size based on 32/64bit. Since we are - // doing an mmap underneath, we need to limit our use of virtual - // address space on 32bit, but don't have to care on 64bit. - dbSize := raftDBSize32bit - if runtime.GOARCH == "amd64" { - dbSize = raftDBSize64bit - } - // Create the base raft path path := filepath.Join(s.config.DataDir, raftState) if err := ensurePath(path, true); err != nil { return err } - // Create the MDB store for logs and stable storage - store, err := raftmdb.NewMDBStoreWithSize(path, dbSize) + // Create the backend raft store for logs and stable storage + store, err := raftboltdb.NewBoltStore(filepath.Join(path, "raft.db")) if err != nil { return err } From ac0f66a91ec03ede0126f5a9961de47b168d823b Mon Sep 17 00:00:00 2001 From: Ryan Uber Date: Thu, 9 Apr 2015 22:58:35 -0700 Subject: [PATCH 2/4] command: automatically migrate raft data on start --- command/agent/command.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/command/agent/command.go b/command/agent/command.go index dfc5483939fd..58e23b600a64 100644 --- a/command/agent/command.go +++ b/command/agent/command.go @@ -15,6 +15,7 @@ import ( "time" "github.com/armon/go-metrics" + "github.com/hashicorp/consul-migrate/migrator" "github.com/hashicorp/consul/watch" "github.com/hashicorp/go-checkpoint" "github.com/hashicorp/go-syslog" @@ -597,6 +598,28 @@ func (c *Command) Run(args []string) int { metrics.NewGlobal(metricsConf, inm) } + // If we are starting a consul 0.5.1+ server for the first time, + // and we have data from a previous Consul version, attempt to + // migrate the data from LMDB to BoltDB using the migrator utility. + if config.Server { + m, err := migrator.New(config.DataDir) + if err != nil { + c.Ui.Error(err.Error()) + return 1 + } + + start := time.Now() + migrated, err := m.Migrate() + if err != nil { + c.Ui.Error(fmt.Sprintf("Failed to migrate raft data: %s", err)) + return 1 + } + if migrated { + duration := time.Now().Sub(start) + c.Ui.Output(fmt.Sprintf("Successfully migrated raft data in %s", duration)) + } + } + // Create the agent if err := c.setupAgent(config, logOutput, logWriter); err != nil { return 1 From 57ba747f543b567961b4061e435850eb23c593af Mon Sep 17 00:00:00 2001 From: Ryan Uber Date: Fri, 10 Apr 2015 17:52:49 -0700 Subject: [PATCH 3/4] website: add mention of consul-migrate --- .../source/docs/upgrade-specific.html.markdown | 17 +++++++++++++++++ website/source/downloads_tools.html.erb | 3 +++ 2 files changed, 20 insertions(+) diff --git a/website/source/docs/upgrade-specific.html.markdown b/website/source/docs/upgrade-specific.html.markdown index 4ed93b90f8d9..8dea2cc12334 100644 --- a/website/source/docs/upgrade-specific.html.markdown +++ b/website/source/docs/upgrade-specific.html.markdown @@ -14,6 +14,23 @@ details provided for their upgrades as a result of new features or changed behavior. This page is used to document those details seperately from the standard upgrade flow. +## Consul 0.5.1 + +Consul version 0.5.1 uses a different backend store for persisting the Raft +log. Because of this change, a data migration is necessary to move the log +entries out of LMDB and into the newer backend, BoltDB. + +Consul version 0.5.1 makes this transition seamless and easy. As a user, there +are no special steps you need to take. When Consul 0.5.1 starts, it checks +for presence of the legacy LMDB data files, and migrates them automatically +if any are found. + +The automatic upgrade will only exist in Consul 0.5.1. In later versions +(0.6.0+), the migration code will not be included in the Consul binary. It +is still possible to upgrade directly from pre-0.5.1 versions by using the +consul-migrate utility, which is available on the +[Consul Tools page](/downloads_tools.html). + ## Consul 0.5 Consul version 0.5 adds two features that complicate the upgrade process: diff --git a/website/source/downloads_tools.html.erb b/website/source/downloads_tools.html.erb index 1c747142bb7b..3e3caae0fa1d 100644 --- a/website/source/downloads_tools.html.erb +++ b/website/source/downloads_tools.html.erb @@ -29,6 +29,9 @@ description: |-
  • Consul Template - Generic template rendering and notifications with Consul
  • +
  • + Consul Migrate - Data migration tool to handle Consul upgrades to 0.5.1+ +
  • From 72fa55043c3841b296495777004eeb17998960b5 Mon Sep 17 00:00:00 2001 From: Ryan Uber Date: Fri, 10 Apr 2015 18:24:09 -0700 Subject: [PATCH 4/4] website: add example cli output from migration --- website/source/docs/upgrade-specific.html.markdown | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/website/source/docs/upgrade-specific.html.markdown b/website/source/docs/upgrade-specific.html.markdown index 8dea2cc12334..9db7c63533f1 100644 --- a/website/source/docs/upgrade-specific.html.markdown +++ b/website/source/docs/upgrade-specific.html.markdown @@ -23,7 +23,12 @@ entries out of LMDB and into the newer backend, BoltDB. Consul version 0.5.1 makes this transition seamless and easy. As a user, there are no special steps you need to take. When Consul 0.5.1 starts, it checks for presence of the legacy LMDB data files, and migrates them automatically -if any are found. +if any are found. You will see a log emitted when Raft data is migrated, like +this: + +``` +==> Successfully migrated raft data in 5.839642ms +``` The automatic upgrade will only exist in Consul 0.5.1. In later versions (0.6.0+), the migration code will not be included in the Consul binary. It