diff --git a/data/test/tabletserver/ddl_cases.txt b/data/test/tabletserver/ddl_cases.txt index 8da256f6829..f6accdba701 100644 --- a/data/test/tabletserver/ddl_cases.txt +++ b/data/test/tabletserver/ddl_cases.txt @@ -38,6 +38,11 @@ "Action": "alter", "TableName": "b.c", "NewName": "b.c" } +"drop index a on b lock=none" +{ + "Action": "alter", "TableName": "b", "NewName": "b" +} + "rename table a to b" { "Action": "rename", "TableName": "a", "NewTable": "b" diff --git a/data/test/vtexplain/comments-output.json b/data/test/vtexplain/comments-output.json index fad73a09944..137b11362b0 100644 --- a/data/test/vtexplain/comments-output.json +++ b/data/test/vtexplain/comments-output.json @@ -85,5 +85,381 @@ ] } } + }, + { + "SQL": "select /* ; */ 1 from user", + "Plans": [ + { + "Original": "select /* ; */ :vtg1 from user", + "Instructions": { + "Opcode": "SelectScatter", + "Keyspace": { + "Name": "ks_sharded", + "Sharded": true + }, + "Query": "select /* ; */ :vtg1 from user", + "FieldQuery": "select :vtg1 from user where 1 != 1" + } + } + ], + "TabletActions": { + "ks_sharded/-40": { + "TabletQueries": [ + { + "Time": 1, + "SQL": "select /* ; */ :vtg1 from user", + "BindVars": { + "#maxLimit": "10001", + "vtg1": "1" + } + } + ], + "MysqlQueries": [ + { + "Time": 1, + "SQL": "select /* ; */ 1 from user limit 10001" + } + ] + }, + "ks_sharded/40-80": { + "TabletQueries": [ + { + "Time": 1, + "SQL": "select /* ; */ :vtg1 from user", + "BindVars": { + "#maxLimit": "10001", + "vtg1": "1" + } + } + ], + "MysqlQueries": [ + { + "Time": 1, + "SQL": "select /* ; */ 1 from user limit 10001" + } + ] + }, + "ks_sharded/80-c0": { + "TabletQueries": [ + { + "Time": 1, + "SQL": "select /* ; */ :vtg1 from user", + "BindVars": { + "#maxLimit": "10001", + "vtg1": "1" + } + } + ], + "MysqlQueries": [ + { + "Time": 1, + "SQL": "select /* ; */ 1 from user limit 10001" + } + ] + }, + "ks_sharded/c0-": { + "TabletQueries": [ + { + "Time": 1, + "SQL": "select /* ; */ :vtg1 from user", + "BindVars": { + "#maxLimit": "10001", + "vtg1": "1" + } + } + ], + "MysqlQueries": [ + { + "Time": 1, + "SQL": "select /* ; */ 1 from user limit 10001" + } + ] + } + } + }, + { + "SQL": "select 1 from user where x=';'", + "Plans": [ + { + "Original": "select :vtg1 from user where x = :vtg2", + "Instructions": { + "Opcode": "SelectScatter", + "Keyspace": { + "Name": "ks_sharded", + "Sharded": true + }, + "Query": "select :vtg1 from user where x = :vtg2", + "FieldQuery": "select :vtg1 from user where 1 != 1" + } + } + ], + "TabletActions": { + "ks_sharded/-40": { + "TabletQueries": [ + { + "Time": 1, + "SQL": "select :vtg1 from user where x = :vtg2", + "BindVars": { + "#maxLimit": "10001", + "vtg1": "1", + "vtg2": "';'" + } + } + ], + "MysqlQueries": [ + { + "Time": 1, + "SQL": "select 1 from user where x = ';' limit 10001" + } + ] + }, + "ks_sharded/40-80": { + "TabletQueries": [ + { + "Time": 1, + "SQL": "select :vtg1 from user where x = :vtg2", + "BindVars": { + "#maxLimit": "10001", + "vtg1": "1", + "vtg2": "';'" + } + } + ], + "MysqlQueries": [ + { + "Time": 1, + "SQL": "select 1 from user where x = ';' limit 10001" + } + ] + }, + "ks_sharded/80-c0": { + "TabletQueries": [ + { + "Time": 1, + "SQL": "select :vtg1 from user where x = :vtg2", + "BindVars": { + "#maxLimit": "10001", + "vtg1": "1", + "vtg2": "';'" + } + } + ], + "MysqlQueries": [ + { + "Time": 1, + "SQL": "select 1 from user where x = ';' limit 10001" + } + ] + }, + "ks_sharded/c0-": { + "TabletQueries": [ + { + "Time": 1, + "SQL": "select :vtg1 from user where x = :vtg2", + "BindVars": { + "#maxLimit": "10001", + "vtg1": "1", + "vtg2": "';'" + } + } + ], + "MysqlQueries": [ + { + "Time": 1, + "SQL": "select 1 from user where x = ';' limit 10001" + } + ] + } + } + }, + { + "SQL": "select 1 from user where x='/* hello */'", + "Plans": [ + { + "Original": "select :vtg1 from user where x = :vtg2", + "Instructions": { + "Opcode": "SelectScatter", + "Keyspace": { + "Name": "ks_sharded", + "Sharded": true + }, + "Query": "select :vtg1 from user where x = :vtg2", + "FieldQuery": "select :vtg1 from user where 1 != 1" + } + } + ], + "TabletActions": { + "ks_sharded/-40": { + "TabletQueries": [ + { + "Time": 1, + "SQL": "select :vtg1 from user where x = :vtg2", + "BindVars": { + "#maxLimit": "10001", + "vtg1": "1", + "vtg2": "'/* hello */'" + } + } + ], + "MysqlQueries": [ + { + "Time": 1, + "SQL": "select 1 from user where x = '/* hello */' limit 10001" + } + ] + }, + "ks_sharded/40-80": { + "TabletQueries": [ + { + "Time": 1, + "SQL": "select :vtg1 from user where x = :vtg2", + "BindVars": { + "#maxLimit": "10001", + "vtg1": "1", + "vtg2": "'/* hello */'" + } + } + ], + "MysqlQueries": [ + { + "Time": 1, + "SQL": "select 1 from user where x = '/* hello */' limit 10001" + } + ] + }, + "ks_sharded/80-c0": { + "TabletQueries": [ + { + "Time": 1, + "SQL": "select :vtg1 from user where x = :vtg2", + "BindVars": { + "#maxLimit": "10001", + "vtg1": "1", + "vtg2": "'/* hello */'" + } + } + ], + "MysqlQueries": [ + { + "Time": 1, + "SQL": "select 1 from user where x = '/* hello */' limit 10001" + } + ] + }, + "ks_sharded/c0-": { + "TabletQueries": [ + { + "Time": 1, + "SQL": "select :vtg1 from user where x = :vtg2", + "BindVars": { + "#maxLimit": "10001", + "vtg1": "1", + "vtg2": "'/* hello */'" + } + } + ], + "MysqlQueries": [ + { + "Time": 1, + "SQL": "select 1 from user where x = '/* hello */' limit 10001" + } + ] + } + } + }, + { + "SQL": "select 1 from user where x='/* ; */'", + "Plans": [ + { + "Original": "select :vtg1 from user where x = :vtg2", + "Instructions": { + "Opcode": "SelectScatter", + "Keyspace": { + "Name": "ks_sharded", + "Sharded": true + }, + "Query": "select :vtg1 from user where x = :vtg2", + "FieldQuery": "select :vtg1 from user where 1 != 1" + } + } + ], + "TabletActions": { + "ks_sharded/-40": { + "TabletQueries": [ + { + "Time": 1, + "SQL": "select :vtg1 from user where x = :vtg2", + "BindVars": { + "#maxLimit": "10001", + "vtg1": "1", + "vtg2": "'/* ; */'" + } + } + ], + "MysqlQueries": [ + { + "Time": 1, + "SQL": "select 1 from user where x = '/* ; */' limit 10001" + } + ] + }, + "ks_sharded/40-80": { + "TabletQueries": [ + { + "Time": 1, + "SQL": "select :vtg1 from user where x = :vtg2", + "BindVars": { + "#maxLimit": "10001", + "vtg1": "1", + "vtg2": "'/* ; */'" + } + } + ], + "MysqlQueries": [ + { + "Time": 1, + "SQL": "select 1 from user where x = '/* ; */' limit 10001" + } + ] + }, + "ks_sharded/80-c0": { + "TabletQueries": [ + { + "Time": 1, + "SQL": "select :vtg1 from user where x = :vtg2", + "BindVars": { + "#maxLimit": "10001", + "vtg1": "1", + "vtg2": "'/* ; */'" + } + } + ], + "MysqlQueries": [ + { + "Time": 1, + "SQL": "select 1 from user where x = '/* ; */' limit 10001" + } + ] + }, + "ks_sharded/c0-": { + "TabletQueries": [ + { + "Time": 1, + "SQL": "select :vtg1 from user where x = :vtg2", + "BindVars": { + "#maxLimit": "10001", + "vtg1": "1", + "vtg2": "'/* ; */'" + } + } + ], + "MysqlQueries": [ + { + "Time": 1, + "SQL": "select 1 from user where x = '/* ; */' limit 10001" + } + ] + } + } } ] diff --git a/data/test/vtexplain/comments-output.txt b/data/test/vtexplain/comments-output.txt index f57ae23f4ff..922dec1543a 100644 --- a/data/test/vtexplain/comments-output.txt +++ b/data/test/vtexplain/comments-output.txt @@ -7,3 +7,35 @@ SELECT * from user 1 ks_sharded/c0-: select * from user limit 10001 ---------------------------------------------------------------------- +select /* ; */ 1 from user + +1 ks_sharded/-40: select /* ; */ 1 from user limit 10001 +1 ks_sharded/40-80: select /* ; */ 1 from user limit 10001 +1 ks_sharded/80-c0: select /* ; */ 1 from user limit 10001 +1 ks_sharded/c0-: select /* ; */ 1 from user limit 10001 + +---------------------------------------------------------------------- +select 1 from user where x=';' + +1 ks_sharded/-40: select 1 from user where x = ';' limit 10001 +1 ks_sharded/40-80: select 1 from user where x = ';' limit 10001 +1 ks_sharded/80-c0: select 1 from user where x = ';' limit 10001 +1 ks_sharded/c0-: select 1 from user where x = ';' limit 10001 + +---------------------------------------------------------------------- +select 1 from user where x='/* hello */' + +1 ks_sharded/-40: select 1 from user where x = '/* hello */' limit 10001 +1 ks_sharded/40-80: select 1 from user where x = '/* hello */' limit 10001 +1 ks_sharded/80-c0: select 1 from user where x = '/* hello */' limit 10001 +1 ks_sharded/c0-: select 1 from user where x = '/* hello */' limit 10001 + +---------------------------------------------------------------------- +select 1 from user where x='/* ; */' + +1 ks_sharded/-40: select 1 from user where x = '/* ; */' limit 10001 +1 ks_sharded/40-80: select 1 from user where x = '/* ; */' limit 10001 +1 ks_sharded/80-c0: select 1 from user where x = '/* ; */' limit 10001 +1 ks_sharded/c0-: select 1 from user where x = '/* ; */' limit 10001 + +---------------------------------------------------------------------- diff --git a/data/test/vtexplain/comments-queries.sql b/data/test/vtexplain/comments-queries.sql index 342fa4a0ac4..1581b1472c5 100644 --- a/data/test/vtexplain/comments-queries.sql +++ b/data/test/vtexplain/comments-queries.sql @@ -12,3 +12,15 @@ SELECT * from user; ; -- this is a single line comment at the end of the file + +-- semicolon in comment +select /* ; */ 1 from user; + +-- semicolon in string +select 1 from user where x=';'; + +-- comment value in string +select 1 from user where x='/* hello */'; + +-- comment value with semicolon in string +select 1 from user where x='/* ; */'; diff --git a/go/cgzip/adler32.go b/go/cgzip/adler32.go index 670c5844d5d..d0eef089632 100644 --- a/go/cgzip/adler32.go +++ b/go/cgzip/adler32.go @@ -33,8 +33,8 @@ type adler32Hash struct { adler C.uLong } -// an empty buffer has an adler32 of '1' by default, so start with that -// (the go hash/adler32 does the same) +// NewAdler32 creates an empty buffer which has an adler32 of '1'. The go +// hash/adler32 does the same. func NewAdler32() hash.Hash32 { a := &adler32Hash{} a.Reset() @@ -76,9 +76,9 @@ func (a *adler32Hash) Sum32() uint32 { return uint32(a.adler) } -// helper method for partial checksums. From the zlib.h header: +// Adler32Combine method for partial checksums. From the zlib.h header: // -// Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 +// Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 // and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for // each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of // seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. diff --git a/go/cgzip/crc32.go b/go/cgzip/crc32.go index bc832b7f758..75fac466759 100644 --- a/go/cgzip/crc32.go +++ b/go/cgzip/crc32.go @@ -33,8 +33,8 @@ type crc32Hash struct { crc C.uLong } -// an empty buffer has an crc32 of '1' by default, so start with that -// (the go hash/crc32 does the same) +// NewCrc32 creates an empty buffer which has an crc32 of '1'. The go +// hash/crc32 does the same. func NewCrc32() hash.Hash32 { c := &crc32Hash{} c.Reset() @@ -76,9 +76,9 @@ func (a *crc32Hash) Sum32() uint32 { return uint32(a.crc) } -// helper method for partial checksums. From the zlib.h header: +// Crc32Combine helper method for partial checksums. From the zlib.h header: // -// Combine two CRC-32 checksums into one. For two sequences of bytes, seq1 +// Combine two CRC-32 checksums into one. For two sequences of bytes, seq1 // and seq2 with lengths len1 and len2, CRC-32 checksums were calculated for // each, crc1 and crc2. crc32_combine() returns the CRC-32 checksum of // seq1 and seq2 concatenated, requiring only crc1, crc2, and len2. diff --git a/go/cgzip/reader.go b/go/cgzip/reader.go index fc442f4647f..82805f4acd1 100644 --- a/go/cgzip/reader.go +++ b/go/cgzip/reader.go @@ -30,10 +30,14 @@ type reader struct { skipIn bool } +// NewReader returns a new cgzip.reader for reading gzip files with the C gzip +// library. func NewReader(r io.Reader) (io.ReadCloser, error) { return NewReaderBuffer(r, DEFAULT_COMPRESSED_BUFFER_SIZE) } +// NewReaderBuffer returns a new cgzip.reader with a given buffer size for +// reading gzip files with the C gzip library. func NewReaderBuffer(r io.Reader, bufferSize int) (io.ReadCloser, error) { z := &reader{r: r, in: make([]byte, bufferSize)} if err := z.strm.inflateInit(); err != nil { @@ -42,6 +46,7 @@ func NewReaderBuffer(r io.Reader, bufferSize int) (io.ReadCloser, error) { return z, nil } +// Read reads from the gz stream. func (z *reader) Read(p []byte) (int, error) { if z.err != nil { return 0, z.err diff --git a/go/fileutil/wildcards.go b/go/fileutil/wildcards.go index 65fcf7987ae..4da5365b76a 100644 --- a/go/fileutil/wildcards.go +++ b/go/fileutil/wildcards.go @@ -26,9 +26,8 @@ func HasWildcard(path string) bool { case '\\': if i+1 >= len(path) { return true - } else { - i++ } + i++ case '*', '?', '[': return true } diff --git a/go/flagutil/flagutil.go b/go/flagutil/flagutil.go index f4b4e2ced1b..e447598c1f5 100644 --- a/go/flagutil/flagutil.go +++ b/go/flagutil/flagutil.go @@ -29,6 +29,7 @@ import ( // it with a backslash '\'. type StringListValue []string +// Get returns the []string value of this flag. func (value StringListValue) Get() interface{} { return []string(value) } @@ -60,11 +61,13 @@ func parseListWithEscapes(v string, delimiter rune) (value []string) { return value } +// Set sets the value of this flag from parsing the given string. func (value *StringListValue) Set(v string) error { *value = parseListWithEscapes(v, ',') return nil } +// String returns the string representation of this flag. func (value StringListValue) String() string { parts := make([]string, len(value)) for i, v := range value { @@ -86,6 +89,7 @@ func StringListVar(p *[]string, name string, defaultValue []string, usage string // keys cannot contain colons. type StringMapValue map[string]string +// Set sets the value of this flag from parsing the given string. func (value *StringMapValue) Set(v string) error { dict := make(map[string]string) pairs := parseListWithEscapes(v, ',') @@ -97,10 +101,12 @@ func (value *StringMapValue) Set(v string) error { return nil } +// Get returns the map[string]string value of this flag. func (value StringMapValue) Get() interface{} { return map[string]string(value) } +// String returns the string representation of this flag. func (value StringMapValue) String() string { parts := make([]string, 0) for k, v := range value { diff --git a/go/ioutil2/ioutil.go b/go/ioutil2/ioutil.go index 49fff18cb39..21e64294d6b 100644 --- a/go/ioutil2/ioutil.go +++ b/go/ioutil2/ioutil.go @@ -23,7 +23,7 @@ import ( "path" ) -// Write file to temp and atomically move when everything else succeeds. +// WriteFileAtomic writes the data to a temp file and atomically move if everything else succeeds. func WriteFileAtomic(filename string, data []byte, perm os.FileMode) error { dir, name := path.Split(filename) f, err := ioutil.TempFile(dir, name) diff --git a/go/sqltypes/bind_variables_test.go b/go/sqltypes/bind_variables_test.go index aefa0ebd331..36241aca91c 100644 --- a/go/sqltypes/bind_variables_test.go +++ b/go/sqltypes/bind_variables_test.go @@ -523,7 +523,7 @@ func TestBindVariableToValue(t *testing.T) { v, err = BindVariableToValue(&querypb.BindVariable{Type: querypb.Type_TUPLE}) wantErr := "cannot convert a TUPLE bind var into a value" if err == nil || err.Error() != wantErr { - t.Errorf(" BindVarToValue(TUPLE): %v, want %s", err, wantErr) + t.Errorf(" BindVarToValue(TUPLE): (%v, %v), want %s", v, err, wantErr) } } diff --git a/go/sqltypes/plan_value.go b/go/sqltypes/plan_value.go index 4745241ef0e..ee8b7cf5c68 100644 --- a/go/sqltypes/plan_value.go +++ b/go/sqltypes/plan_value.go @@ -221,7 +221,7 @@ func ResolveRows(pvs []PlanValue, bindVars map[string]*querypb.BindVariable) ([] rows[i] = make([]Value, len(pvs)) } - // Using j becasue we're resolving by columns. + // Using j because we're resolving by columns. for j, pv := range pvs { switch { case pv.Key != "": diff --git a/go/sqltypes/value.go b/go/sqltypes/value.go index fa82e2159f9..03188e4f55d 100644 --- a/go/sqltypes/value.go +++ b/go/sqltypes/value.go @@ -48,7 +48,7 @@ type BinWriter interface { } // Value can store any SQL value. If the value represents -// an integral type, the bytes are always stored as a cannonical +// an integral type, the bytes are always stored as a canonical // representation that matches how MySQL returns such values. type Value struct { typ querypb.Type @@ -126,7 +126,7 @@ func NewVarBinary(v string) Value { return MakeTrusted(VarBinary, []byte(v)) } -// NewIntegral builds an integral type from a string representaion. +// NewIntegral builds an integral type from a string representation. // The type will be Int64 or Uint64. Int64 will be preferred where possible. func NewIntegral(val string) (n Value, err error) { signed, err := strconv.ParseInt(val, 0, 64) @@ -169,7 +169,7 @@ func (v Value) Type() querypb.Type { return v.typ } -// Raw returns the internal represenation of the value. For newer types, +// Raw returns the internal representation of the value. For newer types, // this may not match MySQL's representation. func (v Value) Raw() []byte { return v.val diff --git a/go/vt/binlog/binlog_streamer.go b/go/vt/binlog/binlog_streamer.go index f21a6a5dc7e..5cf6b121ae8 100644 --- a/go/vt/binlog/binlog_streamer.go +++ b/go/vt/binlog/binlog_streamer.go @@ -171,6 +171,11 @@ func NewStreamer(dbname string, mysqld mysqlctl.MysqlDaemon, se *schema.Engine, // Stream starts streaming binlog events using the settings from NewStreamer(). func (bls *Streamer) Stream(ctx context.Context) (err error) { + // Ensure se is Open. If vttablet came up in a non_serving role, + // the schema engine may not have been initialized. + if err := bls.se.Open(); err != nil { + return err + } stopPos := bls.startPos defer func() { if err != nil && err != mysqlctl.ErrBinlogUnavailable { diff --git a/go/vt/sqlparser/ast.go b/go/vt/sqlparser/ast.go index f38392a8899..358eff16305 100644 --- a/go/vt/sqlparser/ast.go +++ b/go/vt/sqlparser/ast.go @@ -97,6 +97,26 @@ func ParseNext(tokenizer *Tokenizer) (Statement, error) { return tokenizer.ParseTree, nil } +// SplitStatement returns the first sql statement up to either a ; or EOF +// and the remainder from the given buffer +func SplitStatement(blob string) (string, string, error) { + tokenizer := NewStringTokenizer(blob) + tkn := 0 + for { + tkn, _ = tokenizer.Scan() + if tkn == 0 || tkn == ';' || tkn == eofChar { + break + } + } + if tokenizer.LastError != nil { + return "", "", tokenizer.LastError + } + if tkn == ';' { + return blob[:tokenizer.Position-2], blob[tokenizer.Position-1:], nil + } + return blob, "", nil +} + // SQLNode defines the interface for all nodes // generated by the parser. type SQLNode interface { diff --git a/go/vt/sqlparser/ast_test.go b/go/vt/sqlparser/ast_test.go index f49bd331c74..3d2eb9311a8 100644 --- a/go/vt/sqlparser/ast_test.go +++ b/go/vt/sqlparser/ast_test.go @@ -297,7 +297,9 @@ func TestColIdentMarshal(t *testing.T) { t.Errorf("json.Marshal()= %s, want %s", got, want) } var out ColIdent - err = json.Unmarshal(b, &out) + if err := json.Unmarshal(b, &out); err != nil { + t.Errorf("Unmarshal err: %v, want nil", err) + } if !reflect.DeepEqual(out, str) { t.Errorf("Unmarshal: %v, want %v", out, str) } @@ -323,7 +325,9 @@ func TestTableIdentMarshal(t *testing.T) { t.Errorf("json.Marshal()= %s, want %s", got, want) } var out TableIdent - err = json.Unmarshal(b, &out) + if err := json.Unmarshal(b, &out); err != nil { + t.Errorf("Unmarshal err: %v, want nil", err) + } if !reflect.DeepEqual(out, str) { t.Errorf("Unmarshal: %v, want %v", out, str) } diff --git a/go/vt/sqlparser/normalizer_test.go b/go/vt/sqlparser/normalizer_test.go index 9f6742c61e0..b9b1a17d1d7 100644 --- a/go/vt/sqlparser/normalizer_test.go +++ b/go/vt/sqlparser/normalizer_test.go @@ -201,6 +201,6 @@ func TestGetBindVars(t *testing.T) { "v5": {}, } if !reflect.DeepEqual(got, want) { - t.Errorf("GetBindVars: %v, wnat %v", got, want) + t.Errorf("GetBindVars: %v, want: %v", got, want) } } diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index 8c34316f044..fd7d24f3db9 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -1101,6 +1101,17 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 224, 0, 0, 0, 0, 0, 98, 0, 0, 0, + 72, 0, 102, 96, 113, 0, 97, 101, 85, 107, + 65, 111, 105, 89, 80, 81, 64, 0, 100, 75, + 79, 74, 94, 108, 109, 73, 122, 68, 117, 67, + 69, 116, 93, 106, 112, 90, 87, 66, 110, 88, + 86, 82, 77, 0, 0, 0, 104, 114, 123, 95, + 0, 118, 119, 120, 92, 70, 0, 0, 76, 0, + 0, 0, 0, 0, 84, 0, 0, 103, 91, 0, + 0, 63, 0, 83, 121, 99, 78, 115, 0, 0, + 0, 0, 0, 0, 0, 61, 0, 0, 536, 0, + 0, 537, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 99, 0, 0, 0, 73, @@ -1117,6 +1128,19 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, + 0, 0, 0, 0, 98, 0, 0, 0, 72, 0, + 102, 96, 113, 0, 97, 101, 85, 107, 65, 111, + 105, 89, 80, 81, 64, 0, 100, 75, 79, 74, + 94, 108, 109, 73, 122, 68, 117, 67, 69, 116, + 93, 106, 112, 90, 87, 66, 110, 88, 86, 82, + 77, 0, 0, 0, 104, 114, 123, 0, 0, 118, + 119, 120, 92, 70, 0, 0, 0, 0, 0, 0, + 0, 95, 0, 0, 0, 382, 0, 0, 0, 63, + 76, 83, 121, 99, 78, 115, 84, 0, 0, 103, + 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 226, 0, 384, + 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 99, 0, 0, 0, 73, 0, 103, @@ -1134,6 +1158,17 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 224, 0, 0, 0, 0, 0, 98, 0, 0, 0, + 72, 0, 102, 96, 113, 0, 97, 101, 85, 107, + 65, 111, 105, 89, 80, 81, 64, 0, 100, 75, + 79, 74, 94, 108, 109, 73, 122, 68, 117, 67, + 69, 116, 93, 106, 112, 90, 87, 66, 110, 88, + 86, 82, 77, 0, 0, 0, 104, 114, 123, 95, + 0, 118, 119, 120, 92, 70, 0, 0, 76, 0, + 0, 0, 0, 0, 84, 0, 0, 103, 91, 0, + 0, 63, 0, 83, 121, 99, 78, 115, 0, 0, + 0, 0, 40, 0, 0, 226, 0, 0, 0, 0, + 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 99, 0, 0, 0, 73, @@ -1150,6 +1185,18 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, + 0, 0, 0, 0, 98, 0, 0, 0, 72, 0, + 102, 96, 113, 0, 97, 101, 85, 107, 65, 111, + 105, 89, 80, 81, 64, 0, 100, 75, 79, 74, + 94, 108, 109, 73, 122, 68, 117, 67, 69, 116, + 93, 106, 112, 90, 87, 66, 110, 88, 86, 82, + 77, 0, 0, 0, 104, 114, 123, 95, 0, 118, + 119, 120, 92, 70, 0, 0, 76, 0, 0, 0, + 0, 0, 84, 0, 0, 103, 91, 0, 0, 63, + 0, 83, 121, 99, 78, 115, 0, 0, 0, 0, + 0, 0, 0, 61, 0, 798, 0, 0, 0, 0, + 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 99, 0, 0, 0, 73, 0, 103, @@ -1166,6 +1213,18 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, + 0, 0, 98, 0, 0, 0, 72, 0, 102, 96, + 113, 0, 97, 101, 85, 107, 65, 111, 105, 89, + 80, 81, 64, 0, 100, 75, 79, 74, 94, 108, + 109, 73, 122, 68, 117, 67, 69, 116, 93, 106, + 112, 90, 87, 66, 110, 88, 86, 82, 77, 0, + 0, 0, 104, 114, 123, 95, 0, 118, 119, 120, + 92, 70, 0, 0, 76, 0, 0, 0, 0, 0, + 84, 0, 0, 103, 91, 0, 0, 63, 0, 83, + 121, 99, 78, 115, 0, 0, 0, 0, 0, 0, + 0, 226, 0, 384, 0, 0, 0, 0, 0, 0, + 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 99, 0, 0, 0, 73, 0, 103, 97, 0, @@ -1277,6 +1336,17 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, + 0, 98, 0, 0, 0, 72, 0, 102, 96, 113, + 0, 97, 101, 85, 107, 65, 111, 105, 89, 80, + 81, 64, 0, 100, 75, 79, 74, 94, 108, 109, + 73, 122, 68, 117, 67, 69, 116, 93, 106, 112, + 90, 87, 66, 110, 88, 86, 82, 77, 0, 0, + 0, 104, 114, 123, 95, 0, 118, 119, 120, 92, + 70, 0, 0, 76, 0, 0, 0, 0, 0, 84, + 0, 0, 103, 91, 0, 0, 63, 0, 83, 121, + 99, 78, 115, 0, 0, 0, 0, 0, 0, 0, + 270, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 99, 0, 0, 0, 73, 0, 103, 97, 0, 0, 98, 102, @@ -1293,6 +1363,13 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 224, 0, 0, 0, 0, 0, 98, + 0, 0, 0, 72, 0, 102, 96, 113, 0, 97, + 101, 85, 107, 65, 111, 105, 89, 80, 81, 64, + 0, 100, 75, 79, 74, 94, 108, 109, 73, 122, + 68, 117, 67, 264, 116, 93, 106, 112, 90, 87, + 66, 110, 88, 86, 82, 77, 0, 0, 0, 104, + 114, 123, 0, 0, 118, 119, 120, 265, 263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 99, 0, 0, 0, 73, 0, 103, 97, 0, 0, 98, 102, 86, 108, diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index ffd724e0599..b89e75d7618 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -989,7 +989,7 @@ drop_statement: } $$ = &DDL{Action: DropStr, Table: $4, IfExists: exists} } -| DROP INDEX ID ON table_name +| DROP INDEX ID ON table_name ddl_force_eof { // Change this to an alter statement $$ = &DDL{Action: AlterStr, Table: $5, NewName: $5} diff --git a/go/vt/sqlparser/token_test.go b/go/vt/sqlparser/token_test.go index 30257b602fb..93543545178 100644 --- a/go/vt/sqlparser/token_test.go +++ b/go/vt/sqlparser/token_test.go @@ -136,3 +136,56 @@ func TestString(t *testing.T) { } } } + +func TestSplitStatement(t *testing.T) { + testcases := []struct { + in string + sql string + rem string + }{{ + in: "select * from table", + sql: "select * from table", + }, { + in: "select * from table; ", + sql: "select * from table", + rem: " ", + }, { + in: "select * from table; select * from table2;", + sql: "select * from table", + rem: " select * from table2;", + }, { + in: "select * from /* comment */ table;", + sql: "select * from /* comment */ table", + }, { + in: "select * from /* comment ; */ table;", + sql: "select * from /* comment ; */ table", + }, { + in: "select * from table where semi = ';';", + sql: "select * from table where semi = ';'", + }, { + in: "-- select * from table", + sql: "-- select * from table", + }, { + in: " ", + sql: " ", + }, { + in: "", + sql: "", + }} + + for _, tcase := range testcases { + sql, rem, err := SplitStatement(tcase.in) + if err != nil { + t.Errorf("EndOfStatementPosition(%s): ERROR: %v", tcase.in, err) + continue + } + + if tcase.sql != sql { + t.Errorf("EndOfStatementPosition(%s) got sql \"%s\" want \"%s\"", tcase.in, sql, tcase.sql) + } + + if tcase.rem != rem { + t.Errorf("EndOfStatementPosition(%s) got remainder \"%s\" want \"%s\"", tcase.in, rem, tcase.rem) + } + } +} diff --git a/go/vt/sqlparser/truncate_query.go b/go/vt/sqlparser/truncate_query.go index ae0a9b6136f..c72e4658fa0 100644 --- a/go/vt/sqlparser/truncate_query.go +++ b/go/vt/sqlparser/truncate_query.go @@ -21,8 +21,10 @@ import ( ) var ( - // Maximum length for a query in a sqlerror string. 0 means unlimited. - TruncateUILen = flag.Int("sql-max-length-ui", 512, "truncate queries in debug UIs to the given length (default 512)") + // TruncateUILen truncate queries in debug UIs to the given length. 0 means unlimited. + TruncateUILen = flag.Int("sql-max-length-ui", 512, "truncate queries in debug UIs to the given length (default 512)") + + // TruncateErrLen truncate queries in error logs to the given length. 0 means unlimited. TruncateErrLen = flag.Int("sql-max-length-errors", 0, "truncate queries in error logs to the given length (default unlimited)") ) diff --git a/go/vt/vtexplain/vtexplain.go b/go/vt/vtexplain/vtexplain.go index 3d762cf6ab5..658ebc6cf35 100644 --- a/go/vt/vtexplain/vtexplain.go +++ b/go/vt/vtexplain/vtexplain.go @@ -146,7 +146,15 @@ func Init(vSchemaStr, sqlSchema string, opts *Options) error { func parseSchema(sqlSchema string) ([]*sqlparser.DDL, error) { parsedDDLs := make([]*sqlparser.DDL, 0, 16) - for _, sql := range strings.Split(sqlSchema, ";") { + for { + sql, rem, err := sqlparser.SplitStatement(sqlSchema) + sqlSchema = rem + if err != nil { + return nil, err + } + if sql == "" { + break + } s := sqlparser.StripLeadingComments(sql) s, _ = sqlparser.SplitTrailingComments(sql) s = strings.TrimSpace(s) @@ -181,6 +189,11 @@ func parseSchema(sqlSchema string) ([]*sqlparser.DDL, error) { func Run(sql string) ([]*Explain, error) { explains := make([]*Explain, 0, 16) + var ( + rem string + err error + ) + for { // Need to strip comments in a loop to handle multiple comments // in a row. @@ -191,11 +204,10 @@ func Run(sql string) ([]*Explain, error) { } sql = s } - rem := "" - idx := strings.Index(sql, ";") - if idx != -1 { - rem = sql[idx+1:] - sql = sql[:idx] + + sql, rem, err = sqlparser.SplitStatement(sql) + if err != nil { + return nil, err } if sql != "" { diff --git a/go/vt/vttablet/heartbeat/reader.go b/go/vt/vttablet/heartbeat/reader.go index 774d19f4d7a..afaf4ede255 100644 --- a/go/vt/vttablet/heartbeat/reader.go +++ b/go/vt/vttablet/heartbeat/reader.go @@ -49,6 +49,8 @@ const ( // table against the current time at read time. This value is reported in metrics and // also to the healthchecks. type Reader struct { + dbconfigs dbconfigs.DBConfigs + enabled bool interval time.Duration keyspaceShard string @@ -82,19 +84,24 @@ func NewReader(checker connpool.MySQLChecker, config tabletenv.TabletConfig) *Re } } +// InitDBConfig must be called before Init. +func (r *Reader) InitDBConfig(dbcfgs dbconfigs.DBConfigs) { + r.dbconfigs = dbcfgs +} + // Init does last minute initialization of db settings, such as dbName // and keyspaceShard -func (r *Reader) Init(dbc dbconfigs.DBConfigs, target query.Target) { +func (r *Reader) Init(target query.Target) { if !r.enabled { return } - r.dbName = sqlescape.EscapeID(dbc.SidecarDBName) + r.dbName = sqlescape.EscapeID(r.dbconfigs.SidecarDBName) r.keyspaceShard = fmt.Sprintf("%s:%s", target.Keyspace, target.Shard) } // Open starts the heartbeat ticker and opens the db pool. It may be called multiple // times, as long as it was closed since last invocation. -func (r *Reader) Open(dbc dbconfigs.DBConfigs) { +func (r *Reader) Open() { if !r.enabled { return } @@ -105,7 +112,7 @@ func (r *Reader) Open(dbc dbconfigs.DBConfigs) { } log.Info("Beginning heartbeat reads") - r.pool.Open(&dbc.App, &dbc.Dba, &dbc.AppDebug) + r.pool.Open(&r.dbconfigs.App, &r.dbconfigs.Dba, &r.dbconfigs.AppDebug) r.ticks.Start(func() { r.readHeartbeat() }) r.isOpen = true } diff --git a/go/vt/vttablet/heartbeat/writer.go b/go/vt/vttablet/heartbeat/writer.go index 4c085dbbc55..812c571b272 100644 --- a/go/vt/vttablet/heartbeat/writer.go +++ b/go/vt/vttablet/heartbeat/writer.go @@ -57,6 +57,8 @@ const ( // Writer runs on master tablets and writes heartbeats to the _vt.heartbeat // table at a regular interval, defined by heartbeat_interval. type Writer struct { + dbconfigs dbconfigs.DBConfigs + enabled bool interval time.Duration tabletAlias topodata.TabletAlias @@ -87,18 +89,23 @@ func NewWriter(checker connpool.MySQLChecker, alias topodata.TabletAlias, config } } +// InitDBConfig must be called before Init. +func (w *Writer) InitDBConfig(dbcfgs dbconfigs.DBConfigs) { + w.dbconfigs = dbcfgs +} + // Init runs at tablet startup and last minute initialization of db settings, and // creates the necessary tables for heartbeat. -func (w *Writer) Init(dbc dbconfigs.DBConfigs, target query.Target) error { +func (w *Writer) Init(target query.Target) error { if !w.enabled { return nil } w.mu.Lock() defer w.mu.Unlock() log.Info("Initializing heartbeat table.") - w.dbName = sqlescape.EscapeID(dbc.SidecarDBName) + w.dbName = sqlescape.EscapeID(w.dbconfigs.SidecarDBName) w.keyspaceShard = fmt.Sprintf("%s:%s", target.Keyspace, target.Shard) - err := w.initializeTables(&dbc.Dba) + err := w.initializeTables(&w.dbconfigs.Dba) if err != nil { w.recordError(err) return err @@ -111,7 +118,7 @@ func (w *Writer) Init(dbc dbconfigs.DBConfigs, target query.Target) error { // responsible for periodically writing to the heartbeat table. // Open may be called multiple times, as long as it was closed since // last invocation. -func (w *Writer) Open(dbc dbconfigs.DBConfigs) { +func (w *Writer) Open() { if !w.enabled { return } @@ -121,7 +128,7 @@ func (w *Writer) Open(dbc dbconfigs.DBConfigs) { return } log.Info("Beginning heartbeat writes") - w.pool.Open(&dbc.App, &dbc.Dba, &dbc.AppDebug) + w.pool.Open(&w.dbconfigs.App, &w.dbconfigs.Dba, &w.dbconfigs.AppDebug) w.ticks.Start(func() { w.writeHeartbeat() }) w.isOpen = true } diff --git a/go/vt/vttablet/tabletserver/messager/engine.go b/go/vt/vttablet/tabletserver/messager/engine.go index 53a8713383a..3ef51893094 100644 --- a/go/vt/vttablet/tabletserver/messager/engine.go +++ b/go/vt/vttablet/tabletserver/messager/engine.go @@ -46,6 +46,8 @@ type TabletService interface { // Engine is the engine for handling messages. type Engine struct { + dbconfigs dbconfigs.DBConfigs + mu sync.Mutex isOpen bool managers map[string]*messageManager @@ -72,12 +74,17 @@ func NewEngine(tsv TabletService, se *schema.Engine, config tabletenv.TabletConf } } +// InitDBConfig must be called before Open. +func (me *Engine) InitDBConfig(dbcfgs dbconfigs.DBConfigs) { + me.dbconfigs = dbcfgs +} + // Open starts the Engine service. -func (me *Engine) Open(dbconfigs dbconfigs.DBConfigs) error { +func (me *Engine) Open() error { if me.isOpen { return nil } - me.conns.Open(&dbconfigs.App, &dbconfigs.Dba, &dbconfigs.AppDebug) + me.conns.Open(&me.dbconfigs.App, &me.dbconfigs.Dba, &me.dbconfigs.AppDebug) me.se.RegisterNotifier("messages", me.schemaChanged) me.isOpen = true return nil diff --git a/go/vt/vttablet/tabletserver/messager/engine_test.go b/go/vt/vttablet/tabletserver/messager/engine_test.go index a01599a0256..9b010b7392e 100644 --- a/go/vt/vttablet/tabletserver/messager/engine_test.go +++ b/go/vt/vttablet/tabletserver/messager/engine_test.go @@ -261,11 +261,11 @@ func newTestEngine(db *fakesqldb.DB) *Engine { tsv := newFakeTabletServer() se := schema.NewEngine(tsv, config) te := NewEngine(tsv, se, config) - dbconfigs := dbconfigs.DBConfigs{ + te.InitDBConfig(dbconfigs.DBConfigs{ App: *db.ConnParams(), SidecarDBName: "_vt", - } - te.Open(dbconfigs) + }) + te.Open() return te } diff --git a/go/vt/vttablet/tabletserver/query_engine.go b/go/vt/vttablet/tabletserver/query_engine.go index b3f76b7a0f4..cf557d2b38e 100644 --- a/go/vt/vttablet/tabletserver/query_engine.go +++ b/go/vt/vttablet/tabletserver/query_engine.go @@ -244,9 +244,13 @@ func NewQueryEngine(checker connpool.MySQLChecker, se *schema.Engine, config tab return qe } +// InitDBConfig must be called before Open. +func (qe *QueryEngine) InitDBConfig(dbcfgs dbconfigs.DBConfigs) { + qe.dbconfigs = dbcfgs +} + // Open must be called before sending requests to QueryEngine. -func (qe *QueryEngine) Open(dbconfigs dbconfigs.DBConfigs) error { - qe.dbconfigs = dbconfigs +func (qe *QueryEngine) Open() error { qe.conns.Open(&qe.dbconfigs.App, &qe.dbconfigs.Dba, &qe.dbconfigs.AppDebug) conn, err := qe.conns.Get(tabletenv.LocalContext()) diff --git a/go/vt/vttablet/tabletserver/query_engine_test.go b/go/vt/vttablet/tabletserver/query_engine_test.go index 20ef702c144..59b78905c3f 100644 --- a/go/vt/vttablet/tabletserver/query_engine_test.go +++ b/go/vt/vttablet/tabletserver/query_engine_test.go @@ -29,11 +29,13 @@ import ( "github.com/youtube/vitess/go/mysql/fakesqldb" "github.com/youtube/vitess/go/sqltypes" - querypb "github.com/youtube/vitess/go/vt/proto/query" + "github.com/youtube/vitess/go/vt/dbconfigs" "github.com/youtube/vitess/go/vt/vttablet/tabletserver/planbuilder" "github.com/youtube/vitess/go/vt/vttablet/tabletserver/schema" "github.com/youtube/vitess/go/vt/vttablet/tabletserver/schema/schematest" "github.com/youtube/vitess/go/vt/vttablet/tabletserver/tabletenv" + + querypb "github.com/youtube/vitess/go/vt/proto/query" ) func TestStrictTransTables(t *testing.T) { @@ -43,14 +45,15 @@ func TestStrictTransTables(t *testing.T) { db.AddQuery(query, result) } testUtils := newTestUtils() - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) // Test default behavior. config := tabletenv.DefaultQsConfig // config.EnforceStrictTransTable is true by default. qe := NewQueryEngine(DummyChecker, schema.NewEngine(DummyChecker, config), config) - qe.se.Open(db.ConnParams()) - if err := qe.Open(dbconfigs); err != nil { + qe.InitDBConfig(dbcfgs) + qe.se.Open() + if err := qe.Open(); err != nil { t.Error(err) } qe.Close() @@ -64,7 +67,8 @@ func TestStrictTransTables(t *testing.T) { }, ) qe = NewQueryEngine(DummyChecker, schema.NewEngine(DummyChecker, config), config) - err := qe.Open(dbconfigs) + qe.InitDBConfig(dbcfgs) + err := qe.Open() wantErr := "require sql_mode to be STRICT_TRANS_TABLES: got ''" if err == nil || err.Error() != wantErr { t.Errorf("Open: %v, want %s", err, wantErr) @@ -74,8 +78,9 @@ func TestStrictTransTables(t *testing.T) { // Test that we succeed if the enforcement flag is off. config.EnforceStrictTransTables = false qe = NewQueryEngine(DummyChecker, schema.NewEngine(DummyChecker, config), config) - if err := qe.Open(dbconfigs); err != nil { - t.Error(err) + qe.InitDBConfig(dbcfgs) + if err := qe.Open(); err != nil { + t.Fatal(err) } qe.Close() } @@ -86,11 +91,11 @@ func TestGetPlanPanicDuetoEmptyQuery(t *testing.T) { for query, result := range schematest.Queries() { db.AddQuery(query, result) } - qe := newTestQueryEngine(10, 10*time.Second, true) testUtils := newTestUtils() - dbconfigs := testUtils.newDBConfigs(db) - qe.se.Open(db.ConnParams()) - qe.Open(dbconfigs) + dbcfgs := testUtils.newDBConfigs(db) + qe := newTestQueryEngine(10, 10*time.Second, true, dbcfgs) + qe.se.Open() + qe.Open() defer qe.Close() ctx := context.Background() @@ -108,11 +113,11 @@ func TestGetMessageStreamPlan(t *testing.T) { for query, result := range schematest.Queries() { db.AddQuery(query, result) } - qe := newTestQueryEngine(10, 10*time.Second, true) testUtils := newTestUtils() - dbconfigs := testUtils.newDBConfigs(db) - qe.se.Open(db.ConnParams()) - qe.Open(dbconfigs) + dbcfgs := testUtils.newDBConfigs(db) + qe := newTestQueryEngine(10, 10*time.Second, true, dbcfgs) + qe.se.Open() + qe.Open() defer qe.Close() plan, err := qe.GetMessageStreamPlan("msg") @@ -143,11 +148,11 @@ func TestQueryPlanCache(t *testing.T) { db.AddQuery("select * from test_table_01 where 1 != 1", &sqltypes.Result{}) db.AddQuery("select * from test_table_02 where 1 != 1", &sqltypes.Result{}) - qe := newTestQueryEngine(10, 10*time.Second, true) testUtils := newTestUtils() - dbconfigs := testUtils.newDBConfigs(db) - qe.se.Open(db.ConnParams()) - qe.Open(dbconfigs) + dbcfgs := testUtils.newDBConfigs(db) + qe := newTestQueryEngine(10, 10*time.Second, true, dbcfgs) + qe.se.Open() + qe.Open() defer qe.Close() ctx := context.Background() @@ -187,11 +192,11 @@ func TestNoQueryPlanCache(t *testing.T) { db.AddQuery("select * from test_table_01 where 1 != 1", &sqltypes.Result{}) db.AddQuery("select * from test_table_02 where 1 != 1", &sqltypes.Result{}) - qe := newTestQueryEngine(10, 10*time.Second, true) testUtils := newTestUtils() - dbconfigs := testUtils.newDBConfigs(db) - qe.se.Open(db.ConnParams()) - qe.Open(dbconfigs) + dbcfgs := testUtils.newDBConfigs(db) + qe := newTestQueryEngine(10, 10*time.Second, true, dbcfgs) + qe.se.Open() + qe.Open() defer qe.Close() ctx := context.Background() @@ -218,11 +223,11 @@ func TestStatsURL(t *testing.T) { } query := "select * from test_table_01" db.AddQuery("select * from test_table_01 where 1 != 1", &sqltypes.Result{}) - qe := newTestQueryEngine(10, 1*time.Second, true) testUtils := newTestUtils() - dbconfigs := testUtils.newDBConfigs(db) - qe.se.Open(db.ConnParams()) - qe.Open(dbconfigs) + dbcfgs := testUtils.newDBConfigs(db) + qe := newTestQueryEngine(10, 1*time.Second, true, dbcfgs) + qe.se.Open() + qe.Open() defer qe.Close() // warm up cache ctx := context.Background() @@ -246,9 +251,13 @@ func TestStatsURL(t *testing.T) { qe.ServeHTTP(response, request) } -func newTestQueryEngine(queryCacheSize int, idleTimeout time.Duration, strict bool) *QueryEngine { +func newTestQueryEngine(queryCacheSize int, idleTimeout time.Duration, strict bool, dbcfgs dbconfigs.DBConfigs) *QueryEngine { config := tabletenv.DefaultQsConfig config.QueryCacheSize = queryCacheSize config.IdleTimeout = float64(idleTimeout) / 1e9 - return NewQueryEngine(DummyChecker, schema.NewEngine(DummyChecker, config), config) + se := schema.NewEngine(DummyChecker, config) + qe := NewQueryEngine(DummyChecker, se, config) + se.InitDBConfig(dbcfgs) + qe.InitDBConfig(dbcfgs) + return qe } diff --git a/go/vt/vttablet/tabletserver/queryz_test.go b/go/vt/vttablet/tabletserver/queryz_test.go index 29498b2ec8b..9884329b654 100644 --- a/go/vt/vttablet/tabletserver/queryz_test.go +++ b/go/vt/vttablet/tabletserver/queryz_test.go @@ -26,6 +26,7 @@ import ( "testing" "time" + "github.com/youtube/vitess/go/vt/dbconfigs" "github.com/youtube/vitess/go/vt/sqlparser" "github.com/youtube/vitess/go/vt/vttablet/tabletserver/planbuilder" "github.com/youtube/vitess/go/vt/vttablet/tabletserver/schema" @@ -34,7 +35,7 @@ import ( func TestQueryzHandler(t *testing.T) { resp := httptest.NewRecorder() req, _ := http.NewRequest("GET", "/schemaz", nil) - qe := newTestQueryEngine(100, 10*time.Second, true) + qe := newTestQueryEngine(100, 10*time.Second, true, dbconfigs.DBConfigs{}) plan1 := &TabletPlan{ Plan: &planbuilder.Plan{ diff --git a/go/vt/vttablet/tabletserver/replication_watcher.go b/go/vt/vttablet/tabletserver/replication_watcher.go index ff74ba66415..4d5f4ab2221 100644 --- a/go/vt/vttablet/tabletserver/replication_watcher.go +++ b/go/vt/vttablet/tabletserver/replication_watcher.go @@ -40,6 +40,9 @@ import ( // replication stream. It can tell you the current event token, // and it will trigger schema reloads if a DDL is encountered. type ReplicationWatcher struct { + dbconfigs dbconfigs.DBConfigs + mysqld mysqlctl.MysqlDaemon + // Life cycle management vars isOpen bool cancel context.CancelFunc @@ -77,15 +80,21 @@ func NewReplicationWatcher(se *schema.Engine, config tabletenv.TabletConfig) *Re return rpw } +// InitDBConfig must be called before Open. +func (rpw *ReplicationWatcher) InitDBConfig(dbcfgs dbconfigs.DBConfigs, mysqld mysqlctl.MysqlDaemon) { + rpw.dbconfigs = dbcfgs + rpw.mysqld = mysqld +} + // Open starts the ReplicationWatcher service. -func (rpw *ReplicationWatcher) Open(dbconfigs dbconfigs.DBConfigs, mysqld mysqlctl.MysqlDaemon) { +func (rpw *ReplicationWatcher) Open() { if rpw.isOpen || !rpw.watchReplication { return } ctx, cancel := context.WithCancel(tabletenv.LocalContext()) rpw.cancel = cancel rpw.wg.Add(1) - go rpw.Process(ctx, dbconfigs, mysqld) + go rpw.Process(ctx, rpw.dbconfigs, rpw.mysqld) rpw.isOpen = true } diff --git a/go/vt/vttablet/tabletserver/schema/engine.go b/go/vt/vttablet/tabletserver/schema/engine.go index 91ef405e462..ce28b7a320c 100644 --- a/go/vt/vttablet/tabletserver/schema/engine.go +++ b/go/vt/vttablet/tabletserver/schema/engine.go @@ -33,6 +33,7 @@ import ( "github.com/youtube/vitess/go/stats" "github.com/youtube/vitess/go/timer" "github.com/youtube/vitess/go/vt/concurrency" + "github.com/youtube/vitess/go/vt/dbconfigs" "github.com/youtube/vitess/go/vt/sqlparser" "github.com/youtube/vitess/go/vt/vterrors" "github.com/youtube/vitess/go/vt/vttablet/tabletserver/connpool" @@ -48,6 +49,8 @@ type notifier func(full map[string]*Table, created, altered, dropped []string) // Engine stores the schema info and performs operations that // keep itself up-to-date. type Engine struct { + dbconfigs dbconfigs.DBConfigs + // mu protects the following fields. mu sync.Mutex isOpen bool @@ -89,9 +92,14 @@ func NewEngine(checker connpool.MySQLChecker, config tabletenv.TabletConfig) *En return se } +// InitDBConfig must be called before Open. +func (se *Engine) InitDBConfig(dbcfgs dbconfigs.DBConfigs) { + se.dbconfigs = dbcfgs +} + // Open initializes the Engine. Calling Open on an already // open engine is a no-op. -func (se *Engine) Open(dbaParams *mysql.ConnParams) error { +func (se *Engine) Open() error { se.mu.Lock() defer se.mu.Unlock() if se.isOpen { @@ -100,6 +108,7 @@ func (se *Engine) Open(dbaParams *mysql.ConnParams) error { start := time.Now() defer log.Infof("Time taken to load the schema: %v", time.Now().Sub(start)) ctx := tabletenv.LocalContext() + dbaParams := &se.dbconfigs.Dba se.conns.Open(dbaParams, dbaParams, dbaParams) conn, err := se.conns.Get(ctx) diff --git a/go/vt/vttablet/tabletserver/schema/engine_test.go b/go/vt/vttablet/tabletserver/schema/engine_test.go index b676a91ce25..31ac5472a1e 100644 --- a/go/vt/vttablet/tabletserver/schema/engine_test.go +++ b/go/vt/vttablet/tabletserver/schema/engine_test.go @@ -31,6 +31,7 @@ import ( "github.com/youtube/vitess/go/mysql" "github.com/youtube/vitess/go/mysql/fakesqldb" "github.com/youtube/vitess/go/sqltypes" + "github.com/youtube/vitess/go/vt/dbconfigs" "github.com/youtube/vitess/go/vt/sqlparser" "github.com/youtube/vitess/go/vt/vttablet/tabletserver/schema/schematest" "github.com/youtube/vitess/go/vt/vttablet/tabletserver/tabletenv" @@ -51,8 +52,8 @@ func TestOpenFailedDueToMissMySQLTime(t *testing.T) { {sqltypes.NewVarBinary("1427325875")}, }, }) - se := newEngine(10, 1*time.Second, 1*time.Second, false) - err := se.Open(db.ConnParams()) + se := newEngine(10, 1*time.Second, 1*time.Second, false, db) + err := se.Open() want := "could not get MySQL time" if err == nil || !strings.Contains(err.Error(), want) { t.Errorf("se.Open: %v, want %s", err, want) @@ -71,8 +72,8 @@ func TestOpenFailedDueToIncorrectMysqlRowNum(t *testing.T) { {sqltypes.NULL}, }, }) - se := newEngine(10, 1*time.Second, 1*time.Second, false) - err := se.Open(db.ConnParams()) + se := newEngine(10, 1*time.Second, 1*time.Second, false, db) + err := se.Open() want := "unexpected result for MySQL time" if err == nil || !strings.Contains(err.Error(), want) { t.Errorf("se.Open: %v, want %s", err, want) @@ -91,8 +92,8 @@ func TestOpenFailedDueToInvalidTimeFormat(t *testing.T) { {sqltypes.NewVarBinary("invalid_time")}, }, }) - se := newEngine(10, 1*time.Second, 1*time.Second, false) - err := se.Open(db.ConnParams()) + se := newEngine(10, 1*time.Second, 1*time.Second, false, db) + err := se.Open() want := "could not parse time" if err == nil || !strings.Contains(err.Error(), want) { t.Errorf("se.Open: %v, want %s", err, want) @@ -106,8 +107,8 @@ func TestOpenFailedDueToExecErr(t *testing.T) { db.AddQuery(query, result) } db.AddRejectedQuery(mysql.BaseShowTables, fmt.Errorf("injected error")) - se := newEngine(10, 1*time.Second, 1*time.Second, false) - err := se.Open(db.ConnParams()) + se := newEngine(10, 1*time.Second, 1*time.Second, false, db) + err := se.Open() want := "could not get table list" if err == nil || !strings.Contains(err.Error(), want) { t.Errorf("se.Open: %v, want %s", err, want) @@ -138,8 +139,8 @@ func TestOpenFailedDueToTableErr(t *testing.T) { {sqltypes.NewVarBinary("")}, }, }) - se := newEngine(10, 1*time.Second, 1*time.Second, false) - err := se.Open(db.ConnParams()) + se := newEngine(10, 1*time.Second, 1*time.Second, false, db) + err := se.Open() want := "could not get schema for any tables" if err == nil || !strings.Contains(err.Error(), want) { t.Errorf("se.Open: %v, want %s", err, want) @@ -154,8 +155,8 @@ func TestReload(t *testing.T) { db.AddQuery(query, result) } idleTimeout := 10 * time.Second - se := newEngine(10, 10*time.Second, idleTimeout, true) - se.Open(db.ConnParams()) + se := newEngine(10, 10*time.Second, idleTimeout, true, db) + se.Open() defer se.Close() // this new table does not exist newTable := sqlparser.NewTableIdent("test_table_04") @@ -235,8 +236,8 @@ func TestCreateOrUpdateTableFailedDuetoExecErr(t *testing.T) { db.AddQuery(query, result) } db.AddRejectedQuery(mysql.BaseShowTablesForTable("test_table"), fmt.Errorf("forced fail")) - se := newEngine(10, 1*time.Second, 1*time.Second, false) - se.Open(db.ConnParams()) + se := newEngine(10, 1*time.Second, 1*time.Second, false, db) + se.Open() defer se.Close() originalSchemaErrorCount := tabletenv.InternalErrors.Counts()["Schema"] // should silently fail: no errors returned, but increment a counter @@ -255,8 +256,8 @@ func TestCreateOrUpdateTable(t *testing.T) { for query, result := range schematest.Queries() { db.AddQuery(query, result) } - se := newEngine(10, 1*time.Second, 1*time.Second, false) - se.Open(db.ConnParams()) + se := newEngine(10, 1*time.Second, 1*time.Second, false, db) + se.Open() defer se.Close() existingTable := "test_table_01" db.AddQuery(mysql.BaseShowTablesForTable(existingTable), &sqltypes.Result{ @@ -298,8 +299,8 @@ func TestExportVars(t *testing.T) { for query, result := range schematest.Queries() { db.AddQuery(query, result) } - se := newEngine(10, 1*time.Second, 1*time.Second, true) - se.Open(db.ConnParams()) + se := newEngine(10, 1*time.Second, 1*time.Second, true, db) + se.Open() defer se.Close() expvar.Do(func(kv expvar.KeyValue) { _ = kv.Value.String() @@ -314,8 +315,8 @@ func TestUpdatedMysqlStats(t *testing.T) { db.AddQuery(query, result) } idleTimeout := 10 * time.Second - se := newEngine(10, 10*time.Second, idleTimeout, true) - se.Open(db.ConnParams()) + se := newEngine(10, 10*time.Second, idleTimeout, true, db) + se.Open() defer se.Close() // Add new table tableName := sqlparser.NewTableIdent("mysql_stats_test_table") @@ -406,8 +407,8 @@ func TestStatsURL(t *testing.T) { for query, result := range schematest.Queries() { db.AddQuery(query, result) } - se := newEngine(10, 1*time.Second, 1*time.Second, true) - se.Open(db.ConnParams()) + se := newEngine(10, 1*time.Second, 1*time.Second, true, db) + se.Open() defer se.Close() request, _ := http.NewRequest("GET", "/debug/schema", nil) @@ -422,10 +423,20 @@ func (dummyChecker) CheckMySQL() {} var DummyChecker = dummyChecker{} -func newEngine(queryCacheSize int, reloadTime time.Duration, idleTimeout time.Duration, strict bool) *Engine { +func newEngine(queryCacheSize int, reloadTime time.Duration, idleTimeout time.Duration, strict bool, db *fakesqldb.DB) *Engine { config := tabletenv.DefaultQsConfig config.QueryCacheSize = queryCacheSize config.SchemaReloadTime = float64(reloadTime) / 1e9 config.IdleTimeout = float64(idleTimeout) / 1e9 - return NewEngine(DummyChecker, config) + se := NewEngine(DummyChecker, config) + se.InitDBConfig(newDBConfigs(db)) + return se +} + +func newDBConfigs(db *fakesqldb.DB) dbconfigs.DBConfigs { + return dbconfigs.DBConfigs{ + App: *db.ConnParams(), + Dba: *db.ConnParams(), + SidecarDBName: "_vt", + } } diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index 8b74919d6ed..299d9097ed6 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -98,6 +98,19 @@ var stateName = []string{ } // TabletServer implements the RPC interface for the query service. +// TabletServer is initialized in the following sequence: +// NewTabletServer->InitDBConfig->SetServingType. +// Subcomponents of TabletServer are initialized using one of the +// following sequences: +// New->InitDBConfig->Init->Open, or New->InitDBConfig->Open. +// Essentially, InitDBConfig is a continuation of New. However, +// the db config is not initially available. For this reason, +// the initialization is done in two phases. +// Some subcomponents have Init functions. Such functions usually +// perform one-time initializations like creating metadata tables +// in the sidecar database. These functions must be idempotent. +// Open and Close can be called repeatedly during the lifetime of +// a subcomponent. These should also be idempotent. type TabletServer struct { QueryTimeout sync2.AtomicDuration BeginTimeout sync2.AtomicDuration @@ -290,31 +303,39 @@ func (tsv *TabletServer) IsServing() bool { // InitDBConfig inititalizes the db config variables for TabletServer. You must call this function before // calling SetServingType. -func (tsv *TabletServer) InitDBConfig(target querypb.Target, dbconfigs dbconfigs.DBConfigs, mysqld mysqlctl.MysqlDaemon) error { +func (tsv *TabletServer) InitDBConfig(target querypb.Target, dbcfgs dbconfigs.DBConfigs, mysqld mysqlctl.MysqlDaemon) error { tsv.mu.Lock() defer tsv.mu.Unlock() if tsv.state != StateNotConnected { return vterrors.Errorf(vtrpcpb.Code_UNKNOWN, "InitDBConfig failed, current state: %s", stateName[tsv.state]) } tsv.target = target - tsv.dbconfigs = dbconfigs + tsv.dbconfigs = dbcfgs // Massage Dba so that it inherits the // App values but keeps the credentials. - tsv.dbconfigs.Dba = dbconfigs.App - if n, p := dbconfigs.Dba.Uname, dbconfigs.Dba.Pass; n != "" { + tsv.dbconfigs.Dba = dbcfgs.App + if n, p := dbcfgs.Dba.Uname, dbcfgs.Dba.Pass; n != "" { tsv.dbconfigs.Dba.Uname = n tsv.dbconfigs.Dba.Pass = p } tsv.mysqld = mysqld + + tsv.se.InitDBConfig(tsv.dbconfigs) + tsv.qe.InitDBConfig(tsv.dbconfigs) + tsv.te.InitDBConfig(tsv.dbconfigs) + tsv.hw.InitDBConfig(tsv.dbconfigs) + tsv.hr.InitDBConfig(tsv.dbconfigs) + tsv.messager.InitDBConfig(tsv.dbconfigs) + tsv.watcher.InitDBConfig(tsv.dbconfigs, mysqld) return nil } // StartService is a convenience function for InitDBConfig->SetServingType // with serving=true. -func (tsv *TabletServer) StartService(target querypb.Target, dbconfigs dbconfigs.DBConfigs, mysqld mysqlctl.MysqlDaemon) (err error) { +func (tsv *TabletServer) StartService(target querypb.Target, dbcfgs dbconfigs.DBConfigs, mysqld mysqlctl.MysqlDaemon) (err error) { // Save tablet type away to prevent data races tabletType := target.TabletType - err = tsv.InitDBConfig(target, dbconfigs, mysqld) + err = tsv.InitDBConfig(target, dbcfgs, mysqld) if err != nil { return err } @@ -426,19 +447,19 @@ func (tsv *TabletServer) fullStart() (err error) { } c.Close() - if err := tsv.se.Open(&tsv.dbconfigs.Dba); err != nil { + if err := tsv.se.Open(); err != nil { return err } - if err := tsv.qe.Open(tsv.dbconfigs); err != nil { + if err := tsv.qe.Open(); err != nil { return err } - if err := tsv.te.Init(tsv.dbconfigs); err != nil { + if err := tsv.te.Init(); err != nil { return err } - if err := tsv.hw.Init(tsv.dbconfigs, tsv.target); err != nil { + if err := tsv.hw.Init(tsv.target); err != nil { return err } - tsv.hr.Init(tsv.dbconfigs, tsv.target) + tsv.hr.Init(tsv.target) tsv.updateStreamList.Init() return tsv.serveNewType() } @@ -449,13 +470,13 @@ func (tsv *TabletServer) serveNewType() (err error) { return err } tsv.watcher.Close() - tsv.te.Open(tsv.dbconfigs) - tsv.messager.Open(tsv.dbconfigs) + tsv.te.Open() + tsv.messager.Open() tsv.hr.Close() - tsv.hw.Open(tsv.dbconfigs) + tsv.hw.Open() } else { tsv.messager.Close() - tsv.hr.Open(tsv.dbconfigs) + tsv.hr.Open() tsv.hw.Close() // Wait for in-flight transactional requests to complete @@ -464,7 +485,7 @@ func (tsv *TabletServer) serveNewType() (err error) { // be sure that the tx pool won't change after the wait. tsv.txRequests.Wait() tsv.te.Close(true) - tsv.watcher.Open(tsv.dbconfigs, tsv.mysqld) + tsv.watcher.Open() tsv.txThrottler.Close() // Reset the sequences. diff --git a/go/vt/vttablet/tabletserver/tabletserver_test.go b/go/vt/vttablet/tabletserver/tabletserver_test.go index af2c62e8afa..c53aa1afec2 100644 --- a/go/vt/vttablet/tabletserver/tabletserver_test.go +++ b/go/vt/vttablet/tabletserver/tabletserver_test.go @@ -83,9 +83,9 @@ func TestTabletServerAllowQueriesFailBadConn(t *testing.T) { config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) checkTabletServerState(t, tsv, StateNotConnected) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err == nil { t.Fatalf("TabletServer.StartService should fail") } @@ -99,17 +99,17 @@ func TestTabletServerAllowQueries(t *testing.T) { config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) checkTabletServerState(t, tsv, StateNotConnected) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) tsv.setState(StateServing) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) tsv.StopService() want := "InitDBConfig failed" if err == nil || !strings.Contains(err.Error(), want) { t.Fatalf("TabletServer.StartService: %v, must contain %s", err, want) } tsv.setState(StateShuttingDown) - err = tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err = tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err == nil { t.Fatalf("TabletServer.StartService should fail") } @@ -124,14 +124,14 @@ func TestTabletServerInitDBConfig(t *testing.T) { tsv := NewTabletServerWithNilTopoServer(config) tsv.setState(StateServing) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - dbconfigs := testUtils.newDBConfigs(db) - err := tsv.InitDBConfig(target, dbconfigs, nil) + dbcfgs := testUtils.newDBConfigs(db) + err := tsv.InitDBConfig(target, dbcfgs, nil) want := "InitDBConfig failed" if err == nil || !strings.Contains(err.Error(), want) { t.Errorf("InitDBConfig: %v, must contain %s", err, want) } tsv.setState(StateNotConnected) - err = tsv.InitDBConfig(target, dbconfigs, nil) + err = tsv.InitDBConfig(target, dbcfgs, nil) if err != nil { t.Error(err) } @@ -144,8 +144,8 @@ func TestDecideAction(t *testing.T) { config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - dbconfigs := testUtils.newDBConfigs(db) - err := tsv.InitDBConfig(target, dbconfigs, nil) + dbcfgs := testUtils.newDBConfigs(db) + err := tsv.InitDBConfig(target, dbcfgs, nil) if err != nil { t.Error(err) } @@ -250,9 +250,9 @@ func TestSetServingType(t *testing.T) { testUtils := newTestUtils() config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.InitDBConfig(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.InitDBConfig(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Error(err) } @@ -332,10 +332,10 @@ func TestTabletServerSingleSchemaFailure(t *testing.T) { testUtils := newTestUtils() config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} originalSchemaErrorCount := tabletenv.InternalErrors.Counts()["Schema"] - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) defer tsv.StopService() if err != nil { t.Fatalf("TabletServer should successfully start even if a table's schema is unloadable, but got error: %v", err) @@ -364,9 +364,9 @@ func TestTabletServerAllSchemaFailure(t *testing.T) { testUtils := newTestUtils() config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) defer tsv.StopService() // tabletsever shouldn't start if it can't access schema for any tables wantErr := "could not get schema for any tables" @@ -381,9 +381,9 @@ func TestTabletServerCheckMysql(t *testing.T) { testUtils := newTestUtils() config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) defer tsv.StopService() if err != nil { t.Fatal(err) @@ -410,9 +410,9 @@ func TestTabletServerCheckMysqlFailInvalidConn(t *testing.T) { testUtils := newTestUtils() config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) defer tsv.StopService() if err != nil { t.Fatalf("TabletServer.StartService should succeed, but got error: %v", err) @@ -457,9 +457,9 @@ func TestTabletServerReconnect(t *testing.T) { testUtils := newTestUtils() config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) defer tsv.StopService() if tsv.GetState() != "SERVING" { @@ -488,8 +488,8 @@ func TestTabletServerReconnect(t *testing.T) { db = setUpTabletServerTest(t) db.AddQuery(query, want) db.AddQuery("select addr from test_table where 1 != 1", &sqltypes.Result{}) - dbconfigs = testUtils.newDBConfigs(db) - err = tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + dbcfgs = testUtils.newDBConfigs(db) + err = tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Error(err) } @@ -505,13 +505,13 @@ func TestTabletServerTarget(t *testing.T) { testUtils := newTestUtils() config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target1 := querypb.Target{ Keyspace: "test_keyspace", Shard: "test_shard", TabletType: topodatapb.TabletType_MASTER, } - err := tsv.StartService(target1, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target1, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Fatalf("StartService failed: %v", err) } @@ -965,9 +965,9 @@ func TestTabletServerBeginFail(t *testing.T) { config := testUtils.newQueryServiceConfig() config.TransactionCap = 1 tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Fatalf("StartService failed: %v", err) } @@ -1000,9 +1000,9 @@ func TestTabletServerCommitTransaction(t *testing.T) { db.AddQuery(executeSQL, executeSQLResult) config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Fatalf("StartService failed: %v", err) } @@ -1026,9 +1026,9 @@ func TestTabletServerCommiRollbacktFail(t *testing.T) { testUtils := newTestUtils() config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Fatalf("StartService failed: %v", err) } @@ -1063,9 +1063,9 @@ func TestTabletServerRollback(t *testing.T) { db.AddQuery(executeSQL, executeSQLResult) config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Fatalf("StartService failed: %v", err) } @@ -1167,9 +1167,9 @@ func TestTabletServerStreamExecute(t *testing.T) { config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Fatalf("StartService failed: %v", err) } @@ -1194,9 +1194,9 @@ func TestTabletServerExecuteBatch(t *testing.T) { db.AddQuery(expanedSQL, sqlResult) config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Fatalf("StartService failed: %v", err) } @@ -1218,9 +1218,9 @@ func TestTabletServerExecuteBatchFailEmptyQueryList(t *testing.T) { testUtils := newTestUtils() config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Fatalf("StartService failed: %v", err) } @@ -1239,9 +1239,9 @@ func TestTabletServerExecuteBatchFailAsTransaction(t *testing.T) { testUtils := newTestUtils() config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Fatalf("StartService failed: %v", err) } @@ -1267,9 +1267,9 @@ func TestTabletServerExecuteBatchBeginFail(t *testing.T) { db.AddRejectedQuery("begin", errRejected) config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Fatalf("StartService failed: %v", err) } @@ -1293,9 +1293,9 @@ func TestTabletServerExecuteBatchCommitFail(t *testing.T) { db.AddRejectedQuery("commit", errRejected) config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Fatalf("StartService failed: %v", err) } @@ -1332,9 +1332,9 @@ func TestTabletServerExecuteBatchSqlExecFailInTransaction(t *testing.T) { config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Fatalf("StartService failed: %v", err) } @@ -1375,9 +1375,9 @@ func TestTabletServerExecuteBatchSqlSucceedInTransaction(t *testing.T) { config := testUtils.newQueryServiceConfig() config.EnableAutoCommit = true tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Fatalf("StartService failed: %v", err) } @@ -1399,9 +1399,9 @@ func TestTabletServerExecuteBatchCallCommitWithoutABegin(t *testing.T) { testUtils := newTestUtils() config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Fatalf("StartService failed: %v", err) } @@ -1429,9 +1429,9 @@ func TestExecuteBatchNestedTransaction(t *testing.T) { db.AddQuery(expanedSQL, sqlResult) config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Fatalf("StartService failed: %v", err) } @@ -1481,9 +1481,9 @@ func TestSerializeTransactionsSameRow(t *testing.T) { // Reduce the txpool to 2 because we should never consume more than two slots. config.TransactionCap = 2 tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - if err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)); err != nil { + if err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)); err != nil { t.Fatalf("StartService failed: %v", err) } defer tsv.StopService() @@ -1608,9 +1608,9 @@ func TestSerializeTransactionsSameRow_ExecuteBatchAsTransaction(t *testing.T) { // Reduce the txpool to 2 because we should never consume more than two slots. config.TransactionCap = 2 tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - if err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)); err != nil { + if err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)); err != nil { t.Fatalf("StartService failed: %v", err) } defer tsv.StopService() @@ -1726,9 +1726,9 @@ func TestSerializeTransactionsSameRow_ConcurrentTransactions(t *testing.T) { // Reduce the txpool to 2 because we should never consume more than two slots. config.TransactionCap = 2 tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - if err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)); err != nil { + if err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)); err != nil { t.Fatalf("StartService failed: %v", err) } defer tsv.StopService() @@ -1867,9 +1867,9 @@ func TestSerializeTransactionsSameRow_TooManyPendingRequests(t *testing.T) { config.HotRowProtectionMaxQueueSize = 1 config.HotRowProtectionConcurrentTransactions = 1 tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - if err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)); err != nil { + if err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)); err != nil { t.Fatalf("StartService failed: %v", err) } defer tsv.StopService() @@ -1956,9 +1956,9 @@ func TestSerializeTransactionsSameRow_TooManyPendingRequests_ExecuteBatchAsTrans config.HotRowProtectionMaxQueueSize = 1 config.HotRowProtectionConcurrentTransactions = 1 tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - if err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)); err != nil { + if err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)); err != nil { t.Fatalf("StartService failed: %v", err) } defer tsv.StopService() @@ -2048,9 +2048,9 @@ func TestSerializeTransactionsSameRow_RequestCanceled(t *testing.T) { config.EnableHotRowProtection = true config.HotRowProtectionConcurrentTransactions = 1 tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - if err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)); err != nil { + if err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)); err != nil { t.Fatalf("StartService failed: %v", err) } defer tsv.StopService() @@ -2342,9 +2342,9 @@ func TestTabletServerSplitQuery(t *testing.T) { testUtils := newTestUtils() config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_RDONLY} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Fatalf("StartService failed: %v", err) } @@ -2373,9 +2373,9 @@ func TestTabletServerSplitQueryInvalidQuery(t *testing.T) { testUtils := newTestUtils() config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_RDONLY} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Fatalf("StartService failed: %v", err) } @@ -2403,9 +2403,9 @@ func TestTabletServerSplitQueryInvalidParams(t *testing.T) { testUtils := newTestUtils() config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_RDONLY} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Fatalf("StartService failed: %v", err) } @@ -2432,9 +2432,9 @@ func TestTabletServerSplitQueryEqualSplitsOnStringColumn(t *testing.T) { testUtils := newTestUtils() config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_RDONLY} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Fatalf("StartService failed: %v", err) } @@ -2680,9 +2680,9 @@ func TestConfigChanges(t *testing.T) { testUtils := newTestUtils() config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs)) + err := tsv.StartService(target, dbcfgs, testUtils.newMysqld(&dbcfgs)) if err != nil { t.Fatalf("StartService failed: %v", err) } diff --git a/go/vt/vttablet/tabletserver/testutils_test.go b/go/vt/vttablet/tabletserver/testutils_test.go index 66256ade822..da82f581ebf 100644 --- a/go/vt/vttablet/tabletserver/testutils_test.go +++ b/go/vt/vttablet/tabletserver/testutils_test.go @@ -65,6 +65,7 @@ func (util *testUtils) newMysqld(dbcfgs *dbconfigs.DBConfigs) mysqlctl.MysqlDaem func (util *testUtils) newDBConfigs(db *fakesqldb.DB) dbconfigs.DBConfigs { return dbconfigs.DBConfigs{ App: *db.ConnParams(), + Dba: *db.ConnParams(), SidecarDBName: "_vt", } } diff --git a/go/vt/vttablet/tabletserver/tx_engine.go b/go/vt/vttablet/tabletserver/tx_engine.go index 7f470d0418c..4199af09b1c 100644 --- a/go/vt/vttablet/tabletserver/tx_engine.go +++ b/go/vt/vttablet/tabletserver/tx_engine.go @@ -35,6 +35,8 @@ import ( // TxEngine handles transactions. type TxEngine struct { + dbconfigs dbconfigs.DBConfigs + isOpen, twopcEnabled bool shutdownGracePeriod time.Duration coordinatorAddress string @@ -90,28 +92,33 @@ func NewTxEngine(checker connpool.MySQLChecker, config tabletenv.TabletConfig) * return te } +// InitDBConfig must be called before Init. +func (te *TxEngine) InitDBConfig(dbcfgs dbconfigs.DBConfigs) { + te.dbconfigs = dbcfgs +} + // Init must be called once when vttablet starts for setting // up the metadata tables. -func (te *TxEngine) Init(dbconfigs dbconfigs.DBConfigs) error { +func (te *TxEngine) Init() error { if te.twopcEnabled { - return te.twoPC.Init(dbconfigs.SidecarDBName, &dbconfigs.Dba) + return te.twoPC.Init(te.dbconfigs.SidecarDBName, &te.dbconfigs.Dba) } return nil } // Open opens the TxEngine. If 2pc is enabled, it restores // all previously prepared transactions from the redo log. -func (te *TxEngine) Open(dbconfigs dbconfigs.DBConfigs) { +func (te *TxEngine) Open() { if te.isOpen { return } - te.txPool.Open(&dbconfigs.App, &dbconfigs.Dba, &dbconfigs.AppDebug) + te.txPool.Open(&te.dbconfigs.App, &te.dbconfigs.Dba, &te.dbconfigs.AppDebug) if !te.twopcEnabled { te.isOpen = true return } - te.twoPC.Open(dbconfigs) + te.twoPC.Open(te.dbconfigs) if err := te.prepareFromRedo(); err != nil { // If this operation fails, we choose to raise an alert and // continue anyway. Serving traffic is considered more important diff --git a/go/vt/vttablet/tabletserver/tx_engine_test.go b/go/vt/vttablet/tabletserver/tx_engine_test.go index 38c3a66e5c9..687c4fe622a 100644 --- a/go/vt/vttablet/tabletserver/tx_engine_test.go +++ b/go/vt/vttablet/tabletserver/tx_engine_test.go @@ -30,16 +30,17 @@ func TestTxEngineClose(t *testing.T) { db := setUpQueryExecutorTest(t) defer db.Close() testUtils := newTestUtils() - dbconfigs := testUtils.newDBConfigs(db) + dbcfgs := testUtils.newDBConfigs(db) ctx := context.Background() config := tabletenv.DefaultQsConfig config.TransactionCap = 10 config.TransactionTimeout = 0.5 config.TxShutDownGracePeriod = 0 te := NewTxEngine(nil, config) + te.InitDBConfig(dbcfgs) // Normal close. - te.Open(dbconfigs) + te.Open() start := time.Now() te.Close(false) if diff := time.Now().Sub(start); diff > 500*time.Millisecond { @@ -47,7 +48,7 @@ func TestTxEngineClose(t *testing.T) { } // Normal close with timeout wait. - te.Open(dbconfigs) + te.Open() c, err := te.txPool.LocalBegin(ctx, false, querypb.ExecuteOptions_DEFAULT) if err != nil { t.Fatal(err) @@ -60,7 +61,7 @@ func TestTxEngineClose(t *testing.T) { } // Immediate close. - te.Open(dbconfigs) + te.Open() c, err = te.txPool.LocalBegin(ctx, false, querypb.ExecuteOptions_DEFAULT) if err != nil { t.Fatal(err) @@ -74,7 +75,7 @@ func TestTxEngineClose(t *testing.T) { // Normal close with short grace period. te.shutdownGracePeriod = 250 * time.Millisecond - te.Open(dbconfigs) + te.Open() c, err = te.txPool.LocalBegin(ctx, false, querypb.ExecuteOptions_DEFAULT) if err != nil { t.Fatal(err) @@ -91,7 +92,7 @@ func TestTxEngineClose(t *testing.T) { // Normal close with short grace period, but pool gets empty early. te.shutdownGracePeriod = 250 * time.Millisecond - te.Open(dbconfigs) + te.Open() c, err = te.txPool.LocalBegin(ctx, false, querypb.ExecuteOptions_DEFAULT) if err != nil { t.Fatal(err) @@ -115,7 +116,7 @@ func TestTxEngineClose(t *testing.T) { } // Immediate close, but connection is in use. - te.Open(dbconfigs) + te.Open() c, err = te.txPool.LocalBegin(ctx, false, querypb.ExecuteOptions_DEFAULT) if err != nil { t.Fatal(err) diff --git a/go/vt/vttablet/tabletservermock/controller.go b/go/vt/vttablet/tabletservermock/controller.go index a3a45bd70cd..b588c46ed2e 100644 --- a/go/vt/vttablet/tabletservermock/controller.go +++ b/go/vt/vttablet/tabletservermock/controller.go @@ -102,7 +102,7 @@ func (tqsc *Controller) AddStatusPart() { } // InitDBConfig is part of the tabletserver.Controller interface -func (tqsc *Controller) InitDBConfig(target querypb.Target, dbConfigs dbconfigs.DBConfigs, mysqld mysqlctl.MysqlDaemon) error { +func (tqsc *Controller) InitDBConfig(target querypb.Target, dbcfgs dbconfigs.DBConfigs, mysqld mysqlctl.MysqlDaemon) error { tqsc.mu.Lock() defer tqsc.mu.Unlock() diff --git a/go/vt/vttest/local_cluster_old_test.go b/go/vt/vttest/local_cluster_old_test.go index e1669d91848..e578249e8b9 100644 --- a/go/vt/vttest/local_cluster_old_test.go +++ b/go/vt/vttest/local_cluster_old_test.go @@ -17,6 +17,7 @@ limitations under the License. package vttest import ( + "fmt" "io/ioutil" "os" "path/filepath" @@ -72,6 +73,8 @@ func TestVitess(t *testing.T) { } hdl, err := LaunchVitess(ProtoTopo(topology), Schema(schema), VSchema(vschema)) + fmt.Printf("sleeping\n") + time.Sleep(1 * time.Minute) if err != nil { t.Error(err) return diff --git a/web/vtctld2/app/index.html b/web/vtctld2/app/index.html index 14a769ee64b..7d834237d87 100644 --- a/web/vtctld2/app/index.html +++ b/web/vtctld2/app/index.html @@ -13,8 +13,8 @@