github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/milevadb-server/main.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 main 15 16 import ( 17 "context" 18 "flag" 19 "fmt" 20 "io/ioutil" 21 "os" 22 "runtime" 23 "strconv" 24 "strings" 25 "sync/atomic" 26 "time" 27 28 fidel "github.com/einsteindb/fidel/client" 29 "github.com/opentracing/opentracing-go" 30 "github.com/prometheus/client_golang/prometheus" 31 "github.com/prometheus/client_golang/prometheus/push" 32 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 33 "github.com/whtcorpsinc/BerolinaSQL/terror" 34 BerolinaSQLtypes "github.com/whtcorpsinc/BerolinaSQL/types" 35 "github.com/whtcorpsinc/errors" 36 "github.com/whtcorpsinc/log" 37 pumpcli "github.com/whtcorpsinc/milevadb-tools/milevadb-binlog/pump_client" 38 "github.com/whtcorpsinc/milevadb/bindinfo" 39 causetembedded "github.com/whtcorpsinc/milevadb/causet/embedded" 40 ekvstore "github.com/whtcorpsinc/milevadb/causetstore" 41 "github.com/whtcorpsinc/milevadb/causetstore/einsteindb" 42 "github.com/whtcorpsinc/milevadb/causetstore/einsteindb/gcworker" 43 "github.com/whtcorpsinc/milevadb/causetstore/mockstore" 44 "github.com/whtcorpsinc/milevadb/config" 45 "github.com/whtcorpsinc/milevadb/dbs" 46 "github.com/whtcorpsinc/milevadb/ekv" 47 "github.com/whtcorpsinc/milevadb/interlock" 48 "github.com/whtcorpsinc/milevadb/metrics" 49 "github.com/whtcorpsinc/milevadb/petri" 50 "github.com/whtcorpsinc/milevadb/plugin" 51 "github.com/whtcorpsinc/milevadb/privilege/privileges" 52 "github.com/whtcorpsinc/milevadb/server" 53 "github.com/whtcorpsinc/milevadb/soliton" 54 "github.com/whtcorpsinc/milevadb/soliton/disk" 55 "github.com/whtcorpsinc/milevadb/soliton/ekvcache" 56 "github.com/whtcorpsinc/milevadb/soliton/logutil" 57 "github.com/whtcorpsinc/milevadb/soliton/memory" 58 "github.com/whtcorpsinc/milevadb/soliton/petriutil" 59 "github.com/whtcorpsinc/milevadb/soliton/printer" 60 "github.com/whtcorpsinc/milevadb/soliton/profile" 61 "github.com/whtcorpsinc/milevadb/soliton/signal" 62 "github.com/whtcorpsinc/milevadb/soliton/storeutil" 63 "github.com/whtcorpsinc/milevadb/soliton/sys/linux" 64 storageSys "github.com/whtcorpsinc/milevadb/soliton/sys/storage" 65 "github.com/whtcorpsinc/milevadb/soliton/systimemon" 66 "github.com/whtcorpsinc/milevadb/statistics" 67 "github.com/whtcorpsinc/milevadb/stochastik" 68 "github.com/whtcorpsinc/milevadb/stochastikctx/binloginfo" 69 "github.com/whtcorpsinc/milevadb/stochastikctx/variable" 70 "go.uber.org/automaxprocs/maxprocs" 71 "go.uber.org/zap" 72 "google.golang.org/grpc/grpclog" 73 ) 74 75 // Flag Names 76 const ( 77 nmVersion = "V" 78 nmConfig = "config" 79 nmConfigCheck = "config-check" 80 nmConfigStrict = "config-strict" 81 nmStore = "causetstore" 82 nmStorePath = "path" 83 nmHost = "host" 84 nmAdvertiseAddress = "advertise-address" 85 nmPort = "P" 86 nmCors = "cors" 87 nmSocket = "socket" 88 nmEnableBinlog = "enable-binlog" 89 nmRunDBS = "run-dbs" 90 nmLogLevel = "L" 91 nmLogFile = "log-file" 92 nmLogSlowQuery = "log-slow-query" 93 nmReportStatus = "report-status" 94 nmStatusHost = "status-host" 95 nmStatusPort = "status" 96 nmMetricsAddr = "metrics-addr" 97 nmMetricsInterval = "metrics-interval" 98 nmDdlLease = "lease" 99 nmTokenLimit = "token-limit" 100 nmPluginDir = "plugin-dir" 101 nmPluginLoad = "plugin-load" 102 nmRepairMode = "repair-mode" 103 nmRepairList = "repair-list" 104 nmRequireSecureTransport = "require-secure-transport" 105 106 nmProxyProtocolNetworks = "proxy-protocol-networks" 107 nmProxyProtocolHeaderTimeout = "proxy-protocol-header-timeout" 108 nmAffinityCPU = "affinity-cpus" 109 ) 110 111 var ( 112 version = flagBoolean(nmVersion, false, "print version information and exit") 113 configPath = flag.String(nmConfig, "", "config file path") 114 configCheck = flagBoolean(nmConfigCheck, false, "check config file validity and exit") 115 configStrict = flagBoolean(nmConfigStrict, false, "enforce config file validity") 116 117 // Base 118 causetstore = flag.String(nmStore, "entangledstore", "registered causetstore name, [einsteindb, mockeinsteindb, entangledstore]") 119 storePath = flag.String(nmStorePath, "/tmp/milevadb", "milevadb storage path") 120 host = flag.String(nmHost, "0.0.0.0", "milevadb server host") 121 advertiseAddress = flag.String(nmAdvertiseAddress, "", "milevadb server advertise IP") 122 port = flag.String(nmPort, "4000", "milevadb server port") 123 cors = flag.String(nmCors, "", "milevadb server allow cors origin") 124 socket = flag.String(nmSocket, "", "The socket file to use for connection.") 125 enableBinlog = flagBoolean(nmEnableBinlog, false, "enable generate binlog") 126 runDBS = flagBoolean(nmRunDBS, true, "run dbs worker on this milevadb-server") 127 dbsLease = flag.String(nmDdlLease, "45s", "schemaReplicant lease duration, very dangerous to change only if you know what you do") 128 tokenLimit = flag.Int(nmTokenLimit, 1000, "the limit of concurrent executed stochastik") 129 pluginDir = flag.String(nmPluginDir, "/data/deploy/plugin", "the folder that hold plugin") 130 pluginLoad = flag.String(nmPluginLoad, "", "wait load plugin name(separated by comma)") 131 affinityCPU = flag.String(nmAffinityCPU, "", "affinity cpu (cpu-no. separated by comma, e.g. 1,2,3)") 132 repairMode = flagBoolean(nmRepairMode, false, "enable admin repair mode") 133 repairList = flag.String(nmRepairList, "", "admin repair causet list") 134 requireTLS = flag.Bool(nmRequireSecureTransport, false, "require client use secure transport") 135 136 // Log 137 logLevel = flag.String(nmLogLevel, "info", "log level: info, debug, warn, error, fatal") 138 logFile = flag.String(nmLogFile, "", "log file path") 139 logSlowQuery = flag.String(nmLogSlowQuery, "", "slow query file path") 140 141 // Status 142 reportStatus = flagBoolean(nmReportStatus, true, "If enable status report HTTP service.") 143 statusHost = flag.String(nmStatusHost, "0.0.0.0", "milevadb server status host") 144 statusPort = flag.String(nmStatusPort, "10080", "milevadb server status port") 145 metricsAddr = flag.String(nmMetricsAddr, "", "prometheus pushgateway address, leaves it empty will disable prometheus push.") 146 metricsInterval = flag.Uint(nmMetricsInterval, 15, "prometheus client push interval in second, set \"0\" to disable prometheus push.") 147 148 // PROXY Protocol 149 proxyProtocolNetworks = flag.String(nmProxyProtocolNetworks, "", "proxy protocol networks allowed IP or *, empty mean disable proxy protocol support") 150 proxyProtocolHeaderTimeout = flag.Uint(nmProxyProtocolHeaderTimeout, 5, "proxy protocol header read timeout, unit is second.") 151 ) 152 153 var ( 154 storage ekv.CausetStorage 155 dom *petri.Petri 156 svr *server.Server 157 graceful bool 158 ) 159 160 func main() { 161 flag.Parse() 162 if *version { 163 fmt.Println(printer.GetMilevaDBInfo()) 164 os.Exit(0) 165 } 166 registerStores() 167 registerMetrics() 168 config.InitializeConfig(*configPath, *configCheck, *configStrict, reloadConfig, overrideConfig) 169 if config.GetGlobalConfig().OOMUseTmpStorage { 170 config.GetGlobalConfig().UFIDelateTempStoragePath() 171 err := disk.InitializeTemFIDelir() 172 terror.MustNil(err) 173 checkTempStorageQuota() 174 } 175 setGlobalVars() 176 setCPUAffinity() 177 setupLog() 178 setHeapProfileTracker() 179 setupTracing() // Should before createServer and after setup config. 180 printInfo() 181 setupBinlogClient() 182 setupMetrics() 183 createStoreAndPetri() 184 createServer() 185 signal.SetupSignalHandler(serverShutdown) 186 runServer() 187 cleanup() 188 syncLog() 189 } 190 191 func exit() { 192 syncLog() 193 os.Exit(0) 194 } 195 196 func syncLog() { 197 if err := log.Sync(); err != nil { 198 fmt.Fprintln(os.Stderr, "sync log err:", err) 199 os.Exit(1) 200 } 201 } 202 203 func checkTempStorageQuota() { 204 // check capacity and the quota when OOMUseTmpStorage is enabled 205 c := config.GetGlobalConfig() 206 if c.TempStorageQuota < 0 { 207 // means unlimited, do nothing 208 } else { 209 capacityByte, err := storageSys.GetTargetDirectoryCapacity(c.TempStoragePath) 210 if err != nil { 211 log.Fatal(err.Error()) 212 } else if capacityByte < uint64(c.TempStorageQuota) { 213 log.Fatal(fmt.Sprintf("value of [tmp-storage-quota](%d byte) exceeds the capacity(%d byte) of the [%s] directory", c.TempStorageQuota, capacityByte, c.TempStoragePath)) 214 } 215 } 216 } 217 218 func setCPUAffinity() { 219 if affinityCPU == nil || len(*affinityCPU) == 0 { 220 return 221 } 222 var cpu []int 223 for _, af := range strings.Split(*affinityCPU, ",") { 224 af = strings.TrimSpace(af) 225 if len(af) > 0 { 226 c, err := strconv.Atoi(af) 227 if err != nil { 228 fmt.Fprintf(os.Stderr, "wrong affinity cpu config: %s", *affinityCPU) 229 exit() 230 } 231 cpu = append(cpu, c) 232 } 233 } 234 err := linux.SetAffinity(cpu) 235 if err != nil { 236 fmt.Fprintf(os.Stderr, "set cpu affinity failure: %v", err) 237 exit() 238 } 239 runtime.GOMAXPROCS(len(cpu)) 240 metrics.MaxProcs.Set(float64(runtime.GOMAXPROCS(0))) 241 } 242 243 func setHeapProfileTracker() { 244 c := config.GetGlobalConfig() 245 d := parseDuration(c.Performance.MemProfileInterval) 246 go profile.HeapProfileForGlobalMemTracker(d) 247 } 248 249 func registerStores() { 250 err := ekvstore.Register("einsteindb", einsteindb.Driver{}) 251 terror.MustNil(err) 252 einsteindb.NewGCHandlerFunc = gcworker.NewGCWorker 253 err = ekvstore.Register("mockeinsteindb", mockstore.MockEinsteinDBDriver{}) 254 terror.MustNil(err) 255 err = ekvstore.Register("entangledstore", mockstore.EmbedEntangledStoreDriver{}) 256 terror.MustNil(err) 257 } 258 259 func registerMetrics() { 260 metrics.RegisterMetrics() 261 } 262 263 func createStoreAndPetri() { 264 cfg := config.GetGlobalConfig() 265 fullPath := fmt.Sprintf("%s://%s", cfg.CausetStore, cfg.Path) 266 var err error 267 storage, err = ekvstore.New(fullPath) 268 terror.MustNil(err) 269 // Bootstrap a stochastik to load information schemaReplicant. 270 dom, err = stochastik.BootstrapStochastik(storage) 271 terror.MustNil(err) 272 } 273 274 func setupBinlogClient() { 275 cfg := config.GetGlobalConfig() 276 if !cfg.Binlog.Enable { 277 return 278 } 279 280 if cfg.Binlog.IgnoreError { 281 binloginfo.SetIgnoreError(true) 282 } 283 284 var ( 285 client *pumpcli.PumpsClient 286 err error 287 ) 288 289 securityOption := fidel.SecurityOption{ 290 CAPath: cfg.Security.ClusterSSLCA, 291 CertPath: cfg.Security.ClusterSSLCert, 292 KeyPath: cfg.Security.ClusterSSLKey, 293 } 294 295 if len(cfg.Binlog.BinlogSocket) == 0 { 296 client, err = pumpcli.NewPumpsClient(cfg.Path, cfg.Binlog.Strategy, parseDuration(cfg.Binlog.WriteTimeout), securityOption) 297 } else { 298 client, err = pumpcli.NewLocalPumpsClient(cfg.Path, cfg.Binlog.BinlogSocket, parseDuration(cfg.Binlog.WriteTimeout), securityOption) 299 } 300 301 terror.MustNil(err) 302 303 err = pumpcli.InitLogger(cfg.Log.ToLogConfig()) 304 terror.MustNil(err) 305 306 binloginfo.SetPumpsClient(client) 307 log.Info("milevadb-server", zap.Bool("create pumps client success, ignore binlog error", cfg.Binlog.IgnoreError)) 308 } 309 310 // Prometheus push. 311 const zeroDuration = time.Duration(0) 312 313 // pushMetric pushes metrics in background. 314 func pushMetric(addr string, interval time.Duration) { 315 if interval == zeroDuration || len(addr) == 0 { 316 log.Info("disable Prometheus push client") 317 return 318 } 319 log.Info("start prometheus push client", zap.String("server addr", addr), zap.String("interval", interval.String())) 320 go prometheusPushClient(addr, interval) 321 } 322 323 // prometheusPushClient pushes metrics to Prometheus Pushgateway. 324 func prometheusPushClient(addr string, interval time.Duration) { 325 // TODO: MilevaDB do not have uniq name, so we use host+port to compose a name. 326 job := "milevadb" 327 pusher := push.New(addr, job) 328 pusher = pusher.Gatherer(prometheus.DefaultGatherer) 329 pusher = pusher.Grouping("instance", instanceName()) 330 for { 331 err := pusher.Push() 332 if err != nil { 333 log.Error("could not push metrics to prometheus pushgateway", zap.String("err", err.Error())) 334 } 335 time.Sleep(interval) 336 } 337 } 338 339 func instanceName() string { 340 cfg := config.GetGlobalConfig() 341 hostname, err := os.Hostname() 342 if err != nil { 343 return "unknown" 344 } 345 return fmt.Sprintf("%s_%d", hostname, cfg.Port) 346 } 347 348 // parseDuration parses lease argument string. 349 func parseDuration(lease string) time.Duration { 350 dur, err := time.ParseDuration(lease) 351 if err != nil { 352 dur, err = time.ParseDuration(lease + "s") 353 } 354 if err != nil || dur < 0 { 355 log.Fatal("invalid lease duration", zap.String("lease", lease)) 356 } 357 return dur 358 } 359 360 func flagBoolean(name string, defaultVal bool, usage string) *bool { 361 if !defaultVal { 362 // Fix #4125, golang do not print default false value in usage, so we append it. 363 usage = fmt.Sprintf("%s (default false)", usage) 364 return flag.Bool(name, defaultVal, usage) 365 } 366 return flag.Bool(name, defaultVal, usage) 367 } 368 369 func reloadConfig(nc, c *config.Config) { 370 // Just a part of config items need to be reload explicitly. 371 // Some of them like OOMCausetAction are always used by getting from global config directly 372 // like config.GetGlobalConfig().OOMCausetAction. 373 // These config items will become available naturally after the global config pointer 374 // is uFIDelated in function ReloadGlobalConfig. 375 if nc.Performance.ServerMemoryQuota != c.Performance.ServerMemoryQuota { 376 causetembedded.PreparedCausetCacheMaxMemory.CausetStore(nc.Performance.ServerMemoryQuota) 377 } 378 if nc.Performance.CrossJoin != c.Performance.CrossJoin { 379 causetembedded.AllowCartesianProduct.CausetStore(nc.Performance.CrossJoin) 380 } 381 if nc.Performance.FeedbackProbability != c.Performance.FeedbackProbability { 382 statistics.FeedbackProbability.CausetStore(nc.Performance.FeedbackProbability) 383 } 384 if nc.Performance.QueryFeedbackLimit != c.Performance.QueryFeedbackLimit { 385 statistics.MaxQueryFeedbackCount.CausetStore(int64(nc.Performance.QueryFeedbackLimit)) 386 } 387 if nc.Performance.PseudoEstimateRatio != c.Performance.PseudoEstimateRatio { 388 statistics.RatioOfPseudoEstimate.CausetStore(nc.Performance.PseudoEstimateRatio) 389 } 390 if nc.Performance.MaxProcs != c.Performance.MaxProcs { 391 runtime.GOMAXPROCS(int(nc.Performance.MaxProcs)) 392 metrics.MaxProcs.Set(float64(runtime.GOMAXPROCS(0))) 393 } 394 if nc.EinsteinDBClient.StoreLimit != c.EinsteinDBClient.StoreLimit { 395 storeutil.StoreLimit.CausetStore(nc.EinsteinDBClient.StoreLimit) 396 } 397 398 if nc.PreparedCausetCache.Enabled != c.PreparedCausetCache.Enabled { 399 causetembedded.SetPreparedCausetCache(nc.PreparedCausetCache.Enabled) 400 } 401 if nc.Log.Level != c.Log.Level { 402 if err := logutil.SetLevel(nc.Log.Level); err != nil { 403 logutil.BgLogger().Error("uFIDelate log level error", zap.Error(err)) 404 } 405 } 406 } 407 408 // overrideConfig considers command arguments and overrides some config items in the Config. 409 func overrideConfig(cfg *config.Config) { 410 actualFlags := make(map[string]bool) 411 flag.Visit(func(f *flag.Flag) { 412 actualFlags[f.Name] = true 413 }) 414 415 // Base 416 if actualFlags[nmHost] { 417 cfg.Host = *host 418 } 419 if actualFlags[nmAdvertiseAddress] { 420 cfg.AdvertiseAddress = *advertiseAddress 421 } 422 if len(cfg.AdvertiseAddress) == 0 { 423 cfg.AdvertiseAddress = soliton.GetLocalIP() 424 } 425 if len(cfg.AdvertiseAddress) == 0 { 426 cfg.AdvertiseAddress = cfg.Host 427 } 428 var err error 429 if actualFlags[nmPort] { 430 var p int 431 p, err = strconv.Atoi(*port) 432 terror.MustNil(err) 433 cfg.Port = uint(p) 434 } 435 if actualFlags[nmCors] { 436 fmt.Println(cors) 437 cfg.Cors = *cors 438 } 439 if actualFlags[nmStore] { 440 cfg.CausetStore = *causetstore 441 } 442 if actualFlags[nmStorePath] { 443 cfg.Path = *storePath 444 } 445 if actualFlags[nmSocket] { 446 cfg.Socket = *socket 447 } 448 if actualFlags[nmEnableBinlog] { 449 cfg.Binlog.Enable = *enableBinlog 450 } 451 if actualFlags[nmRunDBS] { 452 cfg.RunDBS = *runDBS 453 } 454 if actualFlags[nmDdlLease] { 455 cfg.Lease = *dbsLease 456 } 457 if actualFlags[nmTokenLimit] { 458 cfg.TokenLimit = uint(*tokenLimit) 459 } 460 if actualFlags[nmPluginLoad] { 461 cfg.Plugin.Load = *pluginLoad 462 } 463 if actualFlags[nmPluginDir] { 464 cfg.Plugin.Dir = *pluginDir 465 } 466 if actualFlags[nmRequireSecureTransport] { 467 cfg.Security.RequireSecureTransport = *requireTLS 468 } 469 if actualFlags[nmRepairMode] { 470 cfg.RepairMode = *repairMode 471 } 472 if actualFlags[nmRepairList] { 473 if cfg.RepairMode { 474 cfg.RepairTableList = stringToList(*repairList) 475 } 476 } 477 478 // Log 479 if actualFlags[nmLogLevel] { 480 cfg.Log.Level = *logLevel 481 } 482 if actualFlags[nmLogFile] { 483 cfg.Log.File.Filename = *logFile 484 } 485 if actualFlags[nmLogSlowQuery] { 486 cfg.Log.SlowQueryFile = *logSlowQuery 487 } 488 489 // Status 490 if actualFlags[nmReportStatus] { 491 cfg.Status.ReportStatus = *reportStatus 492 } 493 if actualFlags[nmStatusHost] { 494 cfg.Status.StatusHost = *statusHost 495 } 496 if actualFlags[nmStatusPort] { 497 var p int 498 p, err = strconv.Atoi(*statusPort) 499 terror.MustNil(err) 500 cfg.Status.StatusPort = uint(p) 501 } 502 if actualFlags[nmMetricsAddr] { 503 cfg.Status.MetricsAddr = *metricsAddr 504 } 505 if actualFlags[nmMetricsInterval] { 506 cfg.Status.MetricsInterval = *metricsInterval 507 } 508 509 // PROXY Protocol 510 if actualFlags[nmProxyProtocolNetworks] { 511 cfg.ProxyProtocol.Networks = *proxyProtocolNetworks 512 } 513 if actualFlags[nmProxyProtocolHeaderTimeout] { 514 cfg.ProxyProtocol.HeaderTimeout = *proxyProtocolHeaderTimeout 515 } 516 } 517 518 func setGlobalVars() { 519 cfg := config.GetGlobalConfig() 520 521 // Disable automaxprocs log 522 nopLog := func(string, ...interface{}) {} 523 _, err := maxprocs.Set(maxprocs.Logger(nopLog)) 524 terror.MustNil(err) 525 // We should respect to user's settings in config file. 526 // The default value of MaxProcs is 0, runtime.GOMAXPROCS(0) is no-op. 527 runtime.GOMAXPROCS(int(cfg.Performance.MaxProcs)) 528 metrics.MaxProcs.Set(float64(runtime.GOMAXPROCS(0))) 529 530 dbsLeaseDuration := parseDuration(cfg.Lease) 531 stochastik.SetSchemaLease(dbsLeaseDuration) 532 statsLeaseDuration := parseDuration(cfg.Performance.StatsLease) 533 stochastik.SetStatsLease(statsLeaseDuration) 534 indexUsageSyncLeaseDuration := parseDuration(cfg.Performance.IndexUsageSyncLease) 535 stochastik.SetIndexUsageSyncLease(indexUsageSyncLeaseDuration) 536 bindinfo.Lease = parseDuration(cfg.Performance.BindInfoLease) 537 petri.RunAutoAnalyze = cfg.Performance.RunAutoAnalyze 538 statistics.FeedbackProbability.CausetStore(cfg.Performance.FeedbackProbability) 539 statistics.MaxQueryFeedbackCount.CausetStore(int64(cfg.Performance.QueryFeedbackLimit)) 540 statistics.RatioOfPseudoEstimate.CausetStore(cfg.Performance.PseudoEstimateRatio) 541 dbs.RunWorker = cfg.RunDBS 542 if cfg.SplitTable { 543 atomic.StoreUint32(&dbs.EnableSplitTableRegion, 1) 544 } 545 causetembedded.AllowCartesianProduct.CausetStore(cfg.Performance.CrossJoin) 546 privileges.SkipWithGrant = cfg.Security.SkipGrantTable 547 ekv.TxnTotalSizeLimit = cfg.Performance.TxnTotalSizeLimit 548 if cfg.Performance.TxnEntrySizeLimit > 120*1024*1024 { 549 log.Fatal("cannot set txn entry size limit larger than 120M") 550 } 551 ekv.TxnEntrySizeLimit = cfg.Performance.TxnEntrySizeLimit 552 553 priority := allegrosql.Str2Priority(cfg.Performance.ForcePriority) 554 variable.ForcePriority = int32(priority) 555 variable.SysVars[variable.MilevaDBForcePriority].Value = allegrosql.Priority2Str[priority] 556 variable.SysVars[variable.MilevaDBOptDistinctAggPushDown].Value = variable.BoolToIntStr(cfg.Performance.DistinctAggPushDown) 557 558 variable.SysVars[variable.MilevaDBMemQuotaQuery].Value = strconv.FormatInt(cfg.MemQuotaQuery, 10) 559 variable.SysVars["lower_case_block_names"].Value = strconv.Itoa(cfg.LowerCaseTableNames) 560 variable.SysVars[variable.LogBin].Value = variable.BoolToIntStr(config.GetGlobalConfig().Binlog.Enable) 561 562 variable.SysVars[variable.Port].Value = fmt.Sprintf("%d", cfg.Port) 563 variable.SysVars[variable.Socket].Value = cfg.Socket 564 variable.SysVars[variable.DataDir].Value = cfg.Path 565 variable.SysVars[variable.MilevaDBSlowQueryFile].Value = cfg.Log.SlowQueryFile 566 variable.SysVars[variable.MilevaDBIsolationReadEngines].Value = strings.Join(cfg.IsolationRead.Engines, ", ") 567 568 // For CI environment we default enable prepare-plan-cache. 569 causetembedded.SetPreparedCausetCache(config.CheckTableBeforeDrop || cfg.PreparedCausetCache.Enabled) 570 if causetembedded.PreparedCausetCacheEnabled() { 571 causetembedded.PreparedCausetCacheCapacity = cfg.PreparedCausetCache.Capacity 572 causetembedded.PreparedCausetCacheMemoryGuardRatio = cfg.PreparedCausetCache.MemoryGuardRatio 573 if causetembedded.PreparedCausetCacheMemoryGuardRatio < 0.0 || causetembedded.PreparedCausetCacheMemoryGuardRatio > 1.0 { 574 causetembedded.PreparedCausetCacheMemoryGuardRatio = 0.1 575 } 576 causetembedded.PreparedCausetCacheMaxMemory.CausetStore(cfg.Performance.ServerMemoryQuota) 577 total, err := memory.MemTotal() 578 terror.MustNil(err) 579 if causetembedded.PreparedCausetCacheMaxMemory.Load() > total || causetembedded.PreparedCausetCacheMaxMemory.Load() <= 0 { 580 causetembedded.PreparedCausetCacheMaxMemory.CausetStore(total) 581 } 582 } 583 584 atomic.StoreUint64(&einsteindb.CommitMaxBackoff, uint64(parseDuration(cfg.EinsteinDBClient.CommitTimeout).Seconds()*1000)) 585 einsteindb.RegionCacheTTLSec = int64(cfg.EinsteinDBClient.RegionCacheTTL) 586 petriutil.RepairInfo.SetRepairMode(cfg.RepairMode) 587 petriutil.RepairInfo.SetRepairTableList(cfg.RepairTableList) 588 c := config.GetGlobalConfig() 589 interlock.GlobalDiskUsageTracker.SetBytesLimit(c.TempStorageQuota) 590 if c.Performance.ServerMemoryQuota < 1 { 591 // If MaxMemory equals 0, it means unlimited 592 interlock.GlobalMemoryUsageTracker.SetBytesLimit(-1) 593 } else { 594 interlock.GlobalMemoryUsageTracker.SetBytesLimit(int64(c.Performance.ServerMemoryQuota)) 595 } 596 ekvcache.GlobalLRUMemUsageTracker.AttachToGlobalTracker(interlock.GlobalMemoryUsageTracker) 597 598 t, err := time.ParseDuration(cfg.EinsteinDBClient.StoreLivenessTimeout) 599 if err != nil { 600 logutil.BgLogger().Fatal("invalid duration value for causetstore-liveness-timeout", 601 zap.String("currentValue", config.GetGlobalConfig().EinsteinDBClient.StoreLivenessTimeout)) 602 } 603 einsteindb.StoreLivenessTimeout = t 604 BerolinaSQLtypes.MilevaDBStrictIntegerDisplayWidth = config.GetGlobalConfig().DeprecateIntegerDisplayWidth 605 } 606 607 func setupLog() { 608 cfg := config.GetGlobalConfig() 609 err := logutil.InitZapLogger(cfg.Log.ToLogConfig()) 610 terror.MustNil(err) 611 612 err = logutil.InitLogger(cfg.Log.ToLogConfig()) 613 terror.MustNil(err) 614 615 if len(os.Getenv("GRPC_DEBUG")) > 0 { 616 grpclog.SetLoggerV2(grpclog.NewLoggerV2WithVerbosity(os.Stderr, os.Stderr, os.Stderr, 999)) 617 } else { 618 grpclog.SetLoggerV2(grpclog.NewLoggerV2(ioutil.Discard, ioutil.Discard, os.Stderr)) 619 } 620 // trigger internal http(s) client init. 621 soliton.InternalHTTPClient() 622 } 623 624 func printInfo() { 625 // Make sure the MilevaDB info is always printed. 626 level := log.GetLevel() 627 log.SetLevel(zap.InfoLevel) 628 printer.PrintMilevaDBInfo() 629 log.SetLevel(level) 630 } 631 632 func createServer() { 633 cfg := config.GetGlobalConfig() 634 driver := server.NewMilevaDBDriver(storage) 635 var err error 636 svr, err = server.NewServer(cfg, driver) 637 // Both petri and storage have started, so we have to clean them before exiting. 638 terror.MustNil(err, closePetriAndStorage) 639 svr.SetPetri(dom) 640 go dom.ExpensiveQueryHandle().SetStochastikManager(svr).Run() 641 dom.InfoSyncer().SetStochastikManager(svr) 642 } 643 644 func serverShutdown(isgraceful bool) { 645 if isgraceful { 646 graceful = true 647 } 648 svr.Close() 649 } 650 651 func setupMetrics() { 652 cfg := config.GetGlobalConfig() 653 // Enable the mutex profile, 1/10 of mutex blocking event sampling. 654 runtime.SetMutexProfileFraction(10) 655 systimeErrHandler := func() { 656 metrics.TimeJumpBackCounter.Inc() 657 } 658 callBackCount := 0 659 sucessCallBack := func() { 660 callBackCount++ 661 // It is callback by monitor per second, we increase metrics.KeepAliveCounter per 5s. 662 if callBackCount >= 5 { 663 callBackCount = 0 664 metrics.KeepAliveCounter.Inc() 665 } 666 } 667 go systimemon.StartMonitor(time.Now, systimeErrHandler, sucessCallBack) 668 669 pushMetric(cfg.Status.MetricsAddr, time.Duration(cfg.Status.MetricsInterval)*time.Second) 670 } 671 672 func setupTracing() { 673 cfg := config.GetGlobalConfig() 674 tracingCfg := cfg.OpenTracing.ToTracingConfig() 675 tracingCfg.ServiceName = "MilevaDB" 676 tracer, _, err := tracingCfg.NewTracer() 677 if err != nil { 678 log.Fatal("setup jaeger tracer failed", zap.String("error message", err.Error())) 679 } 680 opentracing.SetGlobalTracer(tracer) 681 } 682 683 func runServer() { 684 err := svr.Run() 685 terror.MustNil(err) 686 } 687 688 func closePetriAndStorage() { 689 atomic.StoreUint32(&einsteindb.ShuttingDown, 1) 690 dom.Close() 691 err := storage.Close() 692 terror.Log(errors.Trace(err)) 693 } 694 695 func cleanup() { 696 if graceful { 697 svr.GracefulDown(context.Background(), nil) 698 } else { 699 svr.TryGracefulDown() 700 } 701 plugin.Shutdown(context.Background()) 702 closePetriAndStorage() 703 disk.CleanUp() 704 } 705 706 func stringToList(repairString string) []string { 707 if len(repairString) <= 0 { 708 return []string{} 709 } 710 if repairString[0] == '[' && repairString[len(repairString)-1] == ']' { 711 repairString = repairString[1 : len(repairString)-1] 712 } 713 return strings.FieldsFunc(repairString, func(r rune) bool { 714 return r == ',' || r == ' ' || r == '"' 715 }) 716 }