From 40f6d99748f3d816d2e1d62abbb38b4c460ffe3a Mon Sep 17 00:00:00 2001 From: xia Date: Wed, 11 Nov 2015 12:32:40 +0800 Subject: [PATCH 1/4] *: store status variables to the db and add the corresponding test --- bootstrap.go | 29 +++++++++++++++++++++++++---- mysql/const.go | 2 ++ tidb_test.go | 7 ++++++- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/bootstrap.go b/bootstrap.go index 5c7538e424..d25b2c1f9f 100644 --- a/bootstrap.go +++ b/bootstrap.go @@ -92,6 +92,11 @@ const ( CreateGloablVariablesTable = `CREATE TABLE if not exists mysql.GLOBAL_VARIABLES( VARIABLE_NAME VARCHAR(64) Not Null PRIMARY KEY, VARIABLE_VALUE VARCHAR(1024) DEFAULT Null);` + // CreateGloablStatusTable is the SQL statement creates global status variable table in system db. + // TODO: MySQL puts GLOBAL_STATUS table in INFORMATION_SCHEMA db. + CreateGloablStatusTable = `CREATE TABLE if not exists mysql.GLOBAL_STATUS( + VARIABLE_NAME VARCHAR(64) Not Null PRIMARY KEY, + VARIABLE_VALUE VARCHAR(1024) DEFAULT Null);` // CreateTiDBTable is the SQL statement creates a table in system db. // This table is a key-value struct contains some information used by TiDB. // Currently we only put bootstrapped in it which indicates if the system is already bootstrapped. @@ -134,7 +139,8 @@ func checkBootstrapped(s Session) (bool, error) { } func checkBootstrappedVar(s Session) (bool, error) { - sql := fmt.Sprintf(`SELECT VARIABLE_VALUE FROM %s.%s WHERE VARIABLE_NAME="%s"`, mysql.SystemDB, mysql.TiDBTable, bootstrappedVar) + sql := fmt.Sprintf(`SELECT VARIABLE_VALUE FROM %s.%s WHERE VARIABLE_NAME="%s"`, + mysql.SystemDB, mysql.TiDBTable, bootstrappedVar) rs, err := s.Execute(sql) if err != nil { if terror.TableNotExists.Equal(err) { @@ -167,6 +173,8 @@ func doDDLWorks(s Session) { mustExecute(s, CreateColumnPrivTable) // Create global systemt variable table. mustExecute(s, CreateGloablVariablesTable) + // Create global status variable table. + mustExecute(s, CreateGloablStatusTable) // Create TiDB table. mustExecute(s, CreateTiDBTable) } @@ -176,7 +184,8 @@ func doDDLWorks(s Session) { func doDMLWorks(s Session) { mustExecute(s, "BEGIN") // Insert a default user with empty password. - mustExecute(s, `INSERT INTO mysql.user VALUES ("localhost", "root", "", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y"), + mustExecute(s, `INSERT INTO mysql.user VALUES + ("localhost", "root", "", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y"), ("127.0.0.1", "root", "", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y"), ("::1", "root", "", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y");`) // Init global system variable table. @@ -185,9 +194,21 @@ func doDMLWorks(s Session) { value := fmt.Sprintf(`("%s", "%s")`, strings.ToLower(k), v.Value) values = append(values, value) } - sql := fmt.Sprintf("INSERT INTO %s.%s VALUES %s;", mysql.SystemDB, mysql.GlobalVariablesTable, strings.Join(values, ", ")) + sql := fmt.Sprintf("INSERT INTO %s.%s VALUES %s;", mysql.SystemDB, mysql.GlobalVariablesTable, + strings.Join(values, ", ")) mustExecute(s, sql) - sql = fmt.Sprintf(`INSERT INTO %s.%s VALUES("%s", "%s", "Bootstrap flag. Do not delete.") ON DUPLICATE KEY UPDATE VARIABLE_VALUE="%s"`, mysql.SystemDB, mysql.TiDBTable, bootstrappedVar, bootstrappedVarTrue, bootstrappedVarTrue) + // Init global status variable table. + values := make([]string, 0, len(variable.StatusVars)) + for k, v := range variable.StatusVars { + value := fmt.Sprintf(`("%s", "%s")`, strings.ToLower(k), v.Value) + values = append(values, value) + } + sql := fmt.Sprintf("INSERT INTO %s.%s VALUES %s;", mysql.SystemDB, mysql.GlobalStatusTable, + strings.Join(values, ", ")) + mustExecute(s, sql) + sql = fmt.Sprintf(`INSERT INTO %s.%s VALUES("%s", "%s", "Bootstrap flag. Do not delete.") + ON DUPLICATE KEY UPDATE VARIABLE_VALUE="%s"`, + mysql.SystemDB, mysql.TiDBTable, bootstrappedVar, bootstrappedVarTrue, bootstrappedVarTrue) mustExecute(s, sql) mustExecute(s, "COMMIT") } diff --git a/mysql/const.go b/mysql/const.go index 3172ec6932..9d1e1bab42 100644 --- a/mysql/const.go +++ b/mysql/const.go @@ -130,6 +130,8 @@ const ( ColumnPrivTable = "Columns_priv" // GlobalVariablesTable is the table contains global system variables. GlobalVariablesTable = "GLOBAL_VARIABLES" + // GlobalStatusTable is the table contains global status variables. + GlobalStatusTable = "GLOBAL_STATUS" // TiDBTable is the table contains tidb info. TiDBTable = "tidb" ) diff --git a/tidb_test.go b/tidb_test.go index 2832e1b0e7..e6ca839e40 100644 --- a/tidb_test.go +++ b/tidb_test.go @@ -1072,11 +1072,16 @@ func (s *testSessionSuite) TestBootstrapWithError(c *C) { mustExecSQL(c, se, "SELECT * from mysql.db;") mustExecSQL(c, se, "SELECT * from mysql.tables_priv;") mustExecSQL(c, se, "SELECT * from mysql.columns_priv;") - // Check privilege tables. + // Check global variables. r = mustExecSQL(c, se, "SELECT COUNT(*) from mysql.global_variables;") v, err := r.FirstRow() c.Assert(err, IsNil) c.Assert(v[0], Equals, int64(len(variable.SysVars))) + // Check global status. + r = mustExecSQL(c, se, "SELECT COUNT(*) from mysql.global_status;") + v, err = r.FirstRow() + c.Assert(err, IsNil) + c.Assert(v[0], Equals, int64(len(variable.StatusVars))) r = mustExecSQL(c, se, `SELECT VARIABLE_VALUE from mysql.TiDB where VARIABLE_NAME="bootstrapped";`) row, err = r.Next() c.Assert(err, IsNil) From 915ce8447407d4f560c644f62709476000905648 Mon Sep 17 00:00:00 2001 From: xia Date: Thu, 12 Nov 2015 20:33:56 +0800 Subject: [PATCH 2/4] ddl: update log --- ddl/ddl.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddl/ddl.go b/ddl/ddl.go index 2762d9722f..2b93e87b49 100644 --- a/ddl/ddl.go +++ b/ddl/ddl.go @@ -124,7 +124,7 @@ func (d *ddl) CreateSchema(ctx context.Context, schema model.CIStr) (err error) err = t.CreateDatabase(info) - log.Warnf("save schema %s", info) + log.Warnf("save schema %v", info) return errors.Trace(err) }) if d.onDDLChange != nil { From 6cf2c6f3b05db7ebf57a536d7daf497e1381cfed Mon Sep 17 00:00:00 2001 From: xia Date: Thu, 12 Nov 2015 20:34:43 +0800 Subject: [PATCH 3/4] plan: add init function --- plan/plans/info.go | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/plan/plans/info.go b/plan/plans/info.go index 6c45fb002c..b09f182b79 100644 --- a/plan/plans/info.go +++ b/plan/plans/info.go @@ -44,14 +44,14 @@ type InfoSchemaPlan struct { } var ( - schemataFields = buildResultFieldsForSchemata() - tablesFields = buildResultFieldsForTables() - columnsFields = buildResultFieldsForColumns() - statisticsFields = buildResultFieldsForStatistics() - characterSetsFields = buildResultFieldsForCharacterSets() - characterSetsRecords = buildCharacterSetsRecords() - collationsFields = buildResultFieldsForCollations() - collationsRecords = buildColltionsRecords() + schemataFields []*field.ResultField + tablesFields []*field.ResultField + columnsFields []*field.ResultField + statisticsFields []*field.ResultField + characterSetsFields []*field.ResultField + collationsFields []*field.ResultField + characterSetsRecords [][]interface{} + collationsRecords [][]interface{} ) const ( @@ -453,3 +453,14 @@ func (isp *InfoSchemaPlan) Close() error { isp.cursor = 0 return nil } + +func init() { + schemataFields = buildResultFieldsForSchemata() + tablesFields = buildResultFieldsForTables() + columnsFields = buildResultFieldsForColumns() + statisticsFields = buildResultFieldsForStatistics() + characterSetsFields = buildResultFieldsForCharacterSets() + collationsFields = buildResultFieldsForCollations() + characterSetsRecords = buildCharacterSetsRecords() + collationsRecords = buildColltionsRecords() +} From 2b7064c567f727dd665045a398a41684badc363f Mon Sep 17 00:00:00 2001 From: xia Date: Thu, 12 Nov 2015 20:36:29 +0800 Subject: [PATCH 4/4] *: store status variables to the db and update info test --- bootstrap.go | 4 ++-- plan/plans/info_test.go | 2 +- session.go | 32 +++++++++++++++++--------------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/bootstrap.go b/bootstrap.go index d25b2c1f9f..06cdcc0036 100644 --- a/bootstrap.go +++ b/bootstrap.go @@ -198,12 +198,12 @@ func doDMLWorks(s Session) { strings.Join(values, ", ")) mustExecute(s, sql) // Init global status variable table. - values := make([]string, 0, len(variable.StatusVars)) + values = make([]string, 0, len(variable.StatusVars)) for k, v := range variable.StatusVars { value := fmt.Sprintf(`("%s", "%s")`, strings.ToLower(k), v.Value) values = append(values, value) } - sql := fmt.Sprintf("INSERT INTO %s.%s VALUES %s;", mysql.SystemDB, mysql.GlobalStatusTable, + sql = fmt.Sprintf("INSERT INTO %s.%s VALUES %s;", mysql.SystemDB, mysql.GlobalStatusTable, strings.Join(values, ", ")) mustExecute(s, sql) sql = fmt.Sprintf(`INSERT INTO %s.%s VALUES("%s", "%s", "Bootstrap flag. Do not delete.") diff --git a/plan/plans/info_test.go b/plan/plans/info_test.go index 06f7acdc11..57daaa0068 100644 --- a/plan/plans/info_test.go +++ b/plan/plans/info_test.go @@ -86,7 +86,7 @@ func (p *testInfoSchemaSuit) TestInfoSchema(c *C) { cnt = mustQuery(c, testDB, "select * from information_schema.columns") c.Assert(cnt, Greater, 0) cnt = mustQuery(c, testDB, "select * from information_schema.statistics") - c.Assert(cnt, Equals, 16) + c.Assert(cnt, Equals, 17) cnt = mustQuery(c, testDB, "select * from information_schema.character_sets") c.Assert(cnt, Greater, 0) cnt = mustQuery(c, testDB, "select * from information_schema.collations") diff --git a/session.go b/session.go index c47b506716..b5f3326337 100644 --- a/session.go +++ b/session.go @@ -287,30 +287,31 @@ func (s *session) getExecRet(ctx context.Context, sql string) (string, error) { // GetGlobalStatusVar implements GlobalVarAccessor.GetGlobalStatusVar interface. func (s *session) GetGlobalStatusVar(ctx context.Context, name string) (string, error) { - // TODO: get global status variables from store. - v := variable.GetStatusVar(name) - if v == nil { - return "", terror.UnknownStatusVar.Gen("unknown status variable:%s", name) + sql := fmt.Sprintf(`SELECT VARIABLE_VALUE FROM %s.%s WHERE VARIABLE_NAME="%s";`, + mysql.SystemDB, mysql.GlobalStatusTable, name) + statusVar, err := s.getExecRet(ctx, sql) + if err != nil { + if terror.ExecResultIsEmpty.Equal(err) { + return "", terror.ExecResultIsEmpty.Gen("unknown status variable:%s", name) + } + return "", errors.Trace(err) } - return v.Value, nil + return statusVar, nil } // SetGlobalStatusVar implements GlobalVarAccessor.SetGlobalStatusVar interface. func (s *session) SetGlobalStatusVar(ctx context.Context, name string, value string) error { - // TODO: set global status variables from store. - v := variable.GetStatusVar(name) - if v == nil { - return terror.UnknownStatusVar.Gen("unknown status variable:%s", name) - } - v.Value = value - - return nil + sql := fmt.Sprintf(`UPDATE %s.%s SET VARIABLE_VALUE="%s" WHERE VARIABLE_NAME="%s";`, + mysql.SystemDB, mysql.GlobalStatusTable, value, strings.ToLower(name)) + _, err := s.ExecRestrictedSQL(ctx, sql) + return errors.Trace(err) } // GetGlobalSysVar implements GlobalVarAccessor.GetGlobalSysVar interface. func (s *session) GetGlobalSysVar(ctx context.Context, name string) (string, error) { - sql := fmt.Sprintf(`SELECT VARIABLE_VALUE FROM %s.%s WHERE VARIABLE_NAME="%s";`, mysql.SystemDB, mysql.GlobalVariablesTable, name) + sql := fmt.Sprintf(`SELECT VARIABLE_VALUE FROM %s.%s WHERE VARIABLE_NAME="%s";`, + mysql.SystemDB, mysql.GlobalVariablesTable, name) sysVar, err := s.getExecRet(ctx, sql) if err != nil { if terror.ExecResultIsEmpty.Equal(err) { @@ -324,7 +325,8 @@ func (s *session) GetGlobalSysVar(ctx context.Context, name string) (string, err // SetGlobalSysVar implements GlobalVarAccessor.SetGlobalSysVar interface. func (s *session) SetGlobalSysVar(ctx context.Context, name string, value string) error { - sql := fmt.Sprintf(`UPDATE %s.%s SET VARIABLE_VALUE="%s" WHERE VARIABLE_NAME="%s";`, mysql.SystemDB, mysql.GlobalVariablesTable, value, strings.ToLower(name)) + sql := fmt.Sprintf(`UPDATE %s.%s SET VARIABLE_VALUE="%s" WHERE VARIABLE_NAME="%s";`, + mysql.SystemDB, mysql.GlobalVariablesTable, value, strings.ToLower(name)) _, err := s.ExecRestrictedSQL(ctx, sql) return errors.Trace(err) }