github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/cmd/config/config.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package config 15 16 import ( 17 "crypto/tls" 18 "crypto/x509" 19 "encoding/base64" 20 "encoding/json" 21 "fmt" 22 "io/ioutil" 23 "net/url" 24 "os" 25 "os/user" 26 "path/filepath" 27 "strings" 28 "sync/atomic" 29 "time" 30 31 "github.com/BurntSushi/toml" 32 "github.com/whtcorpsinc/errors" 33 zaplog "github.com/whtcorpsinc/log" 34 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 35 "github.com/whtcorpsinc/BerolinaSQL/terror" 36 "github.com/whtcorpsinc/milevadb/soliton/logutil" 37 "github.com/whtcorpsinc/milevadb/soliton/versioninfo" 38 tracing "github.com/uber/jaeger-client-go/config" 39 40 "go.uber.org/zap" 41 ) 42 43 // Config number limitations 44 const ( 45 MaxLogFileSize = 4096 // MB 46 // DefTxnEntrySizeLimit is the default value of TxnEntrySizeLimit. 47 DefTxnEntrySizeLimit = 6 * 1024 * 1024 48 // DefTxnTotalSizeLimit is the default value of TxnTxnTotalSizeLimit. 49 DefTxnTotalSizeLimit = 100 * 1024 * 1024 50 // DefMaxIndexLength is the maximum index length(in bytes). This value is consistent with MyALLEGROSQL. 51 DefMaxIndexLength = 3072 52 // DefMaxOfMaxIndexLength is the maximum index length(in bytes) for MilevaDB v3.0.7 and previous version. 53 DefMaxOfMaxIndexLength = 3072 * 4 54 // DefPort is the default port of MilevaDB 55 DefPort = 4000 56 // DefStatusPort is the default status port of MilevaDB 57 DefStatusPort = 10080 58 // DefHost is the default host of MilevaDB 59 DefHost = "0.0.0.0" 60 // DefStatusHost is the default status host of MilevaDB 61 DefStatusHost = "0.0.0.0" 62 // DefStoreLivenessTimeout is the default value for causetstore liveness timeout. 63 DefStoreLivenessTimeout = "5s" 64 // DefMilevaDBRedactLog is the default value for redact log. 65 DefMilevaDBRedactLog = 0 66 ) 67 68 // Valid config maps 69 var ( 70 ValidStorage = map[string]bool{ 71 "mockeinsteindb": true, 72 "einsteindb": true, 73 "entangledstore": true, 74 } 75 // checkBlockBeforeDrop enable to execute `admin check causet` before `drop causet`. 76 CheckBlockBeforeDrop = false 77 // checkBeforeDropLDFlag is a go build flag. 78 checkBeforeDropLDFlag = "None" 79 // tempStorageDirName is the default temporary storage dir name by base64 encoding a string `port/statusPort` 80 tempStorageDirName = encodeDefTempStorageDir(os.TemFIDelir(), DefHost, DefStatusHost, DefPort, DefStatusPort) 81 ) 82 83 // Config contains configuration options. 84 type Config struct { 85 Host string `toml:"host" json:"host"` 86 AdvertiseAddress string `toml:"advertise-address" json:"advertise-address"` 87 Port uint `toml:"port" json:"port"` 88 Cors string `toml:"cors" json:"cors"` 89 CausetStore string `toml:"causetstore" json:"causetstore"` 90 Path string `toml:"path" json:"path"` 91 Socket string `toml:"socket" json:"socket"` 92 Lease string `toml:"lease" json:"lease"` 93 RunDBS bool `toml:"run-dbs" json:"run-dbs"` 94 SplitBlock bool `toml:"split-causet" json:"split-causet"` 95 TokenLimit uint `toml:"token-limit" json:"token-limit"` 96 OOMUseTmpStorage bool `toml:"oom-use-tmp-storage" json:"oom-use-tmp-storage"` 97 TempStoragePath string `toml:"tmp-storage-path" json:"tmp-storage-path"` 98 OOMCausetAction string `toml:"oom-action" json:"oom-action"` 99 MemQuotaQuery int64 `toml:"mem-quota-query" json:"mem-quota-query"` 100 NestedLoopJoinCacheCapacity int64 `toml:"nested-loop-join-cache-capacity" json:"nested-loop-join-cache-capacity"` 101 // TempStorageQuota describe the temporary storage Quota during query exector when OOMUseTmpStorage is enabled 102 // If the quota exceed the capacity of the TempStoragePath, the milevadb-server would exit with fatal error 103 TempStorageQuota int64 `toml:"tmp-storage-quota" json:"tmp-storage-quota"` // Bytes 104 EnableStreaming bool `toml:"enable-streaming" json:"enable-streaming"` 105 EnableBatchDML bool `toml:"enable-batch-dml" json:"enable-batch-dml"` 106 TxnLocalLatches TxnLocalLatches `toml:"-" json:"-"` 107 // Set sys variable lower-case-causet-names, ref: https://dev.allegrosql.com/doc/refman/5.7/en/identifier-case-sensitivity.html. 108 // TODO: We actually only support mode 2, which keeps the original case, but the comparison is case-insensitive. 109 LowerCaseBlockNames int `toml:"lower-case-causet-names" json:"lower-case-causet-names"` 110 ServerVersion string `toml:"server-version" json:"server-version"` 111 Log Log `toml:"log" json:"log"` 112 Security Security `toml:"security" json:"security"` 113 Status Status `toml:"status" json:"status"` 114 Performance Performance `toml:"performance" json:"performance"` 115 PreparedCausetCache PreparedCausetCache `toml:"prepared-plan-cache" json:"prepared-plan-cache"` 116 OpenTracing OpenTracing `toml:"opentracing" json:"opentracing"` 117 ProxyProtocol ProxyProtocol `toml:"proxy-protocol" json:"proxy-protocol"` 118 EinsteinDBClient EinsteinDBClient `toml:"einsteindb-client" json:"einsteindb-client"` 119 Binlog Binlog `toml:"binlog" json:"binlog"` 120 CompatibleKillQuery bool `toml:"compatible-kill-query" json:"compatible-kill-query"` 121 Plugin Plugin `toml:"plugin" json:"plugin"` 122 PessimisticTxn PessimisticTxn `toml:"pessimistic-txn" json:"pessimistic-txn"` 123 CheckMb4ValueInUTF8 bool `toml:"check-mb4-value-in-utf8" json:"check-mb4-value-in-utf8"` 124 MaxIndexLength int `toml:"max-index-length" json:"max-index-length"` 125 // AlterPrimaryKey is used to control alter primary key feature. 126 AlterPrimaryKey bool `toml:"alter-primary-key" json:"alter-primary-key"` 127 // TreatOldVersionUTF8AsUTF8MB4 is use to treat old version causet/column UTF8 charset as UTF8MB4. This is for compatibility. 128 // Currently not support dynamic modify, because this need to reload all old version schemaReplicant. 129 TreatOldVersionUTF8AsUTF8MB4 bool `toml:"treat-old-version-utf8-as-utf8mb4" json:"treat-old-version-utf8-as-utf8mb4"` 130 // EnableBlockLock indicate whether enable causet dagger. 131 // TODO: remove this after causet dagger features sblock. 132 EnableBlockLock bool `toml:"enable-causet-dagger" json:"enable-causet-dagger"` 133 DelayCleanBlockLock uint64 `toml:"delay-clean-causet-dagger" json:"delay-clean-causet-dagger"` 134 SplitRegionMaxNum uint64 `toml:"split-region-max-num" json:"split-region-max-num"` 135 StmtSummary StmtSummary `toml:"stmt-summary" json:"stmt-summary"` 136 // RepairMode indicates that the MilevaDB is in the repair mode for causet spacetime. 137 RepairMode bool `toml:"repair-mode" json:"repair-mode"` 138 RepairBlockList []string `toml:"repair-causet-list" json:"repair-causet-list"` 139 // IsolationRead indicates that the MilevaDB reads data from which isolation level(engine and label). 140 IsolationRead IsolationRead `toml:"isolation-read" json:"isolation-read"` 141 // MaxServerConnections is the maximum permitted number of simultaneous client connections. 142 MaxServerConnections uint32 `toml:"max-server-connections" json:"max-server-connections"` 143 // NewDefCauslationsEnabledOnFirstBootstrap indicates if the new collations are enabled, it effects only when a MilevaDB cluster bootstrapped on the first time. 144 NewDefCauslationsEnabledOnFirstBootstrap bool `toml:"new_collations_enabled_on_first_bootstrap" json:"new_collations_enabled_on_first_bootstrap"` 145 // Experimental contains parameters for experimental features. 146 Experimental Experimental `toml:"experimental" json:"experimental"` 147 // EnableDefCauslectInterDircutionInfo enables the MilevaDB to collect execution info. 148 EnableDefCauslectInterDircutionInfo bool `toml:"enable-collect-execution-info" json:"enable-collect-execution-info"` 149 // SkipRegisterToDashboard tells MilevaDB don't register itself to the dashboard. 150 SkipRegisterToDashboard bool `toml:"skip-register-to-dashboard" json:"skip-register-to-dashboard"` 151 // EnableTelemetry enables the usage data report to WHTCORPS INC. 152 EnableTelemetry bool `toml:"enable-telemetry" json:"enable-telemetry"` 153 // Labels indicates the labels set for the milevadb server. The labels describe some specific properties for the milevadb 154 // server like `zone`/`rack`/`host`. Currently, labels won't affect the milevadb server except for some special 155 // label keys. Now we only have `group` as a special label key. 156 // Note that: 'group' is a special label key which should be automatically set by milevadb-operator. We don't suggest 157 // users to set 'group' in labels. 158 Labels map[string]string `toml:"labels" json:"labels"` 159 // EnableGlobalIndex enables creating global index. 160 EnableGlobalIndex bool `toml:"enable-global-index" json:"enable-global-index"` 161 // DeprecateIntegerDisplayWidth indicates whether deprecating the max display length for integer. 162 DeprecateIntegerDisplayWidth bool `toml:"deprecate-integer-display-length" json:"deprecate-integer-display-length"` 163 // EnableRedactLog indicates that whether redact log, 0 is disable. 1 is enable. 164 EnableRedactLog int32 `toml:"enable-redact-log" json:"enable-redact-log"` 165 } 166 167 // UFIDelateTempStoragePath is to uFIDelate the `TempStoragePath` if port/statusPort was changed 168 // and the `tmp-storage-path` was not specified in the conf.toml or was specified the same as the default value. 169 func (c *Config) UFIDelateTempStoragePath() { 170 if c.TempStoragePath == tempStorageDirName { 171 c.TempStoragePath = encodeDefTempStorageDir(os.TemFIDelir(), c.Host, c.Status.StatusHost, c.Port, c.Status.StatusPort) 172 } else { 173 c.TempStoragePath = encodeDefTempStorageDir(c.TempStoragePath, c.Host, c.Status.StatusHost, c.Port, c.Status.StatusPort) 174 } 175 } 176 177 func encodeDefTempStorageDir(temFIDelir string, host, statusHost string, port, statusPort uint) string { 178 dirName := base64.URLEncoding.EncodeToString([]byte(fmt.Sprintf("%v:%v/%v:%v", host, port, statusHost, statusPort))) 179 var osUID string 180 currentUser, err := user.Current() 181 if err != nil { 182 osUID = "" 183 } else { 184 osUID = currentUser.Uid 185 } 186 return filepath.Join(temFIDelir, osUID+"_milevadb", dirName, "tmp-storage") 187 } 188 189 // nullableBool defaults unset bool options to unset instead of false, which enables us to know if the user has set 2 190 // conflict options at the same time. 191 type nullableBool struct { 192 IsValid bool 193 IsTrue bool 194 } 195 196 var ( 197 nbUnset = nullableBool{false, false} 198 nbFalse = nullableBool{true, false} 199 nbTrue = nullableBool{true, true} 200 ) 201 202 func (b *nullableBool) toBool() bool { 203 return b.IsValid && b.IsTrue 204 } 205 206 func (b nullableBool) MarshalJSON() ([]byte, error) { 207 switch b { 208 case nbTrue: 209 return json.Marshal(true) 210 case nbFalse: 211 return json.Marshal(false) 212 default: 213 return json.Marshal(nil) 214 } 215 } 216 217 func (b *nullableBool) UnmarshalText(text []byte) error { 218 str := string(text) 219 switch str { 220 case "", "null": 221 *b = nbUnset 222 return nil 223 case "true": 224 *b = nbTrue 225 case "false": 226 *b = nbFalse 227 default: 228 *b = nbUnset 229 return errors.New("Invalid value for bool type: " + str) 230 } 231 return nil 232 } 233 234 func (b nullableBool) MarshalText() ([]byte, error) { 235 if !b.IsValid { 236 return []byte(""), nil 237 } 238 if b.IsTrue { 239 return []byte("true"), nil 240 } 241 return []byte("false"), nil 242 } 243 244 func (b *nullableBool) UnmarshalJSON(data []byte) error { 245 var err error 246 var v interface{} 247 if err = json.Unmarshal(data, &v); err != nil { 248 return err 249 } 250 switch raw := v.(type) { 251 case bool: 252 *b = nullableBool{true, raw} 253 default: 254 *b = nbUnset 255 } 256 return err 257 } 258 259 // Log is the log section of config. 260 type Log struct { 261 // Log level. 262 Level string `toml:"level" json:"level"` 263 // Log format. one of json, text, or console. 264 Format string `toml:"format" json:"format"` 265 // Disable automatic timestamps in output. Deprecated: use EnableTimestamp instead. 266 DisableTimestamp nullableBool `toml:"disable-timestamp" json:"disable-timestamp"` 267 // EnableTimestamp enables automatic timestamps in log output. 268 EnableTimestamp nullableBool `toml:"enable-timestamp" json:"enable-timestamp"` 269 // DisableErrorStack stops annotating logs with the full stack error 270 // message. Deprecated: use EnableErrorStack instead. 271 DisableErrorStack nullableBool `toml:"disable-error-stack" json:"disable-error-stack"` 272 // EnableErrorStack enables annotating logs with the full stack error 273 // message. 274 EnableErrorStack nullableBool `toml:"enable-error-stack" json:"enable-error-stack"` 275 // File log config. 276 File logutil.FileLogConfig `toml:"file" json:"file"` 277 278 EnableSlowLog bool `toml:"enable-slow-log" json:"enable-slow-log"` 279 SlowQueryFile string `toml:"slow-query-file" json:"slow-query-file"` 280 SlowThreshold uint64 `toml:"slow-threshold" json:"slow-threshold"` 281 ExpensiveThreshold uint `toml:"expensive-threshold" json:"expensive-threshold"` 282 QueryLogMaxLen uint64 `toml:"query-log-max-len" json:"query-log-max-len"` 283 RecordCausetInSlowLog uint32 `toml:"record-plan-in-slow-log" json:"record-plan-in-slow-log"` 284 } 285 286 func (l *Log) getDisableTimestamp() bool { 287 if l.EnableTimestamp == nbUnset && l.DisableTimestamp == nbUnset { 288 return false 289 } 290 if l.EnableTimestamp == nbUnset { 291 return l.DisableTimestamp.toBool() 292 } 293 return !l.EnableTimestamp.toBool() 294 } 295 296 func (l *Log) getDisableErrorStack() bool { 297 if l.EnableErrorStack == nbUnset && l.DisableErrorStack == nbUnset { 298 return true 299 } 300 if l.EnableErrorStack == nbUnset { 301 return l.DisableErrorStack.toBool() 302 } 303 return !l.EnableErrorStack.toBool() 304 } 305 306 // The following constants represents the valid action configurations for Security.SpilledFileEncryptionMethod. 307 // "plaintext" means encryption is disabled. 308 // NOTE: Although the values is case insensitive, we should use lower-case 309 // strings because the configuration value will be transformed to lower-case 310 // string and compared with these constants in the further usage. 311 const ( 312 SpilledFileEncryptionMethodPlaintext = "plaintext" 313 SpilledFileEncryptionMethodAES128CTR = "aes128-ctr" 314 ) 315 316 // Security is the security section of the config. 317 type Security struct { 318 SkipGrantBlock bool `toml:"skip-grant-causet" json:"skip-grant-causet"` 319 SSLCA string `toml:"ssl-ca" json:"ssl-ca"` 320 SSLCert string `toml:"ssl-cert" json:"ssl-cert"` 321 SSLKey string `toml:"ssl-key" json:"ssl-key"` 322 RequireSecureTransport bool `toml:"require-secure-transport" json:"require-secure-transport"` 323 ClusterSSLCA string `toml:"cluster-ssl-ca" json:"cluster-ssl-ca"` 324 ClusterSSLCert string `toml:"cluster-ssl-cert" json:"cluster-ssl-cert"` 325 ClusterSSLKey string `toml:"cluster-ssl-key" json:"cluster-ssl-key"` 326 ClusterVerifyCN []string `toml:"cluster-verify-cn" json:"cluster-verify-cn"` 327 // If set to "plaintext", the spilled files will not be encrypted. 328 SpilledFileEncryptionMethod string `toml:"spilled-file-encryption-method" json:"spilled-file-encryption-method"` 329 } 330 331 // The ErrConfigValidationFailed error is used so that external callers can do a type assertion 332 // to defer handling of this specific error when someone does not want strict type checking. 333 // This is needed only because logging hasn't been set up at the time we parse the config file. 334 // This should all be ripped out once strict config checking is made the default behavior. 335 type ErrConfigValidationFailed struct { 336 confFile string 337 UndecodedItems []string 338 } 339 340 func (e *ErrConfigValidationFailed) Error() string { 341 return fmt.Sprintf("config file %s contained invalid configuration options: %s; check "+ 342 "MilevaDB manual to make sure this option has not been deprecated and removed from your MilevaDB "+ 343 "version if the option does not appear to be a typo", e.confFile, strings.Join( 344 e.UndecodedItems, ", ")) 345 346 } 347 348 // ToTLSConfig generates tls's config based on security section of the config. 349 func (s *Security) ToTLSConfig() (tlsConfig *tls.Config, err error) { 350 if len(s.ClusterSSLCA) != 0 { 351 certPool := x509.NewCertPool() 352 // Create a certificate pool from the certificate authority 353 var ca []byte 354 ca, err = ioutil.ReadFile(s.ClusterSSLCA) 355 if err != nil { 356 err = errors.Errorf("could not read ca certificate: %s", err) 357 return 358 } 359 // Append the certificates from the CA 360 if !certPool.AppendCertsFromPEM(ca) { 361 err = errors.New("failed to append ca certs") 362 return 363 } 364 tlsConfig = &tls.Config{ 365 RootCAs: certPool, 366 ClientCAs: certPool, 367 } 368 369 if len(s.ClusterSSLCert) != 0 && len(s.ClusterSSLKey) != 0 { 370 getCert := func() (*tls.Certificate, error) { 371 // Load the client certificates from disk 372 cert, err := tls.LoadX509KeyPair(s.ClusterSSLCert, s.ClusterSSLKey) 373 if err != nil { 374 return nil, errors.Errorf("could not load client key pair: %s", err) 375 } 376 return &cert, nil 377 } 378 // pre-test cert's loading. 379 if _, err = getCert(); err != nil { 380 return 381 } 382 tlsConfig.GetClientCertificate = func(info *tls.CertificateRequestInfo) (certificate *tls.Certificate, err error) { 383 return getCert() 384 } 385 tlsConfig.GetCertificate = func(info *tls.ClientHelloInfo) (certificate *tls.Certificate, err error) { 386 return getCert() 387 } 388 } 389 } 390 return 391 } 392 393 // Status is the status section of the config. 394 type Status struct { 395 StatusHost string `toml:"status-host" json:"status-host"` 396 MetricsAddr string `toml:"metrics-addr" json:"metrics-addr"` 397 StatusPort uint `toml:"status-port" json:"status-port"` 398 MetricsInterval uint `toml:"metrics-interval" json:"metrics-interval"` 399 ReportStatus bool `toml:"report-status" json:"report-status"` 400 RecordQPSbyDB bool `toml:"record-EDB-qps" json:"record-EDB-qps"` 401 } 402 403 // Performance is the performance section of the config. 404 type Performance struct { 405 MaxProcs uint `toml:"max-procs" json:"max-procs"` 406 // Deprecated: use ServerMemoryQuota instead 407 MaxMemory uint64 `toml:"max-memory" json:"max-memory"` 408 ServerMemoryQuota uint64 `toml:"server-memory-quota" json:"server-memory-quota"` 409 StatsLease string `toml:"stats-lease" json:"stats-lease"` 410 StmtCountLimit uint `toml:"stmt-count-limit" json:"stmt-count-limit"` 411 FeedbackProbability float64 `toml:"feedback-probability" json:"feedback-probability"` 412 QueryFeedbackLimit uint `toml:"query-feedback-limit" json:"query-feedback-limit"` 413 PseudoEstimateRatio float64 `toml:"pseudo-estimate-ratio" json:"pseudo-estimate-ratio"` 414 ForcePriority string `toml:"force-priority" json:"force-priority"` 415 BindInfoLease string `toml:"bind-info-lease" json:"bind-info-lease"` 416 TxnEntrySizeLimit uint64 `toml:"txn-entry-size-limit" json:"txn-entry-size-limit"` 417 TxnTotalSizeLimit uint64 `toml:"txn-total-size-limit" json:"txn-total-size-limit"` 418 TCPKeepAlive bool `toml:"tcp-keep-alive" json:"tcp-keep-alive"` 419 CrossJoin bool `toml:"cross-join" json:"cross-join"` 420 RunAutoAnalyze bool `toml:"run-auto-analyze" json:"run-auto-analyze"` 421 DistinctAggPushDown bool `toml:"distinct-agg-push-down" json:"agg-push-down-join"` 422 CommitterConcurrency int `toml:"committer-concurrency" json:"committer-concurrency"` 423 MaxTxnTTL uint64 `toml:"max-txn-ttl" json:"max-txn-ttl"` 424 MemProfileInterval string `toml:"mem-profile-interval" json:"mem-profile-interval"` 425 IndexUsageSyncLease string `toml:"index-usage-sync-lease" json:"index-usage-sync-lease"` 426 } 427 428 // CausetCache is the CausetCache section of the config. 429 type CausetCache struct { 430 Enabled bool `toml:"enabled" json:"enabled"` 431 Capacity uint `toml:"capacity" json:"capacity"` 432 Shards uint `toml:"shards" json:"shards"` 433 } 434 435 // TxnLocalLatches is the TxnLocalLatches section of the config. 436 type TxnLocalLatches struct { 437 Enabled bool `toml:"-" json:"-"` 438 Capacity uint `toml:"-" json:"-"` 439 } 440 441 // PreparedCausetCache is the PreparedCausetCache section of the config. 442 type PreparedCausetCache struct { 443 Enabled bool `toml:"enabled" json:"enabled"` 444 Capacity uint `toml:"capacity" json:"capacity"` 445 MemoryGuardRatio float64 `toml:"memory-guard-ratio" json:"memory-guard-ratio"` 446 } 447 448 // OpenTracing is the opentracing section of the config. 449 type OpenTracing struct { 450 Enable bool `toml:"enable" json:"enable"` 451 RPCMetrics bool `toml:"rpc-metrics" json:"rpc-metrics"` 452 Sampler OpenTracingSampler `toml:"sampler" json:"sampler"` 453 Reporter OpenTracingReporter `toml:"reporter" json:"reporter"` 454 } 455 456 // OpenTracingSampler is the config for opentracing sampler. 457 // See https://godoc.org/github.com/uber/jaeger-client-go/config#SamplerConfig 458 type OpenTracingSampler struct { 459 Type string `toml:"type" json:"type"` 460 Param float64 `toml:"param" json:"param"` 461 SamplingServerURL string `toml:"sampling-server-url" json:"sampling-server-url"` 462 MaxOperations int `toml:"max-operations" json:"max-operations"` 463 SamplingRefreshInterval time.Duration `toml:"sampling-refresh-interval" json:"sampling-refresh-interval"` 464 } 465 466 // OpenTracingReporter is the config for opentracing reporter. 467 // See https://godoc.org/github.com/uber/jaeger-client-go/config#ReporterConfig 468 type OpenTracingReporter struct { 469 QueueSize int `toml:"queue-size" json:"queue-size"` 470 BufferFlushInterval time.Duration `toml:"buffer-flush-interval" json:"buffer-flush-interval"` 471 LogSpans bool `toml:"log-spans" json:"log-spans"` 472 LocalAgentHostPort string `toml:"local-agent-host-port" json:"local-agent-host-port"` 473 } 474 475 // ProxyProtocol is the PROXY protocol section of the config. 476 type ProxyProtocol struct { 477 // PROXY protocol accepblock client networks. 478 // Empty string means disable PROXY protocol, 479 // * means all networks. 480 Networks string `toml:"networks" json:"networks"` 481 // PROXY protocol header read timeout, Unit is second. 482 HeaderTimeout uint `toml:"header-timeout" json:"header-timeout"` 483 } 484 485 // EinsteinDBClient is the config for einsteindb client. 486 type EinsteinDBClient struct { 487 // GrpcConnectionCount is the max gRPC connections that will be established 488 // with each einsteindb-server. 489 GrpcConnectionCount uint `toml:"grpc-connection-count" json:"grpc-connection-count"` 490 // After a duration of this time in seconds if the client doesn't see any activity it pings 491 // the server to see if the transport is still alive. 492 GrpcKeepAliveTime uint `toml:"grpc-keepalive-time" json:"grpc-keepalive-time"` 493 // After having pinged for keepalive check, the client waits for a duration of Timeout in seconds 494 // and if no activity is seen even after that the connection is closed. 495 GrpcKeepAliveTimeout uint `toml:"grpc-keepalive-timeout" json:"grpc-keepalive-timeout"` 496 // CommitTimeout is the max time which command 'commit' will wait. 497 CommitTimeout string `toml:"commit-timeout" json:"commit-timeout"` 498 // EnableAsyncCommit enables async commit for all transactions. 499 EnableAsyncCommit bool `toml:"enable-async-commit" json:"enable-async-commit"` 500 AsyncCommitKeysLimit uint `toml:"async-commit-keys-limit" json:"async-commit-keys-limit"` 501 502 // MaxBatchSize is the max batch size when calling batch commands API. 503 MaxBatchSize uint `toml:"max-batch-size" json:"max-batch-size"` 504 // If EinsteinDB load is greater than this, MilevaDB will wait for a while to avoid little batch. 505 OverloadThreshold uint `toml:"overload-threshold" json:"overload-threshold"` 506 // MaxBatchWaitTime in nanosecond is the max wait time for batch. 507 MaxBatchWaitTime time.Duration `toml:"max-batch-wait-time" json:"max-batch-wait-time"` 508 // BatchWaitSize is the max wait size for batch. 509 BatchWaitSize uint `toml:"batch-wait-size" json:"batch-wait-size"` 510 // EnableChunkRPC indicate the data encode in chunk format for interlock requests. 511 EnableChunkRPC bool `toml:"enable-chunk-rpc" json:"enable-chunk-rpc"` 512 // If a Region has not been accessed for more than the given duration (in seconds), it 513 // will be reloaded from the FIDel. 514 RegionCacheTTL uint `toml:"region-cache-ttl" json:"region-cache-ttl"` 515 // If a causetstore has been up to the limit, it will return error for successive request to 516 // prevent the causetstore occupying too much token in dispatching level. 517 StoreLimit int64 `toml:"causetstore-limit" json:"causetstore-limit"` 518 // StoreLivenessTimeout is the timeout for causetstore liveness check request. 519 StoreLivenessTimeout string `toml:"causetstore-liveness-timeout" json:"causetstore-liveness-timeout"` 520 CoprCache CoprocessorCache `toml:"copr-cache" json:"copr-cache"` 521 // TTLRefreshedTxnSize controls whether a transaction should uFIDelate its TTL or not. 522 TTLRefreshedTxnSize int64 `toml:"ttl-refreshed-txn-size" json:"ttl-refreshed-txn-size"` 523 } 524 525 // CoprocessorCache is the config for interlock cache. 526 type CoprocessorCache struct { 527 // Whether to enable the copr cache. The copr cache saves the result from EinsteinDB Coprocessor in the memory and 528 // reuses the result when corresponding data in EinsteinDB is unchanged, on a region basis. 529 Enable bool `toml:"enable" json:"enable"` 530 // The capacity in MB of the cache. 531 CapacityMB float64 `toml:"capacity-mb" json:"capacity-mb"` 532 // Only cache requests whose result set is small. 533 AdmissionMaxResultMB float64 `toml:"admission-max-result-mb" json:"admission-max-result-mb"` 534 // Only cache requests takes noblock time to process. 535 AdmissionMinProcessMs uint64 `toml:"admission-min-process-ms" json:"admission-min-process-ms"` 536 } 537 538 // Binlog is the config for binlog. 539 type Binlog struct { 540 Enable bool `toml:"enable" json:"enable"` 541 // If IgnoreError is true, when writing binlog meets error, MilevaDB would 542 // ignore the error. 543 IgnoreError bool `toml:"ignore-error" json:"ignore-error"` 544 WriteTimeout string `toml:"write-timeout" json:"write-timeout"` 545 // Use socket file to write binlog, for compatible with kafka version milevadb-binlog. 546 BinlogSocket string `toml:"binlog-socket" json:"binlog-socket"` 547 // The strategy for sending binlog to pump, value can be "range" or "hash" now. 548 Strategy string `toml:"strategy" json:"strategy"` 549 } 550 551 // Plugin is the config for plugin 552 type Plugin struct { 553 Dir string `toml:"dir" json:"dir"` 554 Load string `toml:"load" json:"load"` 555 } 556 557 // PessimisticTxn is the config for pessimistic transaction. 558 type PessimisticTxn struct { 559 // The max count of retry for a single memex in a pessimistic transaction. 560 MaxRetryCount uint `toml:"max-retry-count" json:"max-retry-count"` 561 } 562 563 // StmtSummary is the config for memex summary. 564 type StmtSummary struct { 565 // Enable memex summary or not. 566 Enable bool `toml:"enable" json:"enable"` 567 // Enable summary internal query. 568 EnableInternalQuery bool `toml:"enable-internal-query" json:"enable-internal-query"` 569 // The maximum number of memexs kept in memory. 570 MaxStmtCount uint `toml:"max-stmt-count" json:"max-stmt-count"` 571 // The maximum length of displayed normalized ALLEGROALLEGROSQL and sample ALLEGROALLEGROSQL. 572 MaxALLEGROSQLLength uint `toml:"max-allegrosql-length" json:"max-allegrosql-length"` 573 // The refresh interval of memex summary. 574 RefreshInterval int `toml:"refresh-interval" json:"refresh-interval"` 575 // The maximum history size of memex summary. 576 HistorySize int `toml:"history-size" json:"history-size"` 577 } 578 579 // IsolationRead is the config for isolation read. 580 type IsolationRead struct { 581 // Engines filters milevadb-server access paths by engine type. 582 Engines []string `toml:"engines" json:"engines"` 583 } 584 585 // Experimental controls the features that are still experimental: their semantics, interfaces are subject to change. 586 // Using these features in the production environment is not recommended. 587 type Experimental struct { 588 } 589 590 var defaultConf = Config{ 591 Host: DefHost, 592 AdvertiseAddress: "", 593 Port: DefPort, 594 Cors: "", 595 CausetStore: "entangledstore", 596 Path: "/tmp/milevadb", 597 RunDBS: true, 598 SplitBlock: true, 599 Lease: "45s", 600 TokenLimit: 1000, 601 OOMUseTmpStorage: true, 602 TempStorageQuota: -1, 603 TempStoragePath: tempStorageDirName, 604 OOMCausetAction: OOMCausetActionCancel, 605 MemQuotaQuery: 1 << 30, 606 NestedLoopJoinCacheCapacity: 20971520, 607 EnableStreaming: false, 608 EnableBatchDML: false, 609 CheckMb4ValueInUTF8: true, 610 MaxIndexLength: 3072, 611 AlterPrimaryKey: false, 612 TreatOldVersionUTF8AsUTF8MB4: true, 613 EnableBlockLock: false, 614 DelayCleanBlockLock: 0, 615 SplitRegionMaxNum: 1000, 616 RepairMode: false, 617 RepairBlockList: []string{}, 618 MaxServerConnections: 0, 619 TxnLocalLatches: TxnLocalLatches{ 620 Enabled: false, 621 Capacity: 0, 622 }, 623 LowerCaseBlockNames: 2, 624 ServerVersion: "", 625 Log: Log{ 626 Level: "info", 627 Format: "text", 628 File: logutil.NewFileLogConfig(logutil.DefaultLogMaxSize), 629 SlowQueryFile: "milevadb-slow.log", 630 SlowThreshold: logutil.DefaultSlowThreshold, 631 ExpensiveThreshold: 10000, 632 DisableErrorStack: nbUnset, 633 EnableErrorStack: nbUnset, // If both options are nbUnset, getDisableErrorStack() returns true 634 EnableTimestamp: nbUnset, 635 DisableTimestamp: nbUnset, // If both options are nbUnset, getDisableTimestamp() returns false 636 QueryLogMaxLen: logutil.DefaultQueryLogMaxLen, 637 RecordCausetInSlowLog: logutil.DefaultRecordCausetInSlowLog, 638 EnableSlowLog: logutil.DefaultMilevaDBEnableSlowLog, 639 }, 640 Status: Status{ 641 ReportStatus: true, 642 StatusHost: DefStatusHost, 643 StatusPort: DefStatusPort, 644 MetricsInterval: 15, 645 RecordQPSbyDB: false, 646 }, 647 Performance: Performance{ 648 MaxMemory: 0, 649 ServerMemoryQuota: 0, 650 TCPKeepAlive: true, 651 CrossJoin: true, 652 StatsLease: "3s", 653 RunAutoAnalyze: true, 654 StmtCountLimit: 5000, 655 FeedbackProbability: 0.05, 656 QueryFeedbackLimit: 512, 657 PseudoEstimateRatio: 0.8, 658 ForcePriority: "NO_PRIORITY", 659 BindInfoLease: "3s", 660 TxnEntrySizeLimit: DefTxnEntrySizeLimit, 661 TxnTotalSizeLimit: DefTxnTotalSizeLimit, 662 DistinctAggPushDown: false, 663 CommitterConcurrency: 16, 664 MaxTxnTTL: 60 * 60 * 1000, // 1hour 665 MemProfileInterval: "1m", 666 IndexUsageSyncLease: "60s", 667 }, 668 ProxyProtocol: ProxyProtocol{ 669 Networks: "", 670 HeaderTimeout: 5, 671 }, 672 PreparedCausetCache: PreparedCausetCache{ 673 Enabled: false, 674 Capacity: 100, 675 MemoryGuardRatio: 0.1, 676 }, 677 OpenTracing: OpenTracing{ 678 Enable: false, 679 Sampler: OpenTracingSampler{ 680 Type: "const", 681 Param: 1.0, 682 }, 683 Reporter: OpenTracingReporter{}, 684 }, 685 EinsteinDBClient: EinsteinDBClient{ 686 GrpcConnectionCount: 4, 687 GrpcKeepAliveTime: 10, 688 GrpcKeepAliveTimeout: 3, 689 CommitTimeout: "41s", 690 EnableAsyncCommit: false, 691 AsyncCommitKeysLimit: 256, 692 693 MaxBatchSize: 128, 694 OverloadThreshold: 200, 695 MaxBatchWaitTime: 0, 696 BatchWaitSize: 8, 697 698 EnableChunkRPC: true, 699 700 RegionCacheTTL: 600, 701 StoreLimit: 0, 702 StoreLivenessTimeout: DefStoreLivenessTimeout, 703 704 TTLRefreshedTxnSize: 32 * 1024 * 1024, 705 706 CoprCache: CoprocessorCache{ 707 Enable: true, 708 CapacityMB: 1000, 709 AdmissionMaxResultMB: 10, 710 AdmissionMinProcessMs: 5, 711 }, 712 }, 713 Binlog: Binlog{ 714 WriteTimeout: "15s", 715 Strategy: "range", 716 }, 717 PessimisticTxn: PessimisticTxn{ 718 MaxRetryCount: 256, 719 }, 720 StmtSummary: StmtSummary{ 721 Enable: true, 722 EnableInternalQuery: false, 723 MaxStmtCount: 200, 724 MaxALLEGROSQLLength: 4096, 725 RefreshInterval: 1800, 726 HistorySize: 24, 727 }, 728 IsolationRead: IsolationRead{ 729 Engines: []string{"einsteindb", "tiflash", "milevadb"}, 730 }, 731 Experimental: Experimental{}, 732 EnableDefCauslectInterDircutionInfo: true, 733 EnableTelemetry: true, 734 Labels: make(map[string]string), 735 EnableGlobalIndex: false, 736 Security: Security{ 737 SpilledFileEncryptionMethod: SpilledFileEncryptionMethodPlaintext, 738 }, 739 DeprecateIntegerDisplayWidth: false, 740 EnableRedactLog: DefMilevaDBRedactLog, 741 } 742 743 var ( 744 globalConf atomic.Value 745 ) 746 747 // NewConfig creates a new config instance with default value. 748 func NewConfig() *Config { 749 conf := defaultConf 750 return &conf 751 } 752 753 // GetGlobalConfig returns the global configuration for this server. 754 // It should causetstore configuration from command line and configuration file. 755 // Other parts of the system can read the global configuration use this function. 756 func GetGlobalConfig() *Config { 757 return globalConf.Load().(*Config) 758 } 759 760 // StoreGlobalConfig stores a new config to the globalConf. It mostly uses in the test to avoid some data races. 761 func StoreGlobalConfig(config *Config) { 762 globalConf.CausetStore(config) 763 } 764 765 var deprecatedConfig = map[string]struct{}{ 766 "pessimistic-txn.ttl": {}, 767 "pessimistic-txn.enable": {}, 768 "log.file.log-rotate": {}, 769 "log.log-slow-query": {}, 770 "txn-local-latches": {}, 771 "txn-local-latches.enabled": {}, 772 "txn-local-latches.capacity": {}, 773 "performance.max-memory": {}, 774 "max-txn-time-use": {}, 775 "experimental.allow-auto-random": {}, 776 } 777 778 func isAllDeprecatedConfigItems(items []string) bool { 779 for _, item := range items { 780 if _, ok := deprecatedConfig[item]; !ok { 781 return false 782 } 783 } 784 return true 785 } 786 787 // InitializeConfig initialize the global config handler. 788 // The function enforceCmdArgs is used to merge the config file with command arguments: 789 // For example, if you start MilevaDB by the command "./milevadb-server --port=3000", the port number should be 790 // overwritten to 3000 and ignore the port number in the config file. 791 func InitializeConfig(confPath string, configCheck, configStrict bool, reloadFunc ConfReloadFunc, enforceCmdArgs func(*Config)) { 792 cfg := GetGlobalConfig() 793 var err error 794 if confPath != "" { 795 if err = cfg.Load(confPath); err != nil { 796 // Unused config item error turns to warnings. 797 if tmp, ok := err.(*ErrConfigValidationFailed); ok { 798 // This causet is to accommodate an interim situation where strict config checking 799 // is not the default behavior of MilevaDB. The warning message must be deferred until 800 // logging has been set up. After strict config checking is the default behavior, 801 // This should all be removed. 802 if (!configCheck && !configStrict) || isAllDeprecatedConfigItems(tmp.UndecodedItems) { 803 fmt.Fprintln(os.Stderr, err.Error()) 804 err = nil 805 } 806 } 807 } 808 809 terror.MustNil(err) 810 } else { 811 // configCheck should have the config file specified. 812 if configCheck { 813 fmt.Fprintln(os.Stderr, "config check failed", errors.New("no config file specified for config-check")) 814 os.Exit(1) 815 } 816 } 817 enforceCmdArgs(cfg) 818 819 if err := cfg.Valid(); err != nil { 820 if !filepath.IsAbs(confPath) { 821 if tmp, err := filepath.Abs(confPath); err == nil { 822 confPath = tmp 823 } 824 } 825 fmt.Fprintln(os.Stderr, "load config file:", confPath) 826 fmt.Fprintln(os.Stderr, "invalid config", err) 827 os.Exit(1) 828 } 829 if configCheck { 830 fmt.Println("config check successful") 831 os.Exit(0) 832 } 833 StoreGlobalConfig(cfg) 834 } 835 836 // Load loads config options from a toml file. 837 func (c *Config) Load(confFile string) error { 838 spacetimeData, err := toml.DecodeFile(confFile, c) 839 if c.TokenLimit == 0 { 840 c.TokenLimit = 1000 841 } 842 if len(c.ServerVersion) > 0 { 843 allegrosql.ServerVersion = c.ServerVersion 844 } 845 // If any items in confFile file are not mapped into the Config struct, issue 846 // an error and stop the server from starting. 847 undecoded := spacetimeData.Undecoded() 848 if len(undecoded) > 0 && err == nil { 849 var undecodedItems []string 850 for _, item := range undecoded { 851 undecodedItems = append(undecodedItems, item.String()) 852 } 853 err = &ErrConfigValidationFailed{confFile, undecodedItems} 854 } 855 856 return err 857 } 858 859 // Valid checks if this config is valid. 860 func (c *Config) Valid() error { 861 if c.Log.EnableErrorStack == c.Log.DisableErrorStack && c.Log.EnableErrorStack != nbUnset { 862 logutil.BgLogger().Warn(fmt.Sprintf("\"enable-error-stack\" (%v) conflicts \"disable-error-stack\" (%v). \"disable-error-stack\" is deprecated, please use \"enable-error-stack\" instead. disable-error-stack is ignored.", c.Log.EnableErrorStack, c.Log.DisableErrorStack)) 863 // if two options conflict, we will use the value of EnableErrorStack 864 c.Log.DisableErrorStack = nbUnset 865 } 866 if c.Log.EnableTimestamp == c.Log.DisableTimestamp && c.Log.EnableTimestamp != nbUnset { 867 logutil.BgLogger().Warn(fmt.Sprintf("\"enable-timestamp\" (%v) conflicts \"disable-timestamp\" (%v). \"disable-timestamp\" is deprecated, please use \"enable-timestamp\" instead", c.Log.EnableTimestamp, c.Log.DisableTimestamp)) 868 // if two options conflict, we will use the value of EnableTimestamp 869 c.Log.DisableTimestamp = nbUnset 870 } 871 if c.Security.SkipGrantBlock && !hasRootPrivilege() { 872 return fmt.Errorf("MilevaDB run with skip-grant-causet need root privilege") 873 } 874 if _, ok := ValidStorage[c.CausetStore]; !ok { 875 nameList := make([]string, 0, len(ValidStorage)) 876 for k, v := range ValidStorage { 877 if v { 878 nameList = append(nameList, k) 879 } 880 } 881 return fmt.Errorf("invalid causetstore=%s, valid storages=%v", c.CausetStore, nameList) 882 } 883 if c.CausetStore == "mockeinsteindb" && !c.RunDBS { 884 return fmt.Errorf("can't disable DBS on mockeinsteindb") 885 } 886 if c.MaxIndexLength < DefMaxIndexLength || c.MaxIndexLength > DefMaxOfMaxIndexLength { 887 return fmt.Errorf("max-index-length should be [%d, %d]", DefMaxIndexLength, DefMaxOfMaxIndexLength) 888 } 889 if c.Log.File.MaxSize > MaxLogFileSize { 890 return fmt.Errorf("invalid max log file size=%v which is larger than max=%v", c.Log.File.MaxSize, MaxLogFileSize) 891 } 892 c.OOMCausetAction = strings.ToLower(c.OOMCausetAction) 893 if c.OOMCausetAction != OOMCausetActionLog && c.OOMCausetAction != OOMCausetActionCancel { 894 return fmt.Errorf("unsupported OOMCausetAction %v, MilevaDB only supports [%v, %v]", c.OOMCausetAction, OOMCausetActionLog, OOMCausetActionCancel) 895 } 896 897 // lower_case_block_names is allowed to be 0, 1, 2 898 if c.LowerCaseBlockNames < 0 || c.LowerCaseBlockNames > 2 { 899 return fmt.Errorf("lower-case-causet-names should be 0 or 1 or 2") 900 } 901 902 if c.TxnLocalLatches.Enabled && c.TxnLocalLatches.Capacity == 0 { 903 return fmt.Errorf("txn-local-latches.capacity can not be 0") 904 } 905 906 // For einsteindbclient. 907 if c.EinsteinDBClient.GrpcConnectionCount == 0 { 908 return fmt.Errorf("grpc-connection-count should be greater than 0") 909 } 910 911 if c.Performance.TxnTotalSizeLimit > 10<<30 { 912 return fmt.Errorf("txn-total-size-limit should be less than %d", 10<<30) 913 } 914 915 if c.StmtSummary.MaxStmtCount <= 0 { 916 return fmt.Errorf("max-stmt-count in [stmt-summary] should be greater than 0") 917 } 918 if c.StmtSummary.HistorySize < 0 { 919 return fmt.Errorf("history-size in [stmt-summary] should be greater than or equal to 0") 920 } 921 if c.StmtSummary.RefreshInterval <= 0 { 922 return fmt.Errorf("refresh-interval in [stmt-summary] should be greater than 0") 923 } 924 925 if c.PreparedCausetCache.Capacity < 1 { 926 return fmt.Errorf("capacity in [prepared-plan-cache] should be at least 1") 927 } 928 if c.PreparedCausetCache.MemoryGuardRatio < 0 || c.PreparedCausetCache.MemoryGuardRatio > 1 { 929 return fmt.Errorf("memory-guard-ratio in [prepared-plan-cache] must be NOT less than 0 and more than 1") 930 } 931 if len(c.IsolationRead.Engines) < 1 { 932 return fmt.Errorf("the number of [isolation-read]engines for isolation read should be at least 1") 933 } 934 for _, engine := range c.IsolationRead.Engines { 935 if engine != "milevadb" && engine != "einsteindb" && engine != "tiflash" { 936 return fmt.Errorf("type of [isolation-read]engines can't be %v should be one of milevadb or einsteindb or tiflash", engine) 937 } 938 } 939 940 // test security 941 c.Security.SpilledFileEncryptionMethod = strings.ToLower(c.Security.SpilledFileEncryptionMethod) 942 switch c.Security.SpilledFileEncryptionMethod { 943 case SpilledFileEncryptionMethodPlaintext, SpilledFileEncryptionMethodAES128CTR: 944 default: 945 return fmt.Errorf("unsupported [security]spilled-file-encryption-method %v, MilevaDB only supports [%v, %v]", 946 c.Security.SpilledFileEncryptionMethod, SpilledFileEncryptionMethodPlaintext, SpilledFileEncryptionMethodAES128CTR) 947 } 948 949 // test log level 950 l := zap.NewAtomicLevel() 951 return l.UnmarshalText([]byte(c.Log.Level)) 952 } 953 954 // UFIDelateGlobal uFIDelates the global config, and provide a restore function that can be used to restore to the original. 955 func UFIDelateGlobal(f func(conf *Config)) { 956 g := GetGlobalConfig() 957 newConf := *g 958 f(&newConf) 959 StoreGlobalConfig(&newConf) 960 } 961 962 // RestoreFunc gets a function that restore the config to the current value. 963 func RestoreFunc() (restore func()) { 964 g := GetGlobalConfig() 965 return func() { 966 StoreGlobalConfig(g) 967 } 968 } 969 970 func hasRootPrivilege() bool { 971 return os.Geteuid() == 0 972 } 973 974 // BlockLockEnabled uses to check whether enabled the causet dagger feature. 975 func BlockLockEnabled() bool { 976 return GetGlobalConfig().EnableBlockLock 977 } 978 979 // BlockLockDelayClean uses to get the time of delay clean causet dagger. 980 var BlockLockDelayClean = func() uint64 { 981 return GetGlobalConfig().DelayCleanBlockLock 982 } 983 984 // RedactLogEnabled uses to check whether enabled the log redact. 985 func RedactLogEnabled() bool { 986 return atomic.LoadInt32(&GetGlobalConfig().EnableRedactLog) == 1 987 } 988 989 // SetRedactLog uses to set log redact status. 990 func SetRedactLog(enable bool) { 991 value := int32(0) 992 if enable { 993 value = 1 994 } 995 g := GetGlobalConfig() 996 newConf := *g 997 newConf.EnableRedactLog = value 998 StoreGlobalConfig(&newConf) 999 } 1000 1001 // ToLogConfig converts *Log to *logutil.LogConfig. 1002 func (l *Log) ToLogConfig() *logutil.LogConfig { 1003 return logutil.NewLogConfig(l.Level, l.Format, l.SlowQueryFile, l.File, l.getDisableTimestamp(), func(config *zaplog.Config) { config.DisableErrorVerbose = l.getDisableErrorStack() }) 1004 } 1005 1006 // ToTracingConfig converts *OpenTracing to *tracing.Configuration. 1007 func (t *OpenTracing) ToTracingConfig() *tracing.Configuration { 1008 ret := &tracing.Configuration{ 1009 Disabled: !t.Enable, 1010 RPCMetrics: t.RPCMetrics, 1011 Reporter: &tracing.ReporterConfig{}, 1012 Sampler: &tracing.SamplerConfig{}, 1013 } 1014 ret.Reporter.QueueSize = t.Reporter.QueueSize 1015 ret.Reporter.BufferFlushInterval = t.Reporter.BufferFlushInterval 1016 ret.Reporter.LogSpans = t.Reporter.LogSpans 1017 ret.Reporter.LocalAgentHostPort = t.Reporter.LocalAgentHostPort 1018 1019 ret.Sampler.Type = t.Sampler.Type 1020 ret.Sampler.Param = t.Sampler.Param 1021 ret.Sampler.SamplingServerURL = t.Sampler.SamplingServerURL 1022 ret.Sampler.MaxOperations = t.Sampler.MaxOperations 1023 ret.Sampler.SamplingRefreshInterval = t.Sampler.SamplingRefreshInterval 1024 return ret 1025 } 1026 1027 func init() { 1028 initByLDFlags(versioninfo.MilevaDBEdition, checkBeforeDropLDFlag) 1029 } 1030 1031 func initByLDFlags(edition, checkBeforeDropLDFlag string) { 1032 if edition != versioninfo.CommunityEdition { 1033 defaultConf.EnableTelemetry = false 1034 } 1035 conf := defaultConf 1036 StoreGlobalConfig(&conf) 1037 if checkBeforeDropLDFlag == "1" { 1038 CheckBlockBeforeDrop = true 1039 } 1040 } 1041 1042 // The following constants represents the valid action configurations for OOMCausetAction. 1043 // NOTE: Although the values is case insensitive, we should use lower-case 1044 // strings because the configuration value will be transformed to lower-case 1045 // string and compared with these constants in the further usage. 1046 const ( 1047 OOMCausetActionCancel = "cancel" 1048 OOMCausetActionLog = "log" 1049 ) 1050 1051 // ParsePath parses this path. 1052 func ParsePath(path string) (etcdAddrs []string, disableGC bool, err error) { 1053 var u *url.URL 1054 u, err = url.Parse(path) 1055 if err != nil { 1056 err = errors.Trace(err) 1057 return 1058 } 1059 if strings.ToLower(u.Scheme) != "einsteindb" { 1060 err = errors.Errorf("Uri scheme expected [einsteindb] but found [%s]", u.Scheme) 1061 logutil.BgLogger().Error("parsePath error", zap.Error(err)) 1062 return 1063 } 1064 switch strings.ToLower(u.Query().Get("disableGC")) { 1065 case "true": 1066 disableGC = true 1067 case "false", "": 1068 default: 1069 err = errors.New("disableGC flag should be true/false") 1070 return 1071 } 1072 etcdAddrs = strings.Split(u.Host, ",") 1073 return 1074 }