vitess.io/vitess@v0.16.2/go/vt/vttablet/tabletserver/tabletenv/config.go (about)

     1  /*
     2  Copyright 2019 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package tabletenv
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"sync"
    23  	"time"
    24  
    25  	"github.com/spf13/pflag"
    26  	"google.golang.org/protobuf/encoding/prototext"
    27  
    28  	"vitess.io/vitess/go/cache"
    29  	"vitess.io/vitess/go/flagutil"
    30  	"vitess.io/vitess/go/streamlog"
    31  	"vitess.io/vitess/go/vt/dbconfigs"
    32  	"vitess.io/vitess/go/vt/log"
    33  	querypb "vitess.io/vitess/go/vt/proto/query"
    34  	"vitess.io/vitess/go/vt/servenv"
    35  	"vitess.io/vitess/go/vt/throttler"
    36  )
    37  
    38  // These constants represent values for various config parameters.
    39  const (
    40  	Enable       = "enable"
    41  	Disable      = "disable"
    42  	Dryrun       = "dryRun"
    43  	NotOnPrimary = "notOnPrimary"
    44  	Polling      = "polling"
    45  	Heartbeat    = "heartbeat"
    46  )
    47  
    48  var (
    49  	currentConfig TabletConfig
    50  
    51  	// TxLogger can be used to enable logging of transactions.
    52  	// Call TxLogger.ServeLogs in your main program to enable logging.
    53  	// The log format can be inferred by looking at TxConnection.Format.
    54  	TxLogger = streamlog.New("TxLog", 10)
    55  
    56  	// StatsLogger is the main stream logger object
    57  	StatsLogger = streamlog.New("TabletServer", 50)
    58  
    59  	// The following vars are used for custom initialization of Tabletconfig.
    60  	enableHotRowProtection       bool
    61  	enableHotRowProtectionDryRun bool
    62  	enableConsolidator           bool
    63  	enableConsolidatorReplicas   bool
    64  	enableHeartbeat              bool
    65  	heartbeatInterval            time.Duration
    66  	heartbeatOnDemandDuration    time.Duration
    67  	healthCheckInterval          time.Duration
    68  	degradedThreshold            time.Duration
    69  	unhealthyThreshold           time.Duration
    70  	transitionGracePeriod        time.Duration
    71  	enableReplicationReporter    bool
    72  )
    73  
    74  func init() {
    75  	currentConfig = *NewDefaultConfig()
    76  	currentConfig.DB = &dbconfigs.GlobalDBConfigs
    77  	servenv.OnParseFor("vtcombo", registerTabletEnvFlags)
    78  	servenv.OnParseFor("vttablet", registerTabletEnvFlags)
    79  }
    80  
    81  var (
    82  	queryLogHandler = "/debug/querylog"
    83  	txLogHandler    = "/debug/txlog"
    84  )
    85  
    86  // RegisterTabletEnvFlags is a public API to register tabletenv flags for use by test cases that expect
    87  // some flags to be set with default values
    88  func RegisterTabletEnvFlags(fs *pflag.FlagSet) {
    89  	registerTabletEnvFlags(fs)
    90  }
    91  
    92  func registerTabletEnvFlags(fs *pflag.FlagSet) {
    93  	fs.StringVar(&queryLogHandler, "query-log-stream-handler", queryLogHandler, "URL handler for streaming queries log")
    94  	fs.StringVar(&txLogHandler, "transaction-log-stream-handler", txLogHandler, "URL handler for streaming transactions log")
    95  
    96  	fs.IntVar(&currentConfig.OltpReadPool.Size, "queryserver-config-pool-size", defaultConfig.OltpReadPool.Size, "query server read pool size, connection pool is used by regular queries (non streaming, not in a transaction)")
    97  	fs.IntVar(&currentConfig.OltpReadPool.PrefillParallelism, "queryserver-config-pool-prefill-parallelism", defaultConfig.OltpReadPool.PrefillParallelism, "Query server read pool prefill parallelism, a non-zero value will prefill the pool using the specified parallism.")
    98  	_ = fs.MarkDeprecated("queryserver-config-pool-prefill-parallelism", "it will be removed in a future release.")
    99  	fs.IntVar(&currentConfig.OlapReadPool.Size, "queryserver-config-stream-pool-size", defaultConfig.OlapReadPool.Size, "query server stream connection pool size, stream pool is used by stream queries: queries that return results to client in a streaming fashion")
   100  	fs.IntVar(&currentConfig.OlapReadPool.PrefillParallelism, "queryserver-config-stream-pool-prefill-parallelism", defaultConfig.OlapReadPool.PrefillParallelism, "Query server stream pool prefill parallelism, a non-zero value will prefill the pool using the specified parallelism")
   101  	_ = fs.MarkDeprecated("queryserver-config-stream-pool-prefill-parallelism", "it will be removed in a future release.")
   102  	fs.IntVar(&currentConfig.TxPool.Size, "queryserver-config-transaction-cap", defaultConfig.TxPool.Size, "query server transaction cap is the maximum number of transactions allowed to happen at any given point of a time for a single vttablet. E.g. by setting transaction cap to 100, there are at most 100 transactions will be processed by a vttablet and the 101th transaction will be blocked (and fail if it cannot get connection within specified timeout)")
   103  	fs.IntVar(&currentConfig.TxPool.PrefillParallelism, "queryserver-config-transaction-prefill-parallelism", defaultConfig.TxPool.PrefillParallelism, "Query server transaction prefill parallelism, a non-zero value will prefill the pool using the specified parallism.")
   104  	_ = fs.MarkDeprecated("queryserver-config-transaction-prefill-parallelism", "it will be removed in a future release.")
   105  	fs.IntVar(&currentConfig.MessagePostponeParallelism, "queryserver-config-message-postpone-cap", defaultConfig.MessagePostponeParallelism, "query server message postpone cap is the maximum number of messages that can be postponed at any given time. Set this number to substantially lower than transaction cap, so that the transaction pool isn't exhausted by the message subsystem.")
   106  	SecondsVar(fs, &currentConfig.Oltp.TxTimeoutSeconds, "queryserver-config-transaction-timeout", defaultConfig.Oltp.TxTimeoutSeconds, "query server transaction timeout (in seconds), a transaction will be killed if it takes longer than this value")
   107  	SecondsVar(fs, &currentConfig.GracePeriods.ShutdownSeconds, "shutdown_grace_period", defaultConfig.GracePeriods.ShutdownSeconds, "how long to wait (in seconds) for queries and transactions to complete during graceful shutdown.")
   108  	fs.IntVar(&currentConfig.Oltp.MaxRows, "queryserver-config-max-result-size", defaultConfig.Oltp.MaxRows, "query server max result size, maximum number of rows allowed to return from vttablet for non-streaming queries.")
   109  	fs.IntVar(&currentConfig.Oltp.WarnRows, "queryserver-config-warn-result-size", defaultConfig.Oltp.WarnRows, "query server result size warning threshold, warn if number of rows returned from vttablet for non-streaming queries exceeds this")
   110  	fs.BoolVar(&currentConfig.PassthroughDML, "queryserver-config-passthrough-dmls", defaultConfig.PassthroughDML, "query server pass through all dml statements without rewriting")
   111  
   112  	fs.IntVar(&currentConfig.StreamBufferSize, "queryserver-config-stream-buffer-size", defaultConfig.StreamBufferSize, "query server stream buffer size, the maximum number of bytes sent from vttablet for each stream call. It's recommended to keep this value in sync with vtgate's stream_buffer_size.")
   113  	fs.IntVar(&currentConfig.QueryCacheSize, "queryserver-config-query-cache-size", defaultConfig.QueryCacheSize, "query server query cache size, maximum number of queries to be cached. vttablet analyzes every incoming query and generate a query plan, these plans are being cached in a lru cache. This config controls the capacity of the lru cache.")
   114  	fs.Int64Var(&currentConfig.QueryCacheMemory, "queryserver-config-query-cache-memory", defaultConfig.QueryCacheMemory, "query server query cache size in bytes, maximum amount of memory to be used for caching. vttablet analyzes every incoming query and generate a query plan, these plans are being cached in a lru cache. This config controls the capacity of the lru cache.")
   115  	fs.BoolVar(&currentConfig.QueryCacheLFU, "queryserver-config-query-cache-lfu", defaultConfig.QueryCacheLFU, "query server cache algorithm. when set to true, a new cache algorithm based on a TinyLFU admission policy will be used to improve cache behavior and prevent pollution from sparse queries")
   116  	SecondsVar(fs, &currentConfig.SchemaReloadIntervalSeconds, "queryserver-config-schema-reload-time", defaultConfig.SchemaReloadIntervalSeconds, "query server schema reload time, how often vttablet reloads schemas from underlying MySQL instance in seconds. vttablet keeps table schemas in its own memory and periodically refreshes it from MySQL. This config controls the reload time.")
   117  	SecondsVar(fs, &currentConfig.SignalSchemaChangeReloadIntervalSeconds, "queryserver-config-schema-change-signal-interval", defaultConfig.SignalSchemaChangeReloadIntervalSeconds, "query server schema change signal interval defines at which interval the query server shall send schema updates to vtgate.")
   118  	fs.BoolVar(&currentConfig.SignalWhenSchemaChange, "queryserver-config-schema-change-signal", defaultConfig.SignalWhenSchemaChange, "query server schema signal, will signal connected vtgates that schema has changed whenever this is detected. VTGates will need to have -schema_change_signal enabled for this to work")
   119  	SecondsVar(fs, &currentConfig.Olap.TxTimeoutSeconds, "queryserver-config-olap-transaction-timeout", defaultConfig.Olap.TxTimeoutSeconds, "query server transaction timeout (in seconds), after which a transaction in an OLAP session will be killed")
   120  	SecondsVar(fs, &currentConfig.Oltp.QueryTimeoutSeconds, "queryserver-config-query-timeout", defaultConfig.Oltp.QueryTimeoutSeconds, "query server query timeout (in seconds), this is the query timeout in vttablet side. If a query takes more than this timeout, it will be killed.")
   121  	SecondsVar(fs, &currentConfig.OltpReadPool.TimeoutSeconds, "queryserver-config-query-pool-timeout", defaultConfig.OltpReadPool.TimeoutSeconds, "query server query pool timeout (in seconds), it is how long vttablet waits for a connection from the query pool. If set to 0 (default) then the overall query timeout is used instead.")
   122  	SecondsVar(fs, &currentConfig.OlapReadPool.TimeoutSeconds, "queryserver-config-stream-pool-timeout", defaultConfig.OlapReadPool.TimeoutSeconds, "query server stream pool timeout (in seconds), it is how long vttablet waits for a connection from the stream pool. If set to 0 (default) then there is no timeout.")
   123  	SecondsVar(fs, &currentConfig.TxPool.TimeoutSeconds, "queryserver-config-txpool-timeout", defaultConfig.TxPool.TimeoutSeconds, "query server transaction pool timeout, it is how long vttablet waits if tx pool is full")
   124  	SecondsVar(fs, &currentConfig.OltpReadPool.IdleTimeoutSeconds, "queryserver-config-idle-timeout", defaultConfig.OltpReadPool.IdleTimeoutSeconds, "query server idle timeout (in seconds), vttablet manages various mysql connection pools. This config means if a connection has not been used in given idle timeout, this connection will be removed from pool. This effectively manages number of connection objects and optimize the pool performance.")
   125  	SecondsVar(fs, &currentConfig.OltpReadPool.MaxLifetimeSeconds, "queryserver-config-pool-conn-max-lifetime", defaultConfig.OltpReadPool.MaxLifetimeSeconds, "query server connection max lifetime (in seconds), vttablet manages various mysql connection pools. This config means if a connection has lived at least this long, it connection will be removed from pool upon the next time it is returned to the pool.")
   126  	fs.IntVar(&currentConfig.OltpReadPool.MaxWaiters, "queryserver-config-query-pool-waiter-cap", defaultConfig.OltpReadPool.MaxWaiters, "query server query pool waiter limit, this is the maximum number of queries that can be queued waiting to get a connection")
   127  	fs.IntVar(&currentConfig.OlapReadPool.MaxWaiters, "queryserver-config-stream-pool-waiter-cap", defaultConfig.OlapReadPool.MaxWaiters, "query server stream pool waiter limit, this is the maximum number of streaming queries that can be queued waiting to get a connection")
   128  	fs.IntVar(&currentConfig.TxPool.MaxWaiters, "queryserver-config-txpool-waiter-cap", defaultConfig.TxPool.MaxWaiters, "query server transaction pool waiter limit, this is the maximum number of transactions that can be queued waiting to get a connection")
   129  	// tableacl related configurations.
   130  	fs.BoolVar(&currentConfig.StrictTableACL, "queryserver-config-strict-table-acl", defaultConfig.StrictTableACL, "only allow queries that pass table acl checks")
   131  	fs.BoolVar(&currentConfig.EnableTableACLDryRun, "queryserver-config-enable-table-acl-dry-run", defaultConfig.EnableTableACLDryRun, "If this flag is enabled, tabletserver will emit monitoring metrics and let the request pass regardless of table acl check results")
   132  	fs.StringVar(&currentConfig.TableACLExemptACL, "queryserver-config-acl-exempt-acl", defaultConfig.TableACLExemptACL, "an acl that exempt from table acl checking (this acl is free to access any vitess tables).")
   133  	fs.BoolVar(&currentConfig.TerseErrors, "queryserver-config-terse-errors", defaultConfig.TerseErrors, "prevent bind vars from escaping in client error messages")
   134  	fs.BoolVar(&currentConfig.AnnotateQueries, "queryserver-config-annotate-queries", defaultConfig.AnnotateQueries, "prefix queries to MySQL backend with comment indicating vtgate principal (user) and target tablet type")
   135  	fs.BoolVar(&currentConfig.WatchReplication, "watch_replication_stream", false, "When enabled, vttablet will stream the MySQL replication stream from the local server, and use it to update schema when it sees a DDL.")
   136  	fs.BoolVar(&currentConfig.TrackSchemaVersions, "track_schema_versions", false, "When enabled, vttablet will store versions of schemas at each position that a DDL is applied and allow retrieval of the schema corresponding to a position")
   137  	fs.BoolVar(&currentConfig.TwoPCEnable, "twopc_enable", defaultConfig.TwoPCEnable, "if the flag is on, 2pc is enabled. Other 2pc flags must be supplied.")
   138  	fs.StringVar(&currentConfig.TwoPCCoordinatorAddress, "twopc_coordinator_address", defaultConfig.TwoPCCoordinatorAddress, "address of the (VTGate) process(es) that will be used to notify of abandoned transactions.")
   139  	SecondsVar(fs, &currentConfig.TwoPCAbandonAge, "twopc_abandon_age", defaultConfig.TwoPCAbandonAge, "time in seconds. Any unresolved transaction older than this time will be sent to the coordinator to be resolved.")
   140  	flagutil.DualFormatBoolVar(fs, &currentConfig.EnableTxThrottler, "enable_tx_throttler", defaultConfig.EnableTxThrottler, "If true replication-lag-based throttling on transactions will be enabled.")
   141  	flagutil.DualFormatStringVar(fs, &currentConfig.TxThrottlerConfig, "tx_throttler_config", defaultConfig.TxThrottlerConfig, "The configuration of the transaction throttler as a text formatted throttlerdata.Configuration protocol buffer message")
   142  	flagutil.DualFormatStringListVar(fs, &currentConfig.TxThrottlerHealthCheckCells, "tx_throttler_healthcheck_cells", defaultConfig.TxThrottlerHealthCheckCells, "A comma-separated list of cells. Only tabletservers running in these cells will be monitored for replication lag by the transaction throttler.")
   143  
   144  	fs.BoolVar(&enableHotRowProtection, "enable_hot_row_protection", false, "If true, incoming transactions for the same row (range) will be queued and cannot consume all txpool slots.")
   145  	fs.BoolVar(&enableHotRowProtectionDryRun, "enable_hot_row_protection_dry_run", false, "If true, hot row protection is not enforced but logs if transactions would have been queued.")
   146  	fs.IntVar(&currentConfig.HotRowProtection.MaxQueueSize, "hot_row_protection_max_queue_size", defaultConfig.HotRowProtection.MaxQueueSize, "Maximum number of BeginExecute RPCs which will be queued for the same row (range).")
   147  	fs.IntVar(&currentConfig.HotRowProtection.MaxGlobalQueueSize, "hot_row_protection_max_global_queue_size", defaultConfig.HotRowProtection.MaxGlobalQueueSize, "Global queue limit across all row (ranges). Useful to prevent that the queue can grow unbounded.")
   148  	fs.IntVar(&currentConfig.HotRowProtection.MaxConcurrency, "hot_row_protection_concurrent_transactions", defaultConfig.HotRowProtection.MaxConcurrency, "Number of concurrent transactions let through to the txpool/MySQL for the same hot row. Should be > 1 to have enough 'ready' transactions in MySQL and benefit from a pipelining effect.")
   149  
   150  	fs.BoolVar(&currentConfig.EnableTransactionLimit, "enable_transaction_limit", defaultConfig.EnableTransactionLimit, "If true, limit on number of transactions open at the same time will be enforced for all users. User trying to open a new transaction after exhausting their limit will receive an error immediately, regardless of whether there are available slots or not.")
   151  	fs.BoolVar(&currentConfig.EnableTransactionLimitDryRun, "enable_transaction_limit_dry_run", defaultConfig.EnableTransactionLimitDryRun, "If true, limit on number of transactions open at the same time will be tracked for all users, but not enforced.")
   152  	fs.Float64Var(&currentConfig.TransactionLimitPerUser, "transaction_limit_per_user", defaultConfig.TransactionLimitPerUser, "Maximum number of transactions a single user is allowed to use at any time, represented as fraction of -transaction_cap.")
   153  	fs.BoolVar(&currentConfig.TransactionLimitByUsername, "transaction_limit_by_username", defaultConfig.TransactionLimitByUsername, "Include VTGateCallerID.username when considering who the user is for the purpose of transaction limit.")
   154  	fs.BoolVar(&currentConfig.TransactionLimitByPrincipal, "transaction_limit_by_principal", defaultConfig.TransactionLimitByPrincipal, "Include CallerID.principal when considering who the user is for the purpose of transaction limit.")
   155  	fs.BoolVar(&currentConfig.TransactionLimitByComponent, "transaction_limit_by_component", defaultConfig.TransactionLimitByComponent, "Include CallerID.component when considering who the user is for the purpose of transaction limit.")
   156  	fs.BoolVar(&currentConfig.TransactionLimitBySubcomponent, "transaction_limit_by_subcomponent", defaultConfig.TransactionLimitBySubcomponent, "Include CallerID.subcomponent when considering who the user is for the purpose of transaction limit.")
   157  
   158  	fs.BoolVar(&enableHeartbeat, "heartbeat_enable", false, "If true, vttablet records (if master) or checks (if replica) the current time of a replication heartbeat in the table _vt.heartbeat. The result is used to inform the serving state of the vttablet via healthchecks.")
   159  	fs.DurationVar(&heartbeatInterval, "heartbeat_interval", 1*time.Second, "How frequently to read and write replication heartbeat.")
   160  	fs.DurationVar(&heartbeatOnDemandDuration, "heartbeat_on_demand_duration", 0, "If non-zero, heartbeats are only written upon consumer request, and only run for up to given duration following the request. Frequent requests can keep the heartbeat running consistently; when requests are infrequent heartbeat may completely stop between requests")
   161  	flagutil.DualFormatBoolVar(fs, &currentConfig.EnableLagThrottler, "enable_lag_throttler", defaultConfig.EnableLagThrottler, "If true, vttablet will run a throttler service, and will implicitly enable heartbeats")
   162  
   163  	fs.BoolVar(&currentConfig.EnforceStrictTransTables, "enforce_strict_trans_tables", defaultConfig.EnforceStrictTransTables, "If true, vttablet requires MySQL to run with STRICT_TRANS_TABLES or STRICT_ALL_TABLES on. It is recommended to not turn this flag off. Otherwise MySQL may alter your supplied values before saving them to the database.")
   164  	flagutil.DualFormatBoolVar(fs, &enableConsolidator, "enable_consolidator", true, "This option enables the query consolidator.")
   165  	flagutil.DualFormatBoolVar(fs, &enableConsolidatorReplicas, "enable_consolidator_replicas", false, "This option enables the query consolidator only on replicas.")
   166  	fs.Int64Var(&currentConfig.ConsolidatorStreamQuerySize, "consolidator-stream-query-size", defaultConfig.ConsolidatorStreamQuerySize, "Configure the stream consolidator query size in bytes. Setting to 0 disables the stream consolidator.")
   167  	fs.Int64Var(&currentConfig.ConsolidatorStreamTotalSize, "consolidator-stream-total-size", defaultConfig.ConsolidatorStreamTotalSize, "Configure the stream consolidator total size in bytes. Setting to 0 disables the stream consolidator.")
   168  	flagutil.DualFormatBoolVar(fs, &currentConfig.DeprecatedCacheResultFields, "enable_query_plan_field_caching", defaultConfig.DeprecatedCacheResultFields, "This option fetches & caches fields (columns) when storing query plans")
   169  	_ = fs.MarkDeprecated("enable_query_plan_field_caching", "it will be removed in a future release.")
   170  	_ = fs.MarkDeprecated("enable-query-plan-field-caching", "it will be removed in a future release.")
   171  
   172  	fs.DurationVar(&healthCheckInterval, "health_check_interval", 20*time.Second, "Interval between health checks")
   173  	fs.DurationVar(&degradedThreshold, "degraded_threshold", 30*time.Second, "replication lag after which a replica is considered degraded")
   174  	fs.DurationVar(&unhealthyThreshold, "unhealthy_threshold", 2*time.Hour, "replication lag after which a replica is considered unhealthy")
   175  	fs.DurationVar(&transitionGracePeriod, "serving_state_grace_period", 0, "how long to pause after broadcasting health to vtgate, before enforcing a new serving state")
   176  
   177  	fs.BoolVar(&enableReplicationReporter, "enable_replication_reporter", false, "Use polling to track replication lag.")
   178  	fs.BoolVar(&currentConfig.EnableOnlineDDL, "queryserver_enable_online_ddl", true, "Enable online DDL.")
   179  	fs.BoolVar(&currentConfig.SanitizeLogMessages, "sanitize_log_messages", false, "Remove potentially sensitive information in tablet INFO, WARNING, and ERROR log messages such as query parameters.")
   180  	fs.BoolVar(&currentConfig.EnableSettingsPool, "queryserver-enable-settings-pool", false, "Enable pooling of connections with modified system settings")
   181  
   182  	fs.Int64Var(&currentConfig.RowStreamer.MaxInnoDBTrxHistLen, "vreplication_copy_phase_max_innodb_history_list_length", 1000000, "The maximum InnoDB transaction history that can exist on a vstreamer (source) before starting another round of copying rows. This helps to limit the impact on the source tablet.")
   183  	fs.Int64Var(&currentConfig.RowStreamer.MaxMySQLReplLagSecs, "vreplication_copy_phase_max_mysql_replication_lag", 43200, "The maximum MySQL replication lag (in seconds) that can exist on a vstreamer (source) before starting another round of copying rows. This helps to limit the impact on the source tablet.")
   184  
   185  	fs.BoolVar(&currentConfig.EnableViews, "queryserver-enable-views", false, "Enable views support in vttablet.")
   186  }
   187  
   188  var (
   189  	queryLogHandlerOnce sync.Once
   190  	txLogHandlerOnce    sync.Once
   191  )
   192  
   193  // Init must be called after flag.Parse, and before doing any other operations.
   194  func Init() {
   195  	// IdleTimeout is only initialized for OltpReadPool , but the other pools need to inherit the value.
   196  	// TODO(sougou): Make a decision on whether this should be global or per-pool.
   197  	currentConfig.OlapReadPool.IdleTimeoutSeconds = currentConfig.OltpReadPool.IdleTimeoutSeconds
   198  	currentConfig.TxPool.IdleTimeoutSeconds = currentConfig.OltpReadPool.IdleTimeoutSeconds
   199  	currentConfig.OlapReadPool.MaxLifetimeSeconds = currentConfig.OltpReadPool.MaxLifetimeSeconds
   200  	currentConfig.TxPool.MaxLifetimeSeconds = currentConfig.OltpReadPool.MaxLifetimeSeconds
   201  
   202  	if enableHotRowProtection {
   203  		if enableHotRowProtectionDryRun {
   204  			currentConfig.HotRowProtection.Mode = Dryrun
   205  		} else {
   206  			currentConfig.HotRowProtection.Mode = Enable
   207  		}
   208  	} else {
   209  		currentConfig.HotRowProtection.Mode = Disable
   210  	}
   211  
   212  	switch {
   213  	case enableConsolidatorReplicas:
   214  		currentConfig.Consolidator = NotOnPrimary
   215  	case enableConsolidator:
   216  		currentConfig.Consolidator = Enable
   217  	default:
   218  		currentConfig.Consolidator = Disable
   219  	}
   220  
   221  	if heartbeatInterval == 0 {
   222  		heartbeatInterval = time.Duration(defaultConfig.ReplicationTracker.HeartbeatIntervalSeconds*1000) * time.Millisecond
   223  	}
   224  	if heartbeatInterval > time.Second {
   225  		heartbeatInterval = time.Second
   226  	}
   227  	if heartbeatOnDemandDuration < 0 {
   228  		heartbeatOnDemandDuration = 0
   229  	}
   230  	currentConfig.ReplicationTracker.HeartbeatIntervalSeconds.Set(heartbeatInterval)
   231  	currentConfig.ReplicationTracker.HeartbeatOnDemandSeconds.Set(heartbeatOnDemandDuration)
   232  
   233  	switch {
   234  	case enableHeartbeat:
   235  		currentConfig.ReplicationTracker.Mode = Heartbeat
   236  	case enableReplicationReporter:
   237  		currentConfig.ReplicationTracker.Mode = Polling
   238  	default:
   239  		currentConfig.ReplicationTracker.Mode = Disable
   240  	}
   241  
   242  	currentConfig.Healthcheck.IntervalSeconds.Set(healthCheckInterval)
   243  	currentConfig.Healthcheck.DegradedThresholdSeconds.Set(degradedThreshold)
   244  	currentConfig.Healthcheck.UnhealthyThresholdSeconds.Set(unhealthyThreshold)
   245  	currentConfig.GracePeriods.TransitionSeconds.Set(transitionGracePeriod)
   246  
   247  	switch streamlog.GetQueryLogFormat() {
   248  	case streamlog.QueryLogFormatText:
   249  	case streamlog.QueryLogFormatJSON:
   250  	default:
   251  		log.Exitf("Invalid querylog-format value %v: must be either text or json", streamlog.GetQueryLogFormat())
   252  	}
   253  
   254  	if queryLogHandler != "" {
   255  		queryLogHandlerOnce.Do(func() {
   256  			StatsLogger.ServeLogs(queryLogHandler, streamlog.GetFormatter(StatsLogger))
   257  		})
   258  	}
   259  
   260  	if txLogHandler != "" {
   261  		txLogHandlerOnce.Do(func() {
   262  			TxLogger.ServeLogs(txLogHandler, streamlog.GetFormatter(TxLogger))
   263  		})
   264  	}
   265  }
   266  
   267  // TabletConfig contains all the configuration for query service
   268  type TabletConfig struct {
   269  	DB *dbconfigs.DBConfigs `json:"db,omitempty"`
   270  
   271  	OltpReadPool ConnPoolConfig `json:"oltpReadPool,omitempty"`
   272  	OlapReadPool ConnPoolConfig `json:"olapReadPool,omitempty"`
   273  	TxPool       ConnPoolConfig `json:"txPool,omitempty"`
   274  
   275  	Olap             OlapConfig             `json:"olap,omitempty"`
   276  	Oltp             OltpConfig             `json:"oltp,omitempty"`
   277  	HotRowProtection HotRowProtectionConfig `json:"hotRowProtection,omitempty"`
   278  
   279  	Healthcheck  HealthcheckConfig  `json:"healthcheck,omitempty"`
   280  	GracePeriods GracePeriodsConfig `json:"gracePeriods,omitempty"`
   281  
   282  	ReplicationTracker ReplicationTrackerConfig `json:"replicationTracker,omitempty"`
   283  
   284  	// Consolidator can be enable, disable, or notOnPrimary. Default is enable.
   285  	Consolidator                            string  `json:"consolidator,omitempty"`
   286  	PassthroughDML                          bool    `json:"passthroughDML,omitempty"`
   287  	StreamBufferSize                        int     `json:"streamBufferSize,omitempty"`
   288  	ConsolidatorStreamTotalSize             int64   `json:"consolidatorStreamTotalSize,omitempty"`
   289  	ConsolidatorStreamQuerySize             int64   `json:"consolidatorStreamQuerySize,omitempty"`
   290  	QueryCacheSize                          int     `json:"queryCacheSize,omitempty"`
   291  	QueryCacheMemory                        int64   `json:"queryCacheMemory,omitempty"`
   292  	QueryCacheLFU                           bool    `json:"queryCacheLFU,omitempty"`
   293  	SchemaReloadIntervalSeconds             Seconds `json:"schemaReloadIntervalSeconds,omitempty"`
   294  	SignalSchemaChangeReloadIntervalSeconds Seconds `json:"signalSchemaChangeReloadIntervalSeconds,omitempty"`
   295  	WatchReplication                        bool    `json:"watchReplication,omitempty"`
   296  	TrackSchemaVersions                     bool    `json:"trackSchemaVersions,omitempty"`
   297  	TerseErrors                             bool    `json:"terseErrors,omitempty"`
   298  	AnnotateQueries                         bool    `json:"annotateQueries,omitempty"`
   299  	MessagePostponeParallelism              int     `json:"messagePostponeParallelism,omitempty"`
   300  	DeprecatedCacheResultFields             bool    `json:"cacheResultFields,omitempty"`
   301  	SignalWhenSchemaChange                  bool    `json:"signalWhenSchemaChange,omitempty"`
   302  
   303  	ExternalConnections map[string]*dbconfigs.DBConfigs `json:"externalConnections,omitempty"`
   304  
   305  	SanitizeLogMessages     bool    `json:"-"`
   306  	StrictTableACL          bool    `json:"-"`
   307  	EnableTableACLDryRun    bool    `json:"-"`
   308  	TableACLExemptACL       string  `json:"-"`
   309  	TwoPCEnable             bool    `json:"-"`
   310  	TwoPCCoordinatorAddress string  `json:"-"`
   311  	TwoPCAbandonAge         Seconds `json:"-"`
   312  
   313  	EnableTxThrottler           bool     `json:"-"`
   314  	TxThrottlerConfig           string   `json:"-"`
   315  	TxThrottlerHealthCheckCells []string `json:"-"`
   316  
   317  	EnableLagThrottler bool `json:"-"`
   318  	EnableTableGC      bool `json:"-"` // can be turned off programmatically by tests
   319  
   320  	TransactionLimitConfig `json:"-"`
   321  
   322  	EnforceStrictTransTables bool `json:"-"`
   323  	EnableOnlineDDL          bool `json:"-"`
   324  	EnableSettingsPool       bool `json:"-"`
   325  
   326  	RowStreamer RowStreamerConfig `json:"rowStreamer,omitempty"`
   327  
   328  	EnableViews bool `json:"-"`
   329  }
   330  
   331  // ConnPoolConfig contains the config for a conn pool.
   332  type ConnPoolConfig struct {
   333  	Size               int     `json:"size,omitempty"`
   334  	TimeoutSeconds     Seconds `json:"timeoutSeconds,omitempty"`
   335  	IdleTimeoutSeconds Seconds `json:"idleTimeoutSeconds,omitempty"`
   336  	MaxLifetimeSeconds Seconds `json:"maxLifetimeSeconds,omitempty"`
   337  	PrefillParallelism int     `json:"prefillParallelism,omitempty"`
   338  	MaxWaiters         int     `json:"maxWaiters,omitempty"`
   339  }
   340  
   341  // OlapConfig contains the config for olap settings.
   342  type OlapConfig struct {
   343  	TxTimeoutSeconds Seconds `json:"txTimeoutSeconds,omitempty"`
   344  }
   345  
   346  // OltpConfig contains the config for oltp settings.
   347  type OltpConfig struct {
   348  	QueryTimeoutSeconds Seconds `json:"queryTimeoutSeconds,omitempty"`
   349  	TxTimeoutSeconds    Seconds `json:"txTimeoutSeconds,omitempty"`
   350  	MaxRows             int     `json:"maxRows,omitempty"`
   351  	WarnRows            int     `json:"warnRows,omitempty"`
   352  }
   353  
   354  // HotRowProtectionConfig contains the config for hot row protection.
   355  type HotRowProtectionConfig struct {
   356  	// Mode can be disable, dryRun or enable. Default is disable.
   357  	Mode               string `json:"mode,omitempty"`
   358  	MaxQueueSize       int    `json:"maxQueueSize,omitempty"`
   359  	MaxGlobalQueueSize int    `json:"maxGlobalQueueSize,omitempty"`
   360  	MaxConcurrency     int    `json:"maxConcurrency,omitempty"`
   361  }
   362  
   363  // HealthcheckConfig contains the config for healthcheck.
   364  type HealthcheckConfig struct {
   365  	IntervalSeconds           Seconds `json:"intervalSeconds,omitempty"`
   366  	DegradedThresholdSeconds  Seconds `json:"degradedThresholdSeconds,omitempty"`
   367  	UnhealthyThresholdSeconds Seconds `json:"unhealthyThresholdSeconds,omitempty"`
   368  }
   369  
   370  // GracePeriodsConfig contains various grace periods.
   371  // TODO(sougou): move lameduck here?
   372  type GracePeriodsConfig struct {
   373  	ShutdownSeconds   Seconds `json:"shutdownSeconds,omitempty"`
   374  	TransitionSeconds Seconds `json:"transitionSeconds,omitempty"`
   375  }
   376  
   377  // ReplicationTrackerConfig contains the config for the replication tracker.
   378  type ReplicationTrackerConfig struct {
   379  	// Mode can be disable, polling or heartbeat. Default is disable.
   380  	Mode                     string  `json:"mode,omitempty"`
   381  	HeartbeatIntervalSeconds Seconds `json:"heartbeatIntervalSeconds,omitempty"`
   382  	HeartbeatOnDemandSeconds Seconds `json:"heartbeatOnDemandSeconds,omitempty"`
   383  }
   384  
   385  // TransactionLimitConfig captures configuration of transaction pool slots
   386  // limiter configuration.
   387  type TransactionLimitConfig struct {
   388  	EnableTransactionLimit         bool
   389  	EnableTransactionLimitDryRun   bool
   390  	TransactionLimitPerUser        float64
   391  	TransactionLimitByUsername     bool
   392  	TransactionLimitByPrincipal    bool
   393  	TransactionLimitByComponent    bool
   394  	TransactionLimitBySubcomponent bool
   395  }
   396  
   397  // RowStreamerConfig contains configuration parameters for a vstreamer (source) that is
   398  // copying the contents of a table to a target
   399  type RowStreamerConfig struct {
   400  	MaxInnoDBTrxHistLen int64 `json:"maxInnoDBTrxHistLen,omitempty"`
   401  	MaxMySQLReplLagSecs int64 `json:"maxMySQLReplLagSecs,omitempty"`
   402  }
   403  
   404  // NewCurrentConfig returns a copy of the current config.
   405  func NewCurrentConfig() *TabletConfig {
   406  	return currentConfig.Clone()
   407  }
   408  
   409  // NewDefaultConfig returns a new TabletConfig with pre-initialized defaults.
   410  func NewDefaultConfig() *TabletConfig {
   411  	return defaultConfig.Clone()
   412  }
   413  
   414  // Clone creates a clone of TabletConfig.
   415  func (c *TabletConfig) Clone() *TabletConfig {
   416  	tc := *c
   417  	if tc.DB != nil {
   418  		tc.DB = c.DB.Clone()
   419  	}
   420  	return &tc
   421  }
   422  
   423  // SetTxTimeoutForWorkload updates workload transaction timeouts. Used in tests only.
   424  func (c *TabletConfig) SetTxTimeoutForWorkload(val time.Duration, workload querypb.ExecuteOptions_Workload) {
   425  	switch workload {
   426  	case querypb.ExecuteOptions_OLAP:
   427  		c.Olap.TxTimeoutSeconds.Set(val)
   428  	case querypb.ExecuteOptions_OLTP:
   429  		c.Oltp.TxTimeoutSeconds.Set(val)
   430  	default:
   431  		panic(fmt.Sprintf("unsupported workload type: %v", workload))
   432  	}
   433  }
   434  
   435  // TxTimeoutForWorkload returns the transaction timeout for the given workload
   436  // type. Defaults to returning OLTP timeout.
   437  func (c *TabletConfig) TxTimeoutForWorkload(workload querypb.ExecuteOptions_Workload) time.Duration {
   438  	switch workload {
   439  	case querypb.ExecuteOptions_DBA:
   440  		return 0
   441  	case querypb.ExecuteOptions_OLAP:
   442  		return c.Olap.TxTimeoutSeconds.Get()
   443  	default:
   444  		return c.Oltp.TxTimeoutSeconds.Get()
   445  	}
   446  }
   447  
   448  // Verify checks for contradicting flags.
   449  func (c *TabletConfig) Verify() error {
   450  	if err := c.verifyTransactionLimitConfig(); err != nil {
   451  		return err
   452  	}
   453  	if v := c.HotRowProtection.MaxQueueSize; v <= 0 {
   454  		return fmt.Errorf("-hot_row_protection_max_queue_size must be > 0 (specified value: %v)", v)
   455  	}
   456  	if v := c.HotRowProtection.MaxGlobalQueueSize; v <= 0 {
   457  		return fmt.Errorf("-hot_row_protection_max_global_queue_size must be > 0 (specified value: %v)", v)
   458  	}
   459  	if globalSize, size := c.HotRowProtection.MaxGlobalQueueSize, c.HotRowProtection.MaxQueueSize; globalSize < size {
   460  		return fmt.Errorf("global queue size must be >= per row (range) queue size: -hot_row_protection_max_global_queue_size < hot_row_protection_max_queue_size (%v < %v)", globalSize, size)
   461  	}
   462  	if v := c.HotRowProtection.MaxConcurrency; v <= 0 {
   463  		return fmt.Errorf("-hot_row_protection_concurrent_transactions must be > 0 (specified value: %v)", v)
   464  	}
   465  	return nil
   466  }
   467  
   468  // verifyTransactionLimitConfig checks TransactionLimitConfig for sanity
   469  func (c *TabletConfig) verifyTransactionLimitConfig() error {
   470  	actual, dryRun := c.EnableTransactionLimit, c.EnableTransactionLimitDryRun
   471  	if actual && dryRun {
   472  		return errors.New("only one of two flags allowed: -enable_transaction_limit or -enable_transaction_limit_dry_run")
   473  	}
   474  
   475  	// Skip other checks if this is not enabled
   476  	if !actual && !dryRun {
   477  		return nil
   478  	}
   479  
   480  	var (
   481  		byUser      = c.TransactionLimitByUsername
   482  		byPrincipal = c.TransactionLimitByPrincipal
   483  		byComp      = c.TransactionLimitByComponent
   484  		bySubcomp   = c.TransactionLimitBySubcomponent
   485  	)
   486  	if byAny := byUser || byPrincipal || byComp || bySubcomp; !byAny {
   487  		return errors.New("no user discriminating fields selected for transaction limiter, everyone would share single chunk of transaction pool. Override with at least one of -transaction_limit_by flags set to true")
   488  	}
   489  	if v := c.TransactionLimitPerUser; v <= 0 || v >= 1 {
   490  		return fmt.Errorf("-transaction_limit_per_user should be a fraction within range (0, 1) (specified value: %v)", v)
   491  	}
   492  	if limit := int(c.TransactionLimitPerUser * float64(c.TxPool.Size)); limit == 0 {
   493  		return fmt.Errorf("effective transaction limit per user is 0 due to rounding, increase -transaction_limit_per_user")
   494  	}
   495  	return nil
   496  }
   497  
   498  // Some of these values are for documentation purposes.
   499  // They actually get overwritten during Init.
   500  var defaultConfig = TabletConfig{
   501  	OltpReadPool: ConnPoolConfig{
   502  		Size:               16,
   503  		IdleTimeoutSeconds: 30 * 60,
   504  		MaxWaiters:         5000,
   505  	},
   506  	OlapReadPool: ConnPoolConfig{
   507  		Size:               200,
   508  		IdleTimeoutSeconds: 30 * 60,
   509  	},
   510  	TxPool: ConnPoolConfig{
   511  		Size:               20,
   512  		TimeoutSeconds:     1,
   513  		IdleTimeoutSeconds: 30 * 60,
   514  		MaxWaiters:         5000,
   515  	},
   516  	Olap: OlapConfig{
   517  		TxTimeoutSeconds: 30,
   518  	},
   519  	Oltp: OltpConfig{
   520  		QueryTimeoutSeconds: 30,
   521  		TxTimeoutSeconds:    30,
   522  		MaxRows:             10000,
   523  	},
   524  	Healthcheck: HealthcheckConfig{
   525  		IntervalSeconds:           20,
   526  		DegradedThresholdSeconds:  30,
   527  		UnhealthyThresholdSeconds: 7200,
   528  	},
   529  	ReplicationTracker: ReplicationTrackerConfig{
   530  		Mode:                     Disable,
   531  		HeartbeatIntervalSeconds: 0.25,
   532  	},
   533  	HotRowProtection: HotRowProtectionConfig{
   534  		Mode: Disable,
   535  		// Default value is the same as TxPool.Size.
   536  		MaxQueueSize:       20,
   537  		MaxGlobalQueueSize: 1000,
   538  		// Allow more than 1 transaction for the same hot row through to have enough
   539  		// of them ready in MySQL and profit from a pipelining effect.
   540  		MaxConcurrency: 5,
   541  	},
   542  	Consolidator:                Enable,
   543  	ConsolidatorStreamTotalSize: 128 * 1024 * 1024,
   544  	ConsolidatorStreamQuerySize: 2 * 1024 * 1024,
   545  	// The value for StreamBufferSize was chosen after trying out a few of
   546  	// them. Too small buffers force too many packets to be sent. Too big
   547  	// buffers force the clients to read them in multiple chunks and make
   548  	// memory copies.  so with the encoding overhead, this seems to work
   549  	// great (the overhead makes the final packets on the wire about twice
   550  	// bigger than this).
   551  	StreamBufferSize:                        32 * 1024,
   552  	QueryCacheSize:                          int(cache.DefaultConfig.MaxEntries),
   553  	QueryCacheMemory:                        cache.DefaultConfig.MaxMemoryUsage,
   554  	QueryCacheLFU:                           cache.DefaultConfig.LFU,
   555  	SchemaReloadIntervalSeconds:             30 * 60,
   556  	SignalSchemaChangeReloadIntervalSeconds: 5,
   557  	MessagePostponeParallelism:              4,
   558  	DeprecatedCacheResultFields:             true,
   559  	SignalWhenSchemaChange:                  true,
   560  
   561  	EnableTxThrottler:           false,
   562  	TxThrottlerConfig:           defaultTxThrottlerConfig(),
   563  	TxThrottlerHealthCheckCells: []string{},
   564  
   565  	EnableLagThrottler: false, // Feature flag; to switch to 'true' at some stage in the future
   566  
   567  	TransactionLimitConfig: defaultTransactionLimitConfig(),
   568  
   569  	EnforceStrictTransTables: true,
   570  	EnableOnlineDDL:          true,
   571  	EnableTableGC:            true,
   572  
   573  	RowStreamer: RowStreamerConfig{
   574  		MaxInnoDBTrxHistLen: 1000000,
   575  		MaxMySQLReplLagSecs: 43200,
   576  	},
   577  }
   578  
   579  // defaultTxThrottlerConfig formats the default throttlerdata.Configuration
   580  // object in text format. It uses the object returned by
   581  // throttler.DefaultMaxReplicationLagModuleConfig().Configuration and overrides some of its
   582  // fields. It panics on error.
   583  func defaultTxThrottlerConfig() string {
   584  	// Take throttler.DefaultMaxReplicationLagModuleConfig and override some fields.
   585  	config := throttler.DefaultMaxReplicationLagModuleConfig().Configuration
   586  	// TODO(erez): Make DefaultMaxReplicationLagModuleConfig() return a MaxReplicationLagSec of 10
   587  	// and remove this line.
   588  	config.MaxReplicationLagSec = 10
   589  	return prototext.Format(config)
   590  }
   591  
   592  func defaultTransactionLimitConfig() TransactionLimitConfig {
   593  	return TransactionLimitConfig{
   594  		EnableTransactionLimit:       false,
   595  		EnableTransactionLimitDryRun: false,
   596  
   597  		// Single user can use up to 40% of transaction pool slots. Enough to
   598  		// accommodate 2 misbehaving users.
   599  		TransactionLimitPerUser: 0.4,
   600  
   601  		TransactionLimitByUsername:     true,
   602  		TransactionLimitByPrincipal:    true,
   603  		TransactionLimitByComponent:    false,
   604  		TransactionLimitBySubcomponent: false,
   605  	}
   606  }