Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*: modify GetGlobalConfig() to provide a thread safe API for unit test #17954

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 27 additions & 6 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package config

import (
"context"
"crypto/tls"
"crypto/x509"
"encoding/base64"
Expand Down Expand Up @@ -693,10 +694,30 @@ func NewConfig() *Config {
return &conf
}

type ctxGlobalConfigKey struct{}

var overrideConfigForTest ctxGlobalConfigKey

// WithGlobalConfig provides a way for unit test to modify global config without DATA RACE.
// The typical usage looks like this:
//
// ctx := context.Background()
// cfg := *GetGlobalConfig(ctx)
// cfg.XXX = XXX
// ctx := config.WithGlobalConfig(ctx, &cfg)
// tk.MustExecWithCtx(ctx, ...)
//
func WithGlobalConfig(ctx context.Context, cfg *Config) context.Context {
return context.WithValue(ctx, overrideConfigForTest, cfg)
}

// GetGlobalConfig returns the global configuration for this server.
// It should store configuration from command line and configuration file.
// Other parts of the system can read the global configuration use this function.
func GetGlobalConfig() *Config {
func GetGlobalConfig(ctx context.Context) *Config {
if raw := ctx.Value(overrideConfigForTest); raw != nil {
return raw.(*Config)
}
return globalConf.Load().(*Config)
}

Expand Down Expand Up @@ -727,7 +748,7 @@ func isAllDeprecatedConfigItems(items []string) bool {
// For example, if you start TiDB by the command "./tidb-server --port=3000", the port number should be
// overwritten to 3000 and ignore the port number in the config file.
func InitializeConfig(confPath string, configCheck, configStrict bool, reloadFunc ConfReloadFunc, enforceCmdArgs func(*Config)) {
cfg := GetGlobalConfig()
cfg := GetGlobalConfig(context.Background())
var err error
if confPath != "" {
if err = cfg.Load(confPath); err != nil {
Expand Down Expand Up @@ -885,13 +906,13 @@ func hasRootPrivilege() bool {
}

// TableLockEnabled uses to check whether enabled the table lock feature.
func TableLockEnabled() bool {
return GetGlobalConfig().EnableTableLock
func TableLockEnabled(ctx context.Context) bool {
return GetGlobalConfig(ctx).EnableTableLock
}

// TableLockDelayClean uses to get the time of delay clean table lock.
var TableLockDelayClean = func() uint64 {
return GetGlobalConfig().DelayCleanTableLock
var TableLockDelayClean = func(ctx context.Context) uint64 {
return GetGlobalConfig(ctx).DelayCleanTableLock
}

// ToLogConfig converts *Log to *logutil.LogConfig.
Expand Down
15 changes: 14 additions & 1 deletion config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package config

import (
"context"
"encoding/json"
"os"
"os/user"
Expand Down Expand Up @@ -261,7 +262,7 @@ log-rotate = true`)
c.Assert(conf.Load(configFile), IsNil)

// Make sure the example config is the same as default config.
c.Assert(conf, DeepEquals, GetGlobalConfig())
c.Assert(conf, DeepEquals, GetGlobalConfig(context.Background()))

// Test for log config.
c.Assert(conf.Log.ToLogConfig(), DeepEquals, logutil.NewLogConfig("info", "text", "tidb-slow.log", conf.Log.File, false, func(config *zaplog.Config) { config.DisableErrorVerbose = conf.Log.getDisableErrorStack() }))
Expand Down Expand Up @@ -454,3 +455,15 @@ func (s *testConfigSuite) TestEncodeDefTempStorageDir(c *C) {
c.Assert(tempStorageDir, Equals, filepath.Join(dirPrefix, test.expect, "tmp-storage"))
}
}

func (s *testConfigSuite) TestWithGlobalConfig(c *C) {
cfg := NewConfig()
cfg.Binlog.Enable = true
cfg.EnableTableLock = true
ctx := WithGlobalConfig(context.Background(), cfg)

cfg1 := GetGlobalConfig(ctx)
c.Assert(cfg1, Equals, cfg)
c.Assert(cfg.Binlog.Enable, IsTrue)
c.Assert(cfg.EnableTableLock, IsTrue)
}
4 changes: 2 additions & 2 deletions ddl/db_change_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func (s *testStateChangeSuiteBase) TearDownSuite(c *C) {

// TestShowCreateTable tests the result of "show create table" when we are running "add index" or "add column".
func (s *serialTestStateChangeSuite) TestShowCreateTable(c *C) {
config.GetGlobalConfig().Experimental.AllowsExpressionIndex = true
config.GetGlobalConfig(context.Background()).Experimental.AllowsExpressionIndex = true
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("create table t (id int)")
Expand Down Expand Up @@ -858,7 +858,7 @@ func (s *testStateChangeSuite) TestParallelAlterAddIndex(c *C) {
}

func (s *serialTestStateChangeSuite) TestParallelAlterAddExpressionIndex(c *C) {
config.GetGlobalConfig().Experimental.AllowsExpressionIndex = true
config.GetGlobalConfig(context.Background()).Experimental.AllowsExpressionIndex = true
sql1 := "ALTER TABLE t add index expr_index_b((b+1));"
sql2 := "CREATE INDEX expr_index_b ON t ((c+1));"
f := func(c *C, err1, err2 error) {
Expand Down
26 changes: 13 additions & 13 deletions ddl/db_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1705,15 +1705,15 @@ func (s *testIntegrationSuite1) TestTreatOldVersionUTF8AsUTF8MB4(c *C) {
}
updateTableInfo(tblInfo)
s.tk.MustExec("alter table t add column c varchar(10) character set utf8;") // load latest schema.
c.Assert(config.GetGlobalConfig().TreatOldVersionUTF8AsUTF8MB4, IsTrue)
c.Assert(config.GetGlobalConfig(context.Background()).TreatOldVersionUTF8AsUTF8MB4, IsTrue)
s.tk.MustExec("insert into t set a= x'f09f8c80'")
s.tk.MustQuery("show create table t").Check(testkit.Rows("t CREATE TABLE `t` (\n" +
" `a` varchar(10) DEFAULT NULL,\n" +
" `b` varchar(10) CHARACTER SET ascii COLLATE ascii_bin DEFAULT NULL,\n" +
" `c` varchar(10) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"))

config.GetGlobalConfig().TreatOldVersionUTF8AsUTF8MB4 = false
config.GetGlobalConfig(context.Background()).TreatOldVersionUTF8AsUTF8MB4 = false
s.tk.MustExec("alter table t drop column c;") // reload schema.
s.tk.MustGetErrCode("insert into t set a= x'f09f8c80'", errno.ErrTruncatedWrongValueForField)
s.tk.MustQuery("show create table t").Check(testkit.Rows("t CREATE TABLE `t` (\n" +
Expand All @@ -1730,7 +1730,7 @@ func (s *testIntegrationSuite1) TestTreatOldVersionUTF8AsUTF8MB4(c *C) {
tblInfo.Columns[0].Version = model.ColumnInfoVersion0
updateTableInfo(tblInfo)

config.GetGlobalConfig().TreatOldVersionUTF8AsUTF8MB4 = true
config.GetGlobalConfig(context.Background()).TreatOldVersionUTF8AsUTF8MB4 = true
s.tk.MustExec("alter table t add column c varchar(10);") // load latest schema.
s.tk.MustExec("insert into t set a= x'f09f8c80'")
s.tk.MustQuery("show create table t").Check(testkit.Rows("t CREATE TABLE `t` (\n" +
Expand All @@ -1739,7 +1739,7 @@ func (s *testIntegrationSuite1) TestTreatOldVersionUTF8AsUTF8MB4(c *C) {
" `c` varchar(10) DEFAULT NULL\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"))

config.GetGlobalConfig().TreatOldVersionUTF8AsUTF8MB4 = false
config.GetGlobalConfig(context.Background()).TreatOldVersionUTF8AsUTF8MB4 = false
s.tk.MustExec("alter table t drop column c;") // reload schema.
s.tk.MustGetErrCode("insert into t set a= x'f09f8c80'", errno.ErrTruncatedWrongValueForField)
s.tk.MustQuery("show create table t").Check(testkit.Rows("t CREATE TABLE `t` (\n" +
Expand All @@ -1748,7 +1748,7 @@ func (s *testIntegrationSuite1) TestTreatOldVersionUTF8AsUTF8MB4(c *C) {
") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin"))

// Test modify column charset.
config.GetGlobalConfig().TreatOldVersionUTF8AsUTF8MB4 = true
config.GetGlobalConfig(context.Background()).TreatOldVersionUTF8AsUTF8MB4 = true
s.tk.MustExec("alter table t modify column a varchar(10) character set utf8mb4") // change column charset.
tbl = testGetTableByName(c, s.ctx, "test", "t")
c.Assert(tbl.Meta().Columns[0].Charset, Equals, charset.CharsetUTF8MB4)
Expand Down Expand Up @@ -1776,15 +1776,15 @@ func (s *testIntegrationSuite1) TestTreatOldVersionUTF8AsUTF8MB4(c *C) {
tblInfo.Columns[0].Charset = charset.CharsetUTF8
tblInfo.Columns[0].Collate = charset.CollationUTF8
updateTableInfo(tblInfo)
c.Assert(config.GetGlobalConfig().TreatOldVersionUTF8AsUTF8MB4, IsTrue)
c.Assert(config.GetGlobalConfig(context.Background()).TreatOldVersionUTF8AsUTF8MB4, IsTrue)
s.tk.MustExec("alter table t change column b b varchar(20) character set ascii") // reload schema.
s.tk.MustExec("insert into t set a= x'f09f8c80'")
s.tk.MustQuery("show create table t").Check(testkit.Rows("t CREATE TABLE `t` (\n" +
" `a` varchar(20) DEFAULT NULL,\n" +
" `b` varchar(20) CHARACTER SET ascii COLLATE ascii_bin DEFAULT NULL\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"))

config.GetGlobalConfig().TreatOldVersionUTF8AsUTF8MB4 = false
config.GetGlobalConfig(context.Background()).TreatOldVersionUTF8AsUTF8MB4 = false
s.tk.MustExec("alter table t change column b b varchar(30) character set ascii") // reload schema.
s.tk.MustGetErrCode("insert into t set a= x'f09f8c80'", errno.ErrTruncatedWrongValueForField)
s.tk.MustQuery("show create table t").Check(testkit.Rows("t CREATE TABLE `t` (\n" +
Expand All @@ -1793,11 +1793,11 @@ func (s *testIntegrationSuite1) TestTreatOldVersionUTF8AsUTF8MB4(c *C) {
") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin"))

// Test for alter table convert charset
config.GetGlobalConfig().TreatOldVersionUTF8AsUTF8MB4 = true
config.GetGlobalConfig(context.Background()).TreatOldVersionUTF8AsUTF8MB4 = true
s.tk.MustExec("alter table t drop column b") // reload schema.
s.tk.MustExec("alter table t convert to charset utf8mb4;")

config.GetGlobalConfig().TreatOldVersionUTF8AsUTF8MB4 = false
config.GetGlobalConfig(context.Background()).TreatOldVersionUTF8AsUTF8MB4 = false
s.tk.MustExec("alter table t add column b varchar(50);") // reload schema.
s.tk.MustQuery("show create table t").Check(testkit.Rows("t CREATE TABLE `t` (\n" +
" `a` varchar(20) DEFAULT NULL,\n" +
Expand Down Expand Up @@ -2044,7 +2044,7 @@ func (s *testIntegrationSuite3) TestParserIssue284(c *C) {
}

func (s *testIntegrationSuite7) TestAddExpressionIndex(c *C) {
config.GetGlobalConfig().Experimental.AllowsExpressionIndex = true
config.GetGlobalConfig(context.Background()).Experimental.AllowsExpressionIndex = true
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t;")
Expand Down Expand Up @@ -2096,12 +2096,12 @@ func (s *testIntegrationSuite7) TestAddExpressionIndex(c *C) {
tk.MustExec("alter table t1 alter index ei_ab invisible;")

// Test experiment switch.
config.GetGlobalConfig().Experimental.AllowsExpressionIndex = false
config.GetGlobalConfig(context.Background()).Experimental.AllowsExpressionIndex = false
tk.MustGetErrMsg("create index d on t((a+1))", "[ddl:8200]Unsupported creating expression index without allow-expression-index in config")
}

func (s *testIntegrationSuite7) TestCreateExpressionIndexError(c *C) {
config.GetGlobalConfig().Experimental.AllowsExpressionIndex = true
config.GetGlobalConfig(context.Background()).Experimental.AllowsExpressionIndex = true

tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
Expand Down Expand Up @@ -2263,7 +2263,7 @@ func (s *testIntegrationSuite3) TestCreateTableWithAutoIdCache(c *C) {
}

func (s *testIntegrationSuite4) TestAlterIndexVisibility(c *C) {
config.GetGlobalConfig().Experimental.AllowsExpressionIndex = true
config.GetGlobalConfig(context.Background()).Experimental.AllowsExpressionIndex = true
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("create database if not exists alter_index_test")
tk.MustExec("USE alter_index_test;")
Expand Down
2 changes: 1 addition & 1 deletion ddl/db_partition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1138,7 +1138,7 @@ func (s *testIntegrationSuite4) TestExchangePartitionTableCompatiable(c *C) {
}

func (s *testIntegrationSuite7) TestExchangePartitionExpressIndex(c *C) {
config.GetGlobalConfig().Experimental.AllowsExpressionIndex = true
config.GetGlobalConfig(context.Background()).Experimental.AllowsExpressionIndex = true
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists pt1;")
Expand Down
6 changes: 3 additions & 3 deletions ddl/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ func (s *testDBSuite2) TestAddUniqueIndexRollback(c *C) {
}

func (s *testSerialDBSuite) TestAddExpressionIndexRollback(c *C) {
config.GetGlobalConfig().Experimental.AllowsExpressionIndex = true
config.GetGlobalConfig(context.Background()).Experimental.AllowsExpressionIndex = true
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test_db")
tk.MustExec("drop table if exists t1")
Expand Down Expand Up @@ -4454,7 +4454,7 @@ func (s *testDBSuite2) TestTablesLockDelayClean(c *C) {

tk.MustExec("lock tables t1 write")
checkTableLock(c, tk.Se, "test", "t1", model.TableLockWrite)
config.GetGlobalConfig().DelayCleanTableLock = 100
config.GetGlobalConfig(context.Background()).DelayCleanTableLock = 100
var wg sync.WaitGroup
wg.Add(1)
var startTime time.Time
Expand All @@ -4468,7 +4468,7 @@ func (s *testDBSuite2) TestTablesLockDelayClean(c *C) {
wg.Wait()
c.Assert(time.Since(startTime).Seconds() > 0.1, IsTrue)
checkTableLock(c, tk.Se, "test", "t1", model.TableLockNone)
config.GetGlobalConfig().DelayCleanTableLock = 0
config.GetGlobalConfig(context.Background()).DelayCleanTableLock = 0
}

// TestConcurrentLockTables test concurrent lock/unlock tables.
Expand Down
18 changes: 9 additions & 9 deletions ddl/ddl_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ func (d *ddl) DropSchema(ctx sessionctx.Context, schema model.CIStr) (err error)
if err != nil {
return errors.Trace(err)
}
if !config.TableLockEnabled() {
if !config.TableLockEnabled(context.Background()) {
return nil
}
// Clear table locks hold by the session.
Expand Down Expand Up @@ -1266,7 +1266,7 @@ func buildTableInfo(
if err != nil {
return nil, err
}
if !config.GetGlobalConfig().AlterPrimaryKey {
if !config.GetGlobalConfig(context.Background()).AlterPrimaryKey {
singleIntPK := isSingleIntPK(constr, lastCol)
clusteredIdx := ctx.GetSessionVars().EnableClusteredIndex
if singleIntPK || clusteredIdx {
Expand Down Expand Up @@ -4018,7 +4018,7 @@ func (d *ddl) DropTable(ctx sessionctx.Context, ti ast.Ident) (err error) {
if err != nil {
return errors.Trace(err)
}
if !config.TableLockEnabled() {
if !config.TableLockEnabled(context.Background()) {
return nil
}
if ok, _ := ctx.CheckTableLocked(tb.Meta().ID); ok {
Expand Down Expand Up @@ -4072,7 +4072,7 @@ func (d *ddl) TruncateTable(ctx sessionctx.Context, ti ast.Ident) error {
BinlogInfo: &model.HistoryInfo{},
Args: []interface{}{newTableID},
}
if ok, _ := ctx.CheckTableLocked(tb.Meta().ID); ok && config.TableLockEnabled() {
if ok, _ := ctx.CheckTableLocked(tb.Meta().ID); ok && config.TableLockEnabled(context.Background()) {
// AddTableLock here to avoid this ddl job was executed successfully but the session was been kill before return.
// The session will release all table locks it holds, if we don't add the new locking table id here,
// the session may forget to release the new locked table id when this ddl job was executed successfully
Expand All @@ -4082,7 +4082,7 @@ func (d *ddl) TruncateTable(ctx sessionctx.Context, ti ast.Ident) error {
err = d.doDDLJob(ctx, job)
err = d.callHookOnChanged(err)
if err != nil {
if config.TableLockEnabled() {
if config.TableLockEnabled(context.Background()) {
ctx.ReleaseTableLockByTableIDs([]int64{newTableID})
}
return errors.Trace(err)
Expand All @@ -4094,7 +4094,7 @@ func (d *ddl) TruncateTable(ctx sessionctx.Context, ti ast.Ident) error {
}
}

if !config.TableLockEnabled() {
if !config.TableLockEnabled(context.Background()) {
return nil
}
if ok, _ := ctx.CheckTableLocked(tb.Meta().ID); ok {
Expand Down Expand Up @@ -4178,7 +4178,7 @@ func getAnonymousIndex(t table.Table, colName model.CIStr) model.CIStr {

func (d *ddl) CreatePrimaryKey(ctx sessionctx.Context, ti ast.Ident, indexName model.CIStr,
indexPartSpecifications []*ast.IndexPartSpecification, indexOption *ast.IndexOption) error {
if !config.GetGlobalConfig().AlterPrimaryKey {
if !config.GetGlobalConfig(context.Background()).AlterPrimaryKey {
return ErrUnsupportedModifyPrimaryKey.GenWithStack("Unsupported add primary key, alter-primary-key is false")
}

Expand Down Expand Up @@ -4356,7 +4356,7 @@ func (d *ddl) CreateIndex(ctx sessionctx.Context, ti ast.Ident, keyType ast.Inde
if err != nil {
return err
}
if len(hiddenCols) > 0 && !config.GetGlobalConfig().Experimental.AllowsExpressionIndex {
if len(hiddenCols) > 0 && !config.GetGlobalConfig(context.Background()).Experimental.AllowsExpressionIndex {
return ErrUnsupportedExpressionIndex
}
if err = checkAddColumnTooManyColumns(len(t.Cols()) + len(hiddenCols)); err != nil {
Expand Down Expand Up @@ -4552,7 +4552,7 @@ func (d *ddl) DropIndex(ctx sessionctx.Context, ti ast.Ident, indexName model.CI
isPK = true
}
if isPK {
if !config.GetGlobalConfig().AlterPrimaryKey {
if !config.GetGlobalConfig(context.Background()).AlterPrimaryKey {
return ErrUnsupportedModifyPrimaryKey.GenWithStack("Unsupported drop primary key when alter-primary-key is false")

}
Expand Down
2 changes: 1 addition & 1 deletion ddl/ddl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func TestT(t *testing.T) {
ReorgWaitTimeout = 30 * time.Millisecond
batchInsertDeleteRangeSize = 2

cfg := config.GetGlobalConfig()
cfg := config.GetGlobalConfig(context.Background())
newCfg := *cfg
// Test for table lock.
newCfg.EnableTableLock = true
Expand Down
15 changes: 9 additions & 6 deletions ddl/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@ func buildIndexColumns(columns []*model.ColumnInfo, indexPartSpecifications []*a
sumLength += indexColumnLength

// The sum of all lengths must be shorter than the max length for prefix.
if sumLength > config.GetGlobalConfig().MaxIndexLength {
return nil, errTooLongKey.GenWithStackByArgs(config.GetGlobalConfig().MaxIndexLength)
maxIndexLengthConfig := config.GetGlobalConfig(context.Background()).MaxIndexLength
if sumLength > maxIndexLengthConfig {
return nil, errTooLongKey.GenWithStackByArgs(maxIndexLengthConfig)
}

idxParts = append(idxParts, &model.IndexColumn{
Expand Down Expand Up @@ -123,8 +124,9 @@ func checkIndexPrefixLength(columns []*model.ColumnInfo, idxColumns []*model.Ind
}
sumLength += indexColumnLength
// The sum of all lengths must be shorter than the max length for prefix.
if sumLength > config.GetGlobalConfig().MaxIndexLength {
return errTooLongKey.GenWithStackByArgs(config.GetGlobalConfig().MaxIndexLength)
maxIndexLengthConfig := config.GetGlobalConfig(context.Background()).MaxIndexLength
if sumLength > maxIndexLengthConfig {
return errTooLongKey.GenWithStackByArgs(maxIndexLengthConfig)
}
}
return nil
Expand Down Expand Up @@ -168,8 +170,9 @@ func checkIndexColumn(col *model.ColumnInfo, ic *ast.IndexPartSpecification) err
}

// Specified length must be shorter than the max length for prefix.
if ic.Length > config.GetGlobalConfig().MaxIndexLength {
return errTooLongKey.GenWithStackByArgs(config.GetGlobalConfig().MaxIndexLength)
maxIndexLength := config.GetGlobalConfig(context.Background()).MaxIndexLength
if ic.Length > maxIndexLength {
return errTooLongKey.GenWithStackByArgs(maxIndexLength)
}
return nil
}
Expand Down
Loading