diff --git a/.changelog/21759.txt b/.changelog/21759.txt new file mode 100644 index 000000000000..6a3e389b0bf1 --- /dev/null +++ b/.changelog/21759.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +raft: use raft-wal as the default raft log store. +``` diff --git a/agent/config/builder.go b/agent/config/builder.go index f8d0df7b5c93..0e86cfc1586d 100644 --- a/agent/config/builder.go +++ b/agent/config/builder.go @@ -2840,7 +2840,7 @@ func (b *builder) raftLogStoreConfigVal(raw *RaftLogStoreRaw) consul.RaftLogStor cfg.Backend = stringValWithDefault(raw.Backend, consul.LogStoreBackendDefault) cfg.DisableLogCache = boolVal(raw.DisableLogCache) - cfg.Verification.Enabled = boolVal(raw.Verification.Enabled) + cfg.Verification.Enabled = boolValWithDefault(raw.Verification.Enabled, true) cfg.Verification.Interval = b.durationVal("raft_logstore.verification.interval", raw.Verification.Interval) cfg.BoltDB.NoFreelistSync = boolVal(raw.BoltDBConfig.NoFreelistSync) diff --git a/agent/consul/server.go b/agent/consul/server.go index 979d9e3cd434..08b318b804f9 100644 --- a/agent/consul/server.go +++ b/agent/consul/server.go @@ -1055,26 +1055,23 @@ func (s *Server) setupRaft() error { stable = wal return nil } - // Only use WAL if there is no existing raft.db, even if it's enabled. + + // Default to WAL if there is no existing raft.db, even if it's enabled. Log a warning otherwise if s.config.LogStoreConfig.Backend == LogStoreBackendDefault && !boltFileExists { s.config.LogStoreConfig.Backend = LogStoreBackendWAL - if !s.config.LogStoreConfig.Verification.Enabled { - s.config.LogStoreConfig.Verification.Enabled = true - s.config.LogStoreConfig.Verification.Interval = 1 * time.Minute - } - if err = initWAL(); err != nil { - return err - } - } else if s.config.LogStoreConfig.Backend == LogStoreBackendWAL && !boltFileExists { + } else if s.config.LogStoreConfig.Backend == LogStoreBackendWAL || s.config.LogStoreConfig.Backend == LogStoreBackendDefault { + // User configured the new storage, but still has old raft.db. Warn + // them! + s.logger.Warn("BoltDB file raft.db found, IGNORING raft_logstore.backend which is set to 'wal'") + } + + // Only use WAL if there is no existing raft.db, even if it's enabled. + if s.config.LogStoreConfig.Backend == LogStoreBackendWAL && !boltFileExists { + s.config.LogStoreConfig.Backend = LogStoreBackendWAL if err = initWAL(); err != nil { return err } } else { - if s.config.LogStoreConfig.Backend == LogStoreBackendWAL { - // User configured the new storage, but still has old raft.db. Warn - // them! - s.logger.Warn("BoltDB file raft.db found, IGNORING raft_logstore.backend which is set to 'wal'") - } s.config.LogStoreConfig.Backend = LogStoreBackendBoltDB // Create the backend raft store for logs and stable storage. store, err := raftboltdb.New(raftboltdb.Options{ @@ -1096,11 +1093,14 @@ func (s *Server) setupRaft() error { // See if log verification is enabled if s.config.LogStoreConfig.Verification.Enabled { + if s.config.LogStoreConfig.Verification.Interval == 0 { + s.config.LogStoreConfig.Verification.Interval = 1 * time.Minute + } mc := walmetrics.NewGoMetricsCollector([]string{"raft", "logstore", "verifier"}, nil, nil) reportFn := makeLogVerifyReportFn(s.logger.Named("raft.logstore.verifier")) - verifier := verifier.NewLogStore(log, isLogVerifyCheckpoint, reportFn, mc) - s.raftStore = verifier - log = verifier + v := verifier.NewLogStore(log, isLogVerifyCheckpoint, reportFn, mc) + s.raftStore = v + log = v } // Wrap the store in a LogCache to improve performance. diff --git a/agent/consul/server_test.go b/agent/consul/server_test.go index f157fa6dd517..96f028635333 100644 --- a/agent/consul/server_test.go +++ b/agent/consul/server_test.go @@ -30,6 +30,9 @@ import ( "github.com/hashicorp/go-uuid" "github.com/hashicorp/memberlist" "github.com/hashicorp/raft" + raftboltdb "github.com/hashicorp/raft-boltdb/v2" + raftwal "github.com/hashicorp/raft-wal" + "github.com/hashicorp/raft-wal/verifier" "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/consul/multilimiter" @@ -2330,3 +2333,88 @@ func TestServer_ControllerDependencies(t *testing.T) { // expected := golden.Get(t, actual, markdownFileName) // require.Equal(t, expected, actual) } + +func TestServer_RaftBackend_Default(t *testing.T) { + t.Parallel() + // Start up a server and then stop it. + _, s1 := testServerWithConfig(t, func(config *Config) { + config.LogStoreConfig.Backend = LogStoreBackendDefault + config.LogStoreConfig.Verification.Enabled = false + }) + _, ok := s1.raftStore.(*raftwal.WAL) + defer func() { + if err := s1.Shutdown(); err != nil { + t.Fatalf("err: %v", err) + } + }() + require.True(t, ok) + +} + +func TestServer_RaftBackend_Verifier_WAL(t *testing.T) { + t.Parallel() + // Start up a server and then stop it. + _, s1 := testServerWithConfig(t, func(config *Config) { + config.LogStoreConfig.Backend = LogStoreBackendDefault + config.LogStoreConfig.Verification.Enabled = true + }) + _, ok := s1.raftStore.(*verifier.LogStore) + defer func() { + if err := s1.Shutdown(); err != nil { + t.Fatalf("err: %v", err) + } + }() + require.True(t, ok) + +} + +func TestServer_RaftBackend_WAL(t *testing.T) { + t.Parallel() + // Start up a server and then stop it. + _, s1 := testServerWithConfig(t, func(config *Config) { + config.LogStoreConfig.Backend = LogStoreBackendWAL + config.LogStoreConfig.Verification.Enabled = false + }) + _, ok := s1.raftStore.(*raftwal.WAL) + defer func() { + if err := s1.Shutdown(); err != nil { + t.Fatalf("err: %v", err) + } + }() + require.True(t, ok) + +} + +func TestServer_RaftBackend_Verifier_BoltDB(t *testing.T) { + t.Parallel() + // Start up a server and then stop it. + _, s1 := testServerWithConfig(t, func(config *Config) { + config.LogStoreConfig.Backend = LogStoreBackendBoltDB + config.LogStoreConfig.Verification.Enabled = true + }) + _, ok := s1.raftStore.(*verifier.LogStore) + defer func() { + if err := s1.Shutdown(); err != nil { + t.Fatalf("err: %v", err) + } + }() + require.True(t, ok) + +} + +func TestServer_RaftBackend_BoltDB(t *testing.T) { + t.Parallel() + // Start up a server and then stop it. + _, s1 := testServerWithConfig(t, func(config *Config) { + config.LogStoreConfig.Backend = LogStoreBackendBoltDB + config.LogStoreConfig.Verification.Enabled = false + }) + _, ok := s1.raftStore.(*raftboltdb.BoltStore) + defer func() { + if err := s1.Shutdown(); err != nil { + t.Fatalf("err: %v", err) + } + }() + require.True(t, ok) + +}