diff --git a/agent/agent.go b/agent/agent.go index e048b33aab..4b4689eb02 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -1263,6 +1263,7 @@ func newConsulConfig(runtimeCfg *config.RuntimeConfig, logger hclog.Logger) (*co } cfg.ConfigEntryBootstrap = runtimeCfg.ConfigEntryBootstrap + cfg.RaftBoltDBConfig = runtimeCfg.RaftBoltDBConfig // Duplicate our own serf config once to make sure that the duplication // function does not drift. diff --git a/agent/config/builder.go b/agent/config/builder.go index 012229ae34..55c9382126 100644 --- a/agent/config/builder.go +++ b/agent/config/builder.go @@ -1094,6 +1094,10 @@ func (b *builder) build() (rt RuntimeConfig, err error) { rt.UseStreamingBackend = boolValWithDefault(c.UseStreamingBackend, true) + if c.RaftBoltDBConfig != nil { + rt.RaftBoltDBConfig = *c.RaftBoltDBConfig + } + if rt.Cache.EntryFetchMaxBurst <= 0 { return RuntimeConfig{}, fmt.Errorf("cache.entry_fetch_max_burst must be strictly positive, was: %v", rt.Cache.EntryFetchMaxBurst) } diff --git a/agent/config/config.go b/agent/config/config.go index 61161b7b58..7d8ecadbb2 100644 --- a/agent/config/config.go +++ b/agent/config/config.go @@ -4,6 +4,8 @@ import ( "encoding/json" "fmt" + "github.com/hashicorp/consul/agent/consul" + "github.com/hashicorp/hcl" "github.com/mitchellh/mapstructure" @@ -256,6 +258,8 @@ type Config struct { RPC RPC `mapstructure:"rpc"` + RaftBoltDBConfig *consul.RaftBoltDBConfig `mapstructure:"raft_boltdb"` + // UseStreamingBackend instead of blocking queries for service health and // any other endpoints which support streaming. UseStreamingBackend *bool `mapstructure:"use_streaming_backend"` diff --git a/agent/config/runtime.go b/agent/config/runtime.go index 2e7d7cf972..e2393363f3 100644 --- a/agent/config/runtime.go +++ b/agent/config/runtime.go @@ -943,6 +943,8 @@ type RuntimeConfig struct { // hcl: raft_trailing_logs = int RaftTrailingLogs int + RaftBoltDBConfig consul.RaftBoltDBConfig + // ReconnectTimeoutLAN specifies the amount of time to wait to reconnect with // another agent before deciding it's permanently gone. This can be used to // control the time it takes to reap failed nodes from the cluster. diff --git a/agent/config/runtime_test.go b/agent/config/runtime_test.go index 390305902c..8abbcc4033 100644 --- a/agent/config/runtime_test.go +++ b/agent/config/runtime_test.go @@ -6015,6 +6015,7 @@ func TestLoad_FullConfig(t *testing.T) { "args": []interface{}{"dltjDJ2a", "flEa7C2d"}, }, }, + RaftBoltDBConfig: consul.RaftBoltDBConfig{NoFreelistSync: true}, } entFullRuntimeConfig(expected) diff --git a/agent/config/testdata/TestRuntimeConfig_Sanitize.golden b/agent/config/testdata/TestRuntimeConfig_Sanitize.golden index 2d1093d1eb..84c303c761 100644 --- a/agent/config/testdata/TestRuntimeConfig_Sanitize.golden +++ b/agent/config/testdata/TestRuntimeConfig_Sanitize.golden @@ -252,6 +252,9 @@ "RPCMaxConnsPerClient": 0, "RPCProtocol": 0, "RPCRateLimit": 0, + "RaftBoltDBConfig": { + "NoFreelistSync": false + }, "RaftProtocol": 3, "RaftSnapshotInterval": "0s", "RaftSnapshotThreshold": 0, diff --git a/agent/config/testdata/full-config.hcl b/agent/config/testdata/full-config.hcl index 939745c9b9..869f672528 100644 --- a/agent/config/testdata/full-config.hcl +++ b/agent/config/testdata/full-config.hcl @@ -328,6 +328,9 @@ raft_protocol = 3 raft_snapshot_threshold = 16384 raft_snapshot_interval = "30s" raft_trailing_logs = 83749 +raft_boltdb { + NoFreelistSync = true +} read_replica = true reconnect_timeout = "23739s" reconnect_timeout_wan = "26694s" diff --git a/agent/config/testdata/full-config.json b/agent/config/testdata/full-config.json index 4649c86bf7..017651d88f 100644 --- a/agent/config/testdata/full-config.json +++ b/agent/config/testdata/full-config.json @@ -326,6 +326,9 @@ "raft_snapshot_threshold": 16384, "raft_snapshot_interval": "30s", "raft_trailing_logs": 83749, + "raft_boltdb": { + "NoFreelistSync": true + }, "read_replica": true, "reconnect_timeout": "23739s", "reconnect_timeout_wan": "26694s", diff --git a/agent/consul/config.go b/agent/consul/config.go index 86c87f5d74..9c343494ac 100644 --- a/agent/consul/config.go +++ b/agent/consul/config.go @@ -391,6 +391,8 @@ type Config struct { RPCConfig RPCConfig + RaftBoltDBConfig RaftBoltDBConfig + // Embedded Consul Enterprise specific configuration *EnterpriseConfig } @@ -603,3 +605,7 @@ type ReloadableConfig struct { RaftSnapshotInterval time.Duration RaftTrailingLogs int } + +type RaftBoltDBConfig struct { + NoFreelistSync bool +} diff --git a/agent/consul/server.go b/agent/consul/server.go index f52e43cacf..45acf95351 100644 --- a/agent/consul/server.go +++ b/agent/consul/server.go @@ -18,6 +18,7 @@ import ( "time" "github.com/hashicorp/go-version" + "go.etcd.io/bbolt" "github.com/armon/go-metrics" connlimit "github.com/hashicorp/go-connlimit" @@ -729,7 +730,12 @@ func (s *Server) setupRaft() error { } // Create the backend raft store for logs and stable storage. - store, err := raftboltdb.NewBoltStore(filepath.Join(path, "raft.db")) + store, err := raftboltdb.New(raftboltdb.Options{ + BoltOptions: &bbolt.Options{ + NoFreelistSync: s.config.RaftBoltDBConfig.NoFreelistSync, + }, + Path: filepath.Join(path, "raft.db"), + }) if err != nil { return err }