github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/server/server_sql.go (about) 1 // Copyright 2020 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 server 12 13 import ( 14 "context" 15 "fmt" 16 "math" 17 "net" 18 "os" 19 "path/filepath" 20 21 "github.com/cockroachdb/cockroach/pkg/base" 22 "github.com/cockroachdb/cockroach/pkg/blobs" 23 "github.com/cockroachdb/cockroach/pkg/blobs/blobspb" 24 "github.com/cockroachdb/cockroach/pkg/gossip" 25 "github.com/cockroachdb/cockroach/pkg/jobs" 26 "github.com/cockroachdb/cockroach/pkg/keys" 27 "github.com/cockroachdb/cockroach/pkg/kv" 28 "github.com/cockroachdb/cockroach/pkg/kv/bulk" 29 "github.com/cockroachdb/cockroach/pkg/kv/kvclient/kvcoord" 30 "github.com/cockroachdb/cockroach/pkg/kv/kvserver/kvserverbase" 31 "github.com/cockroachdb/cockroach/pkg/kv/kvserver/protectedts" 32 "github.com/cockroachdb/cockroach/pkg/roachpb" 33 "github.com/cockroachdb/cockroach/pkg/rpc" 34 "github.com/cockroachdb/cockroach/pkg/rpc/nodedialer" 35 "github.com/cockroachdb/cockroach/pkg/server/serverpb" 36 "github.com/cockroachdb/cockroach/pkg/server/status" 37 "github.com/cockroachdb/cockroach/pkg/sql" 38 "github.com/cockroachdb/cockroach/pkg/sql/catalog/lease" 39 "github.com/cockroachdb/cockroach/pkg/sql/colexec" 40 "github.com/cockroachdb/cockroach/pkg/sql/distsql" 41 "github.com/cockroachdb/cockroach/pkg/sql/execinfra" 42 "github.com/cockroachdb/cockroach/pkg/sql/execinfrapb" 43 "github.com/cockroachdb/cockroach/pkg/sql/pgwire" 44 "github.com/cockroachdb/cockroach/pkg/sql/querycache" 45 "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" 46 "github.com/cockroachdb/cockroach/pkg/sql/sessiondata" 47 "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" 48 "github.com/cockroachdb/cockroach/pkg/sql/sqlutil" 49 "github.com/cockroachdb/cockroach/pkg/sql/stats" 50 "github.com/cockroachdb/cockroach/pkg/sql/stmtdiagnostics" 51 "github.com/cockroachdb/cockroach/pkg/sqlmigrations" 52 "github.com/cockroachdb/cockroach/pkg/storage" 53 "github.com/cockroachdb/cockroach/pkg/storage/cloud" 54 "github.com/cockroachdb/cockroach/pkg/util/envutil" 55 "github.com/cockroachdb/cockroach/pkg/util/hlc" 56 "github.com/cockroachdb/cockroach/pkg/util/log" 57 "github.com/cockroachdb/cockroach/pkg/util/metric" 58 "github.com/cockroachdb/cockroach/pkg/util/mon" 59 "github.com/cockroachdb/cockroach/pkg/util/netutil" 60 "github.com/cockroachdb/cockroach/pkg/util/stop" 61 "github.com/cockroachdb/errors" 62 "github.com/marusama/semaphore" 63 "google.golang.org/grpc" 64 ) 65 66 type sqlServer struct { 67 pgServer *pgwire.Server 68 distSQLServer *distsql.ServerImpl 69 execCfg *sql.ExecutorConfig 70 internalExecutor *sql.InternalExecutor 71 leaseMgr *lease.Manager 72 blobService *blobs.Service 73 // sessionRegistry can be queried for info on running SQL sessions. It is 74 // shared between the sql.Server and the statusServer. 75 sessionRegistry *sql.SessionRegistry 76 jobRegistry *jobs.Registry 77 migMgr *sqlmigrations.Manager 78 statsRefresher *stats.Refresher 79 temporaryObjectCleaner *sql.TemporaryObjectCleaner 80 internalMemMetrics sql.MemoryMetrics 81 adminMemMetrics sql.MemoryMetrics 82 // sqlMemMetrics are used to track memory usage of sql sessions. 83 sqlMemMetrics sql.MemoryMetrics 84 stmtDiagnosticsRegistry *stmtdiagnostics.Registry 85 } 86 87 // sqlServerOptionalArgs are the arguments supplied to newSQLServer which 88 // are only available if the SQL server runs as part of a KV node. 89 // 90 // TODO(tbg): give all of these fields a wrapper that can signal whether the 91 // respective object is available. When it is not, return 92 // UnsupportedWithMultiTenancy. 93 type sqlServerOptionalArgs struct { 94 // DistSQL uses rpcContext to set up flows. Less centrally, the executor 95 // also uses rpcContext in a number of places to learn whether the server 96 // is running insecure, and to read the cluster name. 97 rpcContext *rpc.Context 98 99 // SQL mostly uses the DistSender "wrapped" under a *kv.DB, but SQL also 100 // uses range descriptors and leaseholders, which DistSender maintains, 101 // for debugging and DistSQL planning purposes. 102 distSender *kvcoord.DistSender 103 // statusServer gives access to the Status service. 104 statusServer serverpb.OptionalStatusServer 105 // Narrowed down version of *NodeLiveness. Used by jobs and DistSQLPlanner 106 nodeLiveness sqlbase.OptionalNodeLiveness 107 // Gossip is relied upon by distSQLCfg (execinfra.ServerConfig), the executor 108 // config, the DistSQL planner, the table statistics cache, the statements 109 // diagnostics registry, and the lease manager. 110 gossip gossip.DeprecatedGossip 111 // Used by DistSQLConfig and DistSQLPlanner. 112 nodeDialer *nodedialer.Dialer 113 // To register blob and DistSQL servers. 114 grpcServer *grpc.Server 115 // Used by executorConfig. 116 recorder *status.MetricsRecorder 117 // For the temporaryObjectCleaner. 118 isMeta1Leaseholder func(hlc.Timestamp) (bool, error) 119 // DistSQL, lease management, and others want to know the node they're on. 120 nodeIDContainer *base.SQLIDContainer 121 122 // Used by backup/restore. 123 externalStorage cloud.ExternalStorageFactory 124 externalStorageFromURI cloud.ExternalStorageFromURIFactory 125 } 126 127 type sqlServerArgs struct { 128 sqlServerOptionalArgs 129 130 *SQLConfig 131 *BaseConfig 132 133 stopper *stop.Stopper 134 135 // SQL uses the clock to assign timestamps to transactions, among many 136 // other things. 137 clock *hlc.Clock 138 139 // DistSQLCfg holds on to this to check for node CPU utilization in 140 // samplerProcessor. 141 runtime execinfra.RuntimeStats 142 143 // SQL uses KV, both for non-DistSQL and DistSQL execution. 144 db *kv.DB 145 146 // Various components want to register themselves with metrics. 147 registry *metric.Registry 148 149 // Used for SHOW/CANCEL QUERIE(S)/SESSION(S). 150 sessionRegistry *sql.SessionRegistry 151 152 // KV depends on the internal executor, so we pass a pointer to an empty 153 // struct in this configuration, which newSQLServer fills. 154 // 155 // TODO(tbg): make this less hacky. 156 circularInternalExecutor *sql.InternalExecutor // empty initially 157 158 // The protected timestamps KV subsystem depends on this, so we pass a 159 // pointer to an empty struct in this configuration, which newSQLServer 160 // fills. 161 circularJobRegistry *jobs.Registry 162 jobAdoptionStopFile string 163 164 // The executorConfig uses the provider. 165 protectedtsProvider protectedts.Provider 166 } 167 168 func newSQLServer(ctx context.Context, cfg sqlServerArgs) (*sqlServer, error) { 169 execCfg := &sql.ExecutorConfig{} 170 codec := keys.MakeSQLCodec(cfg.SQLConfig.TenantID) 171 172 // Create blob service for inter-node file sharing. 173 blobService, err := blobs.NewBlobService(cfg.Settings.ExternalIODir) 174 if err != nil { 175 return nil, errors.Wrap(err, "creating blob service") 176 } 177 blobspb.RegisterBlobServer(cfg.grpcServer, blobService) 178 179 jobRegistry := cfg.circularJobRegistry 180 181 { 182 regLiveness := cfg.nodeLiveness 183 if testingLiveness := cfg.TestingKnobs.RegistryLiveness; testingLiveness != nil { 184 regLiveness = sqlbase.MakeOptionalNodeLiveness(testingLiveness.(*jobs.FakeNodeLiveness)) 185 } 186 *jobRegistry = *jobs.MakeRegistry( 187 cfg.AmbientCtx, 188 cfg.stopper, 189 cfg.clock, 190 regLiveness, 191 cfg.db, 192 cfg.circularInternalExecutor, 193 cfg.nodeIDContainer, 194 cfg.Settings, 195 cfg.HistogramWindowInterval(), 196 func(opName, user string) (interface{}, func()) { 197 // This is a hack to get around a Go package dependency cycle. See comment 198 // in sql/jobs/registry.go on planHookMaker. 199 return sql.NewInternalPlanner(opName, nil, user, &sql.MemoryMetrics{}, execCfg) 200 }, 201 cfg.jobAdoptionStopFile, 202 ) 203 } 204 cfg.registry.AddMetricStruct(jobRegistry.MetricsStruct()) 205 206 distSQLMetrics := execinfra.MakeDistSQLMetrics(cfg.HistogramWindowInterval()) 207 cfg.registry.AddMetricStruct(distSQLMetrics) 208 209 // Set up Lease Manager 210 var lmKnobs lease.ManagerTestingKnobs 211 if leaseManagerTestingKnobs := cfg.TestingKnobs.SQLLeaseManager; leaseManagerTestingKnobs != nil { 212 lmKnobs = *leaseManagerTestingKnobs.(*lease.ManagerTestingKnobs) 213 } 214 leaseMgr := lease.NewLeaseManager( 215 cfg.AmbientCtx, 216 cfg.nodeIDContainer, 217 cfg.db, 218 cfg.clock, 219 cfg.circularInternalExecutor, 220 cfg.Settings, 221 codec, 222 lmKnobs, 223 cfg.stopper, 224 cfg.LeaseManagerConfig, 225 ) 226 227 // Set up internal memory metrics for use by internal SQL executors. 228 internalMemMetrics := sql.MakeMemMetrics("internal", cfg.HistogramWindowInterval()) 229 cfg.registry.AddMetricStruct(internalMemMetrics) 230 231 // We do not set memory monitors or a noteworthy limit because the children of 232 // this monitor will be setting their own noteworthy limits. 233 rootSQLMemoryMonitor := mon.MakeMonitor( 234 "root", 235 mon.MemoryResource, 236 nil, /* curCount */ 237 nil, /* maxHist */ 238 -1, /* increment: use default increment */ 239 math.MaxInt64, /* noteworthy */ 240 cfg.Settings, 241 ) 242 rootSQLMemoryMonitor.Start(context.Background(), nil, mon.MakeStandaloneBudget(cfg.MemoryPoolSize)) 243 244 // bulkMemoryMonitor is the parent to all child SQL monitors tracking bulk 245 // operations (IMPORT, index backfill). It is itself a child of the 246 // ParentMemoryMonitor. 247 bulkMemoryMonitor := mon.MakeMonitorInheritWithLimit("bulk-mon", 0 /* limit */, &rootSQLMemoryMonitor) 248 bulkMetrics := bulk.MakeBulkMetrics(cfg.HistogramWindowInterval()) 249 cfg.registry.AddMetricStruct(bulkMetrics) 250 bulkMemoryMonitor.SetMetrics(bulkMetrics.CurBytesCount, bulkMetrics.MaxBytesHist) 251 bulkMemoryMonitor.Start(context.Background(), &rootSQLMemoryMonitor, mon.BoundAccount{}) 252 253 // Set up the DistSQL temp engine. 254 255 useStoreSpec := cfg.TempStorageConfig.Spec 256 tempEngine, tempFS, err := storage.NewTempEngine(ctx, cfg.StorageEngine, cfg.TempStorageConfig, useStoreSpec) 257 if err != nil { 258 return nil, errors.Wrap(err, "creating temp storage") 259 } 260 cfg.stopper.AddCloser(tempEngine) 261 // Remove temporary directory linked to tempEngine after closing 262 // tempEngine. 263 cfg.stopper.AddCloser(stop.CloserFn(func() { 264 useStore := cfg.TempStorageConfig.Spec 265 var err error 266 if useStore.InMemory { 267 // Used store is in-memory so we remove the temp 268 // directory directly since there is no record file. 269 err = os.RemoveAll(cfg.TempStorageConfig.Path) 270 } else { 271 // If record file exists, we invoke CleanupTempDirs to 272 // also remove the record after the temp directory is 273 // removed. 274 recordPath := filepath.Join(useStore.Path, TempDirsRecordFilename) 275 err = storage.CleanupTempDirs(recordPath) 276 } 277 if err != nil { 278 log.Errorf(ctx, "could not remove temporary store directory: %v", err.Error()) 279 } 280 })) 281 282 // Set up admin memory metrics for use by admin SQL executors. 283 adminMemMetrics := sql.MakeMemMetrics("admin", cfg.HistogramWindowInterval()) 284 cfg.registry.AddMetricStruct(adminMemMetrics) 285 286 // Set up the DistSQL server. 287 distSQLCfg := execinfra.ServerConfig{ 288 AmbientContext: cfg.AmbientCtx, 289 Settings: cfg.Settings, 290 RuntimeStats: cfg.runtime, 291 ClusterID: &cfg.rpcContext.ClusterID, 292 ClusterName: cfg.ClusterName, 293 NodeID: cfg.nodeIDContainer, 294 Codec: codec, 295 DB: cfg.db, 296 Executor: cfg.circularInternalExecutor, 297 RPCContext: cfg.rpcContext, 298 Stopper: cfg.stopper, 299 300 TempStorage: tempEngine, 301 TempStoragePath: cfg.TempStorageConfig.Path, 302 TempFS: tempFS, 303 // COCKROACH_VEC_MAX_OPEN_FDS specifies the maximum number of open file 304 // descriptors that the vectorized execution engine may have open at any 305 // one time. This limit is implemented as a weighted semaphore acquired 306 // before opening files. 307 VecFDSemaphore: semaphore.New(envutil.EnvOrDefaultInt("COCKROACH_VEC_MAX_OPEN_FDS", colexec.VecMaxOpenFDsLimit)), 308 DiskMonitor: cfg.TempStorageConfig.Mon, 309 310 ParentMemoryMonitor: &rootSQLMemoryMonitor, 311 BulkAdder: func( 312 ctx context.Context, db *kv.DB, ts hlc.Timestamp, opts kvserverbase.BulkAdderOptions, 313 ) (kvserverbase.BulkAdder, error) { 314 // Attach a child memory monitor to enable control over the BulkAdder's 315 // memory usage. 316 bulkMon := execinfra.NewMonitor(ctx, &bulkMemoryMonitor, fmt.Sprintf("bulk-adder-monitor")) 317 return bulk.MakeBulkAdder(ctx, db, cfg.distSender.RangeDescriptorCache(), cfg.Settings, ts, opts, bulkMon) 318 }, 319 320 Metrics: &distSQLMetrics, 321 322 JobRegistry: jobRegistry, 323 Gossip: cfg.gossip, 324 NodeDialer: cfg.nodeDialer, 325 LeaseManager: leaseMgr, 326 327 ExternalStorage: cfg.externalStorage, 328 ExternalStorageFromURI: cfg.externalStorageFromURI, 329 } 330 cfg.TempStorageConfig.Mon.SetMetrics(distSQLMetrics.CurDiskBytesCount, distSQLMetrics.MaxDiskBytesHist) 331 if distSQLTestingKnobs := cfg.TestingKnobs.DistSQL; distSQLTestingKnobs != nil { 332 distSQLCfg.TestingKnobs = *distSQLTestingKnobs.(*execinfra.TestingKnobs) 333 } 334 335 distSQLServer := distsql.NewServer(ctx, distSQLCfg) 336 execinfrapb.RegisterDistSQLServer(cfg.grpcServer, distSQLServer) 337 338 virtualSchemas, err := sql.NewVirtualSchemaHolder(ctx, cfg.Settings) 339 if err != nil { 340 return nil, errors.Wrap(err, "creating virtual schema holder") 341 } 342 343 // Set up Executor 344 345 var sqlExecutorTestingKnobs sql.ExecutorTestingKnobs 346 if k := cfg.TestingKnobs.SQLExecutor; k != nil { 347 sqlExecutorTestingKnobs = *k.(*sql.ExecutorTestingKnobs) 348 } else { 349 sqlExecutorTestingKnobs = sql.ExecutorTestingKnobs{} 350 } 351 352 loggerCtx, _ := cfg.stopper.WithCancelOnStop(ctx) 353 354 nodeInfo := sql.NodeInfo{ 355 AdminURL: cfg.AdminURL, 356 PGURL: cfg.PGURL, 357 ClusterID: cfg.rpcContext.ClusterID.Get, 358 NodeID: cfg.nodeIDContainer, 359 } 360 361 var isLive func(roachpb.NodeID) (bool, error) 362 if nl, ok := cfg.nodeLiveness.Optional(47900); ok { 363 isLive = nl.IsLive 364 } else { 365 // We're on a SQL tenant, so this is the only node DistSQL will ever 366 // schedule on - always returning true is fine. 367 isLive = func(roachpb.NodeID) (bool, error) { 368 return true, nil 369 } 370 } 371 372 *execCfg = sql.ExecutorConfig{ 373 Settings: cfg.Settings, 374 NodeInfo: nodeInfo, 375 Codec: codec, 376 DefaultZoneConfig: &cfg.DefaultZoneConfig, 377 Locality: cfg.Locality, 378 AmbientCtx: cfg.AmbientCtx, 379 DB: cfg.db, 380 Gossip: cfg.gossip, 381 MetricsRecorder: cfg.recorder, 382 DistSender: cfg.distSender, 383 RPCContext: cfg.rpcContext, 384 LeaseManager: leaseMgr, 385 Clock: cfg.clock, 386 DistSQLSrv: distSQLServer, 387 StatusServer: cfg.statusServer, 388 SessionRegistry: cfg.sessionRegistry, 389 JobRegistry: jobRegistry, 390 VirtualSchemas: virtualSchemas, 391 HistogramWindowInterval: cfg.HistogramWindowInterval(), 392 RangeDescriptorCache: cfg.distSender.RangeDescriptorCache(), 393 LeaseHolderCache: cfg.distSender.LeaseHolderCache(), 394 RoleMemberCache: &sql.MembershipCache{}, 395 TestingKnobs: sqlExecutorTestingKnobs, 396 397 DistSQLPlanner: sql.NewDistSQLPlanner( 398 ctx, 399 execinfra.Version, 400 cfg.Settings, 401 // The node descriptor will be set later, once it is initialized. 402 roachpb.NodeDescriptor{}, 403 cfg.rpcContext, 404 distSQLServer, 405 cfg.distSender, 406 cfg.gossip, 407 cfg.stopper, 408 isLive, 409 cfg.nodeDialer, 410 ), 411 412 TableStatsCache: stats.NewTableStatisticsCache( 413 cfg.TableStatCacheSize, 414 cfg.gossip, 415 cfg.db, 416 cfg.circularInternalExecutor, 417 codec, 418 ), 419 420 // Note: don't forget to add the secondary loggers as closers 421 // on the Stopper, below. 422 423 ExecLogger: log.NewSecondaryLogger( 424 loggerCtx, nil /* dirName */, "sql-exec", 425 true /* enableGc */, false /*forceSyncWrites*/, true, /* enableMsgCount */ 426 ), 427 428 // Note: the auth logger uses sync writes because we don't want an 429 // attacker to easily "erase their traces" after an attack by 430 // crashing the server before it has a chance to write the last 431 // few log lines to disk. 432 // 433 // TODO(knz): We could worry about disk I/O activity incurred by 434 // logging here in case a malicious user spams the server with 435 // (failing) connection attempts to cause a DoS failure; this 436 // would be a good reason to invest into a syslog sink for logs. 437 AuthLogger: log.NewSecondaryLogger( 438 loggerCtx, nil /* dirName */, "auth", 439 true /* enableGc */, true /*forceSyncWrites*/, true, /* enableMsgCount */ 440 ), 441 442 // AuditLogger syncs to disk for the same reason as AuthLogger. 443 AuditLogger: log.NewSecondaryLogger( 444 loggerCtx, cfg.AuditLogDirName, "sql-audit", 445 true /*enableGc*/, true /*forceSyncWrites*/, true, /* enableMsgCount */ 446 ), 447 448 SlowQueryLogger: log.NewSecondaryLogger( 449 loggerCtx, nil, "sql-slow", 450 true /*enableGc*/, false /*forceSyncWrites*/, true, /* enableMsgCount */ 451 ), 452 453 QueryCache: querycache.New(cfg.QueryCacheSize), 454 ProtectedTimestampProvider: cfg.protectedtsProvider, 455 } 456 457 cfg.stopper.AddCloser(execCfg.ExecLogger) 458 cfg.stopper.AddCloser(execCfg.AuditLogger) 459 cfg.stopper.AddCloser(execCfg.SlowQueryLogger) 460 cfg.stopper.AddCloser(execCfg.AuthLogger) 461 462 if sqlSchemaChangerTestingKnobs := cfg.TestingKnobs.SQLSchemaChanger; sqlSchemaChangerTestingKnobs != nil { 463 execCfg.SchemaChangerTestingKnobs = sqlSchemaChangerTestingKnobs.(*sql.SchemaChangerTestingKnobs) 464 } else { 465 execCfg.SchemaChangerTestingKnobs = new(sql.SchemaChangerTestingKnobs) 466 } 467 if gcJobTestingKnobs := cfg.TestingKnobs.GCJob; gcJobTestingKnobs != nil { 468 execCfg.GCJobTestingKnobs = gcJobTestingKnobs.(*sql.GCJobTestingKnobs) 469 } else { 470 execCfg.GCJobTestingKnobs = new(sql.GCJobTestingKnobs) 471 } 472 if distSQLRunTestingKnobs := cfg.TestingKnobs.DistSQL; distSQLRunTestingKnobs != nil { 473 execCfg.DistSQLRunTestingKnobs = distSQLRunTestingKnobs.(*execinfra.TestingKnobs) 474 } else { 475 execCfg.DistSQLRunTestingKnobs = new(execinfra.TestingKnobs) 476 } 477 if sqlEvalContext := cfg.TestingKnobs.SQLEvalContext; sqlEvalContext != nil { 478 execCfg.EvalContextTestingKnobs = *sqlEvalContext.(*tree.EvalContextTestingKnobs) 479 } 480 if pgwireKnobs := cfg.TestingKnobs.PGWireTestingKnobs; pgwireKnobs != nil { 481 execCfg.PGWireTestingKnobs = pgwireKnobs.(*sql.PGWireTestingKnobs) 482 } 483 if tenantKnobs := cfg.TestingKnobs.TenantTestingKnobs; tenantKnobs != nil { 484 execCfg.TenantTestingKnobs = tenantKnobs.(*sql.TenantTestingKnobs) 485 } 486 487 statsRefresher := stats.MakeRefresher( 488 cfg.Settings, 489 cfg.circularInternalExecutor, 490 execCfg.TableStatsCache, 491 stats.DefaultAsOfTime, 492 ) 493 execCfg.StatsRefresher = statsRefresher 494 495 // Set up internal memory metrics for use by internal SQL executors. 496 // Don't add them to the registry now because it will be added as part of pgServer metrics. 497 sqlMemMetrics := sql.MakeMemMetrics("sql", cfg.HistogramWindowInterval()) 498 pgServer := pgwire.MakeServer( 499 cfg.AmbientCtx, 500 cfg.Config, 501 cfg.Settings, 502 sqlMemMetrics, 503 &rootSQLMemoryMonitor, 504 cfg.HistogramWindowInterval(), 505 execCfg, 506 ) 507 508 // Now that we have a pgwire.Server (which has a sql.Server), we can close a 509 // circular dependency between the rowexec.Server and sql.Server and set 510 // SessionBoundInternalExecutorFactory. The same applies for setting a 511 // SessionBoundInternalExecutor on the the job registry. 512 ieFactory := func( 513 ctx context.Context, sessionData *sessiondata.SessionData, 514 ) sqlutil.InternalExecutor { 515 ie := sql.MakeInternalExecutor( 516 ctx, 517 pgServer.SQLServer, 518 sqlMemMetrics, 519 cfg.Settings, 520 ) 521 ie.SetSessionData(sessionData) 522 return &ie 523 } 524 distSQLServer.ServerConfig.SessionBoundInternalExecutorFactory = ieFactory 525 jobRegistry.SetSessionBoundInternalExecutorFactory(ieFactory) 526 527 distSQLServer.ServerConfig.ProtectedTimestampProvider = execCfg.ProtectedTimestampProvider 528 529 for _, m := range pgServer.Metrics() { 530 cfg.registry.AddMetricStruct(m) 531 } 532 *cfg.circularInternalExecutor = sql.MakeInternalExecutor( 533 ctx, pgServer.SQLServer, internalMemMetrics, cfg.Settings, 534 ) 535 execCfg.InternalExecutor = cfg.circularInternalExecutor 536 stmtDiagnosticsRegistry := stmtdiagnostics.NewRegistry( 537 cfg.circularInternalExecutor, 538 cfg.db, 539 cfg.gossip, 540 cfg.Settings, 541 ) 542 execCfg.StmtDiagnosticsRecorder = stmtDiagnosticsRegistry 543 544 temporaryObjectCleaner := sql.NewTemporaryObjectCleaner( 545 cfg.Settings, 546 cfg.db, 547 codec, 548 cfg.registry, 549 distSQLServer.ServerConfig.SessionBoundInternalExecutorFactory, 550 cfg.statusServer, 551 cfg.isMeta1Leaseholder, 552 sqlExecutorTestingKnobs, 553 ) 554 555 return &sqlServer{ 556 pgServer: pgServer, 557 distSQLServer: distSQLServer, 558 execCfg: execCfg, 559 internalExecutor: cfg.circularInternalExecutor, 560 leaseMgr: leaseMgr, 561 blobService: blobService, 562 sessionRegistry: cfg.sessionRegistry, 563 jobRegistry: jobRegistry, 564 statsRefresher: statsRefresher, 565 temporaryObjectCleaner: temporaryObjectCleaner, 566 internalMemMetrics: internalMemMetrics, 567 adminMemMetrics: adminMemMetrics, 568 sqlMemMetrics: sqlMemMetrics, 569 stmtDiagnosticsRegistry: stmtDiagnosticsRegistry, 570 }, nil 571 } 572 573 func (s *sqlServer) start( 574 ctx context.Context, 575 stopper *stop.Stopper, 576 knobs base.TestingKnobs, 577 connManager netutil.Server, 578 pgL net.Listener, 579 socketFile string, 580 orphanedLeasesTimeThresholdNanos int64, 581 ) error { 582 s.temporaryObjectCleaner.Start(ctx, stopper) 583 s.distSQLServer.Start() 584 s.pgServer.Start(ctx, stopper) 585 if err := s.statsRefresher.Start(ctx, stopper, stats.DefaultRefreshInterval); err != nil { 586 return err 587 } 588 s.stmtDiagnosticsRegistry.Start(ctx, stopper) 589 590 // Before serving SQL requests, we have to make sure the database is 591 // in an acceptable form for this version of the software. 592 // We have to do this after actually starting up the server to be able to 593 // seamlessly use the kv client against other nodes in the cluster. 594 var mmKnobs sqlmigrations.MigrationManagerTestingKnobs 595 if migrationManagerTestingKnobs := knobs.SQLMigrationManager; migrationManagerTestingKnobs != nil { 596 mmKnobs = *migrationManagerTestingKnobs.(*sqlmigrations.MigrationManagerTestingKnobs) 597 } 598 599 s.leaseMgr.RefreshLeases(ctx, stopper, s.execCfg.DB, s.execCfg.Gossip) 600 s.leaseMgr.PeriodicallyRefreshSomeLeases(ctx) 601 602 migrationsExecutor := sql.MakeInternalExecutor( 603 ctx, s.pgServer.SQLServer, s.internalMemMetrics, s.execCfg.Settings) 604 migrationsExecutor.SetSessionData( 605 &sessiondata.SessionData{ 606 // Migrations need an executor with query distribution turned off. This is 607 // because the node crashes if migrations fail to execute, and query 608 // distribution introduces more moving parts. Local execution is more 609 // robust; for example, the DistSender has retries if it can't connect to 610 // another node, but DistSQL doesn't. Also see #44101 for why DistSQL is 611 // particularly fragile immediately after a node is started (i.e. the 612 // present situation). 613 DistSQLMode: sessiondata.DistSQLOff, 614 }) 615 migMgr := sqlmigrations.NewManager( 616 stopper, 617 s.execCfg.DB, 618 s.execCfg.Codec, 619 &migrationsExecutor, 620 s.execCfg.Clock, 621 mmKnobs, 622 s.execCfg.NodeID.SQLInstanceID().String(), 623 s.execCfg.Settings, 624 s.jobRegistry, 625 ) 626 s.migMgr = migMgr // only for testing via TestServer 627 628 if err := s.jobRegistry.Start( 629 ctx, stopper, jobs.DefaultCancelInterval, jobs.DefaultAdoptInterval, 630 ); err != nil { 631 return err 632 } 633 634 var bootstrapVersion roachpb.Version 635 if err := s.execCfg.DB.Txn(ctx, func(ctx context.Context, txn *kv.Txn) error { 636 return txn.GetProto(ctx, keys.BootstrapVersionKey, &bootstrapVersion) 637 }); err != nil { 638 return err 639 } 640 // Run startup migrations (note: these depend on jobs subsystem running). 641 if err := migMgr.EnsureMigrations(ctx, bootstrapVersion); err != nil { 642 return errors.Wrap(err, "ensuring SQL migrations") 643 } 644 645 log.Infof(ctx, "done ensuring all necessary migrations have run") 646 647 // Start serving SQL clients. 648 if err := s.startServeSQL(ctx, stopper, connManager, pgL, socketFile); err != nil { 649 return err 650 } 651 652 // Start the async migration to upgrade 19.2-style jobs so they can be run by 653 // the job registry in 20.1. 654 if err := migMgr.StartSchemaChangeJobMigration(ctx); err != nil { 655 return err 656 } 657 658 // Start the async migration to upgrade namespace entries from the old 659 // namespace table (id 2) to the new one (id 30). 660 if err := migMgr.StartSystemNamespaceMigration(ctx, bootstrapVersion); err != nil { 661 return err 662 } 663 664 // Delete all orphaned table leases created by a prior instance of this 665 // node. This also uses SQL. 666 s.leaseMgr.DeleteOrphanedLeases(orphanedLeasesTimeThresholdNanos) 667 668 return nil 669 }