github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/base/config.go (about) 1 // Copyright 2015 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package base 12 13 import ( 14 "context" 15 "crypto/tls" 16 "net/http" 17 "net/url" 18 "sync" 19 "time" 20 21 "github.com/cockroachdb/cockroach/pkg/roachpb" 22 "github.com/cockroachdb/cockroach/pkg/security" 23 "github.com/cockroachdb/cockroach/pkg/settings/cluster" 24 "github.com/cockroachdb/cockroach/pkg/util/envutil" 25 "github.com/cockroachdb/cockroach/pkg/util/mon" 26 "github.com/cockroachdb/cockroach/pkg/util/retry" 27 "github.com/cockroachdb/errors" 28 ) 29 30 // Base config defaults. 31 const ( 32 defaultInsecure = false 33 defaultUser = security.RootUser 34 httpScheme = "http" 35 httpsScheme = "https" 36 37 // From IANA Service Name and Transport Protocol Port Number Registry. See 38 // https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=cockroachdb 39 // 40 // This is used for both RPC and SQL connections unless --sql-addr 41 // is used on the command line and/or SQLAddr is set in the Config object. 42 DefaultPort = "26257" 43 44 // The default port for HTTP-for-humans. 45 DefaultHTTPPort = "8080" 46 47 // NB: net.JoinHostPort is not a constant. 48 defaultAddr = ":" + DefaultPort 49 defaultHTTPAddr = ":" + DefaultHTTPPort 50 defaultSQLAddr = ":" + DefaultPort 51 52 // NetworkTimeout is the timeout used for network operations. 53 NetworkTimeout = 3 * time.Second 54 55 // DefaultCertsDirectory is the default value for the cert directory flag. 56 DefaultCertsDirectory = "${HOME}/.cockroach-certs" 57 58 // defaultRaftTickInterval is the default resolution of the Raft timer. 59 defaultRaftTickInterval = 200 * time.Millisecond 60 61 // defaultRangeLeaseRaftElectionTimeoutMultiplier specifies what multiple the 62 // leader lease active duration should be of the raft election timeout. 63 defaultRangeLeaseRaftElectionTimeoutMultiplier = 3 64 65 // NB: this can't easily become a variable as the UI hard-codes it to 10s. 66 // See https://github.com/cockroachdb/cockroach/issues/20310. 67 DefaultMetricsSampleInterval = 10 * time.Second 68 69 // defaultRPCHeartbeatInterval is the default value of RPCHeartbeatInterval 70 // used by the rpc context. 71 defaultRPCHeartbeatInterval = 3 * time.Second 72 73 // rangeLeaseRenewalFraction specifies what fraction the range lease 74 // renewal duration should be of the range lease active time. For example, 75 // with a value of 0.2 and a lease duration of 10 seconds, leases would be 76 // eagerly renewed 2 seconds into each lease. 77 rangeLeaseRenewalFraction = 0.5 78 79 // livenessRenewalFraction specifies what fraction the node liveness 80 // renewal duration should be of the node liveness duration. For example, 81 // with a value of 0.2 and a liveness duration of 10 seconds, each node's 82 // liveness record would be eagerly renewed after 2 seconds. 83 livenessRenewalFraction = 0.5 84 85 // DefaultTableDescriptorLeaseDuration is the default mean duration a 86 // lease will be acquired for. The actual duration is jittered using 87 // the jitter fraction. Jittering is done to prevent multiple leases 88 // from being renewed simultaneously if they were all acquired 89 // simultaneously. 90 DefaultTableDescriptorLeaseDuration = 5 * time.Minute 91 92 // DefaultTableDescriptorLeaseJitterFraction is the default factor 93 // that we use to randomly jitter the lease duration when acquiring a 94 // new lease and the lease renewal timeout. 95 DefaultTableDescriptorLeaseJitterFraction = 0.05 96 97 // DefaultTableDescriptorLeaseRenewalTimeout is the default time 98 // before a lease expires when acquisition to renew the lease begins. 99 DefaultTableDescriptorLeaseRenewalTimeout = time.Minute 100 ) 101 102 // DefaultHistogramWindowInterval returns the default rotation window for 103 // histograms. 104 func DefaultHistogramWindowInterval() time.Duration { 105 const defHWI = 6 * DefaultMetricsSampleInterval 106 107 // Rudimentary overflow detection; this can result if 108 // DefaultMetricsSampleInterval is set to an extremely large number, likely 109 // in the context of a test or an intentional attempt to disable metrics 110 // collection. Just return the default in this case. 111 if defHWI < DefaultMetricsSampleInterval { 112 return DefaultMetricsSampleInterval 113 } 114 return defHWI 115 } 116 117 var ( 118 // defaultRaftElectionTimeoutTicks specifies the number of Raft Tick 119 // invocations that must pass between elections. 120 defaultRaftElectionTimeoutTicks = envutil.EnvOrDefaultInt( 121 "COCKROACH_RAFT_ELECTION_TIMEOUT_TICKS", 15) 122 123 // defaultRaftLogTruncationThreshold specifies the upper bound that a single 124 // Range's Raft log can grow to before log truncations are triggered while at 125 // least one follower is missing. If all followers are active, the quota pool 126 // is responsible for ensuring the raft log doesn't grow without bound by 127 // making sure the leader doesn't get too far ahead. 128 defaultRaftLogTruncationThreshold = envutil.EnvOrDefaultInt64( 129 "COCKROACH_RAFT_LOG_TRUNCATION_THRESHOLD", 8<<20 /* 8 MB */) 130 131 // defaultRaftMaxSizePerMsg specifies the maximum aggregate byte size of Raft 132 // log entries that a leader will send to followers in a single MsgApp. 133 defaultRaftMaxSizePerMsg = envutil.EnvOrDefaultInt( 134 "COCKROACH_RAFT_MAX_SIZE_PER_MSG", 32<<10 /* 32 KB */) 135 136 // defaultRaftMaxSizeCommittedSizePerReady specifies the maximum aggregate 137 // byte size of the committed log entries which a node will receive in a 138 // single Ready. 139 defaultRaftMaxCommittedSizePerReady = envutil.EnvOrDefaultInt( 140 "COCKROACH_RAFT_MAX_COMMITTED_SIZE_PER_READY", 64<<20 /* 64 MB */) 141 142 // defaultRaftMaxInflightMsgs specifies how many "inflight" MsgApps a leader 143 // will send to a given follower without hearing a response. 144 defaultRaftMaxInflightMsgs = envutil.EnvOrDefaultInt( 145 "COCKROACH_RAFT_MAX_INFLIGHT_MSGS", 128) 146 ) 147 148 type lazyHTTPClient struct { 149 once sync.Once 150 httpClient http.Client 151 err error 152 } 153 154 type lazyCertificateManager struct { 155 once sync.Once 156 cm *security.CertificateManager 157 err error 158 } 159 160 // Config is embedded by server.Config. A base config is not meant to be used 161 // directly, but embedding configs should call cfg.InitDefaults(). 162 type Config struct { 163 // Insecure specifies whether to use SSL or not. 164 // This is really not recommended. 165 Insecure bool 166 167 // SSLCAKey is used to sign new certs. 168 SSLCAKey string 169 // SSLCertsDir is the path to the certificate/key directory. 170 SSLCertsDir string 171 172 // User running this process. It could be the user under which 173 // the server is running or the user passed in client calls. 174 User string 175 176 // Addr is the address the server is listening on. 177 Addr string 178 179 // AdvertiseAddr is the address advertised by the server to other nodes 180 // in the cluster. It should be reachable by all other nodes and should 181 // route to an interface that Addr is listening on. 182 AdvertiseAddr string 183 184 // ClusterName is the name used as a sanity check when a node joins 185 // an uninitialized cluster, or when an uninitialized node joins an 186 // initialized cluster. The initial RPC handshake verifies that the 187 // name matches on both sides. Once the cluster ID has been 188 // negotiated on both sides, the cluster name is not used any more. 189 ClusterName string 190 191 // DisableClusterNameVerification, when set, alters the cluster name 192 // verification to only verify that a non-empty cluster name on 193 // both sides match. This is meant for use while rolling an 194 // existing cluster into using a new cluster name. 195 DisableClusterNameVerification bool 196 197 // SplitListenSQL indicates whether to listen for SQL 198 // clients on a separate address from RPC requests. 199 SplitListenSQL bool 200 201 // SQLAddr is the configured SQL listen address. 202 // This is used if SplitListenSQL is set to true. 203 SQLAddr string 204 205 // SQLAdvertiseAddr is the advertised SQL address. 206 // This is computed from SQLAddr if specified otherwise Addr. 207 SQLAdvertiseAddr string 208 209 // HTTPAddr is the configured HTTP listen address. 210 HTTPAddr string 211 212 // DisableTLSForHTTP, if set, disables TLS for the HTTP listener. 213 DisableTLSForHTTP bool 214 215 // HTTPAdvertiseAddr is the advertised HTTP address. 216 // This is computed from HTTPAddr if specified otherwise Addr. 217 HTTPAdvertiseAddr string 218 219 // The certificate manager. Must be accessed through GetCertificateManager. 220 certificateManager lazyCertificateManager 221 222 // httpClient uses the client TLS config. It is initialized lazily. 223 httpClient lazyHTTPClient 224 225 // RPCHeartbeatInterval controls how often a Ping request is sent on peer 226 // connections to determine connection health and update the local view 227 // of remote clocks. 228 RPCHeartbeatInterval time.Duration 229 230 // Enables the use of an PTP hardware clock user space API for HLC current time. 231 // This contains the path to the device to be used (i.e. /dev/ptp0) 232 ClockDevicePath string 233 } 234 235 // HistogramWindowInterval is used to determine the approximate length of time 236 // that individual samples are retained in in-memory histograms. Currently, 237 // it is set to the arbitrary length of six times the Metrics sample interval. 238 // 239 // The length of the window must be longer than the sampling interval due to 240 // issue #12998, which was causing histograms to return zero values when sampled 241 // because all samples had been evicted. 242 // 243 // Note that this is only intended to be a temporary fix for the above issue, 244 // as our current handling of metric histograms have numerous additional 245 // problems. These are tracked in github issue #7896, which has been given 246 // a relatively high priority in light of recent confusion around histogram 247 // metrics. For more information on the issues underlying our histogram system 248 // and the proposed fixes, please see issue #7896. 249 func (*Config) HistogramWindowInterval() time.Duration { 250 return DefaultHistogramWindowInterval() 251 } 252 253 func wrapError(err error) error { 254 if !errors.HasType(err, (*security.Error)(nil)) { 255 return &security.Error{ 256 Message: "problem using security settings", 257 Err: err, 258 } 259 } 260 return err 261 } 262 263 // InitDefaults sets up the default values for a config. 264 // This is also used in tests to reset global objects. 265 func (cfg *Config) InitDefaults() { 266 cfg.Insecure = defaultInsecure 267 cfg.User = defaultUser 268 cfg.Addr = defaultAddr 269 cfg.AdvertiseAddr = cfg.Addr 270 cfg.HTTPAddr = defaultHTTPAddr 271 cfg.DisableTLSForHTTP = false 272 cfg.HTTPAdvertiseAddr = "" 273 cfg.SplitListenSQL = false 274 cfg.SQLAddr = defaultSQLAddr 275 cfg.SQLAdvertiseAddr = cfg.SQLAddr 276 cfg.SSLCertsDir = DefaultCertsDirectory 277 cfg.certificateManager = lazyCertificateManager{} 278 cfg.RPCHeartbeatInterval = defaultRPCHeartbeatInterval 279 cfg.ClusterName = "" 280 cfg.DisableClusterNameVerification = false 281 cfg.ClockDevicePath = "" 282 } 283 284 // HTTPRequestScheme returns "http" or "https" based on the value of 285 // Insecure and DisableTLSForHTTP. 286 func (cfg *Config) HTTPRequestScheme() string { 287 if cfg.Insecure || cfg.DisableTLSForHTTP { 288 return httpScheme 289 } 290 return httpsScheme 291 } 292 293 // AdminURL returns the URL for the admin UI. 294 func (cfg *Config) AdminURL() *url.URL { 295 return &url.URL{ 296 Scheme: cfg.HTTPRequestScheme(), 297 Host: cfg.HTTPAdvertiseAddr, 298 } 299 } 300 301 // getClientCertPaths returns the paths to the client cert and key. 302 func (cfg *Config) getClientCertPaths(user string) (string, string, error) { 303 cm, err := cfg.GetCertificateManager() 304 if err != nil { 305 return "", "", err 306 } 307 return cm.GetClientCertPaths(user) 308 } 309 310 // getCACertPath returns the path to the CA certificate. 311 func (cfg *Config) getCACertPath() (string, error) { 312 cm, err := cfg.GetCertificateManager() 313 if err != nil { 314 return "", err 315 } 316 return cm.GetCACertPath() 317 } 318 319 // LoadSecurityOptions extends a url.Values with SSL settings suitable for 320 // the given server config. It returns true if and only if the URL 321 // already contained SSL config options. 322 func (cfg *Config) LoadSecurityOptions(options url.Values, username string) error { 323 if cfg.Insecure { 324 options.Set("sslmode", "disable") 325 options.Del("sslrootcert") 326 options.Del("sslcert") 327 options.Del("sslkey") 328 } else { 329 sslMode := options.Get("sslmode") 330 if sslMode == "" || sslMode == "disable" { 331 options.Set("sslmode", "verify-full") 332 } 333 334 if sslMode != "require" { 335 // verify-ca and verify-full need a CA certificate. 336 if options.Get("sslrootcert") == "" { 337 // Fetch CA cert. This is required. 338 caCertPath, err := cfg.getCACertPath() 339 if err != nil { 340 return wrapError(err) 341 } 342 options.Set("sslrootcert", caCertPath) 343 } 344 } else { 345 // require does not check the CA. 346 options.Del("sslrootcert") 347 } 348 349 // Fetch certs, but don't fail, we may be using a password. 350 certPath, keyPath, err := cfg.getClientCertPaths(username) 351 if err == nil { 352 if options.Get("sslcert") == "" { 353 options.Set("sslcert", certPath) 354 } 355 if options.Get("sslkey") == "" { 356 options.Set("sslkey", keyPath) 357 } 358 } 359 } 360 return nil 361 } 362 363 // PGURL constructs a URL for the postgres endpoint, given a server 364 // config. There is no default database set. 365 func (cfg *Config) PGURL(user *url.Userinfo) (*url.URL, error) { 366 options := url.Values{} 367 if err := cfg.LoadSecurityOptions(options, user.Username()); err != nil { 368 return nil, err 369 } 370 return &url.URL{ 371 Scheme: "postgresql", 372 User: user, 373 Host: cfg.SQLAdvertiseAddr, 374 RawQuery: options.Encode(), 375 }, nil 376 } 377 378 // GetCertificateManager returns the certificate manager, initializing it 379 // on the first call. 380 func (cfg *Config) GetCertificateManager() (*security.CertificateManager, error) { 381 cfg.certificateManager.once.Do(func() { 382 cfg.certificateManager.cm, cfg.certificateManager.err = 383 security.NewCertificateManager(cfg.SSLCertsDir) 384 }) 385 return cfg.certificateManager.cm, cfg.certificateManager.err 386 } 387 388 // GetClientTLSConfig returns the client TLS config, initializing it if needed. 389 // If Insecure is true, return a nil config, otherwise ask the certificate 390 // manager for a TLS config using certs for the config.User. 391 // This TLSConfig might **NOT** be suitable to talk to the Admin UI, use GetUIClientTLSConfig instead. 392 func (cfg *Config) GetClientTLSConfig() (*tls.Config, error) { 393 // Early out. 394 if cfg.Insecure { 395 return nil, nil 396 } 397 398 cm, err := cfg.GetCertificateManager() 399 if err != nil { 400 return nil, wrapError(err) 401 } 402 403 tlsCfg, err := cm.GetClientTLSConfig(cfg.User) 404 if err != nil { 405 return nil, wrapError(err) 406 } 407 return tlsCfg, nil 408 } 409 410 // getUIClientTLSConfig returns the client TLS config for Admin UI clients, initializing it if needed. 411 // If Insecure is true, return a nil config, otherwise ask the certificate 412 // manager for a TLS config configured to talk to the Admin UI. 413 // This TLSConfig is **NOT** suitable to talk to the GRPC or SQL servers, use GetClientTLSConfig instead. 414 func (cfg *Config) getUIClientTLSConfig() (*tls.Config, error) { 415 // Early out. 416 if cfg.Insecure { 417 return nil, nil 418 } 419 420 cm, err := cfg.GetCertificateManager() 421 if err != nil { 422 return nil, wrapError(err) 423 } 424 425 tlsCfg, err := cm.GetUIClientTLSConfig() 426 if err != nil { 427 return nil, wrapError(err) 428 } 429 return tlsCfg, nil 430 } 431 432 // GetServerTLSConfig returns the server TLS config, initializing it if needed. 433 // If Insecure is true, return a nil config, otherwise ask the certificate 434 // manager for a server TLS config. 435 func (cfg *Config) GetServerTLSConfig() (*tls.Config, error) { 436 // Early out. 437 if cfg.Insecure { 438 return nil, nil 439 } 440 441 cm, err := cfg.GetCertificateManager() 442 if err != nil { 443 return nil, wrapError(err) 444 } 445 446 tlsCfg, err := cm.GetServerTLSConfig() 447 if err != nil { 448 return nil, wrapError(err) 449 } 450 return tlsCfg, nil 451 } 452 453 // GetUIServerTLSConfig returns the server TLS config for the Admin UI, initializing it if needed. 454 // If Insecure is true, return a nil config, otherwise ask the certificate 455 // manager for a server UI TLS config. 456 // 457 // TODO(peter): This method is only used by `server.NewServer` and 458 // `Server.Start`. Move it. 459 func (cfg *Config) GetUIServerTLSConfig() (*tls.Config, error) { 460 // Early out. 461 if cfg.Insecure || cfg.DisableTLSForHTTP { 462 return nil, nil 463 } 464 465 cm, err := cfg.GetCertificateManager() 466 if err != nil { 467 return nil, wrapError(err) 468 } 469 470 tlsCfg, err := cm.GetUIServerTLSConfig() 471 if err != nil { 472 return nil, wrapError(err) 473 } 474 return tlsCfg, nil 475 } 476 477 // GetHTTPClient returns the http client, initializing it 478 // if needed. It uses the client TLS config. 479 func (cfg *Config) GetHTTPClient() (http.Client, error) { 480 cfg.httpClient.once.Do(func() { 481 cfg.httpClient.httpClient.Timeout = 10 * time.Second 482 var transport http.Transport 483 cfg.httpClient.httpClient.Transport = &transport 484 transport.TLSClientConfig, cfg.httpClient.err = cfg.getUIClientTLSConfig() 485 }) 486 487 return cfg.httpClient.httpClient, cfg.httpClient.err 488 } 489 490 // RaftConfig holds raft tuning parameters. 491 type RaftConfig struct { 492 // RaftTickInterval is the resolution of the Raft timer. 493 RaftTickInterval time.Duration 494 495 // RaftElectionTimeoutTicks is the number of raft ticks before the 496 // previous election expires. This value is inherited by individual stores 497 // unless overridden. 498 RaftElectionTimeoutTicks int 499 500 // RangeLeaseRaftElectionTimeoutMultiplier specifies what multiple the leader 501 // lease active duration should be of the raft election timeout. 502 RangeLeaseRaftElectionTimeoutMultiplier float64 503 504 // RaftLogTruncationThreshold controls how large a single Range's Raft log 505 // can grow. When a Range's Raft log grows above this size, the Range will 506 // begin performing log truncations. 507 RaftLogTruncationThreshold int64 508 509 // RaftProposalQuota controls the maximum aggregate size of Raft commands 510 // that a leader is allowed to propose concurrently. 511 // 512 // By default, the quota is set to a fraction of the Raft log truncation 513 // threshold. In doing so, we ensure all replicas have sufficiently up to 514 // date logs so that when the log gets truncated, the followers do not need 515 // non-preemptive snapshots. Changing this deserves care. Too low and 516 // everything comes to a grinding halt, too high and we're not really 517 // throttling anything (we'll still generate snapshots). 518 RaftProposalQuota int64 519 520 // RaftMaxUncommittedEntriesSize controls how large the uncommitted tail of 521 // the Raft log can grow. The limit is meant to provide protection against 522 // unbounded Raft log growth when quorum is lost and entries stop being 523 // committed but continue to be proposed. 524 RaftMaxUncommittedEntriesSize uint64 525 526 // RaftMaxSizePerMsg controls the maximum aggregate byte size of Raft log 527 // entries the leader will send to followers in a single MsgApp. Smaller 528 // value lowers the raft recovery cost (during initial probing and after 529 // message loss during normal operation). On the other hand, it limits the 530 // throughput during normal replication. 531 RaftMaxSizePerMsg uint64 532 533 // RaftMaxCommittedSizePerReady controls the maximum aggregate byte size of 534 // committed Raft log entries a replica will receive in a single Ready. 535 RaftMaxCommittedSizePerReady uint64 536 537 // RaftMaxInflightMsgs controls how many "inflight" MsgApps Raft will send 538 // to a follower without hearing a response. The total number of Raft log 539 // entries is a combination of this setting and RaftMaxSizePerMsg. The 540 // current default settings provide for up to 4 MB of raft log to be sent 541 // without acknowledgement. With an average entry size of 1 KB that 542 // translates to ~4096 commands that might be executed in the handling of a 543 // single raft.Ready operation. 544 RaftMaxInflightMsgs int 545 546 // Splitting a range which has a replica needing a snapshot results in two 547 // ranges in that state. The delay configured here slows down splits when in 548 // that situation (limiting to those splits not run through the split 549 // queue). The most important target here are the splits performed by 550 // backup/restore. 551 // 552 // -1 to disable. 553 RaftDelaySplitToSuppressSnapshotTicks int 554 } 555 556 // SetDefaults initializes unset fields. 557 func (cfg *RaftConfig) SetDefaults() { 558 if cfg.RaftTickInterval == 0 { 559 cfg.RaftTickInterval = defaultRaftTickInterval 560 } 561 if cfg.RaftElectionTimeoutTicks == 0 { 562 cfg.RaftElectionTimeoutTicks = defaultRaftElectionTimeoutTicks 563 } 564 if cfg.RangeLeaseRaftElectionTimeoutMultiplier == 0 { 565 cfg.RangeLeaseRaftElectionTimeoutMultiplier = defaultRangeLeaseRaftElectionTimeoutMultiplier 566 } 567 if cfg.RaftLogTruncationThreshold == 0 { 568 cfg.RaftLogTruncationThreshold = defaultRaftLogTruncationThreshold 569 } 570 if cfg.RaftProposalQuota == 0 { 571 // By default, set this to a fraction of RaftLogMaxSize. See the comment 572 // on the field for the tradeoffs of setting this higher or lower. 573 cfg.RaftProposalQuota = cfg.RaftLogTruncationThreshold / 2 574 } 575 if cfg.RaftMaxUncommittedEntriesSize == 0 { 576 // By default, set this to twice the RaftProposalQuota. The logic here 577 // is that the quotaPool should be responsible for throttling proposals 578 // in all cases except for unbounded Raft re-proposals because it queues 579 // efficiently instead of dropping proposals on the floor indiscriminately. 580 cfg.RaftMaxUncommittedEntriesSize = uint64(2 * cfg.RaftProposalQuota) 581 } 582 if cfg.RaftMaxSizePerMsg == 0 { 583 cfg.RaftMaxSizePerMsg = uint64(defaultRaftMaxSizePerMsg) 584 } 585 if cfg.RaftMaxCommittedSizePerReady == 0 { 586 cfg.RaftMaxCommittedSizePerReady = uint64(defaultRaftMaxCommittedSizePerReady) 587 } 588 if cfg.RaftMaxInflightMsgs == 0 { 589 cfg.RaftMaxInflightMsgs = defaultRaftMaxInflightMsgs 590 } 591 if cfg.RaftDelaySplitToSuppressSnapshotTicks == 0 { 592 // The Raft Ticks interval defaults to 200ms, and an election is 15 593 // ticks. Add a generous amount of ticks to make sure even a backed up 594 // Raft snapshot queue is going to make progress when a (not overly 595 // concurrent) amount of splits happens. 596 // The generous amount should result in a delay sufficient to 597 // transmit at least one snapshot with the slow delay, which 598 // with default settings is max 64MB at 2MB/s, ie 32 seconds. 599 // 600 // The resulting delay configured here is about 50s. 601 cfg.RaftDelaySplitToSuppressSnapshotTicks = 3*cfg.RaftElectionTimeoutTicks + 200 602 } 603 604 // Minor validation to ensure sane tuning. 605 if cfg.RaftProposalQuota > int64(cfg.RaftMaxUncommittedEntriesSize) { 606 panic("raft proposal quota should not be above max uncommitted entries size") 607 } 608 if cfg.RaftProposalQuota < int64(cfg.RaftMaxSizePerMsg)*int64(cfg.RaftMaxInflightMsgs) { 609 panic("raft proposal quota should not be below per-replica replication window size") 610 } 611 } 612 613 // RaftElectionTimeout returns the raft election timeout, as computed from the 614 // tick interval and number of election timeout ticks. 615 func (cfg RaftConfig) RaftElectionTimeout() time.Duration { 616 return time.Duration(cfg.RaftElectionTimeoutTicks) * cfg.RaftTickInterval 617 } 618 619 // RangeLeaseDurations computes durations for range lease expiration and 620 // renewal based on a default multiple of Raft election timeout. 621 func (cfg RaftConfig) RangeLeaseDurations() (rangeLeaseActive, rangeLeaseRenewal time.Duration) { 622 rangeLeaseActive = time.Duration(cfg.RangeLeaseRaftElectionTimeoutMultiplier * 623 float64(cfg.RaftElectionTimeout())) 624 rangeLeaseRenewal = time.Duration(float64(rangeLeaseActive) * rangeLeaseRenewalFraction) 625 return 626 } 627 628 // RangeLeaseActiveDuration is the duration of the active period of leader 629 // leases requested. 630 func (cfg RaftConfig) RangeLeaseActiveDuration() time.Duration { 631 rangeLeaseActive, _ := cfg.RangeLeaseDurations() 632 return rangeLeaseActive 633 } 634 635 // RangeLeaseRenewalDuration specifies a time interval at the end of the 636 // active lease interval (i.e. bounded to the right by the start of the stasis 637 // period) during which operations will trigger an asynchronous renewal of the 638 // lease. 639 func (cfg RaftConfig) RangeLeaseRenewalDuration() time.Duration { 640 _, rangeLeaseRenewal := cfg.RangeLeaseDurations() 641 return rangeLeaseRenewal 642 } 643 644 // NodeLivenessDurations computes durations for node liveness expiration and 645 // renewal based on a default multiple of Raft election timeout. 646 func (cfg RaftConfig) NodeLivenessDurations() (livenessActive, livenessRenewal time.Duration) { 647 livenessActive = cfg.RangeLeaseActiveDuration() 648 livenessRenewal = time.Duration(float64(livenessActive) * livenessRenewalFraction) 649 return 650 } 651 652 // SentinelGossipTTL is time-to-live for the gossip sentinel. The sentinel 653 // informs a node whether or not it's connected to the primary gossip network 654 // and not just a partition. As such it must expire fairly quickly and be 655 // continually re-gossiped as a connected gossip network is necessary to 656 // propagate liveness. The replica which is the lease holder of the first range 657 // gossips it. 658 func (cfg RaftConfig) SentinelGossipTTL() time.Duration { 659 return cfg.RangeLeaseActiveDuration() / 2 660 } 661 662 // DefaultRetryOptions should be used for retrying most 663 // network-dependent operations. 664 func DefaultRetryOptions() retry.Options { 665 // TODO(bdarnell): This should vary with network latency. 666 // Derive the retry options from a configured or measured 667 // estimate of latency. 668 return retry.Options{ 669 InitialBackoff: 50 * time.Millisecond, 670 MaxBackoff: 1 * time.Second, 671 Multiplier: 2, 672 } 673 } 674 675 // StorageConfig contains storage configs for all storage engine. 676 type StorageConfig struct { 677 Attrs roachpb.Attributes 678 // Dir is the data directory for the Pebble instance. 679 Dir string 680 // If true, creating the instance fails if the target directory does not hold 681 // an initialized instance. 682 // 683 // Makes no sense for in-memory instances. 684 MustExist bool 685 // MaxSize is used for calculating free space and making rebalancing 686 // decisions. Zero indicates that there is no maximum size. 687 MaxSize int64 688 // Settings instance for cluster-wide knobs. 689 Settings *cluster.Settings 690 // UseFileRegistry is true if the file registry is needed (eg: encryption-at-rest). 691 // This may force the store version to versionFileRegistry if currently lower. 692 UseFileRegistry bool 693 // ExtraOptions is a serialized protobuf set by Go CCL code and passed through 694 // to C CCL code. 695 ExtraOptions []byte 696 } 697 698 const ( 699 // DefaultTempStorageMaxSizeBytes is the default maximum budget 700 // for temp storage. 701 DefaultTempStorageMaxSizeBytes = 32 * 1024 * 1024 * 1024 /* 32GB */ 702 // DefaultInMemTempStorageMaxSizeBytes is the default maximum budget 703 // for in-memory temp storages. 704 DefaultInMemTempStorageMaxSizeBytes = 100 * 1024 * 1024 /* 100MB */ 705 ) 706 707 // TempStorageConfig contains the details that can be specified in the cli 708 // pertaining to temp storage flags, specifically --temp-dir and 709 // --max-disk-temp-storage. 710 type TempStorageConfig struct { 711 // InMemory specifies whether the temporary storage will remain 712 // in-memory or occupy a temporary subdirectory on-disk. 713 InMemory bool 714 // Path is the filepath of the temporary subdirectory created for 715 // the temp storage. 716 Path string 717 // Mon will be used by the temp storage to register all its capacity requests. 718 // It can be used to limit the disk or memory that temp storage is allowed to 719 // use. If InMemory is set, than this has to be a memory monitor; otherwise it 720 // has to be a disk monitor. 721 Mon *mon.BytesMonitor 722 // Spec stores the StoreSpec this TempStorageConfig will use. 723 Spec StoreSpec 724 } 725 726 // ExternalIODirConfig describes various configuration options pertaining 727 // to external storage implementations. 728 type ExternalIODirConfig struct { 729 // Disables the use of external HTTP endpoints. 730 // This turns off http:// external storage as well as any custom 731 // endpoints cloud storage implementations. 732 DisableHTTP bool 733 // Disables the use of implicit credentials when accessing external services. 734 // Implicit credentials are obtained from the system environment. 735 // This turns off implicit credentials, and requires the user to provide 736 // necessary access keys. 737 DisableImplicitCredentials bool 738 } 739 740 // TempStorageConfigFromEnv creates a TempStorageConfig. 741 // If parentDir is not specified and the specified store is in-memory, 742 // then the temp storage will also be in-memory. 743 func TempStorageConfigFromEnv( 744 ctx context.Context, 745 st *cluster.Settings, 746 useStore StoreSpec, 747 parentDir string, 748 maxSizeBytes int64, 749 ) TempStorageConfig { 750 inMem := parentDir == "" && useStore.InMemory 751 var monitorName string 752 if inMem { 753 monitorName = "in-mem temp storage" 754 } else { 755 monitorName = "temp disk storage" 756 } 757 monitor := mon.MakeMonitor( 758 monitorName, 759 mon.DiskResource, 760 nil, /* curCount */ 761 nil, /* maxHist */ 762 1024*1024, /* increment */ 763 maxSizeBytes/10, /* noteworthy */ 764 st, 765 ) 766 monitor.Start(ctx, nil /* pool */, mon.MakeStandaloneBudget(maxSizeBytes)) 767 return TempStorageConfig{ 768 InMemory: inMem, 769 Mon: &monitor, 770 Spec: useStore, 771 } 772 } 773 774 // LeaseManagerConfig holds table lease manager parameters. 775 type LeaseManagerConfig struct { 776 // TableDescriptorLeaseDuration is the mean duration a lease will be 777 // acquired for. 778 TableDescriptorLeaseDuration time.Duration 779 780 // TableDescriptorLeaseJitterFraction is the factor that we use to 781 // randomly jitter the lease duration when acquiring a new lease and 782 // the lease renewal timeout. 783 TableDescriptorLeaseJitterFraction float64 784 785 // DefaultTableDescriptorLeaseRenewalTimeout is the default time 786 // before a lease expires when acquisition to renew the lease begins. 787 TableDescriptorLeaseRenewalTimeout time.Duration 788 } 789 790 // NewLeaseManagerConfig initializes a LeaseManagerConfig with default values. 791 func NewLeaseManagerConfig() *LeaseManagerConfig { 792 return &LeaseManagerConfig{ 793 TableDescriptorLeaseDuration: DefaultTableDescriptorLeaseDuration, 794 TableDescriptorLeaseJitterFraction: DefaultTableDescriptorLeaseJitterFraction, 795 TableDescriptorLeaseRenewalTimeout: DefaultTableDescriptorLeaseRenewalTimeout, 796 } 797 }