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  }