From 2083acea3780ac4756843bde6c03564d151bec63 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Fri, 27 Sep 2019 09:10:26 -0700 Subject: [PATCH 01/28] mysqlctl: GetSchema also returns field info Signed-off-by: Sugu Sougoumarane --- .../fakemysqldaemon/fakemysqldaemon.go | 7 +- go/vt/mysqlctl/fileutil.go | 11 +- go/vt/mysqlctl/mysql_daemon.go | 3 +- go/vt/mysqlctl/schema.go | 11 +- .../tabletmanagerdata/tabletmanagerdata.pb.go | 286 +++++++------ proto/tabletmanagerdata.proto | 4 + py/vtproto/tabletmanagerdata_pb2.py | 405 +++++++++--------- 7 files changed, 375 insertions(+), 352 deletions(-) diff --git a/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go b/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go index c1632bfbb04..6759edebeb4 100644 --- a/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go +++ b/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go @@ -33,6 +33,7 @@ import ( "vitess.io/vitess/go/vt/mysqlctl" "vitess.io/vitess/go/vt/mysqlctl/tmutils" + querypb "vitess.io/vitess/go/vt/proto/query" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" ) @@ -304,7 +305,7 @@ func (fmd *FakeMysqlDaemon) WaitForReparentJournal(ctx context.Context, timeCrea return nil } -// Deprecated: use mysqld.MasterPosition() instead +// DemoteMaster is deprecated: use mysqld.MasterPosition() instead func (fmd *FakeMysqlDaemon) DemoteMaster() (mysql.Position, error) { return fmd.CurrentMasterPosition, nil } @@ -412,8 +413,8 @@ func (fmd *FakeMysqlDaemon) GetSchema(dbName string, tables, excludeTables []str } // GetColumns is part of the MysqlDaemon interface -func (fmd *FakeMysqlDaemon) GetColumns(dbName, table string) ([]string, error) { - return []string{}, nil +func (fmd *FakeMysqlDaemon) GetColumns(dbName, table string) ([]*querypb.Field, []string, error) { + return []*querypb.Field{}, []string{}, nil } // GetPrimaryKeyColumns is part of the MysqlDaemon interface diff --git a/go/vt/mysqlctl/fileutil.go b/go/vt/mysqlctl/fileutil.go index f0b3ec856cf..4b479eab11c 100644 --- a/go/vt/mysqlctl/fileutil.go +++ b/go/vt/mysqlctl/fileutil.go @@ -20,18 +20,9 @@ import ( "encoding/hex" "hash" "hash/crc32" - "os" ) -// Use this to simulate failures in tests -var ( - simulateFailures = false -) - -func init() { - _, statErr := os.Stat("/tmp/vtSimulateFetchFailures") - simulateFailures = statErr == nil -} +// TODO(sougou): this file should be renamed. // our hasher, implemented using crc32 type hasher struct { diff --git a/go/vt/mysqlctl/mysql_daemon.go b/go/vt/mysqlctl/mysql_daemon.go index c76cec70a08..18d6d6816e0 100644 --- a/go/vt/mysqlctl/mysql_daemon.go +++ b/go/vt/mysqlctl/mysql_daemon.go @@ -24,6 +24,7 @@ import ( "vitess.io/vitess/go/vt/dbconnpool" "vitess.io/vitess/go/vt/mysqlctl/tmutils" + querypb "vitess.io/vitess/go/vt/proto/query" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" ) @@ -69,7 +70,7 @@ type MysqlDaemon interface { // Schema related methods GetSchema(dbName string, tables, excludeTables []string, includeViews bool) (*tabletmanagerdatapb.SchemaDefinition, error) - GetColumns(dbName, table string) ([]string, error) + GetColumns(dbName, table string) ([]*querypb.Field, []string, error) GetPrimaryKeyColumns(dbName, table string) ([]string, error) PreflightSchemaChange(dbName string, changes []string) ([]*tabletmanagerdatapb.SchemaChangeResult, error) ApplySchemaChange(dbName string, change *tmutils.SchemaChange) (*tabletmanagerdatapb.SchemaChangeResult, error) diff --git a/go/vt/mysqlctl/schema.go b/go/vt/mysqlctl/schema.go index 1c28895c03b..dd2a91e15d9 100644 --- a/go/vt/mysqlctl/schema.go +++ b/go/vt/mysqlctl/schema.go @@ -29,6 +29,7 @@ import ( "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/mysqlctl/tmutils" + querypb "vitess.io/vitess/go/vt/proto/query" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" ) @@ -122,7 +123,7 @@ func (mysqld *Mysqld) GetSchema(dbName string, tables, excludeTables []string, i td.Name = tableName td.Schema = norm - td.Columns, err = mysqld.GetColumns(dbName, tableName) + td.Fields, td.Columns, err = mysqld.GetColumns(dbName, tableName) if err != nil { return nil, err } @@ -159,21 +160,21 @@ func ResolveTables(mysqld MysqlDaemon, dbName string, tables []string) ([]string } // GetColumns returns the columns of table. -func (mysqld *Mysqld) GetColumns(dbName, table string) ([]string, error) { +func (mysqld *Mysqld) GetColumns(dbName, table string) ([]*querypb.Field, []string, error) { conn, err := getPoolReconnect(context.TODO(), mysqld.dbaPool) if err != nil { - return nil, err + return nil, nil, err } defer conn.Recycle() qr, err := conn.ExecuteFetch(fmt.Sprintf("SELECT * FROM %s.%s WHERE 1=0", sqlescape.EscapeID(dbName), sqlescape.EscapeID(table)), 0, true) if err != nil { - return nil, err + return nil, nil, err } columns := make([]string, len(qr.Fields)) for i, field := range qr.Fields { columns[i] = field.Name } - return columns, nil + return qr.Fields, columns, nil } diff --git a/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go b/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go index a5d42edf3b7..5ce79557270 100644 --- a/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go +++ b/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go @@ -5,9 +5,8 @@ package tabletmanagerdata import ( fmt "fmt" - math "math" - proto "github.com/golang/protobuf/proto" + math "math" logutil "vitess.io/vitess/go/vt/proto/logutil" query "vitess.io/vitess/go/vt/proto/query" replicationdata "vitess.io/vitess/go/vt/proto/replicationdata" @@ -39,10 +38,13 @@ type TableDefinition struct { // how much space the data file takes. DataLength uint64 `protobuf:"varint,6,opt,name=data_length,json=dataLength,proto3" json:"data_length,omitempty"` // approximate number of rows - RowCount uint64 `protobuf:"varint,7,opt,name=row_count,json=rowCount,proto3" json:"row_count,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + RowCount uint64 `protobuf:"varint,7,opt,name=row_count,json=rowCount,proto3" json:"row_count,omitempty"` + // column names along with their types. + // NOTE: this is a superset of columns. + Fields []*query.Field `protobuf:"bytes,8,rep,name=fields,proto3" json:"fields,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *TableDefinition) Reset() { *m = TableDefinition{} } @@ -119,6 +121,13 @@ func (m *TableDefinition) GetRowCount() uint64 { return 0 } +func (m *TableDefinition) GetFields() []*query.Field { + if m != nil { + return m.Fields + } + return nil +} + type SchemaDefinition struct { DatabaseSchema string `protobuf:"bytes,1,opt,name=database_schema,json=databaseSchema,proto3" json:"database_schema,omitempty"` TableDefinitions []*TableDefinition `protobuf:"bytes,2,rep,name=table_definitions,json=tableDefinitions,proto3" json:"table_definitions,omitempty"` @@ -3844,136 +3853,137 @@ func init() { func init() { proto.RegisterFile("tabletmanagerdata.proto", fileDescriptor_ff9ac4f89e61ffa4) } var fileDescriptor_ff9ac4f89e61ffa4 = []byte{ - // 2084 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x59, 0xdd, 0x6e, 0x1b, 0xc7, - 0xf5, 0x07, 0x49, 0x49, 0x96, 0x0e, 0x3f, 0x44, 0x2e, 0x29, 0x91, 0x92, 0xff, 0x91, 0xe4, 0xb5, - 0xf3, 0x8f, 0xeb, 0xa2, 0x54, 0xa2, 0xa4, 0x41, 0x90, 0x22, 0x45, 0x65, 0x7d, 0xd8, 0x4e, 0x94, - 0x58, 0x59, 0x59, 0x76, 0x11, 0x14, 0x58, 0x0c, 0xb9, 0x23, 0x72, 0xa1, 0xe5, 0xce, 0x7a, 0x66, - 0x96, 0x12, 0x5f, 0xa2, 0x4f, 0xd0, 0xbb, 0x02, 0xed, 0x7d, 0x2f, 0xfb, 0x20, 0x29, 0xfa, 0x24, - 0xbd, 0xe8, 0x4d, 0x31, 0x1f, 0x4b, 0xce, 0x92, 0x4b, 0x5b, 0x12, 0x5c, 0xa0, 0x37, 0x02, 0xcf, - 0xef, 0x9c, 0x39, 0x5f, 0x73, 0xce, 0x99, 0xb3, 0x10, 0x34, 0x39, 0xea, 0x04, 0x98, 0x0f, 0x50, - 0x88, 0x7a, 0x98, 0x7a, 0x88, 0xa3, 0x76, 0x44, 0x09, 0x27, 0x56, 0x6d, 0x86, 0xb1, 0x59, 0x7c, - 0x1b, 0x63, 0x3a, 0x52, 0xfc, 0xcd, 0x0a, 0x27, 0x11, 0x99, 0xc8, 0x6f, 0xae, 0x51, 0x1c, 0x05, - 0x7e, 0x17, 0x71, 0x9f, 0x84, 0x06, 0x5c, 0x0e, 0x48, 0x2f, 0xe6, 0x7e, 0xa0, 0x48, 0xfb, 0x9f, - 0x39, 0x58, 0x7d, 0x25, 0x14, 0x1f, 0xe2, 0x0b, 0x3f, 0xf4, 0x85, 0xb0, 0x65, 0xc1, 0x42, 0x88, - 0x06, 0xb8, 0x95, 0xdb, 0xc9, 0x3d, 0x5e, 0x71, 0xe4, 0x6f, 0x6b, 0x1d, 0x96, 0x58, 0xb7, 0x8f, - 0x07, 0xa8, 0x95, 0x97, 0xa8, 0xa6, 0xac, 0x16, 0xdc, 0xeb, 0x92, 0x20, 0x1e, 0x84, 0xac, 0x55, - 0xd8, 0x29, 0x3c, 0x5e, 0x71, 0x12, 0xd2, 0x6a, 0x43, 0x3d, 0xa2, 0xfe, 0x00, 0xd1, 0x91, 0x7b, - 0x89, 0x47, 0x6e, 0x22, 0xb5, 0x20, 0xa5, 0x6a, 0x9a, 0xf5, 0x1d, 0x1e, 0x1d, 0x68, 0x79, 0x0b, - 0x16, 0xf8, 0x28, 0xc2, 0xad, 0x45, 0x65, 0x55, 0xfc, 0xb6, 0xb6, 0xa1, 0x28, 0x5c, 0x77, 0x03, - 0x1c, 0xf6, 0x78, 0xbf, 0xb5, 0xb4, 0x93, 0x7b, 0xbc, 0xe0, 0x80, 0x80, 0x4e, 0x24, 0x62, 0xdd, - 0x87, 0x15, 0x4a, 0xae, 0xdc, 0x2e, 0x89, 0x43, 0xde, 0xba, 0x27, 0xd9, 0xcb, 0x94, 0x5c, 0x1d, - 0x08, 0xda, 0xfe, 0x4b, 0x0e, 0xaa, 0x67, 0xd2, 0x4d, 0x23, 0xb8, 0x4f, 0x60, 0x55, 0x9c, 0xef, - 0x20, 0x86, 0x5d, 0x1d, 0x91, 0x8a, 0xb3, 0x92, 0xc0, 0xea, 0x88, 0xf5, 0x12, 0x54, 0xc6, 0x5d, - 0x6f, 0x7c, 0x98, 0xb5, 0xf2, 0x3b, 0x85, 0xc7, 0xc5, 0x3d, 0xbb, 0x3d, 0x7b, 0x49, 0x53, 0x49, - 0x74, 0xaa, 0x3c, 0x0d, 0x30, 0x91, 0xaa, 0x21, 0xa6, 0xcc, 0x27, 0x61, 0xab, 0x20, 0x2d, 0x26, - 0xa4, 0x70, 0xd4, 0x52, 0x56, 0x0f, 0xfa, 0x28, 0xec, 0x61, 0x07, 0xb3, 0x38, 0xe0, 0xd6, 0x73, - 0x28, 0x77, 0xf0, 0x05, 0xa1, 0x29, 0x47, 0x8b, 0x7b, 0x0f, 0x33, 0xac, 0x4f, 0x87, 0xe9, 0x94, - 0xd4, 0x49, 0x1d, 0xcb, 0x31, 0x94, 0xd0, 0x05, 0xc7, 0xd4, 0x35, 0xee, 0xf0, 0x86, 0x8a, 0x8a, - 0xf2, 0xa0, 0x82, 0xed, 0x7f, 0xe5, 0xa0, 0x72, 0xce, 0x30, 0x3d, 0xc5, 0x74, 0xe0, 0x33, 0xa6, - 0x8b, 0xa5, 0x4f, 0x18, 0x4f, 0x8a, 0x45, 0xfc, 0x16, 0x58, 0xcc, 0x30, 0xd5, 0xa5, 0x22, 0x7f, - 0x5b, 0xbf, 0x84, 0x5a, 0x84, 0x18, 0xbb, 0x22, 0xd4, 0x73, 0xbb, 0x7d, 0xdc, 0xbd, 0x64, 0xf1, - 0x40, 0xe6, 0x61, 0xc1, 0xa9, 0x26, 0x8c, 0x03, 0x8d, 0x5b, 0x3f, 0x02, 0x44, 0xd4, 0x1f, 0xfa, - 0x01, 0xee, 0x61, 0x55, 0x32, 0xc5, 0xbd, 0xcf, 0x32, 0xbc, 0x4d, 0xfb, 0xd2, 0x3e, 0x1d, 0x9f, - 0x39, 0x0a, 0x39, 0x1d, 0x39, 0x86, 0x92, 0xcd, 0x6f, 0x60, 0x75, 0x8a, 0x6d, 0x55, 0xa1, 0x70, - 0x89, 0x47, 0xda, 0x73, 0xf1, 0xd3, 0x6a, 0xc0, 0xe2, 0x10, 0x05, 0x31, 0xd6, 0x9e, 0x2b, 0xe2, - 0xeb, 0xfc, 0x57, 0x39, 0xfb, 0xe7, 0x1c, 0x94, 0x0e, 0x3b, 0xef, 0x89, 0xbb, 0x02, 0x79, 0xaf, - 0xa3, 0xcf, 0xe6, 0xbd, 0xce, 0x38, 0x0f, 0x05, 0x23, 0x0f, 0x2f, 0x33, 0x42, 0xdb, 0xcd, 0x08, - 0xcd, 0x34, 0xf6, 0xdf, 0x0c, 0xec, 0xcf, 0x39, 0x28, 0x4e, 0x2c, 0x31, 0xeb, 0x04, 0xaa, 0xc2, - 0x4f, 0x37, 0x9a, 0x60, 0xad, 0x9c, 0xf4, 0xf2, 0xc1, 0x7b, 0x2f, 0xc0, 0x59, 0x8d, 0x53, 0x34, - 0xb3, 0x8e, 0xa1, 0xe2, 0x75, 0x52, 0xba, 0x54, 0x07, 0x6d, 0xbf, 0x27, 0x62, 0xa7, 0xec, 0x19, - 0x14, 0xb3, 0x3f, 0x81, 0xe2, 0xa9, 0x1f, 0xf6, 0x1c, 0xfc, 0x36, 0xc6, 0x8c, 0x8b, 0x56, 0x8a, - 0xd0, 0x28, 0x20, 0xc8, 0xd3, 0x41, 0x26, 0xa4, 0xfd, 0x18, 0x4a, 0x4a, 0x90, 0x45, 0x24, 0x64, - 0xf8, 0x1d, 0x92, 0x4f, 0xa0, 0x74, 0x16, 0x60, 0x1c, 0x25, 0x3a, 0x37, 0x61, 0xd9, 0x8b, 0xa9, - 0x1c, 0x97, 0x52, 0xb4, 0xe0, 0x8c, 0x69, 0x7b, 0x15, 0xca, 0x5a, 0x56, 0xa9, 0xb5, 0xff, 0x91, - 0x03, 0xeb, 0xe8, 0x1a, 0x77, 0x63, 0x8e, 0x9f, 0x13, 0x72, 0x99, 0xe8, 0xc8, 0x9a, 0x9c, 0x5b, - 0x00, 0x11, 0xa2, 0x68, 0x80, 0x39, 0xa6, 0x2a, 0xfc, 0x15, 0xc7, 0x40, 0xac, 0x53, 0x58, 0xc1, - 0xd7, 0x9c, 0x22, 0x17, 0x87, 0x43, 0x39, 0x43, 0x8b, 0x7b, 0x9f, 0x67, 0x64, 0x67, 0xd6, 0x5a, - 0xfb, 0x48, 0x1c, 0x3b, 0x0a, 0x87, 0xaa, 0x26, 0x96, 0xb1, 0x26, 0x37, 0x7f, 0x03, 0xe5, 0x14, - 0xeb, 0x56, 0xf5, 0x70, 0x01, 0xf5, 0x94, 0x29, 0x9d, 0xc7, 0x6d, 0x28, 0xe2, 0x6b, 0x9f, 0xbb, - 0x8c, 0x23, 0x1e, 0x33, 0x9d, 0x20, 0x10, 0xd0, 0x99, 0x44, 0xe4, 0x03, 0xc1, 0x3d, 0x12, 0xf3, - 0xf1, 0x03, 0x21, 0x29, 0x8d, 0x63, 0x9a, 0x74, 0x81, 0xa6, 0xec, 0x21, 0x54, 0x9f, 0x61, 0xae, - 0xe6, 0x4a, 0x92, 0xbe, 0x75, 0x58, 0x92, 0x81, 0xab, 0x8a, 0x5b, 0x71, 0x34, 0x65, 0x3d, 0x84, - 0xb2, 0x1f, 0x76, 0x83, 0xd8, 0xc3, 0xee, 0xd0, 0xc7, 0x57, 0x4c, 0x9a, 0x58, 0x76, 0x4a, 0x1a, - 0x7c, 0x2d, 0x30, 0xeb, 0x63, 0xa8, 0xe0, 0x6b, 0x25, 0xa4, 0x95, 0xa8, 0x07, 0xa9, 0xac, 0x51, - 0x39, 0xa0, 0x99, 0x8d, 0xa1, 0x66, 0xd8, 0xd5, 0xd1, 0x9d, 0x42, 0x4d, 0x4d, 0x46, 0x63, 0xd8, - 0xdf, 0x66, 0xda, 0x56, 0xd9, 0x14, 0x62, 0x37, 0x61, 0xed, 0x19, 0xe6, 0x46, 0x09, 0xeb, 0x18, - 0xed, 0x9f, 0x60, 0x7d, 0x9a, 0xa1, 0x9d, 0xf8, 0x1d, 0x14, 0xd3, 0x4d, 0x27, 0xcc, 0x6f, 0x65, - 0x98, 0x37, 0x0f, 0x9b, 0x47, 0xec, 0x06, 0x58, 0x67, 0x98, 0x3b, 0x18, 0x79, 0x2f, 0xc3, 0x60, - 0x94, 0x58, 0x5c, 0x83, 0x7a, 0x0a, 0xd5, 0x25, 0x3c, 0x81, 0xdf, 0x50, 0x9f, 0xe3, 0x44, 0x7a, - 0x1d, 0x1a, 0x69, 0x58, 0x8b, 0x7f, 0x0b, 0x35, 0xf5, 0x38, 0xbd, 0x1a, 0x45, 0x89, 0xb0, 0xf5, - 0x6b, 0x28, 0x2a, 0xf7, 0x5c, 0xf9, 0x74, 0x0b, 0x97, 0x2b, 0x7b, 0x8d, 0xf6, 0x78, 0x13, 0x91, - 0x39, 0xe7, 0xf2, 0x04, 0xf0, 0xf1, 0x6f, 0xe1, 0xa7, 0xa9, 0x6b, 0xe2, 0x90, 0x83, 0x2f, 0x28, - 0x66, 0x7d, 0x51, 0x52, 0xa6, 0x43, 0x69, 0x58, 0x8b, 0x37, 0x61, 0xcd, 0x89, 0xc3, 0xe7, 0x18, - 0x05, 0xbc, 0x2f, 0x1f, 0x8e, 0xe4, 0x40, 0x0b, 0xd6, 0xa7, 0x19, 0xfa, 0xc8, 0x17, 0xd0, 0x7a, - 0xd1, 0x0b, 0x09, 0xc5, 0x8a, 0x79, 0x44, 0x29, 0xa1, 0xa9, 0x91, 0xc2, 0x39, 0xa6, 0xe1, 0x64, - 0x50, 0x48, 0xd2, 0xbe, 0x0f, 0x1b, 0x19, 0xa7, 0xb4, 0xca, 0xaf, 0x85, 0xd3, 0x62, 0x9e, 0xa4, - 0x2b, 0xf9, 0x21, 0x94, 0xaf, 0x90, 0xcf, 0xdd, 0x88, 0xb0, 0x49, 0x31, 0xad, 0x38, 0x25, 0x01, - 0x9e, 0x6a, 0x4c, 0x45, 0x66, 0x9e, 0xd5, 0x3a, 0xf7, 0x60, 0xfd, 0x94, 0xe2, 0x8b, 0xc0, 0xef, - 0xf5, 0xa7, 0x1a, 0x44, 0x6c, 0x5b, 0x32, 0x71, 0x49, 0x87, 0x24, 0xa4, 0xdd, 0x83, 0xe6, 0xcc, - 0x19, 0x5d, 0x57, 0x27, 0x50, 0x51, 0x52, 0x2e, 0x95, 0x7b, 0x45, 0x32, 0xcf, 0x3f, 0x9e, 0x5b, - 0xd9, 0xe6, 0x16, 0xe2, 0x94, 0xbb, 0x06, 0xc5, 0xec, 0x7f, 0xe7, 0xc0, 0xda, 0x8f, 0xa2, 0x60, - 0x94, 0xf6, 0xac, 0x0a, 0x05, 0xf6, 0x36, 0x48, 0x46, 0x0c, 0x7b, 0x1b, 0x88, 0x11, 0x73, 0x41, - 0x68, 0x17, 0xeb, 0x66, 0x55, 0x84, 0x58, 0x03, 0x50, 0x10, 0x90, 0x2b, 0xd7, 0xd8, 0x4e, 0xe5, - 0x64, 0x58, 0x76, 0xaa, 0x92, 0xe1, 0x4c, 0xf0, 0xd9, 0x05, 0x68, 0xe1, 0x43, 0x2d, 0x40, 0x8b, - 0x77, 0x5c, 0x80, 0xfe, 0x9a, 0x83, 0x7a, 0x2a, 0x7a, 0x9d, 0xe3, 0xff, 0xbd, 0x55, 0xad, 0x0e, - 0xb5, 0x13, 0xd2, 0xbd, 0x54, 0x53, 0x2f, 0x69, 0x8d, 0x06, 0x58, 0x26, 0x38, 0x69, 0xbc, 0xf3, - 0x30, 0x98, 0x11, 0x5e, 0x87, 0x46, 0x1a, 0xd6, 0xe2, 0x7f, 0xcb, 0x41, 0x4b, 0x3f, 0x11, 0xc7, - 0x98, 0x77, 0xfb, 0xfb, 0xec, 0xb0, 0x33, 0xae, 0x83, 0x06, 0x2c, 0xca, 0x8f, 0x12, 0x99, 0x80, - 0x92, 0xa3, 0x08, 0xab, 0x09, 0xf7, 0xbc, 0x8e, 0x2b, 0x9f, 0x46, 0xfd, 0x3a, 0x78, 0x9d, 0x1f, - 0xc4, 0xe3, 0xb8, 0x01, 0xcb, 0x03, 0x74, 0xed, 0x52, 0x72, 0xc5, 0xf4, 0x32, 0x78, 0x6f, 0x80, - 0xae, 0x1d, 0x72, 0xc5, 0xe4, 0xa2, 0xee, 0x33, 0xb9, 0x81, 0x77, 0xfc, 0x30, 0x20, 0x3d, 0x26, - 0xaf, 0x7f, 0xd9, 0xa9, 0x68, 0xf8, 0xa9, 0x42, 0x45, 0xaf, 0x51, 0xd9, 0x46, 0xe6, 0xe5, 0x2e, - 0x3b, 0x25, 0x6a, 0xf4, 0x96, 0xfd, 0x0c, 0x36, 0x32, 0x7c, 0xd6, 0xb7, 0xf7, 0x04, 0x96, 0x54, - 0x6b, 0xe8, 0x6b, 0xb3, 0xda, 0xea, 0xc3, 0xea, 0x47, 0xf1, 0x57, 0xb7, 0x81, 0x96, 0xb0, 0xff, - 0x98, 0x83, 0x8f, 0xd2, 0x9a, 0xf6, 0x83, 0x40, 0x2c, 0x60, 0xec, 0xc3, 0xa7, 0x60, 0x26, 0xb2, - 0x85, 0x8c, 0xc8, 0x4e, 0x60, 0x6b, 0x9e, 0x3f, 0x77, 0x08, 0xef, 0xbb, 0xe9, 0xbb, 0xdd, 0x8f, - 0xa2, 0x77, 0x07, 0x66, 0xfa, 0x9f, 0x4f, 0xf9, 0x3f, 0x9b, 0x74, 0xa9, 0xec, 0x0e, 0x5e, 0x89, - 0x87, 0x2d, 0x40, 0x43, 0xac, 0x76, 0x8d, 0xa4, 0x40, 0x8f, 0xa1, 0x9e, 0x42, 0xb5, 0xe2, 0x5d, - 0xb1, 0x71, 0x8c, 0xb7, 0x94, 0xe2, 0x5e, 0xb3, 0x3d, 0xfd, 0x25, 0xac, 0x0f, 0x68, 0x31, 0xf1, - 0x92, 0x7c, 0x8f, 0x18, 0xc7, 0x34, 0x99, 0xcc, 0x89, 0x81, 0x2f, 0x60, 0x7d, 0x9a, 0xa1, 0x6d, - 0x6c, 0xc2, 0xf2, 0xd4, 0x68, 0x1f, 0xd3, 0xb6, 0x05, 0xd5, 0x33, 0x4e, 0x22, 0xe9, 0x5a, 0xa2, - 0xa9, 0x0e, 0x35, 0x03, 0xd3, 0x8d, 0xf4, 0x7b, 0x68, 0x8e, 0xc1, 0xef, 0xfd, 0xd0, 0x1f, 0xc4, - 0x03, 0x63, 0x19, 0x9d, 0xa7, 0xdf, 0x7a, 0x00, 0xf2, 0x19, 0x71, 0xb9, 0x3f, 0xc0, 0xc9, 0xbe, - 0x55, 0x70, 0x8a, 0x02, 0x7b, 0xa5, 0x20, 0xfb, 0x4b, 0x68, 0xcd, 0x6a, 0xbe, 0x81, 0xeb, 0xd2, - 0x4d, 0x44, 0x79, 0xca, 0x77, 0x91, 0x7c, 0x03, 0xd4, 0xce, 0xff, 0x01, 0xee, 0x4f, 0xd0, 0xf3, - 0x90, 0xfb, 0xc1, 0xbe, 0x98, 0x3e, 0x1f, 0x28, 0x80, 0x2d, 0xf8, 0xbf, 0x6c, 0xed, 0xda, 0xfa, - 0x21, 0x3c, 0x50, 0xbb, 0xc5, 0xd1, 0xb5, 0x78, 0xa3, 0x51, 0x20, 0x16, 0x9b, 0x08, 0x51, 0x1c, - 0x72, 0xec, 0x25, 0x3e, 0xc8, 0x9d, 0x55, 0xb1, 0x5d, 0x3f, 0xd9, 0xff, 0x21, 0x81, 0x5e, 0x78, - 0xf6, 0x23, 0xb0, 0xdf, 0xa5, 0x45, 0xdb, 0xda, 0x81, 0xad, 0x69, 0xa9, 0xa3, 0x00, 0x77, 0x27, - 0x86, 0xec, 0x07, 0xb0, 0x3d, 0x57, 0x42, 0x2b, 0xb1, 0xd4, 0xba, 0x2b, 0xc2, 0x19, 0xd7, 0xef, - 0x2f, 0xd4, 0x2a, 0xaa, 0x31, 0x7d, 0x3d, 0x0d, 0x58, 0x44, 0x9e, 0x47, 0x93, 0x07, 0x5e, 0x11, - 0xf6, 0x06, 0x34, 0x1d, 0xcc, 0xc4, 0x5e, 0x36, 0xae, 0xe4, 0x44, 0xcb, 0x26, 0xb4, 0x66, 0x59, - 0xda, 0xea, 0x2e, 0x34, 0x5f, 0x1b, 0xb8, 0x68, 0xc6, 0xcc, 0x66, 0x5e, 0xd1, 0xcd, 0x6c, 0x1f, - 0x43, 0x6b, 0xf6, 0xc0, 0x9d, 0xc6, 0xc8, 0x47, 0xa6, 0x9e, 0x37, 0xc8, 0xe7, 0xc7, 0x44, 0xb4, - 0x51, 0x62, 0xbe, 0x02, 0x79, 0x7d, 0x25, 0x05, 0x27, 0xef, 0x7b, 0xa9, 0x7a, 0xc9, 0x4f, 0x55, - 0xe5, 0x0e, 0x6c, 0xcd, 0x53, 0xa6, 0xe3, 0xac, 0x43, 0xed, 0x45, 0xe8, 0x73, 0xd5, 0xac, 0x49, - 0x62, 0x3e, 0x05, 0xcb, 0x04, 0x6f, 0x50, 0xfe, 0x3f, 0xe7, 0x60, 0xeb, 0x94, 0x44, 0x71, 0x20, - 0xf7, 0x4c, 0x55, 0x08, 0xdf, 0x92, 0x58, 0xdc, 0x68, 0xe2, 0xf7, 0xff, 0xc3, 0xaa, 0x28, 0x5b, - 0xb7, 0x4b, 0x31, 0xe2, 0xd8, 0x73, 0xc3, 0xe4, 0x5b, 0xa8, 0x2c, 0xe0, 0x03, 0x85, 0xfe, 0xc0, - 0x44, 0xed, 0xa1, 0xae, 0x50, 0x6a, 0x8e, 0x7c, 0x50, 0x90, 0x1c, 0xfb, 0x5f, 0x41, 0x69, 0x20, - 0x3d, 0x73, 0x51, 0xe0, 0x23, 0x35, 0xfa, 0x8b, 0x7b, 0x6b, 0xd3, 0xbb, 0xf3, 0xbe, 0x60, 0x3a, - 0x45, 0x25, 0x2a, 0x09, 0xeb, 0x33, 0x68, 0x18, 0x03, 0x6d, 0xb2, 0x62, 0x2e, 0x48, 0x1b, 0x75, - 0x83, 0x37, 0xde, 0x34, 0x1f, 0xc0, 0xf6, 0xdc, 0xb8, 0x74, 0x0a, 0xff, 0x94, 0x83, 0xaa, 0x48, - 0x97, 0xd9, 0xfa, 0xd6, 0xaf, 0x60, 0x49, 0x49, 0xeb, 0x2b, 0x9f, 0xe3, 0x9e, 0x16, 0x9a, 0xeb, - 0x59, 0x7e, 0xae, 0x67, 0x59, 0xf9, 0x2c, 0x64, 0xe4, 0x33, 0xb9, 0xe1, 0xf4, 0x0c, 0x5a, 0x83, - 0xfa, 0x21, 0x1e, 0x10, 0x8e, 0xd3, 0x17, 0xbf, 0x07, 0x8d, 0x34, 0x7c, 0x83, 0xab, 0xdf, 0x80, - 0xe6, 0x79, 0xe8, 0x91, 0x2c, 0x75, 0x9b, 0xd0, 0x9a, 0x65, 0x69, 0x0f, 0xbe, 0x81, 0xed, 0x53, - 0x4a, 0x04, 0x43, 0x7a, 0xf6, 0xa6, 0x8f, 0xc3, 0x03, 0x14, 0xf7, 0xfa, 0xfc, 0x3c, 0xba, 0xc1, - 0x24, 0xb4, 0x7f, 0x0b, 0x3b, 0xf3, 0x8f, 0xdf, 0xcc, 0x6b, 0x75, 0x10, 0x31, 0xad, 0xc7, 0x33, - 0xbc, 0x9e, 0x65, 0x69, 0xaf, 0xff, 0x9e, 0x83, 0xea, 0x19, 0x4e, 0xb7, 0xcb, 0x6d, 0xef, 0x3a, - 0xe3, 0xe2, 0xf2, 0x59, 0x8d, 0x30, 0xf3, 0x25, 0xb4, 0x30, 0xfb, 0x25, 0x64, 0x3d, 0x81, 0x9a, - 0xfc, 0x3c, 0x70, 0x99, 0x18, 0xfa, 0x2e, 0x13, 0x8e, 0xeb, 0xaf, 0x82, 0x55, 0xc9, 0x98, 0x3c, - 0x06, 0xf2, 0x8d, 0xc2, 0x53, 0x5d, 0x6d, 0xbf, 0x98, 0x44, 0xeb, 0x60, 0xa9, 0x64, 0xf2, 0x0c, - 0xdc, 0x2e, 0x30, 0xf1, 0xb9, 0x97, 0xa1, 0x4a, 0xdb, 0x79, 0x04, 0xb6, 0x78, 0x58, 0x8d, 0x69, - 0xb4, 0x1f, 0x7a, 0x62, 0x88, 0xa7, 0x16, 0x93, 0xd7, 0xf0, 0xf0, 0x9d, 0x52, 0x77, 0x5d, 0x54, - 0xd6, 0xa0, 0x6e, 0x96, 0x8b, 0x51, 0xef, 0x69, 0xf8, 0x06, 0x95, 0x73, 0x06, 0xe5, 0xa7, 0xa8, - 0x7b, 0x19, 0x8f, 0xcb, 0x74, 0x07, 0x8a, 0x5d, 0x12, 0x76, 0x63, 0x4a, 0x71, 0xd8, 0x1d, 0xe9, - 0xa1, 0x66, 0x42, 0x42, 0x42, 0x7e, 0xa1, 0xa9, 0xd4, 0xeb, 0xcf, 0x3a, 0x13, 0xb2, 0xbf, 0x84, - 0x4a, 0xa2, 0x54, 0xbb, 0xf0, 0x08, 0x16, 0xf1, 0x70, 0x92, 0xfa, 0x4a, 0x3b, 0xf9, 0xef, 0xc3, - 0x91, 0x40, 0x1d, 0xc5, 0xd4, 0x4f, 0x18, 0x27, 0x14, 0x1f, 0x53, 0x32, 0x48, 0xf9, 0x65, 0xef, - 0xc3, 0x46, 0x06, 0xef, 0x36, 0xea, 0x9f, 0x7e, 0xfa, 0x53, 0x7b, 0xe8, 0x73, 0xcc, 0x58, 0xdb, - 0x27, 0xbb, 0xea, 0xd7, 0x6e, 0x8f, 0xec, 0x0e, 0xf9, 0xae, 0xfc, 0x1f, 0xc8, 0xee, 0xcc, 0xa7, - 0x55, 0x67, 0x49, 0x32, 0x3e, 0xff, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1b, 0x23, 0xb8, 0xcf, - 0x8d, 0x19, 0x00, 0x00, + // 2102 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x59, 0x5b, 0x6f, 0x1b, 0xc7, + 0xf5, 0x07, 0x49, 0x49, 0xa6, 0x0e, 0x2f, 0x22, 0x97, 0x94, 0x48, 0xc9, 0xff, 0xe8, 0xb2, 0x76, + 0xfe, 0x51, 0x5d, 0x94, 0x4a, 0x94, 0x34, 0x08, 0x52, 0xa4, 0xa8, 0xac, 0x8b, 0xed, 0x44, 0x89, + 0x95, 0x95, 0x65, 0x17, 0x41, 0x81, 0xc5, 0x90, 0x3b, 0x22, 0x17, 0x5a, 0xee, 0xac, 0x67, 0x66, + 0x29, 0xf1, 0x4b, 0xf4, 0x13, 0xf4, 0xad, 0x40, 0xfb, 0xde, 0xc7, 0x7e, 0x90, 0xf4, 0xa3, 0xf4, + 0xa1, 0x0f, 0x2d, 0xe6, 0xb2, 0xe4, 0x2c, 0x2f, 0xb6, 0x24, 0xb8, 0x40, 0x5f, 0x04, 0x9e, 0xdf, + 0x39, 0x73, 0x6e, 0x73, 0xce, 0x99, 0xb3, 0x10, 0x34, 0x38, 0x6a, 0x07, 0x98, 0xf7, 0x51, 0x88, + 0xba, 0x98, 0x7a, 0x88, 0xa3, 0x56, 0x44, 0x09, 0x27, 0x56, 0x75, 0x8a, 0xb1, 0x51, 0x78, 0x1b, + 0x63, 0x3a, 0x54, 0xfc, 0x8d, 0x32, 0x27, 0x11, 0x19, 0xcb, 0x6f, 0xac, 0x52, 0x1c, 0x05, 0x7e, + 0x07, 0x71, 0x9f, 0x84, 0x06, 0x5c, 0x0a, 0x48, 0x37, 0xe6, 0x7e, 0xa0, 0x48, 0xfb, 0xdf, 0x19, + 0x58, 0x79, 0x25, 0x14, 0x1f, 0xe1, 0x4b, 0x3f, 0xf4, 0x85, 0xb0, 0x65, 0xc1, 0x42, 0x88, 0xfa, + 0xb8, 0x99, 0xd9, 0xce, 0xec, 0x2e, 0x3b, 0xf2, 0xb7, 0xb5, 0x06, 0x4b, 0xac, 0xd3, 0xc3, 0x7d, + 0xd4, 0xcc, 0x4a, 0x54, 0x53, 0x56, 0x13, 0x1e, 0x74, 0x48, 0x10, 0xf7, 0x43, 0xd6, 0xcc, 0x6d, + 0xe7, 0x76, 0x97, 0x9d, 0x84, 0xb4, 0x5a, 0x50, 0x8b, 0xa8, 0xdf, 0x47, 0x74, 0xe8, 0x5e, 0xe1, + 0xa1, 0x9b, 0x48, 0x2d, 0x48, 0xa9, 0xaa, 0x66, 0x7d, 0x87, 0x87, 0x87, 0x5a, 0xde, 0x82, 0x05, + 0x3e, 0x8c, 0x70, 0x73, 0x51, 0x59, 0x15, 0xbf, 0xad, 0x2d, 0x28, 0x08, 0xd7, 0xdd, 0x00, 0x87, + 0x5d, 0xde, 0x6b, 0x2e, 0x6d, 0x67, 0x76, 0x17, 0x1c, 0x10, 0xd0, 0xa9, 0x44, 0xac, 0x87, 0xb0, + 0x4c, 0xc9, 0xb5, 0xdb, 0x21, 0x71, 0xc8, 0x9b, 0x0f, 0x24, 0x3b, 0x4f, 0xc9, 0xf5, 0xa1, 0xa0, + 0xad, 0xc7, 0xb0, 0x74, 0xe9, 0xe3, 0xc0, 0x63, 0xcd, 0xfc, 0x76, 0x6e, 0xb7, 0xb0, 0x5f, 0x6c, + 0xa9, 0x7c, 0x9d, 0x08, 0xd0, 0xd1, 0x3c, 0xfb, 0x2f, 0x19, 0xa8, 0x9c, 0xcb, 0x60, 0x8c, 0x14, + 0x7c, 0x02, 0x2b, 0xc2, 0x4a, 0x1b, 0x31, 0xec, 0xea, 0xb8, 0x55, 0x36, 0xca, 0x09, 0xac, 0x8e, + 0x58, 0x2f, 0x41, 0xdd, 0x8b, 0xeb, 0x8d, 0x0e, 0xb3, 0x66, 0x56, 0x9a, 0xb3, 0x5b, 0xd3, 0x57, + 0x39, 0x91, 0x6a, 0xa7, 0xc2, 0xd3, 0x00, 0x13, 0x09, 0x1d, 0x60, 0xca, 0x7c, 0x12, 0x36, 0x73, + 0xd2, 0x62, 0x42, 0x0a, 0x47, 0x2d, 0x65, 0xf5, 0xb0, 0x87, 0xc2, 0x2e, 0x76, 0x30, 0x8b, 0x03, + 0x6e, 0x3d, 0x87, 0x52, 0x1b, 0x5f, 0x12, 0x9a, 0x72, 0xb4, 0xb0, 0xff, 0x68, 0x86, 0xf5, 0xc9, + 0x30, 0x9d, 0xa2, 0x3a, 0xa9, 0x63, 0x39, 0x81, 0x22, 0xba, 0xe4, 0x98, 0xba, 0xc6, 0x4d, 0xdf, + 0x52, 0x51, 0x41, 0x1e, 0x54, 0xb0, 0xfd, 0xcf, 0x0c, 0x94, 0x2f, 0x18, 0xa6, 0x67, 0x98, 0xf6, + 0x7d, 0xc6, 0x74, 0x49, 0xf5, 0x08, 0xe3, 0x49, 0x49, 0x89, 0xdf, 0x02, 0x8b, 0x19, 0xa6, 0xba, + 0xa0, 0xe4, 0x6f, 0xeb, 0x97, 0x50, 0x8d, 0x10, 0x63, 0xd7, 0x84, 0x7a, 0x6e, 0xa7, 0x87, 0x3b, + 0x57, 0x2c, 0xee, 0xcb, 0x3c, 0x2c, 0x38, 0x95, 0x84, 0x71, 0xa8, 0x71, 0xeb, 0x47, 0x80, 0x88, + 0xfa, 0x03, 0x3f, 0xc0, 0x5d, 0xac, 0x0a, 0xab, 0xb0, 0xff, 0xd9, 0x0c, 0x6f, 0xd3, 0xbe, 0xb4, + 0xce, 0x46, 0x67, 0x8e, 0x43, 0x4e, 0x87, 0x8e, 0xa1, 0x64, 0xe3, 0x1b, 0x58, 0x99, 0x60, 0x5b, + 0x15, 0xc8, 0x5d, 0xe1, 0xa1, 0xf6, 0x5c, 0xfc, 0xb4, 0xea, 0xb0, 0x38, 0x40, 0x41, 0x8c, 0xb5, + 0xe7, 0x8a, 0xf8, 0x3a, 0xfb, 0x55, 0xc6, 0xfe, 0x39, 0x03, 0xc5, 0xa3, 0xf6, 0x7b, 0xe2, 0x2e, + 0x43, 0xd6, 0x6b, 0xeb, 0xb3, 0x59, 0xaf, 0x3d, 0xca, 0x43, 0xce, 0xc8, 0xc3, 0xcb, 0x19, 0xa1, + 0xed, 0xcd, 0x08, 0xcd, 0x34, 0xf6, 0xdf, 0x0c, 0xec, 0xcf, 0x19, 0x28, 0x8c, 0x2d, 0x31, 0xeb, + 0x14, 0x2a, 0xc2, 0x4f, 0x37, 0x1a, 0x63, 0xcd, 0x8c, 0xf4, 0x72, 0xe7, 0xbd, 0x17, 0xe0, 0xac, + 0xc4, 0x29, 0x9a, 0x59, 0x27, 0x50, 0xf6, 0xda, 0x29, 0x5d, 0xaa, 0x83, 0xb6, 0xde, 0x13, 0xb1, + 0x53, 0xf2, 0x0c, 0x8a, 0xd9, 0x9f, 0x40, 0xe1, 0xcc, 0x0f, 0xbb, 0x0e, 0x7e, 0x1b, 0x63, 0xc6, + 0x45, 0x2b, 0x45, 0x68, 0x18, 0x10, 0xe4, 0xe9, 0x20, 0x13, 0xd2, 0xde, 0x85, 0xa2, 0x12, 0x64, + 0x11, 0x09, 0x19, 0x7e, 0x87, 0xe4, 0x13, 0x28, 0x9e, 0x07, 0x18, 0x47, 0x89, 0xce, 0x0d, 0xc8, + 0x7b, 0x31, 0x95, 0x43, 0x55, 0x8a, 0xe6, 0x9c, 0x11, 0x6d, 0xaf, 0x40, 0x49, 0xcb, 0x2a, 0xb5, + 0xf6, 0x3f, 0x32, 0x60, 0x1d, 0xdf, 0xe0, 0x4e, 0xcc, 0xf1, 0x73, 0x42, 0xae, 0x12, 0x1d, 0xb3, + 0xe6, 0xeb, 0x26, 0x40, 0x84, 0x28, 0xea, 0x63, 0x8e, 0xa9, 0x0a, 0x7f, 0xd9, 0x31, 0x10, 0xeb, + 0x0c, 0x96, 0xf1, 0x0d, 0xa7, 0xc8, 0xc5, 0xe1, 0x40, 0x4e, 0xda, 0xc2, 0xfe, 0xe7, 0x33, 0xb2, + 0x33, 0x6d, 0xad, 0x75, 0x2c, 0x8e, 0x1d, 0x87, 0x03, 0x55, 0x13, 0x79, 0xac, 0xc9, 0x8d, 0xdf, + 0x40, 0x29, 0xc5, 0xba, 0x53, 0x3d, 0x5c, 0x42, 0x2d, 0x65, 0x4a, 0xe7, 0x71, 0x0b, 0x0a, 0xf8, + 0xc6, 0xe7, 0x2e, 0xe3, 0x88, 0xc7, 0x4c, 0x27, 0x08, 0x04, 0x74, 0x2e, 0x11, 0xf9, 0x8c, 0x70, + 0x8f, 0xc4, 0x7c, 0xf4, 0x8c, 0x48, 0x4a, 0xe3, 0x98, 0x26, 0x5d, 0xa0, 0x29, 0x7b, 0x00, 0x95, + 0x67, 0x98, 0xab, 0xb9, 0x92, 0xa4, 0x6f, 0x0d, 0x96, 0x64, 0xe0, 0xaa, 0xe2, 0x96, 0x1d, 0x4d, + 0x59, 0x8f, 0xa0, 0xe4, 0x87, 0x9d, 0x20, 0xf6, 0xb0, 0x3b, 0xf0, 0xf1, 0x35, 0x93, 0x26, 0xf2, + 0x4e, 0x51, 0x83, 0xaf, 0x05, 0x66, 0x7d, 0x0c, 0x65, 0x7c, 0xa3, 0x84, 0xb4, 0x12, 0xf5, 0x6c, + 0x95, 0x34, 0x2a, 0x07, 0x34, 0xb3, 0x31, 0x54, 0x0d, 0xbb, 0x3a, 0xba, 0x33, 0xa8, 0xaa, 0xc9, + 0x68, 0x0c, 0xfb, 0xbb, 0x4c, 0xdb, 0x0a, 0x9b, 0x40, 0xec, 0x06, 0xac, 0x3e, 0xc3, 0xdc, 0x28, + 0x61, 0x1d, 0xa3, 0xfd, 0x13, 0xac, 0x4d, 0x32, 0xb4, 0x13, 0xbf, 0x83, 0x42, 0xba, 0xe9, 0x84, + 0xf9, 0xcd, 0x19, 0xe6, 0xcd, 0xc3, 0xe6, 0x11, 0xbb, 0x0e, 0xd6, 0x39, 0xe6, 0x0e, 0x46, 0xde, + 0xcb, 0x30, 0x18, 0x26, 0x16, 0x57, 0xa1, 0x96, 0x42, 0x75, 0x09, 0x8f, 0xe1, 0x37, 0xd4, 0xe7, + 0x38, 0x91, 0x5e, 0x83, 0x7a, 0x1a, 0xd6, 0xe2, 0xdf, 0x42, 0x55, 0x3d, 0x4e, 0xaf, 0x86, 0x51, + 0x22, 0x6c, 0xfd, 0x1a, 0x0a, 0xca, 0x3d, 0x57, 0x3e, 0xf0, 0xc2, 0xe5, 0xf2, 0x7e, 0xbd, 0x35, + 0xda, 0x57, 0x64, 0xce, 0xb9, 0x3c, 0x01, 0x7c, 0xf4, 0x5b, 0xf8, 0x69, 0xea, 0x1a, 0x3b, 0xe4, + 0xe0, 0x4b, 0x8a, 0x59, 0x4f, 0x94, 0x94, 0xe9, 0x50, 0x1a, 0xd6, 0xe2, 0x0d, 0x58, 0x75, 0xe2, + 0xf0, 0x39, 0x46, 0x01, 0xef, 0xc9, 0x87, 0x23, 0x39, 0xd0, 0x84, 0xb5, 0x49, 0x86, 0x3e, 0xf2, + 0x05, 0x34, 0x5f, 0x74, 0x43, 0x42, 0xb1, 0x62, 0x1e, 0x53, 0x4a, 0x68, 0x6a, 0xa4, 0x70, 0x8e, + 0x69, 0x38, 0x1e, 0x14, 0x92, 0xb4, 0x1f, 0xc2, 0xfa, 0x8c, 0x53, 0x5a, 0xe5, 0xd7, 0xc2, 0x69, + 0x31, 0x4f, 0xd2, 0x95, 0xfc, 0x08, 0x4a, 0xd7, 0xc8, 0xe7, 0x6e, 0x44, 0xd8, 0xb8, 0x98, 0x96, + 0x9d, 0xa2, 0x00, 0xcf, 0x34, 0xa6, 0x22, 0x33, 0xcf, 0x6a, 0x9d, 0xfb, 0xb0, 0x76, 0x46, 0xf1, + 0x65, 0xe0, 0x77, 0x7b, 0x13, 0x0d, 0x22, 0x76, 0x32, 0x99, 0xb8, 0xa4, 0x43, 0x12, 0xd2, 0xee, + 0x42, 0x63, 0xea, 0x8c, 0xae, 0xab, 0x53, 0x28, 0x2b, 0x29, 0x97, 0xca, 0xbd, 0x22, 0x99, 0xe7, + 0x1f, 0xcf, 0xad, 0x6c, 0x73, 0x0b, 0x71, 0x4a, 0x1d, 0x83, 0x62, 0xf6, 0xbf, 0x32, 0x60, 0x1d, + 0x44, 0x51, 0x30, 0x4c, 0x7b, 0x56, 0x81, 0x1c, 0x7b, 0x1b, 0x24, 0x23, 0x86, 0xbd, 0x0d, 0xc4, + 0x88, 0xb9, 0x24, 0xb4, 0x83, 0x75, 0xb3, 0x2a, 0x42, 0xac, 0x01, 0x28, 0x08, 0xc8, 0xb5, 0x6b, + 0xec, 0xb0, 0x72, 0x32, 0xe4, 0x9d, 0x8a, 0x64, 0x38, 0x63, 0x7c, 0x7a, 0x01, 0x5a, 0xf8, 0x50, + 0x0b, 0xd0, 0xe2, 0x3d, 0x17, 0xa0, 0xbf, 0x66, 0xa0, 0x96, 0x8a, 0x5e, 0xe7, 0xf8, 0x7f, 0x6f, + 0x55, 0xab, 0x41, 0xf5, 0x94, 0x74, 0xae, 0xd4, 0xd4, 0x4b, 0x5a, 0xa3, 0x0e, 0x96, 0x09, 0x8e, + 0x1b, 0xef, 0x22, 0x0c, 0xa6, 0x84, 0xd7, 0xa0, 0x9e, 0x86, 0xb5, 0xf8, 0xdf, 0x32, 0xd0, 0xd4, + 0x4f, 0xc4, 0x09, 0xe6, 0x9d, 0xde, 0x01, 0x3b, 0x6a, 0x8f, 0xea, 0xa0, 0x0e, 0x8b, 0x72, 0x15, + 0x97, 0x09, 0x28, 0x3a, 0x8a, 0xb0, 0x1a, 0xf0, 0xc0, 0x6b, 0xbb, 0xf2, 0x69, 0xd4, 0xaf, 0x83, + 0xd7, 0xfe, 0x41, 0x3c, 0x8e, 0xeb, 0x90, 0xef, 0xa3, 0x1b, 0x97, 0x92, 0x6b, 0xa6, 0x97, 0xc1, + 0x07, 0x7d, 0x74, 0xe3, 0x90, 0x6b, 0x26, 0x17, 0x75, 0x9f, 0xc9, 0x0d, 0xbc, 0xed, 0x87, 0x01, + 0xe9, 0x32, 0x79, 0xfd, 0x79, 0xa7, 0xac, 0xe1, 0xa7, 0x0a, 0x15, 0xbd, 0x46, 0x65, 0x1b, 0x99, + 0x97, 0x9b, 0x77, 0x8a, 0xd4, 0xe8, 0x2d, 0xfb, 0x19, 0xac, 0xcf, 0xf0, 0x59, 0xdf, 0xde, 0x13, + 0x58, 0x52, 0xad, 0xa1, 0xaf, 0xcd, 0xd2, 0x9f, 0x13, 0x3f, 0x8a, 0xbf, 0xba, 0x0d, 0xb4, 0x84, + 0xfd, 0xc7, 0x0c, 0x7c, 0x94, 0xd6, 0x74, 0x10, 0x04, 0x62, 0x01, 0x63, 0x1f, 0x3e, 0x05, 0x53, + 0x91, 0x2d, 0xcc, 0x88, 0xec, 0x14, 0x36, 0xe7, 0xf9, 0x73, 0x8f, 0xf0, 0xbe, 0x9b, 0xbc, 0xdb, + 0x83, 0x28, 0x7a, 0x77, 0x60, 0xa6, 0xff, 0xd9, 0x94, 0xff, 0xd3, 0x49, 0x97, 0xca, 0xee, 0xe1, + 0x95, 0x78, 0xd8, 0x02, 0x34, 0xc0, 0x6a, 0xd7, 0x48, 0x0a, 0xf4, 0x04, 0x6a, 0x29, 0x54, 0x2b, + 0xde, 0x13, 0x1b, 0xc7, 0x68, 0x4b, 0x29, 0xec, 0x37, 0x5a, 0x93, 0xdf, 0xcb, 0xfa, 0x80, 0x16, + 0x13, 0x2f, 0xc9, 0xf7, 0x88, 0x71, 0x4c, 0x93, 0xc9, 0x9c, 0x18, 0xf8, 0x02, 0xd6, 0x26, 0x19, + 0xda, 0xc6, 0x06, 0xe4, 0x27, 0x46, 0xfb, 0x88, 0xb6, 0x2d, 0xa8, 0x9c, 0x73, 0x12, 0x49, 0xd7, + 0x12, 0x4d, 0x35, 0xa8, 0x1a, 0x98, 0x6e, 0xa4, 0xdf, 0x43, 0x63, 0x04, 0x7e, 0xef, 0x87, 0x7e, + 0x3f, 0xee, 0x1b, 0xcb, 0xe8, 0x3c, 0xfd, 0xd6, 0x0e, 0xc8, 0x67, 0xc4, 0xe5, 0x7e, 0x1f, 0x27, + 0xfb, 0x56, 0xce, 0x29, 0x08, 0xec, 0x95, 0x82, 0xec, 0x2f, 0xa1, 0x39, 0xad, 0xf9, 0x16, 0xae, + 0x4b, 0x37, 0x11, 0xe5, 0x29, 0xdf, 0x45, 0xf2, 0x0d, 0x50, 0x3b, 0xff, 0x07, 0x78, 0x38, 0x46, + 0x2f, 0x42, 0xee, 0x07, 0x07, 0x62, 0xfa, 0x7c, 0xa0, 0x00, 0x36, 0xe1, 0xff, 0x66, 0x6b, 0xd7, + 0xd6, 0x8f, 0x60, 0x47, 0xed, 0x16, 0xc7, 0x37, 0xe2, 0x8d, 0x46, 0x81, 0x58, 0x6c, 0x22, 0x44, + 0x71, 0xc8, 0xb1, 0x97, 0xf8, 0x20, 0x77, 0x56, 0xc5, 0x76, 0xfd, 0x64, 0xff, 0x87, 0x04, 0x7a, + 0xe1, 0xd9, 0x8f, 0xc1, 0x7e, 0x97, 0x16, 0x6d, 0x6b, 0x1b, 0x36, 0x27, 0xa5, 0x8e, 0x03, 0xdc, + 0x19, 0x1b, 0xb2, 0x77, 0x60, 0x6b, 0xae, 0x84, 0x56, 0x62, 0xa9, 0x75, 0x57, 0x84, 0x33, 0xaa, + 0xdf, 0x5f, 0xa8, 0x55, 0x54, 0x63, 0xfa, 0x7a, 0xea, 0xb0, 0x88, 0x3c, 0x8f, 0x26, 0x0f, 0xbc, + 0x22, 0xec, 0x75, 0x68, 0x38, 0x98, 0x89, 0xbd, 0x6c, 0x54, 0xc9, 0x89, 0x96, 0x0d, 0x68, 0x4e, + 0xb3, 0xb4, 0xd5, 0x3d, 0x68, 0xbc, 0x36, 0x70, 0xd1, 0x8c, 0x33, 0x9b, 0x79, 0x59, 0x37, 0xb3, + 0x7d, 0x02, 0xcd, 0xe9, 0x03, 0xf7, 0x1a, 0x23, 0x1f, 0x99, 0x7a, 0xde, 0x20, 0x9f, 0x9f, 0x10, + 0xd1, 0x46, 0x89, 0xf9, 0x32, 0x64, 0xf5, 0x95, 0xe4, 0x9c, 0xac, 0xef, 0xa5, 0xea, 0x25, 0x3b, + 0x51, 0x95, 0xdb, 0xb0, 0x39, 0x4f, 0x99, 0x8e, 0xb3, 0x06, 0xd5, 0x17, 0xa1, 0xcf, 0x55, 0xb3, + 0x26, 0x89, 0xf9, 0x14, 0x2c, 0x13, 0xbc, 0x45, 0xf9, 0xff, 0x9c, 0x81, 0xcd, 0x33, 0x12, 0xc5, + 0x81, 0xdc, 0x33, 0x55, 0x21, 0x7c, 0x4b, 0x62, 0x71, 0xa3, 0x89, 0xdf, 0xff, 0x0f, 0x2b, 0xa2, + 0x6c, 0xdd, 0x0e, 0xc5, 0x88, 0x63, 0xcf, 0x0d, 0x93, 0x6f, 0xa1, 0x92, 0x80, 0x0f, 0x15, 0xfa, + 0x03, 0x13, 0xb5, 0x87, 0x3a, 0x42, 0xa9, 0x39, 0xf2, 0x41, 0x41, 0x72, 0xec, 0x7f, 0x05, 0xc5, + 0xbe, 0xf4, 0xcc, 0x45, 0x81, 0x8f, 0xd4, 0xe8, 0x2f, 0xec, 0xaf, 0x4e, 0xee, 0xce, 0x07, 0x82, + 0xe9, 0x14, 0x94, 0xa8, 0x24, 0xac, 0xcf, 0xa0, 0x6e, 0x0c, 0xb4, 0xf1, 0x8a, 0xb9, 0x20, 0x6d, + 0xd4, 0x0c, 0xde, 0x68, 0xd3, 0xdc, 0x81, 0xad, 0xb9, 0x71, 0xe9, 0x14, 0xfe, 0x29, 0x03, 0x15, + 0x91, 0x2e, 0xb3, 0xf5, 0xad, 0x5f, 0xc1, 0x92, 0x92, 0xd6, 0x57, 0x3e, 0xc7, 0x3d, 0x2d, 0x34, + 0xd7, 0xb3, 0xec, 0x5c, 0xcf, 0x66, 0xe5, 0x33, 0x37, 0x23, 0x9f, 0xc9, 0x0d, 0xa7, 0x67, 0xd0, + 0x2a, 0xd4, 0x8e, 0x70, 0x9f, 0x70, 0x9c, 0xbe, 0xf8, 0x7d, 0xa8, 0xa7, 0xe1, 0x5b, 0x5c, 0xfd, + 0x3a, 0x34, 0x2e, 0x42, 0x8f, 0xcc, 0x52, 0xb7, 0x01, 0xcd, 0x69, 0x96, 0xf6, 0xe0, 0x1b, 0xd8, + 0x3a, 0xa3, 0x44, 0x30, 0xa4, 0x67, 0x6f, 0x7a, 0x38, 0x3c, 0x44, 0x71, 0xb7, 0xc7, 0x2f, 0xa2, + 0x5b, 0x4c, 0x42, 0xfb, 0xb7, 0xb0, 0x3d, 0xff, 0xf8, 0xed, 0xbc, 0x56, 0x07, 0x11, 0xd3, 0x7a, + 0x3c, 0xc3, 0xeb, 0x69, 0x96, 0xf6, 0xfa, 0xef, 0x19, 0xa8, 0x9c, 0xe3, 0x74, 0xbb, 0xdc, 0xf5, + 0xae, 0x67, 0x5c, 0x5c, 0x76, 0x56, 0x23, 0x4c, 0x7d, 0x09, 0x2d, 0x4c, 0x7f, 0x09, 0x59, 0x4f, + 0xa0, 0x2a, 0x3f, 0x0f, 0x5c, 0x26, 0x86, 0xbe, 0xcb, 0x84, 0xe3, 0xfa, 0xab, 0x60, 0x45, 0x32, + 0xc6, 0x8f, 0x81, 0x7c, 0xa3, 0xf0, 0x44, 0x57, 0xdb, 0x2f, 0xc6, 0xd1, 0x3a, 0x58, 0x2a, 0x19, + 0x3f, 0x03, 0x77, 0x0b, 0x4c, 0x7c, 0xee, 0xcd, 0x50, 0xa5, 0xed, 0x3c, 0x06, 0x5b, 0x3c, 0xac, + 0xc6, 0x34, 0x3a, 0x08, 0x3d, 0x31, 0xc4, 0x53, 0x8b, 0xc9, 0x6b, 0x78, 0xf4, 0x4e, 0xa9, 0xfb, + 0x2e, 0x2a, 0xab, 0x50, 0x33, 0xcb, 0xc5, 0xa8, 0xf7, 0x34, 0x7c, 0x8b, 0xca, 0x39, 0x87, 0xd2, + 0x53, 0xd4, 0xb9, 0x8a, 0x47, 0x65, 0xba, 0x0d, 0x85, 0x0e, 0x09, 0x3b, 0x31, 0xa5, 0x38, 0xec, + 0x0c, 0xf5, 0x50, 0x33, 0x21, 0x21, 0x21, 0xbf, 0xd0, 0x54, 0xea, 0xf5, 0x67, 0x9d, 0x09, 0xd9, + 0x5f, 0x42, 0x39, 0x51, 0xaa, 0x5d, 0x78, 0x0c, 0x8b, 0x78, 0x30, 0x4e, 0x7d, 0xb9, 0x95, 0xfc, + 0x8f, 0xe2, 0x58, 0xa0, 0x8e, 0x62, 0xea, 0x27, 0x8c, 0x13, 0x8a, 0x4f, 0x28, 0xe9, 0xa7, 0xfc, + 0xb2, 0x0f, 0x60, 0x7d, 0x06, 0xef, 0x2e, 0xea, 0x9f, 0x7e, 0xfa, 0x53, 0x6b, 0xe0, 0x73, 0xcc, + 0x58, 0xcb, 0x27, 0x7b, 0xea, 0xd7, 0x5e, 0x97, 0xec, 0x0d, 0xf8, 0x9e, 0xfc, 0x4f, 0xc9, 0xde, + 0xd4, 0xa7, 0x55, 0x7b, 0x49, 0x32, 0x3e, 0xff, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xab, 0x03, + 0x4a, 0x1d, 0xb3, 0x19, 0x00, 0x00, } diff --git a/proto/tabletmanagerdata.proto b/proto/tabletmanagerdata.proto index fd0d81f36cd..740f544ec14 100644 --- a/proto/tabletmanagerdata.proto +++ b/proto/tabletmanagerdata.proto @@ -52,6 +52,10 @@ message TableDefinition { // approximate number of rows uint64 row_count = 7; + + // column names along with their types. + // NOTE: this is a superset of columns. + repeated query.Field fields = 8; } message SchemaDefinition { diff --git a/py/vtproto/tabletmanagerdata_pb2.py b/py/vtproto/tabletmanagerdata_pb2.py index 1a623c83833..4fcd650d929 100644 --- a/py/vtproto/tabletmanagerdata_pb2.py +++ b/py/vtproto/tabletmanagerdata_pb2.py @@ -23,7 +23,7 @@ package='tabletmanagerdata', syntax='proto3', serialized_options=_b('Z.vitess.io/vitess/go/vt/proto/tabletmanagerdata'), - serialized_pb=_b('\n\x17tabletmanagerdata.proto\x12\x11tabletmanagerdata\x1a\x0bquery.proto\x1a\x0etopodata.proto\x1a\x15replicationdata.proto\x1a\rlogutil.proto\"\x93\x01\n\x0fTableDefinition\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06schema\x18\x02 \x01(\t\x12\x0f\n\x07\x63olumns\x18\x03 \x03(\t\x12\x1b\n\x13primary_key_columns\x18\x04 \x03(\t\x12\x0c\n\x04type\x18\x05 \x01(\t\x12\x13\n\x0b\x64\x61ta_length\x18\x06 \x01(\x04\x12\x11\n\trow_count\x18\x07 \x01(\x04\"{\n\x10SchemaDefinition\x12\x17\n\x0f\x64\x61tabase_schema\x18\x01 \x01(\t\x12=\n\x11table_definitions\x18\x02 \x03(\x0b\x32\".tabletmanagerdata.TableDefinition\x12\x0f\n\x07version\x18\x03 \x01(\t\"\x8b\x01\n\x12SchemaChangeResult\x12:\n\rbefore_schema\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x02 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\xc1\x01\n\x0eUserPermission\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x0c\n\x04user\x18\x02 \x01(\t\x12\x19\n\x11password_checksum\x18\x03 \x01(\x04\x12\x45\n\nprivileges\x18\x04 \x03(\x0b\x32\x31.tabletmanagerdata.UserPermission.PrivilegesEntry\x1a\x31\n\x0fPrivilegesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xae\x01\n\x0c\x44\x62Permission\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\n\n\x02\x64\x62\x18\x02 \x01(\t\x12\x0c\n\x04user\x18\x03 \x01(\t\x12\x43\n\nprivileges\x18\x04 \x03(\x0b\x32/.tabletmanagerdata.DbPermission.PrivilegesEntry\x1a\x31\n\x0fPrivilegesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x83\x01\n\x0bPermissions\x12;\n\x10user_permissions\x18\x01 \x03(\x0b\x32!.tabletmanagerdata.UserPermission\x12\x37\n\x0e\x64\x62_permissions\x18\x02 \x03(\x0b\x32\x1f.tabletmanagerdata.DbPermission\"\x1e\n\x0bPingRequest\x12\x0f\n\x07payload\x18\x01 \x01(\t\"\x1f\n\x0cPingResponse\x12\x0f\n\x07payload\x18\x01 \x01(\t\" \n\x0cSleepRequest\x12\x10\n\x08\x64uration\x18\x01 \x01(\x03\"\x0f\n\rSleepResponse\"\xaf\x01\n\x12\x45xecuteHookRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\nparameters\x18\x02 \x03(\t\x12\x46\n\textra_env\x18\x03 \x03(\x0b\x32\x33.tabletmanagerdata.ExecuteHookRequest.ExtraEnvEntry\x1a/\n\rExtraEnvEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"J\n\x13\x45xecuteHookResponse\x12\x13\n\x0b\x65xit_status\x18\x01 \x01(\x03\x12\x0e\n\x06stdout\x18\x02 \x01(\t\x12\x0e\n\x06stderr\x18\x03 \x01(\t\"Q\n\x10GetSchemaRequest\x12\x0e\n\x06tables\x18\x01 \x03(\t\x12\x15\n\rinclude_views\x18\x02 \x01(\x08\x12\x16\n\x0e\x65xclude_tables\x18\x03 \x03(\t\"S\n\x11GetSchemaResponse\x12>\n\x11schema_definition\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x17\n\x15GetPermissionsRequest\"M\n\x16GetPermissionsResponse\x12\x33\n\x0bpermissions\x18\x01 \x01(\x0b\x32\x1e.tabletmanagerdata.Permissions\"\x14\n\x12SetReadOnlyRequest\"\x15\n\x13SetReadOnlyResponse\"\x15\n\x13SetReadWriteRequest\"\x16\n\x14SetReadWriteResponse\">\n\x11\x43hangeTypeRequest\x12)\n\x0btablet_type\x18\x01 \x01(\x0e\x32\x14.topodata.TabletType\"\x14\n\x12\x43hangeTypeResponse\"\x15\n\x13RefreshStateRequest\"\x16\n\x14RefreshStateResponse\"\x17\n\x15RunHealthCheckRequest\"\x18\n\x16RunHealthCheckResponse\"+\n\x18IgnoreHealthErrorRequest\x12\x0f\n\x07pattern\x18\x01 \x01(\t\"\x1b\n\x19IgnoreHealthErrorResponse\",\n\x13ReloadSchemaRequest\x12\x15\n\rwait_position\x18\x01 \x01(\t\"\x16\n\x14ReloadSchemaResponse\")\n\x16PreflightSchemaRequest\x12\x0f\n\x07\x63hanges\x18\x01 \x03(\t\"X\n\x17PreflightSchemaResponse\x12=\n\x0e\x63hange_results\x18\x01 \x03(\x0b\x32%.tabletmanagerdata.SchemaChangeResult\"\xc2\x01\n\x12\x41pplySchemaRequest\x12\x0b\n\x03sql\x18\x01 \x01(\t\x12\r\n\x05\x66orce\x18\x02 \x01(\x08\x12\x19\n\x11\x61llow_replication\x18\x03 \x01(\x08\x12:\n\rbefore_schema\x18\x04 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x05 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x8c\x01\n\x13\x41pplySchemaResponse\x12:\n\rbefore_schema\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x02 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x13\n\x11LockTablesRequest\"\x14\n\x12LockTablesResponse\"\x15\n\x13UnlockTablesRequest\"\x16\n\x14UnlockTablesResponse\"|\n\x18\x45xecuteFetchAsDbaRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x0f\n\x07\x64\x62_name\x18\x02 \x01(\t\x12\x10\n\x08max_rows\x18\x03 \x01(\x04\x12\x17\n\x0f\x64isable_binlogs\x18\x04 \x01(\x08\x12\x15\n\rreload_schema\x18\x05 \x01(\x08\"?\n\x19\x45xecuteFetchAsDbaResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"h\n\x1d\x45xecuteFetchAsAllPrivsRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x0f\n\x07\x64\x62_name\x18\x02 \x01(\t\x12\x10\n\x08max_rows\x18\x03 \x01(\x04\x12\x15\n\rreload_schema\x18\x04 \x01(\x08\"D\n\x1e\x45xecuteFetchAsAllPrivsResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\";\n\x18\x45xecuteFetchAsAppRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x10\n\x08max_rows\x18\x02 \x01(\x04\"?\n\x19\x45xecuteFetchAsAppResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"\x14\n\x12SlaveStatusRequest\">\n\x13SlaveStatusResponse\x12\'\n\x06status\x18\x01 \x01(\x0b\x32\x17.replicationdata.Status\"\x17\n\x15MasterPositionRequest\"*\n\x16MasterPositionResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x12\n\x10StopSlaveRequest\"\x13\n\x11StopSlaveResponse\"A\n\x17StopSlaveMinimumRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x14\n\x0cwait_timeout\x18\x02 \x01(\x03\",\n\x18StopSlaveMinimumResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x13\n\x11StartSlaveRequest\"\x14\n\x12StartSlaveResponse\"E\n\x1bStartSlaveUntilAfterRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x14\n\x0cwait_timeout\x18\x02 \x01(\x03\"\x1e\n\x1cStartSlaveUntilAfterResponse\"8\n!TabletExternallyReparentedRequest\x12\x13\n\x0b\x65xternal_id\x18\x01 \x01(\t\"$\n\"TabletExternallyReparentedResponse\" \n\x1eTabletExternallyElectedRequest\"!\n\x1fTabletExternallyElectedResponse\"\x12\n\x10GetSlavesRequest\"\"\n\x11GetSlavesResponse\x12\r\n\x05\x61\x64\x64rs\x18\x01 \x03(\t\"\x19\n\x17ResetReplicationRequest\"\x1a\n\x18ResetReplicationResponse\"(\n\x17VReplicationExecRequest\x12\r\n\x05query\x18\x01 \x01(\t\">\n\x18VReplicationExecResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"=\n\x1dVReplicationWaitForPosRequest\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08position\x18\x02 \x01(\t\" \n\x1eVReplicationWaitForPosResponse\"\x13\n\x11InitMasterRequest\"&\n\x12InitMasterResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x99\x01\n\x1ePopulateReparentJournalRequest\x12\x17\n\x0ftime_created_ns\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63tion_name\x18\x02 \x01(\t\x12+\n\x0cmaster_alias\x18\x03 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x1c\n\x14replication_position\x18\x04 \x01(\t\"!\n\x1fPopulateReparentJournalResponse\"p\n\x10InitSlaveRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x1c\n\x14replication_position\x18\x02 \x01(\t\x12\x17\n\x0ftime_created_ns\x18\x03 \x01(\x03\"\x13\n\x11InitSlaveResponse\"\x15\n\x13\x44\x65moteMasterRequest\"(\n\x14\x44\x65moteMasterResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17UndoDemoteMasterRequest\"\x1a\n\x18UndoDemoteMasterResponse\"3\n\x1fPromoteSlaveWhenCaughtUpRequest\x12\x10\n\x08position\x18\x01 \x01(\t\"4\n PromoteSlaveWhenCaughtUpResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17SlaveWasPromotedRequest\"\x1a\n\x18SlaveWasPromotedResponse\"m\n\x10SetMasterRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x17\n\x0ftime_created_ns\x18\x02 \x01(\x03\x12\x19\n\x11\x66orce_start_slave\x18\x03 \x01(\x08\"\x13\n\x11SetMasterResponse\"A\n\x18SlaveWasRestartedRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\"\x1b\n\x19SlaveWasRestartedResponse\"$\n\"StopReplicationAndGetStatusRequest\"N\n#StopReplicationAndGetStatusResponse\x12\'\n\x06status\x18\x01 \x01(\x0b\x32\x17.replicationdata.Status\"\x15\n\x13PromoteSlaveRequest\"(\n\x14PromoteSlaveResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"9\n\rBackupRequest\x12\x13\n\x0b\x63oncurrency\x18\x01 \x01(\x03\x12\x13\n\x0b\x61llowMaster\x18\x02 \x01(\x08\"/\n\x0e\x42\x61\x63kupResponse\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.logutil.Event\"\x1a\n\x18RestoreFromBackupRequest\":\n\x19RestoreFromBackupResponse\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.logutil.EventB0Z.vitess.io/vitess/go/vt/proto/tabletmanagerdatab\x06proto3') + serialized_pb=_b('\n\x17tabletmanagerdata.proto\x12\x11tabletmanagerdata\x1a\x0bquery.proto\x1a\x0etopodata.proto\x1a\x15replicationdata.proto\x1a\rlogutil.proto\"\xb1\x01\n\x0fTableDefinition\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06schema\x18\x02 \x01(\t\x12\x0f\n\x07\x63olumns\x18\x03 \x03(\t\x12\x1b\n\x13primary_key_columns\x18\x04 \x03(\t\x12\x0c\n\x04type\x18\x05 \x01(\t\x12\x13\n\x0b\x64\x61ta_length\x18\x06 \x01(\x04\x12\x11\n\trow_count\x18\x07 \x01(\x04\x12\x1c\n\x06\x66ields\x18\x08 \x03(\x0b\x32\x0c.query.Field\"{\n\x10SchemaDefinition\x12\x17\n\x0f\x64\x61tabase_schema\x18\x01 \x01(\t\x12=\n\x11table_definitions\x18\x02 \x03(\x0b\x32\".tabletmanagerdata.TableDefinition\x12\x0f\n\x07version\x18\x03 \x01(\t\"\x8b\x01\n\x12SchemaChangeResult\x12:\n\rbefore_schema\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x02 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\xc1\x01\n\x0eUserPermission\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x0c\n\x04user\x18\x02 \x01(\t\x12\x19\n\x11password_checksum\x18\x03 \x01(\x04\x12\x45\n\nprivileges\x18\x04 \x03(\x0b\x32\x31.tabletmanagerdata.UserPermission.PrivilegesEntry\x1a\x31\n\x0fPrivilegesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xae\x01\n\x0c\x44\x62Permission\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\n\n\x02\x64\x62\x18\x02 \x01(\t\x12\x0c\n\x04user\x18\x03 \x01(\t\x12\x43\n\nprivileges\x18\x04 \x03(\x0b\x32/.tabletmanagerdata.DbPermission.PrivilegesEntry\x1a\x31\n\x0fPrivilegesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x83\x01\n\x0bPermissions\x12;\n\x10user_permissions\x18\x01 \x03(\x0b\x32!.tabletmanagerdata.UserPermission\x12\x37\n\x0e\x64\x62_permissions\x18\x02 \x03(\x0b\x32\x1f.tabletmanagerdata.DbPermission\"\x1e\n\x0bPingRequest\x12\x0f\n\x07payload\x18\x01 \x01(\t\"\x1f\n\x0cPingResponse\x12\x0f\n\x07payload\x18\x01 \x01(\t\" \n\x0cSleepRequest\x12\x10\n\x08\x64uration\x18\x01 \x01(\x03\"\x0f\n\rSleepResponse\"\xaf\x01\n\x12\x45xecuteHookRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\nparameters\x18\x02 \x03(\t\x12\x46\n\textra_env\x18\x03 \x03(\x0b\x32\x33.tabletmanagerdata.ExecuteHookRequest.ExtraEnvEntry\x1a/\n\rExtraEnvEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"J\n\x13\x45xecuteHookResponse\x12\x13\n\x0b\x65xit_status\x18\x01 \x01(\x03\x12\x0e\n\x06stdout\x18\x02 \x01(\t\x12\x0e\n\x06stderr\x18\x03 \x01(\t\"Q\n\x10GetSchemaRequest\x12\x0e\n\x06tables\x18\x01 \x03(\t\x12\x15\n\rinclude_views\x18\x02 \x01(\x08\x12\x16\n\x0e\x65xclude_tables\x18\x03 \x03(\t\"S\n\x11GetSchemaResponse\x12>\n\x11schema_definition\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x17\n\x15GetPermissionsRequest\"M\n\x16GetPermissionsResponse\x12\x33\n\x0bpermissions\x18\x01 \x01(\x0b\x32\x1e.tabletmanagerdata.Permissions\"\x14\n\x12SetReadOnlyRequest\"\x15\n\x13SetReadOnlyResponse\"\x15\n\x13SetReadWriteRequest\"\x16\n\x14SetReadWriteResponse\">\n\x11\x43hangeTypeRequest\x12)\n\x0btablet_type\x18\x01 \x01(\x0e\x32\x14.topodata.TabletType\"\x14\n\x12\x43hangeTypeResponse\"\x15\n\x13RefreshStateRequest\"\x16\n\x14RefreshStateResponse\"\x17\n\x15RunHealthCheckRequest\"\x18\n\x16RunHealthCheckResponse\"+\n\x18IgnoreHealthErrorRequest\x12\x0f\n\x07pattern\x18\x01 \x01(\t\"\x1b\n\x19IgnoreHealthErrorResponse\",\n\x13ReloadSchemaRequest\x12\x15\n\rwait_position\x18\x01 \x01(\t\"\x16\n\x14ReloadSchemaResponse\")\n\x16PreflightSchemaRequest\x12\x0f\n\x07\x63hanges\x18\x01 \x03(\t\"X\n\x17PreflightSchemaResponse\x12=\n\x0e\x63hange_results\x18\x01 \x03(\x0b\x32%.tabletmanagerdata.SchemaChangeResult\"\xc2\x01\n\x12\x41pplySchemaRequest\x12\x0b\n\x03sql\x18\x01 \x01(\t\x12\r\n\x05\x66orce\x18\x02 \x01(\x08\x12\x19\n\x11\x61llow_replication\x18\x03 \x01(\x08\x12:\n\rbefore_schema\x18\x04 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x05 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x8c\x01\n\x13\x41pplySchemaResponse\x12:\n\rbefore_schema\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x02 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x13\n\x11LockTablesRequest\"\x14\n\x12LockTablesResponse\"\x15\n\x13UnlockTablesRequest\"\x16\n\x14UnlockTablesResponse\"|\n\x18\x45xecuteFetchAsDbaRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x0f\n\x07\x64\x62_name\x18\x02 \x01(\t\x12\x10\n\x08max_rows\x18\x03 \x01(\x04\x12\x17\n\x0f\x64isable_binlogs\x18\x04 \x01(\x08\x12\x15\n\rreload_schema\x18\x05 \x01(\x08\"?\n\x19\x45xecuteFetchAsDbaResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"h\n\x1d\x45xecuteFetchAsAllPrivsRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x0f\n\x07\x64\x62_name\x18\x02 \x01(\t\x12\x10\n\x08max_rows\x18\x03 \x01(\x04\x12\x15\n\rreload_schema\x18\x04 \x01(\x08\"D\n\x1e\x45xecuteFetchAsAllPrivsResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\";\n\x18\x45xecuteFetchAsAppRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x10\n\x08max_rows\x18\x02 \x01(\x04\"?\n\x19\x45xecuteFetchAsAppResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"\x14\n\x12SlaveStatusRequest\">\n\x13SlaveStatusResponse\x12\'\n\x06status\x18\x01 \x01(\x0b\x32\x17.replicationdata.Status\"\x17\n\x15MasterPositionRequest\"*\n\x16MasterPositionResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x12\n\x10StopSlaveRequest\"\x13\n\x11StopSlaveResponse\"A\n\x17StopSlaveMinimumRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x14\n\x0cwait_timeout\x18\x02 \x01(\x03\",\n\x18StopSlaveMinimumResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x13\n\x11StartSlaveRequest\"\x14\n\x12StartSlaveResponse\"E\n\x1bStartSlaveUntilAfterRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x14\n\x0cwait_timeout\x18\x02 \x01(\x03\"\x1e\n\x1cStartSlaveUntilAfterResponse\"8\n!TabletExternallyReparentedRequest\x12\x13\n\x0b\x65xternal_id\x18\x01 \x01(\t\"$\n\"TabletExternallyReparentedResponse\" \n\x1eTabletExternallyElectedRequest\"!\n\x1fTabletExternallyElectedResponse\"\x12\n\x10GetSlavesRequest\"\"\n\x11GetSlavesResponse\x12\r\n\x05\x61\x64\x64rs\x18\x01 \x03(\t\"\x19\n\x17ResetReplicationRequest\"\x1a\n\x18ResetReplicationResponse\"(\n\x17VReplicationExecRequest\x12\r\n\x05query\x18\x01 \x01(\t\">\n\x18VReplicationExecResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"=\n\x1dVReplicationWaitForPosRequest\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08position\x18\x02 \x01(\t\" \n\x1eVReplicationWaitForPosResponse\"\x13\n\x11InitMasterRequest\"&\n\x12InitMasterResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x99\x01\n\x1ePopulateReparentJournalRequest\x12\x17\n\x0ftime_created_ns\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63tion_name\x18\x02 \x01(\t\x12+\n\x0cmaster_alias\x18\x03 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x1c\n\x14replication_position\x18\x04 \x01(\t\"!\n\x1fPopulateReparentJournalResponse\"p\n\x10InitSlaveRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x1c\n\x14replication_position\x18\x02 \x01(\t\x12\x17\n\x0ftime_created_ns\x18\x03 \x01(\x03\"\x13\n\x11InitSlaveResponse\"\x15\n\x13\x44\x65moteMasterRequest\"(\n\x14\x44\x65moteMasterResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17UndoDemoteMasterRequest\"\x1a\n\x18UndoDemoteMasterResponse\"3\n\x1fPromoteSlaveWhenCaughtUpRequest\x12\x10\n\x08position\x18\x01 \x01(\t\"4\n PromoteSlaveWhenCaughtUpResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17SlaveWasPromotedRequest\"\x1a\n\x18SlaveWasPromotedResponse\"\x84\x01\n\x10SetMasterRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x17\n\x0ftime_created_ns\x18\x02 \x01(\x03\x12\x15\n\rwait_position\x18\x04 \x01(\t\x12\x19\n\x11\x66orce_start_slave\x18\x03 \x01(\x08\"\x13\n\x11SetMasterResponse\"A\n\x18SlaveWasRestartedRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\"\x1b\n\x19SlaveWasRestartedResponse\"$\n\"StopReplicationAndGetStatusRequest\"N\n#StopReplicationAndGetStatusResponse\x12\'\n\x06status\x18\x01 \x01(\x0b\x32\x17.replicationdata.Status\"\x15\n\x13PromoteSlaveRequest\"(\n\x14PromoteSlaveResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"9\n\rBackupRequest\x12\x13\n\x0b\x63oncurrency\x18\x01 \x01(\x03\x12\x13\n\x0b\x61llowMaster\x18\x02 \x01(\x08\"/\n\x0e\x42\x61\x63kupResponse\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.logutil.Event\"\x1a\n\x18RestoreFromBackupRequest\":\n\x19RestoreFromBackupResponse\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.logutil.EventB0Z.vitess.io/vitess/go/vt/proto/tabletmanagerdatab\x06proto3') , dependencies=[query__pb2.DESCRIPTOR,topodata__pb2.DESCRIPTOR,replicationdata__pb2.DESCRIPTOR,logutil__pb2.DESCRIPTOR,]) @@ -86,6 +86,13 @@ message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='fields', full_name='tabletmanagerdata.TableDefinition.fields', index=7, + number=8, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], @@ -99,7 +106,7 @@ oneofs=[ ], serialized_start=114, - serialized_end=261, + serialized_end=291, ) @@ -143,8 +150,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=263, - serialized_end=386, + serialized_start=293, + serialized_end=416, ) @@ -181,8 +188,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=389, - serialized_end=528, + serialized_start=419, + serialized_end=558, ) @@ -219,8 +226,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=675, - serialized_end=724, + serialized_start=705, + serialized_end=754, ) _USERPERMISSION = _descriptor.Descriptor( @@ -270,8 +277,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=531, - serialized_end=724, + serialized_start=561, + serialized_end=754, ) @@ -308,8 +315,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=675, - serialized_end=724, + serialized_start=705, + serialized_end=754, ) _DBPERMISSION = _descriptor.Descriptor( @@ -359,8 +366,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=727, - serialized_end=901, + serialized_start=757, + serialized_end=931, ) @@ -397,8 +404,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=904, - serialized_end=1035, + serialized_start=934, + serialized_end=1065, ) @@ -428,8 +435,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1037, - serialized_end=1067, + serialized_start=1067, + serialized_end=1097, ) @@ -459,8 +466,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1069, - serialized_end=1100, + serialized_start=1099, + serialized_end=1130, ) @@ -490,8 +497,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1102, - serialized_end=1134, + serialized_start=1132, + serialized_end=1164, ) @@ -514,8 +521,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1136, - serialized_end=1151, + serialized_start=1166, + serialized_end=1181, ) @@ -552,8 +559,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1282, - serialized_end=1329, + serialized_start=1312, + serialized_end=1359, ) _EXECUTEHOOKREQUEST = _descriptor.Descriptor( @@ -596,8 +603,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1154, - serialized_end=1329, + serialized_start=1184, + serialized_end=1359, ) @@ -641,8 +648,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1331, - serialized_end=1405, + serialized_start=1361, + serialized_end=1435, ) @@ -686,8 +693,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1407, - serialized_end=1488, + serialized_start=1437, + serialized_end=1518, ) @@ -717,8 +724,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1490, - serialized_end=1573, + serialized_start=1520, + serialized_end=1603, ) @@ -741,8 +748,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1575, - serialized_end=1598, + serialized_start=1605, + serialized_end=1628, ) @@ -772,8 +779,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1600, - serialized_end=1677, + serialized_start=1630, + serialized_end=1707, ) @@ -796,8 +803,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1679, - serialized_end=1699, + serialized_start=1709, + serialized_end=1729, ) @@ -820,8 +827,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1701, - serialized_end=1722, + serialized_start=1731, + serialized_end=1752, ) @@ -844,8 +851,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1724, - serialized_end=1745, + serialized_start=1754, + serialized_end=1775, ) @@ -868,8 +875,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1747, - serialized_end=1769, + serialized_start=1777, + serialized_end=1799, ) @@ -899,8 +906,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1771, - serialized_end=1833, + serialized_start=1801, + serialized_end=1863, ) @@ -923,8 +930,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1835, - serialized_end=1855, + serialized_start=1865, + serialized_end=1885, ) @@ -947,8 +954,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1857, - serialized_end=1878, + serialized_start=1887, + serialized_end=1908, ) @@ -971,8 +978,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1880, - serialized_end=1902, + serialized_start=1910, + serialized_end=1932, ) @@ -995,8 +1002,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1904, - serialized_end=1927, + serialized_start=1934, + serialized_end=1957, ) @@ -1019,8 +1026,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1929, - serialized_end=1953, + serialized_start=1959, + serialized_end=1983, ) @@ -1050,8 +1057,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1955, - serialized_end=1998, + serialized_start=1985, + serialized_end=2028, ) @@ -1074,8 +1081,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2000, - serialized_end=2027, + serialized_start=2030, + serialized_end=2057, ) @@ -1105,8 +1112,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2029, - serialized_end=2073, + serialized_start=2059, + serialized_end=2103, ) @@ -1129,8 +1136,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2075, - serialized_end=2097, + serialized_start=2105, + serialized_end=2127, ) @@ -1160,8 +1167,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2099, - serialized_end=2140, + serialized_start=2129, + serialized_end=2170, ) @@ -1191,8 +1198,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2142, - serialized_end=2230, + serialized_start=2172, + serialized_end=2260, ) @@ -1250,8 +1257,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2233, - serialized_end=2427, + serialized_start=2263, + serialized_end=2457, ) @@ -1288,8 +1295,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2430, - serialized_end=2570, + serialized_start=2460, + serialized_end=2600, ) @@ -1312,8 +1319,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2572, - serialized_end=2591, + serialized_start=2602, + serialized_end=2621, ) @@ -1336,8 +1343,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2593, - serialized_end=2613, + serialized_start=2623, + serialized_end=2643, ) @@ -1360,8 +1367,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2615, - serialized_end=2636, + serialized_start=2645, + serialized_end=2666, ) @@ -1384,8 +1391,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2638, - serialized_end=2660, + serialized_start=2668, + serialized_end=2690, ) @@ -1443,8 +1450,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2662, - serialized_end=2786, + serialized_start=2692, + serialized_end=2816, ) @@ -1474,8 +1481,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2788, - serialized_end=2851, + serialized_start=2818, + serialized_end=2881, ) @@ -1526,8 +1533,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2853, - serialized_end=2957, + serialized_start=2883, + serialized_end=2987, ) @@ -1557,8 +1564,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2959, - serialized_end=3027, + serialized_start=2989, + serialized_end=3057, ) @@ -1595,8 +1602,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3029, - serialized_end=3088, + serialized_start=3059, + serialized_end=3118, ) @@ -1626,8 +1633,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3090, - serialized_end=3153, + serialized_start=3120, + serialized_end=3183, ) @@ -1650,8 +1657,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3155, - serialized_end=3175, + serialized_start=3185, + serialized_end=3205, ) @@ -1681,8 +1688,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3177, - serialized_end=3239, + serialized_start=3207, + serialized_end=3269, ) @@ -1705,8 +1712,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3241, - serialized_end=3264, + serialized_start=3271, + serialized_end=3294, ) @@ -1736,8 +1743,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3266, - serialized_end=3308, + serialized_start=3296, + serialized_end=3338, ) @@ -1760,8 +1767,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3310, - serialized_end=3328, + serialized_start=3340, + serialized_end=3358, ) @@ -1784,8 +1791,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3330, - serialized_end=3349, + serialized_start=3360, + serialized_end=3379, ) @@ -1822,8 +1829,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3351, - serialized_end=3416, + serialized_start=3381, + serialized_end=3446, ) @@ -1853,8 +1860,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3418, - serialized_end=3462, + serialized_start=3448, + serialized_end=3492, ) @@ -1877,8 +1884,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3464, - serialized_end=3483, + serialized_start=3494, + serialized_end=3513, ) @@ -1901,8 +1908,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3485, - serialized_end=3505, + serialized_start=3515, + serialized_end=3535, ) @@ -1939,8 +1946,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3507, - serialized_end=3576, + serialized_start=3537, + serialized_end=3606, ) @@ -1963,8 +1970,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3578, - serialized_end=3608, + serialized_start=3608, + serialized_end=3638, ) @@ -1994,8 +2001,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3610, - serialized_end=3666, + serialized_start=3640, + serialized_end=3696, ) @@ -2018,8 +2025,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3668, - serialized_end=3704, + serialized_start=3698, + serialized_end=3734, ) @@ -2042,8 +2049,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3706, - serialized_end=3738, + serialized_start=3736, + serialized_end=3768, ) @@ -2066,8 +2073,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3740, - serialized_end=3773, + serialized_start=3770, + serialized_end=3803, ) @@ -2090,8 +2097,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3775, - serialized_end=3793, + serialized_start=3805, + serialized_end=3823, ) @@ -2121,8 +2128,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3795, - serialized_end=3829, + serialized_start=3825, + serialized_end=3859, ) @@ -2145,8 +2152,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3831, - serialized_end=3856, + serialized_start=3861, + serialized_end=3886, ) @@ -2169,8 +2176,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3858, - serialized_end=3884, + serialized_start=3888, + serialized_end=3914, ) @@ -2200,8 +2207,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3886, - serialized_end=3926, + serialized_start=3916, + serialized_end=3956, ) @@ -2231,8 +2238,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3928, - serialized_end=3990, + serialized_start=3958, + serialized_end=4020, ) @@ -2269,8 +2276,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3992, - serialized_end=4053, + serialized_start=4022, + serialized_end=4083, ) @@ -2293,8 +2300,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4055, - serialized_end=4087, + serialized_start=4085, + serialized_end=4117, ) @@ -2317,8 +2324,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4089, - serialized_end=4108, + serialized_start=4119, + serialized_end=4138, ) @@ -2348,8 +2355,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4110, - serialized_end=4148, + serialized_start=4140, + serialized_end=4178, ) @@ -2400,8 +2407,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4151, - serialized_end=4304, + serialized_start=4181, + serialized_end=4334, ) @@ -2424,8 +2431,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4306, - serialized_end=4339, + serialized_start=4336, + serialized_end=4369, ) @@ -2469,8 +2476,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4341, - serialized_end=4453, + serialized_start=4371, + serialized_end=4483, ) @@ -2493,8 +2500,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4455, - serialized_end=4474, + serialized_start=4485, + serialized_end=4504, ) @@ -2517,8 +2524,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4476, - serialized_end=4497, + serialized_start=4506, + serialized_end=4527, ) @@ -2548,8 +2555,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4499, - serialized_end=4539, + serialized_start=4529, + serialized_end=4569, ) @@ -2572,8 +2579,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4541, - serialized_end=4566, + serialized_start=4571, + serialized_end=4596, ) @@ -2596,8 +2603,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4568, - serialized_end=4594, + serialized_start=4598, + serialized_end=4624, ) @@ -2627,8 +2634,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4596, - serialized_end=4647, + serialized_start=4626, + serialized_end=4677, ) @@ -2658,8 +2665,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4649, - serialized_end=4701, + serialized_start=4679, + serialized_end=4731, ) @@ -2682,8 +2689,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4703, - serialized_end=4728, + serialized_start=4733, + serialized_end=4758, ) @@ -2706,8 +2713,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4730, - serialized_end=4756, + serialized_start=4760, + serialized_end=4786, ) @@ -2733,7 +2740,14 @@ is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( - name='force_start_slave', full_name='tabletmanagerdata.SetMasterRequest.force_start_slave', index=2, + name='wait_position', full_name='tabletmanagerdata.SetMasterRequest.wait_position', index=2, + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='force_start_slave', full_name='tabletmanagerdata.SetMasterRequest.force_start_slave', index=3, number=3, type=8, cpp_type=7, label=1, has_default_value=False, default_value=False, message_type=None, enum_type=None, containing_type=None, @@ -2751,8 +2765,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4758, - serialized_end=4867, + serialized_start=4789, + serialized_end=4921, ) @@ -2775,8 +2789,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4869, - serialized_end=4888, + serialized_start=4923, + serialized_end=4942, ) @@ -2806,8 +2820,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4890, - serialized_end=4955, + serialized_start=4944, + serialized_end=5009, ) @@ -2830,8 +2844,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4957, - serialized_end=4984, + serialized_start=5011, + serialized_end=5038, ) @@ -2854,8 +2868,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4986, - serialized_end=5022, + serialized_start=5040, + serialized_end=5076, ) @@ -2885,8 +2899,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5024, - serialized_end=5102, + serialized_start=5078, + serialized_end=5156, ) @@ -2909,8 +2923,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5104, - serialized_end=5125, + serialized_start=5158, + serialized_end=5179, ) @@ -2940,8 +2954,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5127, - serialized_end=5167, + serialized_start=5181, + serialized_end=5221, ) @@ -2978,8 +2992,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5169, - serialized_end=5226, + serialized_start=5223, + serialized_end=5280, ) @@ -3009,8 +3023,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5228, - serialized_end=5275, + serialized_start=5282, + serialized_end=5329, ) @@ -3033,8 +3047,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5277, - serialized_end=5303, + serialized_start=5331, + serialized_end=5357, ) @@ -3064,10 +3078,11 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5305, - serialized_end=5363, + serialized_start=5359, + serialized_end=5417, ) +_TABLEDEFINITION.fields_by_name['fields'].message_type = query__pb2._FIELD _SCHEMADEFINITION.fields_by_name['table_definitions'].message_type = _TABLEDEFINITION _SCHEMACHANGERESULT.fields_by_name['before_schema'].message_type = _SCHEMADEFINITION _SCHEMACHANGERESULT.fields_by_name['after_schema'].message_type = _SCHEMADEFINITION From ee052a5ba92247f04fa6f2e574c6a85e46b74efc Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 29 Sep 2019 03:35:19 -0700 Subject: [PATCH 02/28] vdiff: planbuilder initial cut Signed-off-by: Sugu Sougoumarane --- go/vt/mysqlctl/tmutils/schema.go | 8 +- .../vreplication/table_plan_builder.go | 6 +- go/vt/wrangler/vdiff.go | 233 ++++++++++++++++++ 3 files changed, 240 insertions(+), 7 deletions(-) create mode 100644 go/vt/wrangler/vdiff.go diff --git a/go/vt/mysqlctl/tmutils/schema.go b/go/vt/mysqlctl/tmutils/schema.go index 18123742e72..58e547d16a2 100644 --- a/go/vt/mysqlctl/tmutils/schema.go +++ b/go/vt/mysqlctl/tmutils/schema.go @@ -78,8 +78,8 @@ func FilterTables(sd *tabletmanagerdatapb.SchemaDefinition, tables, excludeTable if len(tables) > 0 { tableRegexps = make([]*regexp.Regexp, len(tables)) for i, table := range tables { - if len(table) > 2 && strings.HasPrefix(table, "/") && strings.HasSuffix(table, "/") { - table = table[1 : len(table)-1] + if strings.HasPrefix(table, "/") { + table = strings.Trim(table, "/") var err error tableRegexps[i], err = regexp.Compile(table) if err != nil { @@ -92,8 +92,8 @@ func FilterTables(sd *tabletmanagerdatapb.SchemaDefinition, tables, excludeTable if len(excludeTables) > 0 { excludeTableRegexps = make([]*regexp.Regexp, len(excludeTables)) for i, table := range excludeTables { - if len(table) > 2 && strings.HasPrefix(table, "/") && strings.HasSuffix(table, "/") { - table = table[1 : len(table)-1] + if strings.HasPrefix(table, "/") { + table = strings.Trim(table, "/") var err error excludeTableRegexps[i], err = regexp.Compile(table) if err != nil { diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index bd20a6e226e..434e821f1b2 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -98,7 +98,7 @@ func buildReplicatorPlan(filter *binlogdatapb.Filter, tableKeys map[string][]str // Don't replicate uncopied tables. continue } - rule, err := tableMatches(tableName, filter) + rule, err := MatchTable(tableName, filter) if err != nil { return nil, err } @@ -123,8 +123,8 @@ func buildReplicatorPlan(filter *binlogdatapb.Filter, tableKeys map[string][]str return plan, nil } -// tableMatches is similar to the one defined in vstreamer. -func tableMatches(tableName string, filter *binlogdatapb.Filter) (*binlogdatapb.Rule, error) { +// MatchTable is similar to tableMatches defined in vstreamer. +func MatchTable(tableName string, filter *binlogdatapb.Filter) (*binlogdatapb.Rule, error) { for _, rule := range filter.Rules { switch { case strings.HasPrefix(rule.Match, "/"): diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go new file mode 100644 index 00000000000..08e302cae68 --- /dev/null +++ b/go/vt/wrangler/vdiff.go @@ -0,0 +1,233 @@ +/* +Copyright 2019 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package wrangler + +import ( + "fmt" + "strings" + "time" + + "golang.org/x/net/context" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/key" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + querypb "vitess.io/vitess/go/vt/proto/query" + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vtgate/engine" + "vitess.io/vitess/go/vt/vttablet/tabletmanager/vreplication" +) + +type tableDiffer struct { + targetTable string + targetExpression string + sourceExpression string + compareCols []int + orderBy []engine.OrderbyParams +} + +// VDiff reports differences between the sources and targets of a vreplication workflow. +func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow string, filteredReplicationWaitTime time.Duration) error { + mi, err := wr.buildMigrater(ctx, targetKeyspace, workflow) + if err != nil { + wr.Logger().Errorf("buildMigrater failed: %v", err) + return err + } + if err := mi.validate(ctx, false /* isWrite */); err != nil { + mi.wr.Logger().Errorf("validate failed: %v", err) + return err + } + var oneTarget *miTarget + for _, target := range mi.targets { + oneTarget = target + break + } + var oneFilter *binlogdatapb.Filter + for _, bls := range oneTarget.sources { + oneFilter = bls.Filter + break + } + schm, err := wr.GetSchema(ctx, oneTarget.master.Alias, nil, nil, false) + if err != nil { + return err + } + tableDiffers := make(map[string]*tableDiffer) + for _, table := range schm.TableDefinitions { + rule, err := vreplication.MatchTable(table.Name, oneFilter) + if err != nil { + return err + } + if rule == nil { + continue + } + query := rule.Filter + if rule.Filter == "" || key.IsKeyRange(rule.Filter) { + buf := sqlparser.NewTrackedBuffer(nil) + buf.Myprintf("select * from %v", sqlparser.NewTableIdent(table.Name)) + query = buf.String() + } + tableDiffers[table.Name], err = buildDifferPlan(table, query) + if err != nil { + return err + } + } + return nil +} + +func buildDifferPlan(table *tabletmanagerdatapb.TableDefinition, query string) (*tableDiffer, error) { + statement, err := sqlparser.Parse(query) + if err != nil { + return nil, err + } + sel, ok := statement.(*sqlparser.Select) + if !ok { + return nil, fmt.Errorf("unexpected: %v", sqlparser.String(statement)) + } + td := &tableDiffer{ + targetTable: table.Name, + } + sourceSelect := &sqlparser.Select{} + targetSelect := &sqlparser.Select{} + for _, selExpr := range sel.SelectExprs { + switch selExpr := selExpr.(type) { + case *sqlparser.StarExpr: + for _, col := range table.Columns { + aliased := &sqlparser.AliasedExpr{Expr: &sqlparser.ColName{Name: sqlparser.NewColIdent(col)}} + sourceSelect.SelectExprs = append(sourceSelect.SelectExprs, aliased) + targetSelect.SelectExprs = append(targetSelect.SelectExprs, aliased) + } + case *sqlparser.AliasedExpr: + var targetCol *sqlparser.ColName + if !selExpr.As.IsEmpty() { + targetCol = &sqlparser.ColName{Name: selExpr.As} + } else { + if colAs, ok := selExpr.Expr.(*sqlparser.ColName); ok { + targetCol = colAs + } else { + return nil, fmt.Errorf("expression needs an alias: %v", sqlparser.String(selExpr)) + } + } + sourceSelect.SelectExprs = append(sourceSelect.SelectExprs, selExpr) + targetSelect.SelectExprs = append(targetSelect.SelectExprs, &sqlparser.AliasedExpr{Expr: targetCol}) + } + } + fields := make(map[string]querypb.Type) + for _, field := range table.Fields { + fields[strings.ToLower(field.Name)] = field.Type + } + + td.compareCols = make([]int, len(sourceSelect.SelectExprs)) + for i := range td.compareCols { + colname := sourceSelect.SelectExprs[i].(*sqlparser.AliasedExpr).Expr.(*sqlparser.ColName).Name.Lowered() + typ, ok := fields[colname] + if !ok { + return nil, fmt.Errorf("column %v not found in table %v", colname, table.Name) + } + td.compareCols[i] = i + if sqltypes.IsText(typ) { + sourceSelect.SelectExprs = append(sourceSelect.SelectExprs, wrapWeightString(sourceSelect.SelectExprs[i])) + targetSelect.SelectExprs = append(targetSelect.SelectExprs, wrapWeightString(targetSelect.SelectExprs[i])) + td.compareCols[i] = len(sourceSelect.SelectExprs) - 1 + } + } + + sourceSelect.From = sel.From + targetSelect.From = sqlparser.TableExprs{ + &sqlparser.AliasedTableExpr{ + Expr: &sqlparser.TableName{ + Name: sqlparser.NewTableIdent(table.Name), + }, + }, + } + + var orderby sqlparser.OrderBy + for _, pk := range table.PrimaryKeyColumns { + found := false + for i, selExpr := range targetSelect.SelectExprs { + colname := selExpr.(*sqlparser.AliasedExpr).Expr.(*sqlparser.ColName).Name.Lowered() + if pk == colname { + td.orderBy = append(td.orderBy, engine.OrderbyParams{Col: td.compareCols[i]}) + found = true + break + } + } + if !found { + // Unreachable. + return nil, fmt.Errorf("column %v not found in table %v", pk, table.Name) + } + orderby = append(orderby, &sqlparser.Order{Expr: &sqlparser.ColName{Name: sqlparser.NewColIdent(pk)}}) + } + targetSelect.OrderBy = orderby + + sourceSelect.Where = removeKeyrange(sel.Where) + sourceSelect.GroupBy = sel.GroupBy + sel.OrderBy = orderby + + td.sourceExpression = sqlparser.String(sourceSelect) + td.targetExpression = sqlparser.String(targetSelect) + return td, nil +} + +func removeKeyrange(where *sqlparser.Where) *sqlparser.Where { + if where == nil { + return nil + } + if isFuncKeyrange(where.Expr) { + return nil + } + where.Expr = removeExprKeyrange(where.Expr) + return where +} + +func removeExprKeyrange(node sqlparser.Expr) sqlparser.Expr { + switch node := node.(type) { + case *sqlparser.AndExpr: + if isFuncKeyrange(node.Left) { + return removeExprKeyrange(node.Right) + } + if isFuncKeyrange(node.Right) { + return removeExprKeyrange(node.Left) + } + return &sqlparser.AndExpr{ + Left: removeExprKeyrange(node.Left), + Right: removeExprKeyrange(node.Right), + } + case *sqlparser.ParenExpr: + return &sqlparser.ParenExpr{ + Expr: removeExprKeyrange(node.Expr), + } + } + return node +} + +func isFuncKeyrange(expr sqlparser.Expr) bool { + funcExpr, ok := expr.(*sqlparser.FuncExpr) + return ok && funcExpr.Name.EqualString("in_keyrange") +} + +func wrapWeightString(expr sqlparser.SelectExpr) *sqlparser.AliasedExpr { + return &sqlparser.AliasedExpr{ + Expr: &sqlparser.FuncExpr{ + Name: sqlparser.NewColIdent("weight_string"), + Exprs: []sqlparser.SelectExpr{ + &sqlparser.AliasedExpr{ + Expr: expr.(*sqlparser.AliasedExpr).Expr, + }, + }, + }, + } +} From 8b6eb63f786ccc37bb09868b12d81d23f9655361 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 29 Sep 2019 05:41:41 -0700 Subject: [PATCH 03/28] vdiff: add a test Signed-off-by: Sugu Sougoumarane --- go/vt/wrangler/migrater_env_test.go | 11 ++++--- go/vt/wrangler/migrater_test.go | 4 +-- go/vt/wrangler/vdiff.go | 19 +++++++---- go/vt/wrangler/vdiff_test.go | 50 +++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 13 deletions(-) create mode 100644 go/vt/wrangler/vdiff_test.go diff --git a/go/vt/wrangler/migrater_env_test.go b/go/vt/wrangler/migrater_env_test.go index 7963500d662..5ead8aea8cb 100644 --- a/go/vt/wrangler/migrater_env_test.go +++ b/go/vt/wrangler/migrater_env_test.go @@ -63,10 +63,13 @@ type testShardMigraterEnv struct { } func newTestTableMigrater(ctx context.Context, t *testing.T) *testMigraterEnv { - return newTestTableMigraterCustom(ctx, t, []string{"-40", "40-"}, []string{"-80", "80-"}) + return newTestTableMigraterCustom(ctx, t, []string{"-40", "40-"}, []string{"-80", "80-"}, "select * %s") } -func newTestTableMigraterCustom(ctx context.Context, t *testing.T, sourceShards, targetShards []string) *testMigraterEnv { +// newTestTableMigraterCustom creates a customized test tablet migrater. +// fmtQuery should be of the form: 'select a, b %s group by a'. +// The test will Sprintf a from clause and where clause as needed. +func newTestTableMigraterCustom(ctx context.Context, t *testing.T, sourceShards, targetShards []string, fmtQuery string) *testMigraterEnv { tme := &testMigraterEnv{} tme.ts = memorytopo.NewServer("cell1", "cell2") tme.wr = New(logutil.NewConsoleLogger(), tme.ts, tmclient.NewTabletManagerClient()) @@ -158,10 +161,10 @@ func newTestTableMigraterCustom(ctx context.Context, t *testing.T, sourceShards, Filter: &binlogdatapb.Filter{ Rules: []*binlogdatapb.Rule{{ Match: "t1", - Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", targetShard), + Filter: fmt.Sprintf(fmtQuery, fmt.Sprintf("from t1 where in_keyrange('%s')", targetShard)), }, { Match: "t2", - Filter: fmt.Sprintf("select * from t2 where in_keyrange('%s')", targetShard), + Filter: fmt.Sprintf(fmtQuery, fmt.Sprintf("from t2 where in_keyrange('%s')", targetShard)), }}, }, } diff --git a/go/vt/wrangler/migrater_test.go b/go/vt/wrangler/migrater_test.go index ea445306303..042d5ad09f2 100644 --- a/go/vt/wrangler/migrater_test.go +++ b/go/vt/wrangler/migrater_test.go @@ -730,7 +730,7 @@ func TestShardMigrateMainflow(t *testing.T) { func TestTableMigrateOneToMany(t *testing.T) { ctx := context.Background() - tme := newTestTableMigraterCustom(ctx, t, []string{"0"}, []string{"-80", "80-"}) + tme := newTestTableMigraterCustom(ctx, t, []string{"0"}, []string{"-80", "80-"}, "select * %s") defer tme.stopTablets(t) err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) @@ -813,7 +813,7 @@ func TestTableMigrateOneToMany(t *testing.T) { func TestTableMigrateManyToOne(t *testing.T) { ctx := context.Background() - tme := newTestTableMigraterCustom(ctx, t, []string{"-80", "80-"}, []string{"0"}) + tme := newTestTableMigraterCustom(ctx, t, []string{"-80", "80-"}, []string{"0"}, "select * %s") defer tme.stopTablets(t) err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index 08e302cae68..ace9ec0beae 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -65,11 +65,16 @@ func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow string, if err != nil { return err } + _, err = buildVDiffPlan(ctx, oneFilter, schm) + return err +} + +func buildVDiffPlan(ctx context.Context, filter *binlogdatapb.Filter, schm *tabletmanagerdatapb.SchemaDefinition) (map[string]*tableDiffer, error) { tableDiffers := make(map[string]*tableDiffer) for _, table := range schm.TableDefinitions { - rule, err := vreplication.MatchTable(table.Name, oneFilter) + rule, err := vreplication.MatchTable(table.Name, filter) if err != nil { - return err + return nil, err } if rule == nil { continue @@ -82,10 +87,10 @@ func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow string, } tableDiffers[table.Name], err = buildDifferPlan(table, query) if err != nil { - return err + return nil, err } } - return nil + return tableDiffers, nil } func buildDifferPlan(table *tabletmanagerdatapb.TableDefinition, query string) (*tableDiffer, error) { @@ -105,8 +110,8 @@ func buildDifferPlan(table *tabletmanagerdatapb.TableDefinition, query string) ( for _, selExpr := range sel.SelectExprs { switch selExpr := selExpr.(type) { case *sqlparser.StarExpr: - for _, col := range table.Columns { - aliased := &sqlparser.AliasedExpr{Expr: &sqlparser.ColName{Name: sqlparser.NewColIdent(col)}} + for _, fld := range table.Fields { + aliased := &sqlparser.AliasedExpr{Expr: &sqlparser.ColName{Name: sqlparser.NewColIdent(fld.Name)}} sourceSelect.SelectExprs = append(sourceSelect.SelectExprs, aliased) targetSelect.SelectExprs = append(targetSelect.SelectExprs, aliased) } @@ -175,7 +180,7 @@ func buildDifferPlan(table *tabletmanagerdatapb.TableDefinition, query string) ( sourceSelect.Where = removeKeyrange(sel.Where) sourceSelect.GroupBy = sel.GroupBy - sel.OrderBy = orderby + sourceSelect.OrderBy = orderby td.sourceExpression = sqlparser.String(sourceSelect) td.targetExpression = sqlparser.String(targetSelect) diff --git a/go/vt/wrangler/vdiff_test.go b/go/vt/wrangler/vdiff_test.go new file mode 100644 index 00000000000..177561c0c53 --- /dev/null +++ b/go/vt/wrangler/vdiff_test.go @@ -0,0 +1,50 @@ +/* +Copyright 2019 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package wrangler + +import ( + "fmt" + "testing" + + "golang.org/x/net/context" + "vitess.io/vitess/go/sqltypes" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" +) + +func TestVDiffPlan(t *testing.T) { + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: fmt.Sprintf("select * from t1 where in_keyrange('-80')"), + }}, + } + + schm := &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ + Name: "t1", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2", "int64|int64"), + }}, + } + differs, err := buildVDiffPlan(context.Background(), filter, schm) + if err != nil { + t.Fatal(err) + } + fmt.Printf("%+v\n", differs["t1"]) +} From cd858ac621deeece234ac15f3a9d058af2dd264c Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 29 Sep 2019 11:16:21 -0700 Subject: [PATCH 04/28] vdiff: resultStreamer Signed-off-by: Sugu Sougoumarane --- go/vt/proto/binlogdata/binlogdata.pb.go | 331 ++++++++++++------ go/vt/proto/queryservice/queryservice.pb.go | 140 ++++++-- go/vt/vtcombo/tablet_map.go | 6 + go/vt/vttablet/grpcqueryservice/server.go | 11 + go/vt/vttablet/grpctabletconn/conn.go | 40 +++ go/vt/vttablet/queryservice/queryservice.go | 3 + go/vt/vttablet/queryservice/wrapped.go | 7 + go/vt/vttablet/sandboxconn/sandboxconn.go | 5 + .../tabletconntest/fakequeryservice.go | 5 + go/vt/vttablet/tabletserver/tabletserver.go | 8 + .../vttablet/tabletserver/vstreamer/engine.go | 60 +++- .../tabletserver/vstreamer/resultstreamer.go | 168 +++++++++ proto/binlogdata.proto | 18 + proto/queryservice.proto | 3 + py/vtproto/binlogdata_pb2.py | 132 ++++++- py/vtproto/queryservice_pb2.py | 13 +- py/vtproto/queryservice_pb2_grpc.py | 17 + 17 files changed, 807 insertions(+), 160 deletions(-) create mode 100644 go/vt/vttablet/tabletserver/vstreamer/resultstreamer.go diff --git a/go/vt/proto/binlogdata/binlogdata.pb.go b/go/vt/proto/binlogdata/binlogdata.pb.go index ba32aed0707..904d001d423 100644 --- a/go/vt/proto/binlogdata/binlogdata.pb.go +++ b/go/vt/proto/binlogdata/binlogdata.pb.go @@ -1528,6 +1528,128 @@ func (m *VStreamRowsResponse) GetLastpk() *query.Row { return nil } +// VStreamResultsRequest is the payload for VStreamResults +// The ids match VStreamRows, in case we decide to merge the two. +type VStreamResultsRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId,proto3" json:"effective_caller_id,omitempty"` + ImmediateCallerId *query.VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId,proto3" json:"immediate_caller_id,omitempty"` + Target *query.Target `protobuf:"bytes,3,opt,name=target,proto3" json:"target,omitempty"` + Query string `protobuf:"bytes,4,opt,name=query,proto3" json:"query,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *VStreamResultsRequest) Reset() { *m = VStreamResultsRequest{} } +func (m *VStreamResultsRequest) String() string { return proto.CompactTextString(m) } +func (*VStreamResultsRequest) ProtoMessage() {} +func (*VStreamResultsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_5fd02bcb2e350dad, []int{21} +} + +func (m *VStreamResultsRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_VStreamResultsRequest.Unmarshal(m, b) +} +func (m *VStreamResultsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_VStreamResultsRequest.Marshal(b, m, deterministic) +} +func (m *VStreamResultsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_VStreamResultsRequest.Merge(m, src) +} +func (m *VStreamResultsRequest) XXX_Size() int { + return xxx_messageInfo_VStreamResultsRequest.Size(m) +} +func (m *VStreamResultsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_VStreamResultsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_VStreamResultsRequest proto.InternalMessageInfo + +func (m *VStreamResultsRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *VStreamResultsRequest) GetImmediateCallerId() *query.VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *VStreamResultsRequest) GetTarget() *query.Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *VStreamResultsRequest) GetQuery() string { + if m != nil { + return m.Query + } + return "" +} + +// VStreamResultsResponse is the response from VStreamResults +// The ids match VStreamRows, in case we decide to merge the two. +type VStreamResultsResponse struct { + Fields []*query.Field `protobuf:"bytes,1,rep,name=fields,proto3" json:"fields,omitempty"` + Gtid string `protobuf:"bytes,3,opt,name=gtid,proto3" json:"gtid,omitempty"` + Rows []*query.Row `protobuf:"bytes,4,rep,name=rows,proto3" json:"rows,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *VStreamResultsResponse) Reset() { *m = VStreamResultsResponse{} } +func (m *VStreamResultsResponse) String() string { return proto.CompactTextString(m) } +func (*VStreamResultsResponse) ProtoMessage() {} +func (*VStreamResultsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_5fd02bcb2e350dad, []int{22} +} + +func (m *VStreamResultsResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_VStreamResultsResponse.Unmarshal(m, b) +} +func (m *VStreamResultsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_VStreamResultsResponse.Marshal(b, m, deterministic) +} +func (m *VStreamResultsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_VStreamResultsResponse.Merge(m, src) +} +func (m *VStreamResultsResponse) XXX_Size() int { + return xxx_messageInfo_VStreamResultsResponse.Size(m) +} +func (m *VStreamResultsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_VStreamResultsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_VStreamResultsResponse proto.InternalMessageInfo + +func (m *VStreamResultsResponse) GetFields() []*query.Field { + if m != nil { + return m.Fields + } + return nil +} + +func (m *VStreamResultsResponse) GetGtid() string { + if m != nil { + return m.Gtid + } + return "" +} + +func (m *VStreamResultsResponse) GetRows() []*query.Row { + if m != nil { + return m.Rows + } + return nil +} + func init() { proto.RegisterEnum("binlogdata.OnDDLAction", OnDDLAction_name, OnDDLAction_value) proto.RegisterEnum("binlogdata.VEventType", VEventType_name, VEventType_value) @@ -1556,112 +1678,115 @@ func init() { proto.RegisterType((*VStreamResponse)(nil), "binlogdata.VStreamResponse") proto.RegisterType((*VStreamRowsRequest)(nil), "binlogdata.VStreamRowsRequest") proto.RegisterType((*VStreamRowsResponse)(nil), "binlogdata.VStreamRowsResponse") + proto.RegisterType((*VStreamResultsRequest)(nil), "binlogdata.VStreamResultsRequest") + proto.RegisterType((*VStreamResultsResponse)(nil), "binlogdata.VStreamResultsResponse") } func init() { proto.RegisterFile("binlogdata.proto", fileDescriptor_5fd02bcb2e350dad) } var fileDescriptor_5fd02bcb2e350dad = []byte{ - // 1625 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x57, 0xcd, 0x72, 0xdb, 0xc8, - 0x11, 0x16, 0x49, 0xf0, 0xaf, 0x21, 0x51, 0xd0, 0xe8, 0x27, 0x8c, 0x2a, 0x4e, 0xc9, 0xa8, 0x38, - 0x92, 0x55, 0x15, 0x2a, 0x61, 0x12, 0xe7, 0xe4, 0x38, 0xfc, 0x81, 0x24, 0x4a, 0x20, 0x29, 0x0f, - 0x21, 0x39, 0xe5, 0x0b, 0x0a, 0x22, 0x87, 0x12, 0x22, 0x10, 0xa0, 0x81, 0xa1, 0x14, 0x3d, 0x40, - 0x2a, 0x0f, 0x90, 0x6b, 0x5e, 0x20, 0xe7, 0x5c, 0x93, 0xeb, 0xde, 0xf7, 0x09, 0xf6, 0xb4, 0xef, - 0xb1, 0x35, 0x3f, 0x00, 0x09, 0xc9, 0x6b, 0xcb, 0x5b, 0xb5, 0x87, 0xbd, 0xa0, 0x7a, 0x7a, 0xba, - 0x7b, 0x7a, 0xbe, 0xf9, 0x7a, 0x1a, 0x03, 0xda, 0xa5, 0xeb, 0x7b, 0xc1, 0xd5, 0xc8, 0xa1, 0x4e, - 0x6d, 0x1a, 0x06, 0x34, 0x40, 0x30, 0xd7, 0x6c, 0xab, 0xb7, 0x34, 0x9c, 0x0e, 0xc5, 0xc4, 0xb6, - 0xfa, 0x61, 0x46, 0xc2, 0x7b, 0x39, 0xa8, 0xd0, 0x60, 0x1a, 0xcc, 0xbd, 0xf4, 0x2e, 0x14, 0x5b, - 0xd7, 0x4e, 0x18, 0x11, 0x8a, 0xb6, 0xa0, 0x30, 0xf4, 0x5c, 0xe2, 0xd3, 0x6a, 0x66, 0x27, 0xb3, - 0x97, 0xc7, 0x72, 0x84, 0x10, 0x28, 0xc3, 0xc0, 0xf7, 0xab, 0x59, 0xae, 0xe5, 0x32, 0xb3, 0x8d, - 0x48, 0x78, 0x4b, 0xc2, 0x6a, 0x4e, 0xd8, 0x8a, 0x91, 0xfe, 0x6d, 0x0e, 0xd6, 0x9a, 0x3c, 0x0f, - 0x2b, 0x74, 0xfc, 0xc8, 0x19, 0x52, 0x37, 0xf0, 0xd1, 0x11, 0x40, 0x44, 0x1d, 0x4a, 0x26, 0xc4, - 0xa7, 0x51, 0x35, 0xb3, 0x93, 0xdb, 0x53, 0xeb, 0xbb, 0xb5, 0x85, 0x1d, 0x3c, 0x72, 0xa9, 0x0d, - 0x62, 0x7b, 0xbc, 0xe0, 0x8a, 0xea, 0xa0, 0x92, 0x5b, 0xe2, 0x53, 0x9b, 0x06, 0x37, 0xc4, 0xaf, - 0x2a, 0x3b, 0x99, 0x3d, 0xb5, 0xbe, 0x56, 0x13, 0x1b, 0x34, 0xd8, 0x8c, 0xc5, 0x26, 0x30, 0x90, - 0x44, 0xde, 0xfe, 0x2a, 0x0b, 0xe5, 0x24, 0x1a, 0x32, 0xa1, 0x34, 0x74, 0x28, 0xb9, 0x0a, 0xc2, - 0x7b, 0xbe, 0xcd, 0x4a, 0xfd, 0xb7, 0x4f, 0x4c, 0xa4, 0xd6, 0x92, 0x7e, 0x38, 0x89, 0x80, 0x7e, - 0x03, 0xc5, 0xa1, 0x40, 0x8f, 0xa3, 0xa3, 0xd6, 0xd7, 0x17, 0x83, 0x49, 0x60, 0x71, 0x6c, 0x83, - 0x34, 0xc8, 0x45, 0x1f, 0x3c, 0x0e, 0xd9, 0x32, 0x66, 0xa2, 0xfe, 0x9f, 0x0c, 0x94, 0xe2, 0xb8, - 0x68, 0x1d, 0x56, 0x9b, 0xa6, 0x7d, 0xde, 0xc3, 0x46, 0xab, 0x7f, 0xd4, 0xeb, 0xbc, 0x37, 0xda, - 0xda, 0x12, 0x5a, 0x86, 0x52, 0xd3, 0xb4, 0x9b, 0xc6, 0x51, 0xa7, 0xa7, 0x65, 0xd0, 0x0a, 0x94, - 0x9b, 0xa6, 0xdd, 0xea, 0x77, 0xbb, 0x1d, 0x4b, 0xcb, 0xa2, 0x55, 0x50, 0x9b, 0xa6, 0x8d, 0xfb, - 0xa6, 0xd9, 0x6c, 0xb4, 0x4e, 0xb5, 0x1c, 0xda, 0x84, 0xb5, 0xa6, 0x69, 0xb7, 0xbb, 0xa6, 0xdd, - 0x36, 0xce, 0xb0, 0xd1, 0x6a, 0x58, 0x46, 0x5b, 0x53, 0x10, 0x40, 0x81, 0xa9, 0xdb, 0xa6, 0x96, - 0x97, 0xf2, 0xc0, 0xb0, 0xb4, 0x82, 0x0c, 0xd7, 0xe9, 0x0d, 0x0c, 0x6c, 0x69, 0x45, 0x39, 0x3c, - 0x3f, 0x6b, 0x37, 0x2c, 0x43, 0x2b, 0xc9, 0x61, 0xdb, 0x30, 0x0d, 0xcb, 0xd0, 0xca, 0x27, 0x4a, - 0x29, 0xab, 0xe5, 0x4e, 0x94, 0x52, 0x4e, 0x53, 0xf4, 0x7f, 0x65, 0x60, 0x73, 0x40, 0x43, 0xe2, - 0x4c, 0x4e, 0xc9, 0x3d, 0x76, 0xfc, 0x2b, 0x82, 0xc9, 0x87, 0x19, 0x89, 0x28, 0xda, 0x86, 0xd2, - 0x34, 0x88, 0x5c, 0x86, 0x1d, 0x07, 0xb8, 0x8c, 0x93, 0x31, 0x3a, 0x80, 0xf2, 0x0d, 0xb9, 0xb7, - 0x43, 0x66, 0x2f, 0x01, 0x43, 0xb5, 0x84, 0x90, 0x49, 0xa4, 0xd2, 0x8d, 0x94, 0x16, 0xf1, 0xcd, - 0x7d, 0x1e, 0x5f, 0x7d, 0x0c, 0x5b, 0x0f, 0x93, 0x8a, 0xa6, 0x81, 0x1f, 0x11, 0x64, 0x02, 0x12, - 0x8e, 0x36, 0x9d, 0x9f, 0x2d, 0xcf, 0x4f, 0xad, 0x3f, 0xfb, 0x24, 0x01, 0xf0, 0xda, 0xe5, 0x43, - 0x95, 0xfe, 0x77, 0x58, 0x17, 0xeb, 0x58, 0xce, 0xa5, 0x47, 0xa2, 0xa7, 0x6c, 0x7d, 0x0b, 0x0a, - 0x94, 0x1b, 0x57, 0xb3, 0x3b, 0xb9, 0xbd, 0x32, 0x96, 0xa3, 0x2f, 0xdd, 0xe1, 0x08, 0x36, 0xd2, - 0x2b, 0xff, 0x28, 0xfb, 0xfb, 0x03, 0x28, 0x78, 0xe6, 0x11, 0xb4, 0x01, 0xf9, 0x89, 0x43, 0x87, - 0xd7, 0x72, 0x37, 0x62, 0xc0, 0xb6, 0x32, 0x76, 0x3d, 0x4a, 0x42, 0x7e, 0x84, 0x65, 0x2c, 0x47, - 0xfa, 0x7f, 0x33, 0x50, 0x38, 0xe4, 0x22, 0xfa, 0x35, 0xe4, 0xc3, 0x19, 0xdb, 0xac, 0xa8, 0x75, - 0x6d, 0x31, 0x03, 0x16, 0x19, 0x8b, 0x69, 0xd4, 0x81, 0xca, 0xd8, 0x25, 0xde, 0x88, 0x97, 0x6e, - 0x37, 0x18, 0x09, 0x56, 0x54, 0xea, 0xcf, 0x17, 0x1d, 0x44, 0xcc, 0xda, 0x61, 0xca, 0x10, 0x3f, - 0x70, 0xd4, 0x5f, 0x41, 0x25, 0x6d, 0xc1, 0xca, 0xc9, 0xc0, 0xd8, 0xee, 0xf7, 0xec, 0x6e, 0x67, - 0xd0, 0x6d, 0x58, 0xad, 0x63, 0x6d, 0x89, 0x57, 0x8c, 0x31, 0xb0, 0x6c, 0xe3, 0xf0, 0xb0, 0x8f, - 0x2d, 0x2d, 0xa3, 0xff, 0x3b, 0x0b, 0xcb, 0x02, 0x94, 0x41, 0x30, 0x0b, 0x87, 0x84, 0x9d, 0xe2, - 0x0d, 0xb9, 0x8f, 0xa6, 0xce, 0x90, 0xc4, 0xa7, 0x18, 0x8f, 0x19, 0x20, 0xd1, 0xb5, 0x13, 0x8e, - 0xe4, 0xce, 0xc5, 0x00, 0xfd, 0x11, 0x54, 0x7e, 0x9a, 0xd4, 0xa6, 0xf7, 0x53, 0xc2, 0xcf, 0xb1, - 0x52, 0xdf, 0x98, 0x13, 0x9b, 0x9f, 0x15, 0xb5, 0xee, 0xa7, 0x04, 0x03, 0x4d, 0xe4, 0x74, 0x35, - 0x28, 0x4f, 0xa8, 0x86, 0x39, 0x87, 0xf2, 0x29, 0x0e, 0xed, 0x27, 0x07, 0x52, 0x90, 0x51, 0x1e, - 0xa1, 0x17, 0x1f, 0x12, 0xaa, 0x41, 0x21, 0xf0, 0xed, 0xd1, 0xc8, 0xab, 0x16, 0x79, 0x9a, 0x3f, - 0x5b, 0xb4, 0xed, 0xfb, 0xed, 0xb6, 0xd9, 0x10, 0xb4, 0xc8, 0x07, 0x7e, 0x7b, 0xe4, 0xe9, 0x6f, - 0xa1, 0x8c, 0x83, 0xbb, 0xd6, 0x35, 0x4f, 0x40, 0x87, 0xc2, 0x25, 0x19, 0x07, 0x21, 0x91, 0xcc, - 0x02, 0x79, 0xf3, 0xe2, 0xe0, 0x0e, 0xcb, 0x19, 0xb4, 0x03, 0x79, 0x67, 0x1c, 0x93, 0x23, 0x6d, - 0x22, 0x26, 0x74, 0x07, 0x4a, 0x38, 0xb8, 0xe3, 0xe7, 0x84, 0x9e, 0x81, 0x40, 0xc4, 0xf6, 0x9d, - 0x49, 0x0c, 0x77, 0x99, 0x6b, 0x7a, 0xce, 0x84, 0xa0, 0x57, 0xa0, 0x86, 0xc1, 0x9d, 0x3d, 0xe4, - 0xcb, 0x8b, 0xd2, 0x51, 0xeb, 0x9b, 0x29, 0x36, 0xc5, 0xc9, 0x61, 0x08, 0x63, 0x31, 0xd2, 0xdf, - 0x02, 0xcc, 0xc9, 0xf0, 0xb9, 0x45, 0x7e, 0xc5, 0xe0, 0x23, 0xde, 0x28, 0x8e, 0xbf, 0x2c, 0x53, - 0xe6, 0x11, 0xb0, 0x9c, 0x63, 0x40, 0x0c, 0xd8, 0x69, 0x1f, 0x51, 0x77, 0xf4, 0x03, 0x38, 0x82, - 0x40, 0xb9, 0xa2, 0xee, 0x88, 0x93, 0xa3, 0x8c, 0xb9, 0xac, 0xbf, 0x81, 0xfc, 0x05, 0x0f, 0xf7, - 0x0a, 0x54, 0x6e, 0x65, 0x33, 0x75, 0x5c, 0x34, 0xa9, 0x6d, 0x26, 0x4b, 0x63, 0x88, 0x62, 0x31, - 0xd2, 0x1b, 0xb0, 0x72, 0x2a, 0x97, 0xe5, 0x06, 0x5f, 0x9e, 0x97, 0xfe, 0xbf, 0x2c, 0x14, 0x4f, - 0x82, 0x59, 0xe8, 0x3b, 0x1e, 0xaa, 0x40, 0xd6, 0x1d, 0x71, 0xbf, 0x1c, 0xce, 0xba, 0x23, 0xf4, - 0x17, 0xa8, 0x4c, 0xdc, 0xab, 0xd0, 0x61, 0x7c, 0x10, 0xd4, 0x16, 0xd5, 0xf9, 0xf3, 0xc5, 0xcc, - 0xba, 0xb1, 0x05, 0xe7, 0xf7, 0xca, 0x64, 0x71, 0xb8, 0xc0, 0xd8, 0x5c, 0x8a, 0xb1, 0x2f, 0xa0, - 0xe2, 0x05, 0x43, 0xc7, 0xb3, 0x93, 0xfb, 0x52, 0xe1, 0x49, 0xad, 0x70, 0xed, 0x59, 0x7c, 0x69, - 0x3e, 0xc0, 0x25, 0xff, 0x44, 0x5c, 0xd0, 0x6b, 0x58, 0x9e, 0x3a, 0x21, 0x75, 0x87, 0xee, 0xd4, - 0x61, 0x7f, 0x1c, 0x05, 0xee, 0x98, 0x4a, 0x3b, 0x85, 0x1b, 0x4e, 0x99, 0xa3, 0x97, 0xa0, 0x45, - 0xfc, 0x2e, 0xb0, 0xef, 0x82, 0xf0, 0x66, 0xec, 0x05, 0x77, 0x51, 0xb5, 0xc8, 0xf3, 0x5f, 0x15, - 0xfa, 0x77, 0xb1, 0x5a, 0xff, 0x26, 0x0b, 0x85, 0x0b, 0xc1, 0xb2, 0x7d, 0x50, 0x38, 0x46, 0xe2, - 0xaf, 0x62, 0x6b, 0x71, 0x31, 0x61, 0xc1, 0x01, 0xe2, 0x36, 0xe8, 0x17, 0x50, 0xa6, 0xee, 0x84, - 0x44, 0xd4, 0x99, 0x4c, 0x39, 0xa8, 0x39, 0x3c, 0x57, 0x7c, 0x8c, 0x2b, 0xec, 0xd7, 0x81, 0x15, - 0xad, 0x80, 0x89, 0x89, 0xe8, 0x77, 0x50, 0x66, 0xb5, 0xc1, 0xff, 0x74, 0xaa, 0x79, 0x5e, 0x6c, - 0x1b, 0x0f, 0x2a, 0x83, 0x2f, 0x8b, 0x4b, 0x61, 0x5c, 0x6d, 0x7f, 0x02, 0x95, 0xb3, 0x59, 0x3a, - 0x89, 0xdb, 0x62, 0x2b, 0x7d, 0x5b, 0xc4, 0x55, 0x83, 0x61, 0x7e, 0xc1, 0xa2, 0x5d, 0xc8, 0xdf, - 0xf2, 0x94, 0x8a, 0xf2, 0x8f, 0x6b, 0x71, 0x73, 0x1c, 0x7e, 0x31, 0xcf, 0xda, 0xd9, 0xdf, 0x04, - 0x9b, 0xaa, 0xa5, 0xc7, 0xed, 0x4c, 0x12, 0x0d, 0xc7, 0x36, 0xe8, 0x39, 0x2c, 0x0f, 0x67, 0x61, - 0xc8, 0xff, 0xe8, 0xdc, 0x09, 0xa9, 0x6e, 0x70, 0x28, 0x54, 0xa9, 0xb3, 0xdc, 0x09, 0xd1, 0xff, - 0x99, 0x85, 0xca, 0x85, 0xe8, 0x79, 0x71, 0x9f, 0x7d, 0x03, 0xeb, 0x64, 0x3c, 0x26, 0x43, 0xea, - 0xde, 0x12, 0x7b, 0xe8, 0x78, 0x1e, 0x09, 0x6d, 0x49, 0x5c, 0xb5, 0xbe, 0x5a, 0x13, 0xff, 0xbe, - 0x2d, 0xae, 0xef, 0xb4, 0xf1, 0x5a, 0x62, 0x2b, 0x55, 0x23, 0x64, 0xc0, 0xba, 0x3b, 0x99, 0x90, - 0x91, 0xeb, 0xd0, 0xc5, 0x00, 0xe2, 0xc6, 0xda, 0x94, 0xe5, 0x7f, 0x61, 0x1d, 0x39, 0x94, 0xcc, - 0xc3, 0x24, 0x1e, 0x49, 0x98, 0x17, 0x8c, 0xdd, 0xe1, 0x55, 0xd2, 0xba, 0x57, 0xa4, 0xa7, 0xc5, - 0x95, 0x58, 0x4e, 0xa6, 0x7e, 0x0b, 0x94, 0x07, 0xbf, 0x05, 0xf3, 0xab, 0x3b, 0xff, 0xb9, 0xab, - 0x5b, 0x7f, 0x0d, 0xab, 0x09, 0x10, 0xb2, 0xed, 0xef, 0x43, 0x81, 0x1f, 0x65, 0x7c, 0x67, 0xa0, - 0xc7, 0xac, 0xc3, 0xd2, 0x42, 0xff, 0x47, 0x16, 0x50, 0xec, 0x1f, 0xdc, 0x45, 0x3f, 0x51, 0x30, - 0x37, 0x20, 0xcf, 0xf5, 0x12, 0x49, 0x31, 0x60, 0x38, 0x78, 0x4e, 0x44, 0xa7, 0x37, 0x09, 0x8c, - 0xc2, 0xf9, 0x2d, 0xfb, 0x62, 0x12, 0xcd, 0x3c, 0x8a, 0xa5, 0x85, 0xfe, 0xff, 0x0c, 0xac, 0xa7, - 0x70, 0x90, 0x58, 0xce, 0xdb, 0x40, 0xe6, 0xfb, 0xdb, 0x00, 0xda, 0x83, 0xd2, 0xf4, 0xe6, 0x13, - 0xed, 0x22, 0x99, 0xfd, 0x68, 0x15, 0xff, 0x12, 0x94, 0x90, 0xdd, 0x26, 0x0a, 0xf7, 0x5c, 0xec, - 0x8d, 0x5c, 0xcf, 0x1a, 0x6c, 0x6a, 0x1f, 0xa9, 0x06, 0x2b, 0x66, 0xf6, 0xff, 0x0c, 0xea, 0x42, - 0x9f, 0x66, 0xbf, 0xf3, 0x9d, 0xa3, 0x5e, 0x1f, 0x1b, 0xda, 0x12, 0x2a, 0x81, 0x32, 0xb0, 0xfa, - 0x67, 0x5a, 0x86, 0x49, 0xc6, 0x5f, 0x8d, 0x96, 0x78, 0x22, 0x30, 0xc9, 0x96, 0x46, 0xb9, 0xfd, - 0xaf, 0x33, 0x00, 0xf3, 0x0b, 0x09, 0xa9, 0x50, 0x3c, 0xef, 0x9d, 0xf6, 0xfa, 0xef, 0x7a, 0x22, - 0xc0, 0x91, 0xd5, 0x69, 0x6b, 0x19, 0x54, 0x86, 0xbc, 0x78, 0x73, 0x64, 0xd9, 0x0a, 0xf2, 0xc1, - 0x91, 0x63, 0xaf, 0x91, 0xe4, 0xb5, 0xa1, 0xa0, 0x22, 0xe4, 0x92, 0x37, 0x85, 0x7c, 0x44, 0x14, - 0x58, 0x40, 0x6c, 0x9c, 0x99, 0x8d, 0x96, 0xa1, 0x15, 0xd9, 0x44, 0xf2, 0x9c, 0x00, 0x28, 0xc4, - 0x6f, 0x09, 0xe6, 0xc9, 0x5e, 0x20, 0xc0, 0xd6, 0xe9, 0x5b, 0xc7, 0x06, 0xd6, 0x54, 0xa6, 0xc3, - 0xfd, 0x77, 0xda, 0x32, 0xd3, 0x1d, 0x76, 0x0c, 0xb3, 0xad, 0xad, 0xb0, 0x27, 0xc8, 0xb1, 0xd1, - 0xc0, 0x56, 0xd3, 0x68, 0x58, 0x5a, 0x85, 0xcd, 0x5c, 0xf0, 0x04, 0x57, 0xd9, 0x32, 0x27, 0xfd, - 0x73, 0xdc, 0x6b, 0x98, 0x9a, 0xb6, 0xbf, 0x0b, 0x2b, 0xa9, 0x3e, 0xc4, 0xd6, 0xb2, 0x1a, 0x4d, - 0xd3, 0x18, 0x68, 0x4b, 0x4c, 0x1e, 0x1c, 0x37, 0x70, 0x7b, 0xa0, 0x65, 0x9a, 0x2f, 0xdf, 0xef, - 0xde, 0xba, 0x94, 0x44, 0x51, 0xcd, 0x0d, 0x0e, 0x84, 0x74, 0x70, 0x15, 0x1c, 0xdc, 0xd2, 0x03, - 0xfe, 0x1c, 0x3e, 0x98, 0x97, 0xcf, 0x65, 0x81, 0x6b, 0x7e, 0xff, 0x5d, 0x00, 0x00, 0x00, 0xff, - 0xff, 0x49, 0x0f, 0x06, 0xcd, 0x6a, 0x0f, 0x00, 0x00, + // 1648 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x58, 0x4b, 0x73, 0xe3, 0x4a, + 0x15, 0x8e, 0x6c, 0xf9, 0x75, 0x94, 0x38, 0x4a, 0xe7, 0x81, 0x49, 0x71, 0xa9, 0x5c, 0x15, 0x97, + 0xe4, 0xa6, 0x0a, 0x07, 0x0c, 0x0c, 0xab, 0xcb, 0xc5, 0x0f, 0x25, 0x71, 0x22, 0xdb, 0x99, 0xb6, + 0x92, 0xa1, 0x66, 0xa3, 0x52, 0xec, 0x76, 0x22, 0x22, 0x4b, 0x1e, 0xa9, 0x9d, 0x90, 0x1f, 0x40, + 0xf1, 0x03, 0xd8, 0xf2, 0x07, 0x58, 0xb3, 0x85, 0x2d, 0x7b, 0xf6, 0x54, 0xb1, 0xe2, 0x7f, 0x50, + 0xfd, 0x90, 0x6c, 0x25, 0xc3, 0x4c, 0x66, 0xaa, 0x58, 0xc0, 0xc6, 0x75, 0xfa, 0xf4, 0x39, 0xa7, + 0xcf, 0xf9, 0xce, 0xa3, 0xd5, 0x06, 0xfd, 0xda, 0x0b, 0xfc, 0xf0, 0x66, 0xec, 0x52, 0xb7, 0x3e, + 0x8b, 0x42, 0x1a, 0x22, 0x58, 0x70, 0x76, 0xb5, 0x7b, 0x1a, 0xcd, 0x46, 0x62, 0x63, 0x57, 0x7b, + 0x37, 0x27, 0xd1, 0xa3, 0x5c, 0x54, 0x69, 0x38, 0x0b, 0x17, 0x5a, 0x46, 0x0f, 0x4a, 0xed, 0x5b, + 0x37, 0x8a, 0x09, 0x45, 0x3b, 0x50, 0x1c, 0xf9, 0x1e, 0x09, 0x68, 0x4d, 0xd9, 0x53, 0x0e, 0x0a, + 0x58, 0xae, 0x10, 0x02, 0x75, 0x14, 0x06, 0x41, 0x2d, 0xc7, 0xb9, 0x9c, 0x66, 0xb2, 0x31, 0x89, + 0xee, 0x49, 0x54, 0xcb, 0x0b, 0x59, 0xb1, 0x32, 0xfe, 0x95, 0x87, 0x8d, 0x16, 0xf7, 0xc3, 0x8e, + 0xdc, 0x20, 0x76, 0x47, 0xd4, 0x0b, 0x03, 0x74, 0x02, 0x10, 0x53, 0x97, 0x92, 0x29, 0x09, 0x68, + 0x5c, 0x53, 0xf6, 0xf2, 0x07, 0x5a, 0x63, 0xbf, 0xbe, 0x14, 0xc1, 0x33, 0x95, 0xfa, 0x30, 0x91, + 0xc7, 0x4b, 0xaa, 0xa8, 0x01, 0x1a, 0xb9, 0x27, 0x01, 0x75, 0x68, 0x78, 0x47, 0x82, 0x9a, 0xba, + 0xa7, 0x1c, 0x68, 0x8d, 0x8d, 0xba, 0x08, 0xd0, 0x64, 0x3b, 0x36, 0xdb, 0xc0, 0x40, 0x52, 0x7a, + 0xf7, 0x6f, 0x39, 0xa8, 0xa4, 0xd6, 0x90, 0x05, 0xe5, 0x91, 0x4b, 0xc9, 0x4d, 0x18, 0x3d, 0xf2, + 0x30, 0xab, 0x8d, 0x1f, 0xbf, 0xd0, 0x91, 0x7a, 0x5b, 0xea, 0xe1, 0xd4, 0x02, 0xfa, 0x11, 0x94, + 0x46, 0x02, 0x3d, 0x8e, 0x8e, 0xd6, 0xd8, 0x5c, 0x36, 0x26, 0x81, 0xc5, 0x89, 0x0c, 0xd2, 0x21, + 0x1f, 0xbf, 0xf3, 0x39, 0x64, 0xab, 0x98, 0x91, 0xc6, 0x9f, 0x14, 0x28, 0x27, 0x76, 0xd1, 0x26, + 0xac, 0xb7, 0x2c, 0xe7, 0xb2, 0x8f, 0xcd, 0xf6, 0xe0, 0xa4, 0xdf, 0x7d, 0x6b, 0x76, 0xf4, 0x15, + 0xb4, 0x0a, 0xe5, 0x96, 0xe5, 0xb4, 0xcc, 0x93, 0x6e, 0x5f, 0x57, 0xd0, 0x1a, 0x54, 0x5a, 0x96, + 0xd3, 0x1e, 0xf4, 0x7a, 0x5d, 0x5b, 0xcf, 0xa1, 0x75, 0xd0, 0x5a, 0x96, 0x83, 0x07, 0x96, 0xd5, + 0x6a, 0xb6, 0xcf, 0xf5, 0x3c, 0xda, 0x86, 0x8d, 0x96, 0xe5, 0x74, 0x7a, 0x96, 0xd3, 0x31, 0x2f, + 0xb0, 0xd9, 0x6e, 0xda, 0x66, 0x47, 0x57, 0x11, 0x40, 0x91, 0xb1, 0x3b, 0x96, 0x5e, 0x90, 0xf4, + 0xd0, 0xb4, 0xf5, 0xa2, 0x34, 0xd7, 0xed, 0x0f, 0x4d, 0x6c, 0xeb, 0x25, 0xb9, 0xbc, 0xbc, 0xe8, + 0x34, 0x6d, 0x53, 0x2f, 0xcb, 0x65, 0xc7, 0xb4, 0x4c, 0xdb, 0xd4, 0x2b, 0x67, 0x6a, 0x39, 0xa7, + 0xe7, 0xcf, 0xd4, 0x72, 0x5e, 0x57, 0x8d, 0x3f, 0x28, 0xb0, 0x3d, 0xa4, 0x11, 0x71, 0xa7, 0xe7, + 0xe4, 0x11, 0xbb, 0xc1, 0x0d, 0xc1, 0xe4, 0xdd, 0x9c, 0xc4, 0x14, 0xed, 0x42, 0x79, 0x16, 0xc6, + 0x1e, 0xc3, 0x8e, 0x03, 0x5c, 0xc1, 0xe9, 0x1a, 0x1d, 0x41, 0xe5, 0x8e, 0x3c, 0x3a, 0x11, 0x93, + 0x97, 0x80, 0xa1, 0x7a, 0x5a, 0x90, 0xa9, 0xa5, 0xf2, 0x9d, 0xa4, 0x96, 0xf1, 0xcd, 0x7f, 0x1c, + 0x5f, 0x63, 0x02, 0x3b, 0x4f, 0x9d, 0x8a, 0x67, 0x61, 0x10, 0x13, 0x64, 0x01, 0x12, 0x8a, 0x0e, + 0x5d, 0xe4, 0x96, 0xfb, 0xa7, 0x35, 0xbe, 0xf8, 0x60, 0x01, 0xe0, 0x8d, 0xeb, 0xa7, 0x2c, 0xe3, + 0xb7, 0xb0, 0x29, 0xce, 0xb1, 0xdd, 0x6b, 0x9f, 0xc4, 0x2f, 0x09, 0x7d, 0x07, 0x8a, 0x94, 0x0b, + 0xd7, 0x72, 0x7b, 0xf9, 0x83, 0x0a, 0x96, 0xab, 0x4f, 0x8d, 0x70, 0x0c, 0x5b, 0xd9, 0x93, 0xff, + 0x2b, 0xf1, 0xfd, 0x0c, 0x54, 0x3c, 0xf7, 0x09, 0xda, 0x82, 0xc2, 0xd4, 0xa5, 0xa3, 0x5b, 0x19, + 0x8d, 0x58, 0xb0, 0x50, 0x26, 0x9e, 0x4f, 0x49, 0xc4, 0x53, 0x58, 0xc1, 0x72, 0x65, 0xfc, 0x59, + 0x81, 0xe2, 0x31, 0x27, 0xd1, 0x0f, 0xa1, 0x10, 0xcd, 0x59, 0xb0, 0xa2, 0xd7, 0xf5, 0x65, 0x0f, + 0x98, 0x65, 0x2c, 0xb6, 0x51, 0x17, 0xaa, 0x13, 0x8f, 0xf8, 0x63, 0xde, 0xba, 0xbd, 0x70, 0x2c, + 0xaa, 0xa2, 0xda, 0xf8, 0x72, 0x59, 0x41, 0xd8, 0xac, 0x1f, 0x67, 0x04, 0xf1, 0x13, 0x45, 0xe3, + 0x15, 0x54, 0xb3, 0x12, 0xac, 0x9d, 0x4c, 0x8c, 0x9d, 0x41, 0xdf, 0xe9, 0x75, 0x87, 0xbd, 0xa6, + 0xdd, 0x3e, 0xd5, 0x57, 0x78, 0xc7, 0x98, 0x43, 0xdb, 0x31, 0x8f, 0x8f, 0x07, 0xd8, 0xd6, 0x15, + 0xe3, 0x8f, 0x39, 0x58, 0x15, 0xa0, 0x0c, 0xc3, 0x79, 0x34, 0x22, 0x2c, 0x8b, 0x77, 0xe4, 0x31, + 0x9e, 0xb9, 0x23, 0x92, 0x64, 0x31, 0x59, 0x33, 0x40, 0xe2, 0x5b, 0x37, 0x1a, 0xcb, 0xc8, 0xc5, + 0x02, 0xfd, 0x1c, 0x34, 0x9e, 0x4d, 0xea, 0xd0, 0xc7, 0x19, 0xe1, 0x79, 0xac, 0x36, 0xb6, 0x16, + 0x85, 0xcd, 0x73, 0x45, 0xed, 0xc7, 0x19, 0xc1, 0x40, 0x53, 0x3a, 0xdb, 0x0d, 0xea, 0x0b, 0xba, + 0x61, 0x51, 0x43, 0x85, 0x4c, 0x0d, 0x1d, 0xa6, 0x09, 0x29, 0x4a, 0x2b, 0xcf, 0xd0, 0x4b, 0x92, + 0x84, 0xea, 0x50, 0x0c, 0x03, 0x67, 0x3c, 0xf6, 0x6b, 0x25, 0xee, 0xe6, 0x77, 0x96, 0x65, 0x07, + 0x41, 0xa7, 0x63, 0x35, 0x45, 0x59, 0x14, 0xc2, 0xa0, 0x33, 0xf6, 0x8d, 0xd7, 0x50, 0xc1, 0xe1, + 0x43, 0xfb, 0x96, 0x3b, 0x60, 0x40, 0xf1, 0x9a, 0x4c, 0xc2, 0x88, 0xc8, 0xca, 0x02, 0x39, 0x79, + 0x71, 0xf8, 0x80, 0xe5, 0x0e, 0xda, 0x83, 0x82, 0x3b, 0x49, 0x8a, 0x23, 0x2b, 0x22, 0x36, 0x0c, + 0x17, 0xca, 0x38, 0x7c, 0xe0, 0x79, 0x42, 0x5f, 0x80, 0x40, 0xc4, 0x09, 0xdc, 0x69, 0x02, 0x77, + 0x85, 0x73, 0xfa, 0xee, 0x94, 0xa0, 0x57, 0xa0, 0x45, 0xe1, 0x83, 0x33, 0xe2, 0xc7, 0x8b, 0xd6, + 0xd1, 0x1a, 0xdb, 0x99, 0x6a, 0x4a, 0x9c, 0xc3, 0x10, 0x25, 0x64, 0x6c, 0xbc, 0x06, 0x58, 0x14, + 0xc3, 0xc7, 0x0e, 0xf9, 0x01, 0x83, 0x8f, 0xf8, 0xe3, 0xc4, 0xfe, 0xaa, 0x74, 0x99, 0x5b, 0xc0, + 0x72, 0x8f, 0x01, 0x31, 0x64, 0xd9, 0x3e, 0xa1, 0xde, 0xf8, 0x33, 0x6a, 0x04, 0x81, 0x7a, 0x43, + 0xbd, 0x31, 0x2f, 0x8e, 0x0a, 0xe6, 0xb4, 0xf1, 0x2d, 0x14, 0xae, 0xb8, 0xb9, 0x57, 0xa0, 0x71, + 0x29, 0x87, 0xb1, 0x93, 0xa6, 0xc9, 0x84, 0x99, 0x1e, 0x8d, 0x21, 0x4e, 0xc8, 0xd8, 0x68, 0xc2, + 0xda, 0xb9, 0x3c, 0x96, 0x0b, 0x7c, 0xba, 0x5f, 0xc6, 0x5f, 0x72, 0x50, 0x3a, 0x0b, 0xe7, 0x51, + 0xe0, 0xfa, 0xa8, 0x0a, 0x39, 0x6f, 0xcc, 0xf5, 0xf2, 0x38, 0xe7, 0x8d, 0xd1, 0xaf, 0xa0, 0x3a, + 0xf5, 0x6e, 0x22, 0x97, 0xd5, 0x83, 0x28, 0x6d, 0xd1, 0x9d, 0xdf, 0x5d, 0xf6, 0xac, 0x97, 0x48, + 0xf0, 0xfa, 0x5e, 0x9b, 0x2e, 0x2f, 0x97, 0x2a, 0x36, 0x9f, 0xa9, 0xd8, 0xaf, 0xa0, 0xea, 0x87, + 0x23, 0xd7, 0x77, 0xd2, 0x79, 0xa9, 0x72, 0xa7, 0xd6, 0x38, 0xf7, 0x22, 0x19, 0x9a, 0x4f, 0x70, + 0x29, 0xbc, 0x10, 0x17, 0xf4, 0x0d, 0xac, 0xce, 0xdc, 0x88, 0x7a, 0x23, 0x6f, 0xe6, 0xb2, 0x2f, + 0x8e, 0x22, 0x57, 0xcc, 0xb8, 0x9d, 0xc1, 0x0d, 0x67, 0xc4, 0xd1, 0xd7, 0xa0, 0xc7, 0x7c, 0x16, + 0x38, 0x0f, 0x61, 0x74, 0x37, 0xf1, 0xc3, 0x87, 0xb8, 0x56, 0xe2, 0xfe, 0xaf, 0x0b, 0xfe, 0x9b, + 0x84, 0x6d, 0xfc, 0x33, 0x07, 0xc5, 0x2b, 0x51, 0x65, 0x87, 0xa0, 0x72, 0x8c, 0xc4, 0x57, 0xc5, + 0xce, 0xf2, 0x61, 0x42, 0x82, 0x03, 0xc4, 0x65, 0xd0, 0xf7, 0xa0, 0x42, 0xbd, 0x29, 0x89, 0xa9, + 0x3b, 0x9d, 0x71, 0x50, 0xf3, 0x78, 0xc1, 0x78, 0x5f, 0xad, 0xb0, 0x4f, 0x07, 0xd6, 0xb4, 0x02, + 0x26, 0x46, 0xa2, 0x9f, 0x40, 0x85, 0xf5, 0x06, 0xff, 0xd2, 0xa9, 0x15, 0x78, 0xb3, 0x6d, 0x3d, + 0xe9, 0x0c, 0x7e, 0x2c, 0x2e, 0x47, 0x49, 0xb7, 0xfd, 0x02, 0x34, 0x5e, 0xcd, 0x52, 0x49, 0x4c, + 0x8b, 0x9d, 0xec, 0xb4, 0x48, 0xba, 0x06, 0xc3, 0x62, 0xc0, 0xa2, 0x7d, 0x28, 0xdc, 0x73, 0x97, + 0x4a, 0xf2, 0x8b, 0x6b, 0x39, 0x38, 0x0e, 0xbf, 0xd8, 0x67, 0xd7, 0xd9, 0x6f, 0x44, 0x35, 0xd5, + 0xca, 0xcf, 0xaf, 0x33, 0x59, 0x68, 0x38, 0x91, 0x41, 0x5f, 0xc2, 0xea, 0x68, 0x1e, 0x45, 0xfc, + 0x8b, 0xce, 0x9b, 0x92, 0xda, 0x16, 0x87, 0x42, 0x93, 0x3c, 0xdb, 0x9b, 0x12, 0xe3, 0xf7, 0x39, + 0xa8, 0x5e, 0x89, 0x3b, 0x2f, 0xb9, 0x67, 0xbf, 0x85, 0x4d, 0x32, 0x99, 0x90, 0x11, 0xf5, 0xee, + 0x89, 0x33, 0x72, 0x7d, 0x9f, 0x44, 0x8e, 0x2c, 0x5c, 0xad, 0xb1, 0x5e, 0x17, 0xdf, 0xbe, 0x6d, + 0xce, 0xef, 0x76, 0xf0, 0x46, 0x2a, 0x2b, 0x59, 0x63, 0x64, 0xc2, 0xa6, 0x37, 0x9d, 0x92, 0xb1, + 0xe7, 0xd2, 0x65, 0x03, 0x62, 0x62, 0x6d, 0xcb, 0xf6, 0xbf, 0xb2, 0x4f, 0x5c, 0x4a, 0x16, 0x66, + 0x52, 0x8d, 0xd4, 0xcc, 0x57, 0xac, 0xba, 0xa3, 0x9b, 0xf4, 0xea, 0x5e, 0x93, 0x9a, 0x36, 0x67, + 0x62, 0xb9, 0x99, 0xf9, 0x2c, 0x50, 0x9f, 0x7c, 0x16, 0x2c, 0x46, 0x77, 0xe1, 0x63, 0xa3, 0xdb, + 0xf8, 0x06, 0xd6, 0x53, 0x20, 0xe4, 0xb5, 0x7f, 0x08, 0x45, 0x9e, 0xca, 0x64, 0x66, 0xa0, 0xe7, + 0x55, 0x87, 0xa5, 0x84, 0xf1, 0xbb, 0x1c, 0xa0, 0x44, 0x3f, 0x7c, 0x88, 0xff, 0x47, 0xc1, 0xdc, + 0x82, 0x02, 0xe7, 0x4b, 0x24, 0xc5, 0x82, 0xe1, 0xe0, 0xbb, 0x31, 0x9d, 0xdd, 0xa5, 0x30, 0x0a, + 0xe5, 0xd7, 0xec, 0x17, 0x93, 0x78, 0xee, 0x53, 0x2c, 0x25, 0x8c, 0xbf, 0x2a, 0xb0, 0x99, 0xc1, + 0x41, 0x62, 0xb9, 0xb8, 0x06, 0x94, 0xff, 0x7c, 0x0d, 0xa0, 0x03, 0x28, 0xcf, 0xee, 0x3e, 0x70, + 0x5d, 0xa4, 0xbb, 0xef, 0xed, 0xe2, 0xef, 0x83, 0x1a, 0xb1, 0x69, 0xa2, 0x72, 0xcd, 0xe5, 0xbb, + 0x91, 0xf3, 0xd9, 0x05, 0x9b, 0x89, 0x23, 0x73, 0xc1, 0x4a, 0xff, 0xff, 0xa1, 0xc0, 0xf6, 0xa2, + 0x0e, 0xe6, 0x3e, 0xfd, 0xbf, 0x4a, 0xa5, 0x11, 0xc1, 0xce, 0xd3, 0xe8, 0x3e, 0x29, 0x41, 0x9f, + 0x01, 0xfb, 0xe1, 0x2f, 0x41, 0x5b, 0xfa, 0xf4, 0x61, 0x2f, 0xa4, 0xee, 0x49, 0x7f, 0x80, 0x4d, + 0x7d, 0x05, 0x95, 0x41, 0x1d, 0xda, 0x83, 0x0b, 0x5d, 0x61, 0x94, 0xf9, 0x6b, 0xb3, 0x2d, 0x5e, + 0x5d, 0x8c, 0x72, 0xa4, 0x50, 0xfe, 0xf0, 0xef, 0x0a, 0xc0, 0x62, 0xc6, 0x23, 0x0d, 0x4a, 0x97, + 0xfd, 0xf3, 0xfe, 0xe0, 0x4d, 0x5f, 0x18, 0x38, 0xb1, 0xbb, 0x1d, 0x5d, 0x41, 0x15, 0x28, 0x88, + 0x67, 0x5c, 0x8e, 0x9d, 0x20, 0xdf, 0x70, 0x79, 0xf6, 0xc0, 0x4b, 0x1f, 0x70, 0x2a, 0x2a, 0x41, + 0x3e, 0x7d, 0xa6, 0xc9, 0x77, 0x59, 0x91, 0x19, 0xc4, 0xe6, 0x85, 0xd5, 0x6c, 0x9b, 0x7a, 0x89, + 0x6d, 0xa4, 0x2f, 0x34, 0x80, 0x62, 0xf2, 0x3c, 0x63, 0x9a, 0xec, 0x51, 0x07, 0xec, 0x9c, 0x81, + 0x7d, 0x6a, 0x62, 0x5d, 0x63, 0x3c, 0x3c, 0x78, 0xa3, 0xaf, 0x32, 0xde, 0x71, 0xd7, 0xb4, 0x3a, + 0xfa, 0x1a, 0x7b, 0xd5, 0x9d, 0x9a, 0x4d, 0x6c, 0xb7, 0xcc, 0xa6, 0xad, 0x57, 0xd9, 0xce, 0x15, + 0x77, 0x70, 0x9d, 0x1d, 0x73, 0x36, 0xb8, 0xc4, 0xfd, 0xa6, 0xa5, 0xeb, 0x87, 0xfb, 0xb0, 0x96, + 0xb9, 0xda, 0xd9, 0x59, 0x76, 0xb3, 0x65, 0x99, 0x43, 0x7d, 0x85, 0xd1, 0xc3, 0xd3, 0x26, 0xee, + 0x0c, 0x75, 0xa5, 0xf5, 0xf5, 0xdb, 0xfd, 0x7b, 0x8f, 0x92, 0x38, 0xae, 0x7b, 0xe1, 0x91, 0xa0, + 0x8e, 0x6e, 0xc2, 0xa3, 0x7b, 0x7a, 0xc4, 0xff, 0x61, 0x38, 0x5a, 0x4c, 0xa4, 0xeb, 0x22, 0xe7, + 0xfc, 0xf4, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xe4, 0x09, 0xf3, 0xd7, 0xbd, 0x10, 0x00, 0x00, } diff --git a/go/vt/proto/queryservice/queryservice.pb.go b/go/vt/proto/queryservice/queryservice.pb.go index 4291acefe36..74b816b4ede 100644 --- a/go/vt/proto/queryservice/queryservice.pb.go +++ b/go/vt/proto/queryservice/queryservice.pb.go @@ -30,43 +30,44 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package func init() { proto.RegisterFile("queryservice.proto", fileDescriptor_4bd2dde8711f22e3) } var fileDescriptor_4bd2dde8711f22e3 = []byte{ - // 563 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x95, 0x4f, 0x6f, 0xd3, 0x4c, - 0x10, 0xc6, 0xdf, 0xf7, 0xd0, 0x06, 0x4d, 0x52, 0x28, 0x5b, 0x0a, 0xd4, 0x2d, 0x69, 0xe9, 0x0d, - 0x21, 0x25, 0x08, 0x90, 0x90, 0x2a, 0x71, 0x68, 0x2c, 0x2a, 0x50, 0xc5, 0x3f, 0x87, 0x56, 0x88, - 0x03, 0xd2, 0xc6, 0x5e, 0x05, 0xab, 0x8e, 0xd7, 0xf5, 0x6e, 0x52, 0xf8, 0x7c, 0x7c, 0x31, 0x84, - 0xd7, 0x33, 0xde, 0xdd, 0xd8, 0xdc, 0xb2, 0xcf, 0x33, 0xf3, 0xd3, 0x78, 0x27, 0x33, 0x0b, 0xec, - 0x7a, 0x29, 0xca, 0x5f, 0x4a, 0x94, 0xab, 0x34, 0x16, 0xa3, 0xa2, 0x94, 0x5a, 0xb2, 0x81, 0xad, - 0x05, 0xfd, 0xea, 0x64, 0xac, 0x60, 0x7b, 0x96, 0xe6, 0x99, 0x9c, 0x27, 0x5c, 0x73, 0xa3, 0x3c, - 0xff, 0xbd, 0x05, 0x1b, 0x9f, 0xff, 0x46, 0xb0, 0x13, 0xe8, 0xbd, 0xf9, 0x29, 0xe2, 0xa5, 0x16, - 0x6c, 0x77, 0x64, 0x92, 0xea, 0x73, 0x24, 0xae, 0x97, 0x42, 0xe9, 0xe0, 0xbe, 0x2f, 0xab, 0x42, - 0xe6, 0x4a, 0x1c, 0xff, 0xc7, 0xde, 0xc1, 0xa0, 0x16, 0x27, 0x5c, 0xc7, 0x3f, 0x58, 0xe0, 0x46, - 0x56, 0x22, 0x52, 0xf6, 0x5b, 0x3d, 0x42, 0x7d, 0x80, 0xad, 0xa9, 0x2e, 0x05, 0x5f, 0x60, 0x31, - 0x18, 0xef, 0xa8, 0x08, 0x3b, 0x68, 0x37, 0x91, 0xf6, 0xec, 0x7f, 0xf6, 0x12, 0x36, 0x26, 0x62, - 0x9e, 0xe6, 0x6c, 0xa7, 0x0e, 0xad, 0x4e, 0x98, 0x7f, 0xcf, 0x15, 0xa9, 0x8a, 0x57, 0xb0, 0x19, - 0xca, 0xc5, 0x22, 0xd5, 0x0c, 0x23, 0xcc, 0x11, 0xf3, 0x76, 0x3d, 0x95, 0x12, 0x5f, 0xc3, 0xad, - 0x48, 0x66, 0xd9, 0x8c, 0xc7, 0x57, 0x0c, 0xef, 0x0b, 0x05, 0x4c, 0x7e, 0xb0, 0xa6, 0x53, 0xfa, - 0x09, 0xf4, 0x3e, 0x95, 0xa2, 0xe0, 0x65, 0xd3, 0x84, 0xfa, 0xec, 0x37, 0x81, 0x64, 0xca, 0xfd, - 0x08, 0xb7, 0x4d, 0x39, 0xb5, 0x95, 0xb0, 0x03, 0xa7, 0x4a, 0x94, 0x91, 0xf4, 0xa8, 0xc3, 0x25, - 0xe0, 0x05, 0x6c, 0x63, 0x89, 0x84, 0x1c, 0x7a, 0xb5, 0xfb, 0xd0, 0xc3, 0x4e, 0x9f, 0xb0, 0x5f, - 0xe1, 0x6e, 0x58, 0x0a, 0xae, 0xc5, 0x97, 0x92, 0xe7, 0x8a, 0xc7, 0x3a, 0x95, 0x39, 0xc3, 0xbc, - 0x35, 0x07, 0xc1, 0x47, 0xdd, 0x01, 0x44, 0x3e, 0x83, 0xfe, 0x54, 0xf3, 0x52, 0xd7, 0xad, 0xdb, - 0xa3, 0x3f, 0x07, 0x69, 0x48, 0x0b, 0xda, 0x2c, 0x87, 0x23, 0x34, 0xf5, 0x91, 0x38, 0x8d, 0xb6, - 0xc6, 0xb1, 0x2d, 0xe2, 0x7c, 0x87, 0x9d, 0x50, 0xe6, 0x71, 0xb6, 0x4c, 0x9c, 0x6f, 0x7d, 0x4c, - 0x17, 0xbf, 0xe6, 0x21, 0xf7, 0xf8, 0x5f, 0x21, 0xc4, 0x8f, 0xe0, 0x4e, 0x24, 0x78, 0x62, 0xb3, - 0xb1, 0xa9, 0x9e, 0x8e, 0xdc, 0x61, 0x97, 0x6d, 0x8f, 0x72, 0x35, 0x0c, 0x38, 0x7e, 0x81, 0x3d, - 0x21, 0xde, 0xf4, 0xed, 0xb7, 0x7a, 0x76, 0xa3, 0x6d, 0xc7, 0xac, 0x86, 0xc3, 0x96, 0x1c, 0x67, - 0x3f, 0x1c, 0x75, 0x07, 0xd8, 0x4b, 0xe2, 0xbd, 0x50, 0x8a, 0xcf, 0x85, 0x19, 0x7c, 0x5a, 0x12, - 0x8e, 0xea, 0x2f, 0x09, 0xcf, 0xb4, 0x96, 0x44, 0x08, 0x50, 0x9b, 0xa7, 0xf1, 0x15, 0x7b, 0xe8, - 0xc6, 0x9f, 0x36, 0xed, 0xde, 0x6b, 0x71, 0xa8, 0xa8, 0x10, 0x60, 0x5a, 0x64, 0xa9, 0x36, 0xeb, - 0x14, 0x21, 0x8d, 0xe4, 0x43, 0x6c, 0x87, 0x20, 0xe7, 0x30, 0x30, 0xf5, 0xbd, 0x15, 0x3c, 0xd3, - 0xcd, 0x26, 0xb5, 0x45, 0xff, 0xfa, 0x5d, 0xcf, 0xfa, 0xac, 0x73, 0x18, 0x5c, 0x14, 0x09, 0xd7, - 0x78, 0x4b, 0x08, 0xb3, 0x45, 0x1f, 0xe6, 0x7a, 0x16, 0xec, 0x0c, 0x7a, 0x97, 0xc4, 0xb1, 0xde, - 0x91, 0x4b, 0x9f, 0xd3, 0xe6, 0x59, 0x9c, 0x08, 0xfa, 0x28, 0xcb, 0x1b, 0xc5, 0x86, 0x6d, 0xf1, - 0xf2, 0x46, 0x35, 0x0b, 0xa5, 0xcb, 0x6f, 0x98, 0x93, 0xa7, 0xdf, 0x9e, 0xac, 0x52, 0x2d, 0x94, - 0x1a, 0xa5, 0x72, 0x6c, 0x7e, 0x8d, 0xe7, 0x72, 0xbc, 0xd2, 0xe3, 0xea, 0x95, 0x1b, 0xdb, 0x2f, - 0xe2, 0x6c, 0xb3, 0xd2, 0x5e, 0xfc, 0x09, 0x00, 0x00, 0xff, 0xff, 0xdd, 0x23, 0x8f, 0x51, 0x3c, - 0x07, 0x00, 0x00, + // 582 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x95, 0xdf, 0x6f, 0xd3, 0x30, + 0x10, 0xc7, 0xe1, 0x61, 0x2b, 0xba, 0x96, 0x32, 0x3c, 0x06, 0x2c, 0x1b, 0xdd, 0x8f, 0x37, 0x84, + 0xd4, 0x22, 0x40, 0x42, 0x9a, 0xc4, 0xc3, 0x5a, 0x31, 0x81, 0x26, 0x7e, 0xb5, 0x6c, 0x42, 0x20, + 0x21, 0xb9, 0xa9, 0x55, 0xa2, 0xa5, 0x71, 0x16, 0x3b, 0x1d, 0xfc, 0x37, 0xfc, 0xa9, 0xd3, 0xe2, + 0xdc, 0xc5, 0x76, 0x93, 0xbd, 0xcd, 0xdf, 0xef, 0xdd, 0x67, 0x17, 0x5f, 0xef, 0x0c, 0xec, 0x32, + 0x17, 0xd9, 0x3f, 0x25, 0xb2, 0x65, 0x14, 0x8a, 0x7e, 0x9a, 0x49, 0x2d, 0x59, 0xc7, 0xd6, 0x82, + 0x76, 0x71, 0x32, 0x56, 0xb0, 0x31, 0x8d, 0x92, 0x58, 0xce, 0x67, 0x5c, 0x73, 0xa3, 0xbc, 0xfa, + 0xdf, 0x85, 0xb5, 0x6f, 0x37, 0x11, 0xec, 0x08, 0x5a, 0xef, 0xff, 0x8a, 0x30, 0xd7, 0x82, 0x6d, + 0xf5, 0x4d, 0x52, 0x79, 0x1e, 0x8b, 0xcb, 0x5c, 0x28, 0x1d, 0x3c, 0xf6, 0x65, 0x95, 0xca, 0x44, + 0x89, 0xc3, 0x3b, 0xec, 0x23, 0x74, 0x4a, 0x71, 0xc8, 0x75, 0xf8, 0x87, 0x05, 0x6e, 0x64, 0x21, + 0x22, 0x65, 0xa7, 0xd6, 0x23, 0xd4, 0x67, 0xb8, 0x3f, 0xd1, 0x99, 0xe0, 0x0b, 0x2c, 0x06, 0xe3, + 0x1d, 0x15, 0x61, 0xbb, 0xf5, 0x26, 0xd2, 0x5e, 0xde, 0x65, 0x6f, 0x60, 0x6d, 0x28, 0xe6, 0x51, + 0xc2, 0x36, 0xcb, 0xd0, 0xe2, 0x84, 0xf9, 0x8f, 0x5c, 0x91, 0xaa, 0x78, 0x0b, 0xeb, 0x23, 0xb9, + 0x58, 0x44, 0x9a, 0x61, 0x84, 0x39, 0x62, 0xde, 0x96, 0xa7, 0x52, 0xe2, 0x3b, 0xb8, 0x37, 0x96, + 0x71, 0x3c, 0xe5, 0xe1, 0x05, 0xc3, 0xfb, 0x42, 0x01, 0x93, 0x9f, 0xac, 0xe8, 0x94, 0x7e, 0x04, + 0xad, 0xaf, 0x99, 0x48, 0x79, 0x56, 0x35, 0xa1, 0x3c, 0xfb, 0x4d, 0x20, 0x99, 0x72, 0xbf, 0x40, + 0xd7, 0x94, 0x53, 0x5a, 0x33, 0xb6, 0xeb, 0x54, 0x89, 0x32, 0x92, 0x9e, 0x35, 0xb8, 0x04, 0x3c, + 0x83, 0x0d, 0x2c, 0x91, 0x90, 0x3d, 0xaf, 0x76, 0x1f, 0xba, 0xd7, 0xe8, 0x13, 0xf6, 0x07, 0x3c, + 0x1c, 0x65, 0x82, 0x6b, 0xf1, 0x3d, 0xe3, 0x89, 0xe2, 0xa1, 0x8e, 0x64, 0xc2, 0x30, 0x6f, 0xc5, + 0x41, 0xf0, 0x7e, 0x73, 0x00, 0x91, 0x4f, 0xa0, 0x3d, 0xd1, 0x3c, 0xd3, 0x65, 0xeb, 0xb6, 0xe9, + 0xc7, 0x41, 0x1a, 0xd2, 0x82, 0x3a, 0xcb, 0xe1, 0x08, 0x4d, 0x7d, 0x24, 0x4e, 0xa5, 0xad, 0x70, + 0x6c, 0x8b, 0x38, 0xbf, 0x61, 0x73, 0x24, 0x93, 0x30, 0xce, 0x67, 0xce, 0xb7, 0x1e, 0xd0, 0xc5, + 0xaf, 0x78, 0xc8, 0x3d, 0xbc, 0x2d, 0x84, 0xf8, 0x63, 0x78, 0x30, 0x16, 0x7c, 0x66, 0xb3, 0xb1, + 0xa9, 0x9e, 0x8e, 0xdc, 0x5e, 0x93, 0x6d, 0x8f, 0x72, 0x31, 0x0c, 0x38, 0x7e, 0x81, 0x3d, 0x21, + 0xde, 0xf4, 0xed, 0xd4, 0x7a, 0x76, 0xa3, 0x6d, 0xc7, 0xac, 0x86, 0xbd, 0x9a, 0x1c, 0x67, 0x3f, + 0xec, 0x37, 0x07, 0xd8, 0x4b, 0xe2, 0x93, 0x50, 0x8a, 0xcf, 0x85, 0x19, 0x7c, 0x5a, 0x12, 0x8e, + 0xea, 0x2f, 0x09, 0xcf, 0xb4, 0x96, 0xc4, 0x08, 0xa0, 0x34, 0x8f, 0xc3, 0x0b, 0xf6, 0xd4, 0x8d, + 0x3f, 0xae, 0xda, 0xbd, 0x5d, 0xe3, 0x50, 0x51, 0x23, 0x80, 0x49, 0x1a, 0x47, 0xda, 0xac, 0x53, + 0x84, 0x54, 0x92, 0x0f, 0xb1, 0x1d, 0x82, 0x9c, 0x42, 0xc7, 0xd4, 0xf7, 0x41, 0xf0, 0x58, 0x57, + 0x9b, 0xd4, 0x16, 0xfd, 0xeb, 0x77, 0x3d, 0xeb, 0xb3, 0x4e, 0xa1, 0x73, 0x96, 0xce, 0xb8, 0xc6, + 0x5b, 0x42, 0x98, 0x2d, 0xfa, 0x30, 0xd7, 0xb3, 0x60, 0x27, 0xd0, 0x3a, 0x27, 0x8e, 0xf5, 0x8e, + 0x9c, 0xfb, 0x9c, 0x3a, 0xcf, 0xe2, 0x8c, 0xa1, 0x8d, 0xb2, 0xbc, 0x52, 0xac, 0x57, 0x17, 0x2f, + 0xaf, 0x54, 0xb5, 0x50, 0x9a, 0x7c, 0x8b, 0xf9, 0x0b, 0xba, 0xd5, 0xbf, 0xca, 0x63, 0xad, 0xd8, + 0x41, 0x7d, 0x19, 0x37, 0x5e, 0x35, 0x63, 0xb7, 0x84, 0x54, 0xf0, 0xe1, 0x8b, 0x9f, 0xcf, 0x97, + 0x91, 0x16, 0x4a, 0xf5, 0x23, 0x39, 0x30, 0x7f, 0x0d, 0xe6, 0x72, 0xb0, 0xd4, 0x83, 0xe2, 0x09, + 0x1d, 0xd8, 0xcf, 0xed, 0x74, 0xbd, 0xd0, 0x5e, 0x5f, 0x07, 0x00, 0x00, 0xff, 0xff, 0xbe, 0xb4, + 0xc0, 0x34, 0x99, 0x07, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -134,6 +135,8 @@ type QueryClient interface { VStream(ctx context.Context, in *binlogdata.VStreamRequest, opts ...grpc.CallOption) (Query_VStreamClient, error) // VStreamRows streams rows from the specified starting point. VStreamRows(ctx context.Context, in *binlogdata.VStreamRowsRequest, opts ...grpc.CallOption) (Query_VStreamRowsClient, error) + // VStreamResults streams results along with the gtid of the snapshot. + VStreamResults(ctx context.Context, in *binlogdata.VStreamResultsRequest, opts ...grpc.CallOption) (Query_VStreamResultsClient, error) } type queryClient struct { @@ -489,6 +492,38 @@ func (x *queryVStreamRowsClient) Recv() (*binlogdata.VStreamRowsResponse, error) return m, nil } +func (c *queryClient) VStreamResults(ctx context.Context, in *binlogdata.VStreamResultsRequest, opts ...grpc.CallOption) (Query_VStreamResultsClient, error) { + stream, err := c.cc.NewStream(ctx, &_Query_serviceDesc.Streams[6], "/queryservice.Query/VStreamResults", opts...) + if err != nil { + return nil, err + } + x := &queryVStreamResultsClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Query_VStreamResultsClient interface { + Recv() (*binlogdata.VStreamResultsResponse, error) + grpc.ClientStream +} + +type queryVStreamResultsClient struct { + grpc.ClientStream +} + +func (x *queryVStreamResultsClient) Recv() (*binlogdata.VStreamResultsResponse, error) { + m := new(binlogdata.VStreamResultsResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // Execute executes the specified SQL query (might be in a @@ -544,6 +579,8 @@ type QueryServer interface { VStream(*binlogdata.VStreamRequest, Query_VStreamServer) error // VStreamRows streams rows from the specified starting point. VStreamRows(*binlogdata.VStreamRowsRequest, Query_VStreamRowsServer) error + // VStreamResults streams results along with the gtid of the snapshot. + VStreamResults(*binlogdata.VStreamResultsRequest, Query_VStreamResultsServer) error } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -619,6 +656,9 @@ func (*UnimplementedQueryServer) VStream(req *binlogdata.VStreamRequest, srv Que func (*UnimplementedQueryServer) VStreamRows(req *binlogdata.VStreamRowsRequest, srv Query_VStreamRowsServer) error { return status.Errorf(codes.Unimplemented, "method VStreamRows not implemented") } +func (*UnimplementedQueryServer) VStreamResults(req *binlogdata.VStreamResultsRequest, srv Query_VStreamResultsServer) error { + return status.Errorf(codes.Unimplemented, "method VStreamResults not implemented") +} func RegisterQueryServer(s *grpc.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -1056,6 +1096,27 @@ func (x *queryVStreamRowsServer) Send(m *binlogdata.VStreamRowsResponse) error { return x.ServerStream.SendMsg(m) } +func _Query_VStreamResults_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(binlogdata.VStreamResultsRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(QueryServer).VStreamResults(m, &queryVStreamResultsServer{stream}) +} + +type Query_VStreamResultsServer interface { + Send(*binlogdata.VStreamResultsResponse) error + grpc.ServerStream +} + +type queryVStreamResultsServer struct { + grpc.ServerStream +} + +func (x *queryVStreamResultsServer) Send(m *binlogdata.VStreamResultsResponse) error { + return x.ServerStream.SendMsg(m) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "queryservice.Query", HandlerType: (*QueryServer)(nil), @@ -1160,6 +1221,11 @@ var _Query_serviceDesc = grpc.ServiceDesc{ Handler: _Query_VStreamRows_Handler, ServerStreams: true, }, + { + StreamName: "VStreamResults", + Handler: _Query_VStreamResults_Handler, + ServerStreams: true, + }, }, Metadata: "queryservice.proto", } diff --git a/go/vt/vtcombo/tablet_map.go b/go/vt/vtcombo/tablet_map.go index aaa6f32a3a0..ca93afa61ac 100644 --- a/go/vt/vtcombo/tablet_map.go +++ b/go/vt/vtcombo/tablet_map.go @@ -490,6 +490,12 @@ func (itc *internalTabletConn) VStreamRows(ctx context.Context, target *querypb. return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) } +// VStreamResults is part of the QueryService interface. +func (itc *internalTabletConn) VStreamResults(ctx context.Context, target *querypb.Target, query string, send func(*binlogdatapb.VStreamResultsResponse) error) error { + err := itc.tablet.qsc.QueryService().VStreamResults(ctx, target, query, send) + return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) +} + // // TabletManagerClient implementation // diff --git a/go/vt/vttablet/grpcqueryservice/server.go b/go/vt/vttablet/grpcqueryservice/server.go index 654e3b8e535..7e56b983926 100644 --- a/go/vt/vttablet/grpcqueryservice/server.go +++ b/go/vt/vttablet/grpcqueryservice/server.go @@ -393,6 +393,17 @@ func (q *query) VStreamRows(request *binlogdatapb.VStreamRowsRequest, stream que return vterrors.ToGRPC(err) } +// VStreamResults is part of the queryservice.QueryServer interface +func (q *query) VStreamResults(request *binlogdatapb.VStreamResultsRequest, stream queryservicepb.Query_VStreamResultsServer) (err error) { + defer q.server.HandlePanic(&err) + ctx := callerid.NewContext(callinfo.GRPCCallInfo(stream.Context()), + request.EffectiveCallerId, + request.ImmediateCallerId, + ) + err = q.server.VStreamResults(ctx, request.Target, request.Query, stream.Send) + return vterrors.ToGRPC(err) +} + // Register registers the implementation on the provide gRPC Server. func Register(s *grpc.Server, server queryservice.QueryService) { queryservicepb.RegisterQueryServer(s, &query{server}) diff --git a/go/vt/vttablet/grpctabletconn/conn.go b/go/vt/vttablet/grpctabletconn/conn.go index 7b257bc605d..a10ba36320c 100644 --- a/go/vt/vttablet/grpctabletconn/conn.go +++ b/go/vt/vttablet/grpctabletconn/conn.go @@ -755,6 +755,46 @@ func (conn *gRPCQueryClient) VStreamRows(ctx context.Context, target *querypb.Ta } } +// VStreamResults streams rows of a query from the specified starting point. +func (conn *gRPCQueryClient) VStreamResults(ctx context.Context, target *querypb.Target, query string, send func(*binlogdatapb.VStreamResultsResponse) error) error { + stream, err := func() (queryservicepb.Query_VStreamResultsClient, error) { + conn.mu.RLock() + defer conn.mu.RUnlock() + if conn.cc == nil { + return nil, tabletconn.ConnClosed + } + + req := &binlogdatapb.VStreamResultsRequest{ + Target: target, + EffectiveCallerId: callerid.EffectiveCallerIDFromContext(ctx), + ImmediateCallerId: callerid.ImmediateCallerIDFromContext(ctx), + Query: query, + } + stream, err := conn.c.VStreamResults(ctx, req) + if err != nil { + return nil, tabletconn.ErrorFromGRPC(err) + } + return stream, nil + }() + if err != nil { + return err + } + for { + r, err := stream.Recv() + if err != nil { + return tabletconn.ErrorFromGRPC(err) + } + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + if err := send(r); err != nil { + return err + } + } +} + // HandlePanic is a no-op. func (conn *gRPCQueryClient) HandlePanic(err *error) { } diff --git a/go/vt/vttablet/queryservice/queryservice.go b/go/vt/vttablet/queryservice/queryservice.go index d4acedb6313..4182161a294 100644 --- a/go/vt/vttablet/queryservice/queryservice.go +++ b/go/vt/vttablet/queryservice/queryservice.go @@ -106,6 +106,9 @@ type QueryService interface { // VStreamRows streams rows of a table from the specified starting point. VStreamRows(ctx context.Context, target *querypb.Target, query string, lastpk *querypb.QueryResult, send func(*binlogdatapb.VStreamRowsResponse) error) error + // VStreamResults streams results along with the gtid of the snapshot. + VStreamResults(ctx context.Context, target *querypb.Target, query string, send func(*binlogdatapb.VStreamResultsResponse) error) error + // StreamHealth streams health status. StreamHealth(ctx context.Context, callback func(*querypb.StreamHealthResponse) error) error diff --git a/go/vt/vttablet/queryservice/wrapped.go b/go/vt/vttablet/queryservice/wrapped.go index bb44a5d0563..202dd0a3213 100644 --- a/go/vt/vttablet/queryservice/wrapped.go +++ b/go/vt/vttablet/queryservice/wrapped.go @@ -265,6 +265,13 @@ func (ws *wrappedService) VStreamRows(ctx context.Context, target *querypb.Targe }) } +func (ws *wrappedService) VStreamResults(ctx context.Context, target *querypb.Target, query string, send func(*binlogdatapb.VStreamResultsResponse) error) error { + return ws.wrapper(ctx, target, ws.impl, "VStreamResults", false, func(ctx context.Context, target *querypb.Target, conn QueryService) (bool, error) { + innerErr := conn.VStreamResults(ctx, target, query, send) + return false, innerErr + }) +} + func (ws *wrappedService) StreamHealth(ctx context.Context, callback func(*querypb.StreamHealthResponse) error) error { return ws.wrapper(ctx, nil, ws.impl, "StreamHealth", false, func(ctx context.Context, target *querypb.Target, conn QueryService) (bool, error) { innerErr := conn.StreamHealth(ctx, callback) diff --git a/go/vt/vttablet/sandboxconn/sandboxconn.go b/go/vt/vttablet/sandboxconn/sandboxconn.go index ffa509d222c..5c460c180f7 100644 --- a/go/vt/vttablet/sandboxconn/sandboxconn.go +++ b/go/vt/vttablet/sandboxconn/sandboxconn.go @@ -391,6 +391,11 @@ func (sbc *SandboxConn) VStreamRows(ctx context.Context, target *querypb.Target, return fmt.Errorf("not implemented in test") } +// VStreamResults is part of the QueryService interface. +func (sbc *SandboxConn) VStreamResults(ctx context.Context, target *querypb.Target, query string, send func(*binlogdatapb.VStreamResultsResponse) error) error { + return fmt.Errorf("not implemented in test") +} + // HandlePanic is part of the QueryService interface. func (sbc *SandboxConn) HandlePanic(err *error) { } diff --git a/go/vt/vttablet/tabletconntest/fakequeryservice.go b/go/vt/vttablet/tabletconntest/fakequeryservice.go index cab3029022a..32ea47b3c26 100644 --- a/go/vt/vttablet/tabletconntest/fakequeryservice.go +++ b/go/vt/vttablet/tabletconntest/fakequeryservice.go @@ -863,6 +863,11 @@ func (f *FakeQueryService) VStreamRows(ctx context.Context, target *querypb.Targ panic("not implemented") } +// VStreamResults is part of the QueryService interface. +func (f *FakeQueryService) VStreamResults(ctx context.Context, target *querypb.Target, query string, send func(*binlogdatapb.VStreamResultsResponse) error) error { + panic("not implemented") +} + // CreateFakeServer returns the fake server for the tests func CreateFakeServer(t *testing.T) *FakeQueryService { return &FakeQueryService{ diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index 8e98828963f..1de6dbfa8dd 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -1406,6 +1406,14 @@ func (tsv *TabletServer) VStreamRows(ctx context.Context, target *querypb.Target return tsv.vstreamer.StreamRows(ctx, query, row, send) } +// VStreamResults streams rows from the specified starting point. +func (tsv *TabletServer) VStreamResults(ctx context.Context, target *querypb.Target, query string, send func(*binlogdatapb.VStreamResultsResponse) error) error { + if err := tsv.verifyTarget(ctx, target); err != nil { + return err + } + return tsv.vstreamer.StreamResults(ctx, query, send) +} + // SplitQuery splits a query + bind variables into smaller queries that return a // subset of rows from the original query. This is the new version that supports multiple // split columns and multiple split algorithms. diff --git a/go/vt/vttablet/tabletserver/vstreamer/engine.go b/go/vt/vttablet/tabletserver/vstreamer/engine.go index 828c905b6db..67ae75be8c0 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/engine.go +++ b/go/vt/vttablet/tabletserver/vstreamer/engine.go @@ -56,10 +56,11 @@ type Engine struct { isOpen bool // wg is incremented for every Stream, and decremented on end. // Close waits for all current streams to end by waiting on wg. - wg sync.WaitGroup - streamers map[int]*vstreamer - rowStreamers map[int]*rowStreamer - streamIdx int + wg sync.WaitGroup + streamers map[int]*vstreamer + rowStreamers map[int]*rowStreamer + resultStreamers map[int]*resultStreamer + streamIdx int // watcherOnce is used for initializing kschema // and setting up the vschema watch. It's guaranteed that @@ -80,11 +81,12 @@ type Engine struct { // Open and Close can be called multiple times and are idempotent. func NewEngine(ts srvtopo.Server, se *schema.Engine) *Engine { vse := &Engine{ - streamers: make(map[int]*vstreamer), - rowStreamers: make(map[int]*rowStreamer), - kschema: &vindexes.KeyspaceSchema{}, - ts: ts, - se: se, + streamers: make(map[int]*vstreamer), + rowStreamers: make(map[int]*rowStreamer), + resultStreamers: make(map[int]*resultStreamer), + kschema: &vindexes.KeyspaceSchema{}, + ts: ts, + se: se, } once.Do(func() { vschemaErrors = stats.NewCounter("VSchemaErrors", "Count of VSchema errors") @@ -120,12 +122,14 @@ func (vse *Engine) Close() { if !vse.isOpen { return } + // cancels are non-blocking. for _, s := range vse.streamers { - // cancel is non-blocking. s.Cancel() } for _, s := range vse.rowStreamers { - // cancel is non-blocking. + s.Cancel() + } + for _, s := range vse.resultStreamers { s.Cancel() } vse.isOpen = false @@ -221,6 +225,40 @@ func (vse *Engine) StreamRows(ctx context.Context, query string, lastpk []sqltyp return rowStreamer.Stream() } +// StreamResults streams results of the query with the gtid. +func (vse *Engine) StreamResults(ctx context.Context, query string, send func(*binlogdatapb.VStreamResultsResponse) error) error { + // Create stream and add it to the map. + resultStreamer, idx, err := func() (*resultStreamer, int, error) { + vse.mu.Lock() + defer vse.mu.Unlock() + if !vse.isOpen { + return nil, 0, errors.New("VStreamer is not open") + } + resultStreamer := newResultStreamer(ctx, vse.cp, query, send) + idx := vse.streamIdx + vse.resultStreamers[idx] = resultStreamer + vse.streamIdx++ + // Now that we've added the stream, increment wg. + // This must be done before releasing the lock. + vse.wg.Add(1) + return resultStreamer, idx, nil + }() + if err != nil { + return err + } + + // Remove stream from map and decrement wg when it ends. + defer func() { + vse.mu.Lock() + defer vse.mu.Unlock() + delete(vse.resultStreamers, idx) + vse.wg.Done() + }() + + // No lock is held while streaming, but wg is incremented. + return resultStreamer.Stream() +} + // ServeHTTP shows the current VSchema. func (vse *Engine) ServeHTTP(response http.ResponseWriter, request *http.Request) { if err := acl.CheckAccessHTTP(request, acl.DEBUGGING); err != nil { diff --git a/go/vt/vttablet/tabletserver/vstreamer/resultstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/resultstreamer.go new file mode 100644 index 00000000000..e79b1076434 --- /dev/null +++ b/go/vt/vttablet/tabletserver/vstreamer/resultstreamer.go @@ -0,0 +1,168 @@ +/* +Copyright 2019 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vstreamer + +import ( + "context" + "fmt" + + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/dbconfigs" + "vitess.io/vitess/go/vt/log" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + "vitess.io/vitess/go/vt/sqlparser" +) + +type resultStreamer struct { + ctx context.Context + cancel func() + + cp *mysql.ConnParams + query string + tableName sqlparser.TableIdent + send func(*binlogdatapb.VStreamResultsResponse) error +} + +func newResultStreamer(ctx context.Context, cp *mysql.ConnParams, query string, send func(*binlogdatapb.VStreamResultsResponse) error) *resultStreamer { + ctx, cancel := context.WithCancel(ctx) + return &resultStreamer{ + ctx: ctx, + cancel: cancel, + cp: cp, + query: query, + send: send, + } +} + +func (rs *resultStreamer) Cancel() { + rs.cancel() +} + +func (rs *resultStreamer) Stream() error { + _, fromTable, err := analyzeSelect(rs.query) + if err != nil { + return err + } + rs.tableName = fromTable + + conn, err := rs.mysqlConnect() + if err != nil { + return err + } + defer conn.Close() + gtid, err := rs.startStreaming(conn) + if err != nil { + return err + } + + // first call the callback with the fields + flds, err := conn.Fields() + if err != nil { + return err + } + + err = rs.send(&binlogdatapb.VStreamResultsResponse{ + Fields: flds, + Gtid: gtid, + }) + if err != nil { + return fmt.Errorf("stream send error: %v", err) + } + + response := &binlogdatapb.VStreamResultsResponse{} + byteCount := 0 + for { + select { + case <-rs.ctx.Done(): + return fmt.Errorf("stream ended: %v", rs.ctx.Err()) + default: + } + + row, err := conn.FetchNext() + if err != nil { + return err + } + if row == nil { + break + } + response.Rows = append(response.Rows, sqltypes.RowToProto3(row)) + for _, s := range row { + byteCount += s.Len() + } + + if byteCount >= *PacketSize { + err = rs.send(response) + if err != nil { + return err + } + // empty the rows so we start over, but we keep the + // same capacity + response.Rows = response.Rows[:0] + byteCount = 0 + } + } + + if len(response.Rows) > 0 { + err = rs.send(response) + if err != nil { + return err + } + } + + return nil +} + +func (rs *resultStreamer) startStreaming(conn *mysql.Conn) (string, error) { + lockConn, err := rs.mysqlConnect() + if err != nil { + return "", err + } + // To be safe, always unlock tables, even if lock tables might fail. + defer func() { + _, err := lockConn.ExecuteFetch("unlock tables", 0, false) + if err != nil { + log.Warning("Unlock tables failed: %v", err) + } else { + log.Infof("Tables unlocked", rs.tableName) + } + lockConn.Close() + }() + + log.Infof("Locking table %s for copying", rs.tableName) + if _, err := lockConn.ExecuteFetch(fmt.Sprintf("lock tables %s read", sqlparser.String(rs.tableName)), 0, false); err != nil { + return "", err + } + pos, err := lockConn.MasterPosition() + if err != nil { + return "", err + } + + if err := conn.ExecuteStreamFetch(rs.query); err != nil { + return "", err + } + + return mysql.EncodePosition(pos), nil +} + +func (rs *resultStreamer) mysqlConnect() (*mysql.Conn, error) { + cp, err := dbconfigs.WithCredentials(rs.cp) + if err != nil { + return nil, err + } + return mysql.Connect(rs.ctx, cp) +} diff --git a/proto/binlogdata.proto b/proto/binlogdata.proto index 0f30eb70ffa..9b7e817ed6e 100644 --- a/proto/binlogdata.proto +++ b/proto/binlogdata.proto @@ -290,3 +290,21 @@ message VStreamRowsResponse { repeated query.Row rows = 4; query.Row lastpk = 5; } + +// VStreamResultsRequest is the payload for VStreamResults +// The ids match VStreamRows, in case we decide to merge the two. +message VStreamResultsRequest { + vtrpc.CallerID effective_caller_id = 1; + query.VTGateCallerID immediate_caller_id = 2; + query.Target target = 3; + + string query = 4; +} + +// VStreamResultsResponse is the response from VStreamResults +// The ids match VStreamRows, in case we decide to merge the two. +message VStreamResultsResponse { + repeated query.Field fields = 1; + string gtid = 3; + repeated query.Row rows = 4; +} diff --git a/proto/queryservice.proto b/proto/queryservice.proto index e6b91cdc1f6..fe2bd018150 100644 --- a/proto/queryservice.proto +++ b/proto/queryservice.proto @@ -101,4 +101,7 @@ service Query { // VStreamRows streams rows from the specified starting point. rpc VStreamRows(binlogdata.VStreamRowsRequest) returns (stream binlogdata.VStreamRowsResponse) {}; + + // VStreamResults streams results along with the gtid of the snapshot. + rpc VStreamResults(binlogdata.VStreamResultsRequest) returns (stream binlogdata.VStreamResultsResponse) {}; } diff --git a/py/vtproto/binlogdata_pb2.py b/py/vtproto/binlogdata_pb2.py index 0846f180e05..ae761e90e68 100644 --- a/py/vtproto/binlogdata_pb2.py +++ b/py/vtproto/binlogdata_pb2.py @@ -23,7 +23,7 @@ package='binlogdata', syntax='proto3', serialized_options=_b('Z\'vitess.io/vitess/go/vt/proto/binlogdata'), - serialized_pb=_b('\n\x10\x62inlogdata.proto\x12\nbinlogdata\x1a\x0bvtrpc.proto\x1a\x0bquery.proto\x1a\x0etopodata.proto\"7\n\x07\x43harset\x12\x0e\n\x06\x63lient\x18\x01 \x01(\x05\x12\x0c\n\x04\x63onn\x18\x02 \x01(\x05\x12\x0e\n\x06server\x18\x03 \x01(\x05\"\xb5\x03\n\x11\x42inlogTransaction\x12;\n\nstatements\x18\x01 \x03(\x0b\x32\'.binlogdata.BinlogTransaction.Statement\x12&\n\x0b\x65vent_token\x18\x04 \x01(\x0b\x32\x11.query.EventToken\x1a\xae\x02\n\tStatement\x12\x42\n\x08\x63\x61tegory\x18\x01 \x01(\x0e\x32\x30.binlogdata.BinlogTransaction.Statement.Category\x12$\n\x07\x63harset\x18\x02 \x01(\x0b\x32\x13.binlogdata.Charset\x12\x0b\n\x03sql\x18\x03 \x01(\x0c\"\xa9\x01\n\x08\x43\x61tegory\x12\x13\n\x0f\x42L_UNRECOGNIZED\x10\x00\x12\x0c\n\x08\x42L_BEGIN\x10\x01\x12\r\n\tBL_COMMIT\x10\x02\x12\x0f\n\x0b\x42L_ROLLBACK\x10\x03\x12\x15\n\x11\x42L_DML_DEPRECATED\x10\x04\x12\n\n\x06\x42L_DDL\x10\x05\x12\n\n\x06\x42L_SET\x10\x06\x12\r\n\tBL_INSERT\x10\x07\x12\r\n\tBL_UPDATE\x10\x08\x12\r\n\tBL_DELETE\x10\tJ\x04\x08\x02\x10\x03J\x04\x08\x03\x10\x04\"v\n\x15StreamKeyRangeRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12%\n\tkey_range\x18\x02 \x01(\x0b\x32\x12.topodata.KeyRange\x12$\n\x07\x63harset\x18\x03 \x01(\x0b\x32\x13.binlogdata.Charset\"S\n\x16StreamKeyRangeResponse\x12\x39\n\x12\x62inlog_transaction\x18\x01 \x01(\x0b\x32\x1d.binlogdata.BinlogTransaction\"]\n\x13StreamTablesRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x0e\n\x06tables\x18\x02 \x03(\t\x12$\n\x07\x63harset\x18\x03 \x01(\x0b\x32\x13.binlogdata.Charset\"Q\n\x14StreamTablesResponse\x12\x39\n\x12\x62inlog_transaction\x18\x01 \x01(\x0b\x32\x1d.binlogdata.BinlogTransaction\"%\n\x04Rule\x12\r\n\x05match\x18\x01 \x01(\t\x12\x0e\n\x06\x66ilter\x18\x02 \x01(\t\"\x9c\x01\n\x06\x46ilter\x12\x1f\n\x05rules\x18\x01 \x03(\x0b\x32\x10.binlogdata.Rule\x12\x39\n\x0e\x66ieldEventMode\x18\x02 \x01(\x0e\x32!.binlogdata.Filter.FieldEventMode\"6\n\x0e\x46ieldEventMode\x12\x13\n\x0f\x45RR_ON_MISMATCH\x10\x00\x12\x0f\n\x0b\x42\x45ST_EFFORT\x10\x01\"\xde\x01\n\x0c\x42inlogSource\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\r\n\x05shard\x18\x02 \x01(\t\x12)\n\x0btablet_type\x18\x03 \x01(\x0e\x32\x14.topodata.TabletType\x12%\n\tkey_range\x18\x04 \x01(\x0b\x32\x12.topodata.KeyRange\x12\x0e\n\x06tables\x18\x05 \x03(\t\x12\"\n\x06\x66ilter\x18\x06 \x01(\x0b\x32\x12.binlogdata.Filter\x12\'\n\x06on_ddl\x18\x07 \x01(\x0e\x32\x17.binlogdata.OnDDLAction\"B\n\tRowChange\x12\x1a\n\x06\x62\x65\x66ore\x18\x01 \x01(\x0b\x32\n.query.Row\x12\x19\n\x05\x61\x66ter\x18\x02 \x01(\x0b\x32\n.query.Row\"J\n\x08RowEvent\x12\x12\n\ntable_name\x18\x01 \x01(\t\x12*\n\x0brow_changes\x18\x02 \x03(\x0b\x32\x15.binlogdata.RowChange\">\n\nFieldEvent\x12\x12\n\ntable_name\x18\x01 \x01(\t\x12\x1c\n\x06\x66ields\x18\x02 \x03(\x0b\x32\x0c.query.Field\":\n\tShardGtid\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\r\n\x05shard\x18\x02 \x01(\t\x12\x0c\n\x04gtid\x18\x03 \x01(\t\"3\n\x05VGtid\x12*\n\x0bshard_gtids\x18\x01 \x03(\x0b\x32\x15.binlogdata.ShardGtid\"0\n\rKeyspaceShard\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\r\n\x05shard\x18\x02 \x01(\t\"\xe7\x01\n\x07Journal\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x31\n\x0emigration_type\x18\x02 \x01(\x0e\x32\x19.binlogdata.MigrationType\x12\x0e\n\x06tables\x18\x03 \x03(\t\x12\x16\n\x0elocal_position\x18\x04 \x01(\t\x12*\n\x0bshard_gtids\x18\x05 \x03(\x0b\x32\x15.binlogdata.ShardGtid\x12/\n\x0cparticipants\x18\x06 \x03(\x0b\x32\x19.binlogdata.KeyspaceShard\x12\x18\n\x10source_workflows\x18\x07 \x03(\t\"\x90\x02\n\x06VEvent\x12$\n\x04type\x18\x01 \x01(\x0e\x32\x16.binlogdata.VEventType\x12\x11\n\ttimestamp\x18\x02 \x01(\x03\x12\x0c\n\x04gtid\x18\x03 \x01(\t\x12\x0b\n\x03\x64\x64l\x18\x04 \x01(\t\x12\'\n\trow_event\x18\x05 \x01(\x0b\x32\x14.binlogdata.RowEvent\x12+\n\x0b\x66ield_event\x18\x06 \x01(\x0b\x32\x16.binlogdata.FieldEvent\x12 \n\x05vgtid\x18\x07 \x01(\x0b\x32\x11.binlogdata.VGtid\x12$\n\x07journal\x18\x08 \x01(\x0b\x32\x13.binlogdata.Journal\x12\x14\n\x0c\x63urrent_time\x18\x14 \x01(\x03\"\xc7\x01\n\x0eVStreamRequest\x12,\n\x13\x65\x66\x66\x65\x63tive_caller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12\x32\n\x13immediate_caller_id\x18\x02 \x01(\x0b\x32\x15.query.VTGateCallerID\x12\x1d\n\x06target\x18\x03 \x01(\x0b\x32\r.query.Target\x12\x10\n\x08position\x18\x04 \x01(\t\x12\"\n\x06\x66ilter\x18\x05 \x01(\x0b\x32\x12.binlogdata.Filter\"5\n\x0fVStreamResponse\x12\"\n\x06\x65vents\x18\x01 \x03(\x0b\x32\x12.binlogdata.VEvent\"\xc8\x01\n\x12VStreamRowsRequest\x12,\n\x13\x65\x66\x66\x65\x63tive_caller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12\x32\n\x13immediate_caller_id\x18\x02 \x01(\x0b\x32\x15.query.VTGateCallerID\x12\x1d\n\x06target\x18\x03 \x01(\x0b\x32\r.query.Target\x12\r\n\x05query\x18\x04 \x01(\t\x12\"\n\x06lastpk\x18\x05 \x01(\x0b\x32\x12.query.QueryResult\"\x97\x01\n\x13VStreamRowsResponse\x12\x1c\n\x06\x66ields\x18\x01 \x03(\x0b\x32\x0c.query.Field\x12\x1e\n\x08pkfields\x18\x02 \x03(\x0b\x32\x0c.query.Field\x12\x0c\n\x04gtid\x18\x03 \x01(\t\x12\x18\n\x04rows\x18\x04 \x03(\x0b\x32\n.query.Row\x12\x1a\n\x06lastpk\x18\x05 \x01(\x0b\x32\n.query.Row*>\n\x0bOnDDLAction\x12\n\n\x06IGNORE\x10\x00\x12\x08\n\x04STOP\x10\x01\x12\x08\n\x04\x45XEC\x10\x02\x12\x0f\n\x0b\x45XEC_IGNORE\x10\x03*\xd1\x01\n\nVEventType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x08\n\x04GTID\x10\x01\x12\t\n\x05\x42\x45GIN\x10\x02\x12\n\n\x06\x43OMMIT\x10\x03\x12\x0c\n\x08ROLLBACK\x10\x04\x12\x07\n\x03\x44\x44L\x10\x05\x12\n\n\x06INSERT\x10\x06\x12\x0b\n\x07REPLACE\x10\x07\x12\n\n\x06UPDATE\x10\x08\x12\n\n\x06\x44\x45LETE\x10\t\x12\x07\n\x03SET\x10\n\x12\t\n\x05OTHER\x10\x0b\x12\x07\n\x03ROW\x10\x0c\x12\t\n\x05\x46IELD\x10\r\x12\r\n\tHEARTBEAT\x10\x0e\x12\t\n\x05VGTID\x10\x0f\x12\x0b\n\x07JOURNAL\x10\x10*\'\n\rMigrationType\x12\n\n\x06TABLES\x10\x00\x12\n\n\x06SHARDS\x10\x01\x42)Z\'vitess.io/vitess/go/vt/proto/binlogdatab\x06proto3') + serialized_pb=_b('\n\x10\x62inlogdata.proto\x12\nbinlogdata\x1a\x0bvtrpc.proto\x1a\x0bquery.proto\x1a\x0etopodata.proto\"7\n\x07\x43harset\x12\x0e\n\x06\x63lient\x18\x01 \x01(\x05\x12\x0c\n\x04\x63onn\x18\x02 \x01(\x05\x12\x0e\n\x06server\x18\x03 \x01(\x05\"\xb5\x03\n\x11\x42inlogTransaction\x12;\n\nstatements\x18\x01 \x03(\x0b\x32\'.binlogdata.BinlogTransaction.Statement\x12&\n\x0b\x65vent_token\x18\x04 \x01(\x0b\x32\x11.query.EventToken\x1a\xae\x02\n\tStatement\x12\x42\n\x08\x63\x61tegory\x18\x01 \x01(\x0e\x32\x30.binlogdata.BinlogTransaction.Statement.Category\x12$\n\x07\x63harset\x18\x02 \x01(\x0b\x32\x13.binlogdata.Charset\x12\x0b\n\x03sql\x18\x03 \x01(\x0c\"\xa9\x01\n\x08\x43\x61tegory\x12\x13\n\x0f\x42L_UNRECOGNIZED\x10\x00\x12\x0c\n\x08\x42L_BEGIN\x10\x01\x12\r\n\tBL_COMMIT\x10\x02\x12\x0f\n\x0b\x42L_ROLLBACK\x10\x03\x12\x15\n\x11\x42L_DML_DEPRECATED\x10\x04\x12\n\n\x06\x42L_DDL\x10\x05\x12\n\n\x06\x42L_SET\x10\x06\x12\r\n\tBL_INSERT\x10\x07\x12\r\n\tBL_UPDATE\x10\x08\x12\r\n\tBL_DELETE\x10\tJ\x04\x08\x02\x10\x03J\x04\x08\x03\x10\x04\"v\n\x15StreamKeyRangeRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12%\n\tkey_range\x18\x02 \x01(\x0b\x32\x12.topodata.KeyRange\x12$\n\x07\x63harset\x18\x03 \x01(\x0b\x32\x13.binlogdata.Charset\"S\n\x16StreamKeyRangeResponse\x12\x39\n\x12\x62inlog_transaction\x18\x01 \x01(\x0b\x32\x1d.binlogdata.BinlogTransaction\"]\n\x13StreamTablesRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x0e\n\x06tables\x18\x02 \x03(\t\x12$\n\x07\x63harset\x18\x03 \x01(\x0b\x32\x13.binlogdata.Charset\"Q\n\x14StreamTablesResponse\x12\x39\n\x12\x62inlog_transaction\x18\x01 \x01(\x0b\x32\x1d.binlogdata.BinlogTransaction\"%\n\x04Rule\x12\r\n\x05match\x18\x01 \x01(\t\x12\x0e\n\x06\x66ilter\x18\x02 \x01(\t\"\x9c\x01\n\x06\x46ilter\x12\x1f\n\x05rules\x18\x01 \x03(\x0b\x32\x10.binlogdata.Rule\x12\x39\n\x0e\x66ieldEventMode\x18\x02 \x01(\x0e\x32!.binlogdata.Filter.FieldEventMode\"6\n\x0e\x46ieldEventMode\x12\x13\n\x0f\x45RR_ON_MISMATCH\x10\x00\x12\x0f\n\x0b\x42\x45ST_EFFORT\x10\x01\"\xde\x01\n\x0c\x42inlogSource\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\r\n\x05shard\x18\x02 \x01(\t\x12)\n\x0btablet_type\x18\x03 \x01(\x0e\x32\x14.topodata.TabletType\x12%\n\tkey_range\x18\x04 \x01(\x0b\x32\x12.topodata.KeyRange\x12\x0e\n\x06tables\x18\x05 \x03(\t\x12\"\n\x06\x66ilter\x18\x06 \x01(\x0b\x32\x12.binlogdata.Filter\x12\'\n\x06on_ddl\x18\x07 \x01(\x0e\x32\x17.binlogdata.OnDDLAction\"B\n\tRowChange\x12\x1a\n\x06\x62\x65\x66ore\x18\x01 \x01(\x0b\x32\n.query.Row\x12\x19\n\x05\x61\x66ter\x18\x02 \x01(\x0b\x32\n.query.Row\"J\n\x08RowEvent\x12\x12\n\ntable_name\x18\x01 \x01(\t\x12*\n\x0brow_changes\x18\x02 \x03(\x0b\x32\x15.binlogdata.RowChange\">\n\nFieldEvent\x12\x12\n\ntable_name\x18\x01 \x01(\t\x12\x1c\n\x06\x66ields\x18\x02 \x03(\x0b\x32\x0c.query.Field\":\n\tShardGtid\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\r\n\x05shard\x18\x02 \x01(\t\x12\x0c\n\x04gtid\x18\x03 \x01(\t\"3\n\x05VGtid\x12*\n\x0bshard_gtids\x18\x01 \x03(\x0b\x32\x15.binlogdata.ShardGtid\"0\n\rKeyspaceShard\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\r\n\x05shard\x18\x02 \x01(\t\"\xe7\x01\n\x07Journal\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x31\n\x0emigration_type\x18\x02 \x01(\x0e\x32\x19.binlogdata.MigrationType\x12\x0e\n\x06tables\x18\x03 \x03(\t\x12\x16\n\x0elocal_position\x18\x04 \x01(\t\x12*\n\x0bshard_gtids\x18\x05 \x03(\x0b\x32\x15.binlogdata.ShardGtid\x12/\n\x0cparticipants\x18\x06 \x03(\x0b\x32\x19.binlogdata.KeyspaceShard\x12\x18\n\x10source_workflows\x18\x07 \x03(\t\"\x90\x02\n\x06VEvent\x12$\n\x04type\x18\x01 \x01(\x0e\x32\x16.binlogdata.VEventType\x12\x11\n\ttimestamp\x18\x02 \x01(\x03\x12\x0c\n\x04gtid\x18\x03 \x01(\t\x12\x0b\n\x03\x64\x64l\x18\x04 \x01(\t\x12\'\n\trow_event\x18\x05 \x01(\x0b\x32\x14.binlogdata.RowEvent\x12+\n\x0b\x66ield_event\x18\x06 \x01(\x0b\x32\x16.binlogdata.FieldEvent\x12 \n\x05vgtid\x18\x07 \x01(\x0b\x32\x11.binlogdata.VGtid\x12$\n\x07journal\x18\x08 \x01(\x0b\x32\x13.binlogdata.Journal\x12\x14\n\x0c\x63urrent_time\x18\x14 \x01(\x03\"\xc7\x01\n\x0eVStreamRequest\x12,\n\x13\x65\x66\x66\x65\x63tive_caller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12\x32\n\x13immediate_caller_id\x18\x02 \x01(\x0b\x32\x15.query.VTGateCallerID\x12\x1d\n\x06target\x18\x03 \x01(\x0b\x32\r.query.Target\x12\x10\n\x08position\x18\x04 \x01(\t\x12\"\n\x06\x66ilter\x18\x05 \x01(\x0b\x32\x12.binlogdata.Filter\"5\n\x0fVStreamResponse\x12\"\n\x06\x65vents\x18\x01 \x03(\x0b\x32\x12.binlogdata.VEvent\"\xc8\x01\n\x12VStreamRowsRequest\x12,\n\x13\x65\x66\x66\x65\x63tive_caller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12\x32\n\x13immediate_caller_id\x18\x02 \x01(\x0b\x32\x15.query.VTGateCallerID\x12\x1d\n\x06target\x18\x03 \x01(\x0b\x32\r.query.Target\x12\r\n\x05query\x18\x04 \x01(\t\x12\"\n\x06lastpk\x18\x05 \x01(\x0b\x32\x12.query.QueryResult\"\x97\x01\n\x13VStreamRowsResponse\x12\x1c\n\x06\x66ields\x18\x01 \x03(\x0b\x32\x0c.query.Field\x12\x1e\n\x08pkfields\x18\x02 \x03(\x0b\x32\x0c.query.Field\x12\x0c\n\x04gtid\x18\x03 \x01(\t\x12\x18\n\x04rows\x18\x04 \x03(\x0b\x32\n.query.Row\x12\x1a\n\x06lastpk\x18\x05 \x01(\x0b\x32\n.query.Row\"\xa7\x01\n\x15VStreamResultsRequest\x12,\n\x13\x65\x66\x66\x65\x63tive_caller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12\x32\n\x13immediate_caller_id\x18\x02 \x01(\x0b\x32\x15.query.VTGateCallerID\x12\x1d\n\x06target\x18\x03 \x01(\x0b\x32\r.query.Target\x12\r\n\x05query\x18\x04 \x01(\t\"^\n\x16VStreamResultsResponse\x12\x1c\n\x06\x66ields\x18\x01 \x03(\x0b\x32\x0c.query.Field\x12\x0c\n\x04gtid\x18\x03 \x01(\t\x12\x18\n\x04rows\x18\x04 \x03(\x0b\x32\n.query.Row*>\n\x0bOnDDLAction\x12\n\n\x06IGNORE\x10\x00\x12\x08\n\x04STOP\x10\x01\x12\x08\n\x04\x45XEC\x10\x02\x12\x0f\n\x0b\x45XEC_IGNORE\x10\x03*\xd1\x01\n\nVEventType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x08\n\x04GTID\x10\x01\x12\t\n\x05\x42\x45GIN\x10\x02\x12\n\n\x06\x43OMMIT\x10\x03\x12\x0c\n\x08ROLLBACK\x10\x04\x12\x07\n\x03\x44\x44L\x10\x05\x12\n\n\x06INSERT\x10\x06\x12\x0b\n\x07REPLACE\x10\x07\x12\n\n\x06UPDATE\x10\x08\x12\n\n\x06\x44\x45LETE\x10\t\x12\x07\n\x03SET\x10\n\x12\t\n\x05OTHER\x10\x0b\x12\x07\n\x03ROW\x10\x0c\x12\t\n\x05\x46IELD\x10\r\x12\r\n\tHEARTBEAT\x10\x0e\x12\t\n\x05VGTID\x10\x0f\x12\x0b\n\x07JOURNAL\x10\x10*\'\n\rMigrationType\x12\n\n\x06TABLES\x10\x00\x12\n\n\x06SHARDS\x10\x01\x42)Z\'vitess.io/vitess/go/vt/proto/binlogdatab\x06proto3') , dependencies=[vtrpc__pb2.DESCRIPTOR,query__pb2.DESCRIPTOR,topodata__pb2.DESCRIPTOR,]) @@ -52,8 +52,8 @@ ], containing_type=None, serialized_options=None, - serialized_start=2871, - serialized_end=2933, + serialized_start=3137, + serialized_end=3199, ) _sym_db.RegisterEnumDescriptor(_ONDDLACTION) @@ -135,8 +135,8 @@ ], containing_type=None, serialized_options=None, - serialized_start=2936, - serialized_end=3145, + serialized_start=3202, + serialized_end=3411, ) _sym_db.RegisterEnumDescriptor(_VEVENTTYPE) @@ -158,8 +158,8 @@ ], containing_type=None, serialized_options=None, - serialized_start=3147, - serialized_end=3186, + serialized_start=3413, + serialized_end=3452, ) _sym_db.RegisterEnumDescriptor(_MIGRATIONTYPE) @@ -1291,6 +1291,103 @@ serialized_end=2869, ) + +_VSTREAMRESULTSREQUEST = _descriptor.Descriptor( + name='VStreamResultsRequest', + full_name='binlogdata.VStreamResultsRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='effective_caller_id', full_name='binlogdata.VStreamResultsRequest.effective_caller_id', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='immediate_caller_id', full_name='binlogdata.VStreamResultsRequest.immediate_caller_id', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='target', full_name='binlogdata.VStreamResultsRequest.target', index=2, + number=3, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='query', full_name='binlogdata.VStreamResultsRequest.query', index=3, + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=2872, + serialized_end=3039, +) + + +_VSTREAMRESULTSRESPONSE = _descriptor.Descriptor( + name='VStreamResultsResponse', + full_name='binlogdata.VStreamResultsResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='fields', full_name='binlogdata.VStreamResultsResponse.fields', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='gtid', full_name='binlogdata.VStreamResultsResponse.gtid', index=1, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='rows', full_name='binlogdata.VStreamResultsResponse.rows', index=2, + number=4, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=3041, + serialized_end=3135, +) + _BINLOGTRANSACTION_STATEMENT.fields_by_name['category'].enum_type = _BINLOGTRANSACTION_STATEMENT_CATEGORY _BINLOGTRANSACTION_STATEMENT.fields_by_name['charset'].message_type = _CHARSET _BINLOGTRANSACTION_STATEMENT.containing_type = _BINLOGTRANSACTION @@ -1335,6 +1432,11 @@ _VSTREAMROWSRESPONSE.fields_by_name['pkfields'].message_type = query__pb2._FIELD _VSTREAMROWSRESPONSE.fields_by_name['rows'].message_type = query__pb2._ROW _VSTREAMROWSRESPONSE.fields_by_name['lastpk'].message_type = query__pb2._ROW +_VSTREAMRESULTSREQUEST.fields_by_name['effective_caller_id'].message_type = vtrpc__pb2._CALLERID +_VSTREAMRESULTSREQUEST.fields_by_name['immediate_caller_id'].message_type = query__pb2._VTGATECALLERID +_VSTREAMRESULTSREQUEST.fields_by_name['target'].message_type = query__pb2._TARGET +_VSTREAMRESULTSRESPONSE.fields_by_name['fields'].message_type = query__pb2._FIELD +_VSTREAMRESULTSRESPONSE.fields_by_name['rows'].message_type = query__pb2._ROW DESCRIPTOR.message_types_by_name['Charset'] = _CHARSET DESCRIPTOR.message_types_by_name['BinlogTransaction'] = _BINLOGTRANSACTION DESCRIPTOR.message_types_by_name['StreamKeyRangeRequest'] = _STREAMKEYRANGEREQUEST @@ -1356,6 +1458,8 @@ DESCRIPTOR.message_types_by_name['VStreamResponse'] = _VSTREAMRESPONSE DESCRIPTOR.message_types_by_name['VStreamRowsRequest'] = _VSTREAMROWSREQUEST DESCRIPTOR.message_types_by_name['VStreamRowsResponse'] = _VSTREAMROWSRESPONSE +DESCRIPTOR.message_types_by_name['VStreamResultsRequest'] = _VSTREAMRESULTSREQUEST +DESCRIPTOR.message_types_by_name['VStreamResultsResponse'] = _VSTREAMRESULTSRESPONSE DESCRIPTOR.enum_types_by_name['OnDDLAction'] = _ONDDLACTION DESCRIPTOR.enum_types_by_name['VEventType'] = _VEVENTTYPE DESCRIPTOR.enum_types_by_name['MigrationType'] = _MIGRATIONTYPE @@ -1516,6 +1620,20 @@ )) _sym_db.RegisterMessage(VStreamRowsResponse) +VStreamResultsRequest = _reflection.GeneratedProtocolMessageType('VStreamResultsRequest', (_message.Message,), dict( + DESCRIPTOR = _VSTREAMRESULTSREQUEST, + __module__ = 'binlogdata_pb2' + # @@protoc_insertion_point(class_scope:binlogdata.VStreamResultsRequest) + )) +_sym_db.RegisterMessage(VStreamResultsRequest) + +VStreamResultsResponse = _reflection.GeneratedProtocolMessageType('VStreamResultsResponse', (_message.Message,), dict( + DESCRIPTOR = _VSTREAMRESULTSRESPONSE, + __module__ = 'binlogdata_pb2' + # @@protoc_insertion_point(class_scope:binlogdata.VStreamResultsResponse) + )) +_sym_db.RegisterMessage(VStreamResultsResponse) + DESCRIPTOR._options = None # @@protoc_insertion_point(module_scope) diff --git a/py/vtproto/queryservice_pb2.py b/py/vtproto/queryservice_pb2.py index 986c7701187..b7082eaf642 100644 --- a/py/vtproto/queryservice_pb2.py +++ b/py/vtproto/queryservice_pb2.py @@ -21,7 +21,7 @@ package='queryservice', syntax='proto3', serialized_options=_b('Z)vitess.io/vitess/go/vt/proto/queryservice'), - serialized_pb=_b('\n\x12queryservice.proto\x12\x0cqueryservice\x1a\x0bquery.proto\x1a\x10\x62inlogdata.proto2\xc3\r\n\x05Query\x12:\n\x07\x45xecute\x12\x15.query.ExecuteRequest\x1a\x16.query.ExecuteResponse\"\x00\x12I\n\x0c\x45xecuteBatch\x12\x1a.query.ExecuteBatchRequest\x1a\x1b.query.ExecuteBatchResponse\"\x00\x12N\n\rStreamExecute\x12\x1b.query.StreamExecuteRequest\x1a\x1c.query.StreamExecuteResponse\"\x00\x30\x01\x12\x34\n\x05\x42\x65gin\x12\x13.query.BeginRequest\x1a\x14.query.BeginResponse\"\x00\x12\x37\n\x06\x43ommit\x12\x14.query.CommitRequest\x1a\x15.query.CommitResponse\"\x00\x12=\n\x08Rollback\x12\x16.query.RollbackRequest\x1a\x17.query.RollbackResponse\"\x00\x12:\n\x07Prepare\x12\x15.query.PrepareRequest\x1a\x16.query.PrepareResponse\"\x00\x12O\n\x0e\x43ommitPrepared\x12\x1c.query.CommitPreparedRequest\x1a\x1d.query.CommitPreparedResponse\"\x00\x12U\n\x10RollbackPrepared\x12\x1e.query.RollbackPreparedRequest\x1a\x1f.query.RollbackPreparedResponse\"\x00\x12X\n\x11\x43reateTransaction\x12\x1f.query.CreateTransactionRequest\x1a .query.CreateTransactionResponse\"\x00\x12\x46\n\x0bStartCommit\x12\x19.query.StartCommitRequest\x1a\x1a.query.StartCommitResponse\"\x00\x12\x46\n\x0bSetRollback\x12\x19.query.SetRollbackRequest\x1a\x1a.query.SetRollbackResponse\"\x00\x12^\n\x13\x43oncludeTransaction\x12!.query.ConcludeTransactionRequest\x1a\".query.ConcludeTransactionResponse\"\x00\x12R\n\x0fReadTransaction\x12\x1d.query.ReadTransactionRequest\x1a\x1e.query.ReadTransactionResponse\"\x00\x12I\n\x0c\x42\x65ginExecute\x12\x1a.query.BeginExecuteRequest\x1a\x1b.query.BeginExecuteResponse\"\x00\x12X\n\x11\x42\x65ginExecuteBatch\x12\x1f.query.BeginExecuteBatchRequest\x1a .query.BeginExecuteBatchResponse\"\x00\x12N\n\rMessageStream\x12\x1b.query.MessageStreamRequest\x1a\x1c.query.MessageStreamResponse\"\x00\x30\x01\x12\x43\n\nMessageAck\x12\x18.query.MessageAckRequest\x1a\x19.query.MessageAckResponse\"\x00\x12\x43\n\nSplitQuery\x12\x18.query.SplitQueryRequest\x1a\x19.query.SplitQueryResponse\"\x00\x12K\n\x0cStreamHealth\x12\x1a.query.StreamHealthRequest\x1a\x1b.query.StreamHealthResponse\"\x00\x30\x01\x12K\n\x0cUpdateStream\x12\x1a.query.UpdateStreamRequest\x1a\x1b.query.UpdateStreamResponse\"\x00\x30\x01\x12\x46\n\x07VStream\x12\x1a.binlogdata.VStreamRequest\x1a\x1b.binlogdata.VStreamResponse\"\x00\x30\x01\x12R\n\x0bVStreamRows\x12\x1e.binlogdata.VStreamRowsRequest\x1a\x1f.binlogdata.VStreamRowsResponse\"\x00\x30\x01\x42+Z)vitess.io/vitess/go/vt/proto/queryserviceb\x06proto3') + serialized_pb=_b('\n\x12queryservice.proto\x12\x0cqueryservice\x1a\x0bquery.proto\x1a\x10\x62inlogdata.proto2\xa0\x0e\n\x05Query\x12:\n\x07\x45xecute\x12\x15.query.ExecuteRequest\x1a\x16.query.ExecuteResponse\"\x00\x12I\n\x0c\x45xecuteBatch\x12\x1a.query.ExecuteBatchRequest\x1a\x1b.query.ExecuteBatchResponse\"\x00\x12N\n\rStreamExecute\x12\x1b.query.StreamExecuteRequest\x1a\x1c.query.StreamExecuteResponse\"\x00\x30\x01\x12\x34\n\x05\x42\x65gin\x12\x13.query.BeginRequest\x1a\x14.query.BeginResponse\"\x00\x12\x37\n\x06\x43ommit\x12\x14.query.CommitRequest\x1a\x15.query.CommitResponse\"\x00\x12=\n\x08Rollback\x12\x16.query.RollbackRequest\x1a\x17.query.RollbackResponse\"\x00\x12:\n\x07Prepare\x12\x15.query.PrepareRequest\x1a\x16.query.PrepareResponse\"\x00\x12O\n\x0e\x43ommitPrepared\x12\x1c.query.CommitPreparedRequest\x1a\x1d.query.CommitPreparedResponse\"\x00\x12U\n\x10RollbackPrepared\x12\x1e.query.RollbackPreparedRequest\x1a\x1f.query.RollbackPreparedResponse\"\x00\x12X\n\x11\x43reateTransaction\x12\x1f.query.CreateTransactionRequest\x1a .query.CreateTransactionResponse\"\x00\x12\x46\n\x0bStartCommit\x12\x19.query.StartCommitRequest\x1a\x1a.query.StartCommitResponse\"\x00\x12\x46\n\x0bSetRollback\x12\x19.query.SetRollbackRequest\x1a\x1a.query.SetRollbackResponse\"\x00\x12^\n\x13\x43oncludeTransaction\x12!.query.ConcludeTransactionRequest\x1a\".query.ConcludeTransactionResponse\"\x00\x12R\n\x0fReadTransaction\x12\x1d.query.ReadTransactionRequest\x1a\x1e.query.ReadTransactionResponse\"\x00\x12I\n\x0c\x42\x65ginExecute\x12\x1a.query.BeginExecuteRequest\x1a\x1b.query.BeginExecuteResponse\"\x00\x12X\n\x11\x42\x65ginExecuteBatch\x12\x1f.query.BeginExecuteBatchRequest\x1a .query.BeginExecuteBatchResponse\"\x00\x12N\n\rMessageStream\x12\x1b.query.MessageStreamRequest\x1a\x1c.query.MessageStreamResponse\"\x00\x30\x01\x12\x43\n\nMessageAck\x12\x18.query.MessageAckRequest\x1a\x19.query.MessageAckResponse\"\x00\x12\x43\n\nSplitQuery\x12\x18.query.SplitQueryRequest\x1a\x19.query.SplitQueryResponse\"\x00\x12K\n\x0cStreamHealth\x12\x1a.query.StreamHealthRequest\x1a\x1b.query.StreamHealthResponse\"\x00\x30\x01\x12K\n\x0cUpdateStream\x12\x1a.query.UpdateStreamRequest\x1a\x1b.query.UpdateStreamResponse\"\x00\x30\x01\x12\x46\n\x07VStream\x12\x1a.binlogdata.VStreamRequest\x1a\x1b.binlogdata.VStreamResponse\"\x00\x30\x01\x12R\n\x0bVStreamRows\x12\x1e.binlogdata.VStreamRowsRequest\x1a\x1f.binlogdata.VStreamRowsResponse\"\x00\x30\x01\x12[\n\x0eVStreamResults\x12!.binlogdata.VStreamResultsRequest\x1a\".binlogdata.VStreamResultsResponse\"\x00\x30\x01\x42+Z)vitess.io/vitess/go/vt/proto/queryserviceb\x06proto3') , dependencies=[query__pb2.DESCRIPTOR,binlogdata__pb2.DESCRIPTOR,]) @@ -39,7 +39,7 @@ index=0, serialized_options=None, serialized_start=68, - serialized_end=1799, + serialized_end=1892, methods=[ _descriptor.MethodDescriptor( name='Execute', @@ -248,6 +248,15 @@ output_type=binlogdata__pb2._VSTREAMROWSRESPONSE, serialized_options=None, ), + _descriptor.MethodDescriptor( + name='VStreamResults', + full_name='queryservice.Query.VStreamResults', + index=23, + containing_service=None, + input_type=binlogdata__pb2._VSTREAMRESULTSREQUEST, + output_type=binlogdata__pb2._VSTREAMRESULTSRESPONSE, + serialized_options=None, + ), ]) _sym_db.RegisterServiceDescriptor(_QUERY) diff --git a/py/vtproto/queryservice_pb2_grpc.py b/py/vtproto/queryservice_pb2_grpc.py index f6d80e62adc..f8d31b3ce3e 100644 --- a/py/vtproto/queryservice_pb2_grpc.py +++ b/py/vtproto/queryservice_pb2_grpc.py @@ -130,6 +130,11 @@ def __init__(self, channel): request_serializer=binlogdata__pb2.VStreamRowsRequest.SerializeToString, response_deserializer=binlogdata__pb2.VStreamRowsResponse.FromString, ) + self.VStreamResults = channel.unary_stream( + '/queryservice.Query/VStreamResults', + request_serializer=binlogdata__pb2.VStreamResultsRequest.SerializeToString, + response_deserializer=binlogdata__pb2.VStreamResultsResponse.FromString, + ) class QueryServicer(object): @@ -304,6 +309,13 @@ def VStreamRows(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def VStreamResults(self, request, context): + """VStreamResults streams results along with the gtid of the snapshot. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def add_QueryServicer_to_server(servicer, server): rpc_method_handlers = { @@ -422,6 +434,11 @@ def add_QueryServicer_to_server(servicer, server): request_deserializer=binlogdata__pb2.VStreamRowsRequest.FromString, response_serializer=binlogdata__pb2.VStreamRowsResponse.SerializeToString, ), + 'VStreamResults': grpc.unary_stream_rpc_method_handler( + servicer.VStreamResults, + request_deserializer=binlogdata__pb2.VStreamResultsRequest.FromString, + response_serializer=binlogdata__pb2.VStreamResultsResponse.SerializeToString, + ), } generic_handler = grpc.method_handlers_generic_handler( 'queryservice.Query', rpc_method_handlers) From 0f608e9203c976bf4162d4aeca74e2ef18830b68 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 13 Oct 2019 22:05:17 -0700 Subject: [PATCH 05/28] vdiff: resultStreamer test Signed-off-by: Sugu Sougoumarane --- .../tabletserver/vstreamer/planbuilder.go | 2 +- .../vstreamer/resultstreamer_test.go | 78 +++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 go/vt/vttablet/tabletserver/vstreamer/resultstreamer_test.go diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index f2284f5a006..c620f83d3ca 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -73,7 +73,7 @@ func (plan *Plan) filter(values []sqltypes.Value) (bool, []sqltypes.Value, error result := make([]sqltypes.Value, len(plan.ColExprs)) for i, colExpr := range plan.ColExprs { if colExpr.ColNum >= len(values) { - return false, nil, fmt.Errorf("index out of range. colExpr.ColNum: %d len(values):%d!!", colExpr.ColNum, len(values)) + return false, nil, fmt.Errorf("index out of range, colExpr.ColNum: %d, len(values):%d", colExpr.ColNum, len(values)) } result[i] = values[colExpr.ColNum] } diff --git a/go/vt/vttablet/tabletserver/vstreamer/resultstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/resultstreamer_test.go new file mode 100644 index 00000000000..b84915a08f6 --- /dev/null +++ b/go/vt/vttablet/tabletserver/vstreamer/resultstreamer_test.go @@ -0,0 +1,78 @@ +/* +Copyright 2019 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vstreamer + +import ( + "context" + "fmt" + "testing" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" +) + +func TestStreamResults(t *testing.T) { + if testing.Short() { + t.Skip() + } + + execStatements(t, []string{ + "create table t1(id int, val varbinary(128), primary key(id))", + "insert into t1 values (1, 'aaa'), (2, 'bbb')", + }) + defer execStatements(t, []string{ + "drop table t1", + }) + engine.se.Reload(context.Background()) + + query := "select id, val from t1 order by id" + wantStream := []string{ + `rows: rows: `, + } + i := 0 + ch := make(chan error) + // We don't want to report errors inside callback functions because + // line numbers come out wrong. + go func() { + first := true + defer close(ch) + err := engine.StreamResults(context.Background(), query, func(rows *binlogdatapb.VStreamResultsResponse) error { + if first { + first = false + if rows.Gtid == "" { + ch <- fmt.Errorf("stream gtid is empty") + } + return nil + } + if i >= len(wantStream) { + ch <- fmt.Errorf("unexpected stream rows: %v", rows) + return nil + } + srows := fmt.Sprintf("%v", rows) + if srows != wantStream[i] { + ch <- fmt.Errorf("stream %d:\n%s, want\n%s", i, srows, wantStream[i]) + } + i++ + return nil + }) + if err != nil { + ch <- err + } + }() + for err := range ch { + t.Error(err) + } +} From c6994e5acdbe8e906e54164d59cfff9fd01a9723 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 5 Oct 2019 17:01:20 -0700 Subject: [PATCH 06/28] vdiff: stopTargetStreams, waitForSourceStreams Signed-off-by: Sugu Sougoumarane --- go/vt/wrangler/vdiff.go | 98 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index ace9ec0beae..230b76f4358 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -19,9 +19,12 @@ package wrangler import ( "fmt" "strings" + "sync" "time" + "github.com/golang/protobuf/proto" "golang.org/x/net/context" + "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/key" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" @@ -32,6 +35,11 @@ import ( "vitess.io/vitess/go/vt/vttablet/tabletmanager/vreplication" ) +type vdiff struct { + mi *migrater + differs map[string]*tableDiffer +} + type tableDiffer struct { targetTable string targetExpression string @@ -187,6 +195,96 @@ func buildDifferPlan(table *tabletmanagerdatapb.TableDefinition, query string) ( return td, nil } +func (df *vdiff) stopTargetStreams(ctx context.Context) (map[string]mysql.Position, error) { + var mu sync.Mutex + stoppedPositions := make(map[string]mysql.Position) + + err := df.mi.forAllTargets(func(target *miTarget) error { + query := fmt.Sprintf("update _vt.vreplication set state='Stopped', message='for vdiff' where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.mi.workflow)) + _, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) + if err != nil { + return err + } + query = fmt.Sprintf("select source, pos from _vt.vreplication where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.mi.workflow)) + p3qr, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) + if err != nil { + return err + } + qr := sqltypes.Proto3ToResult(p3qr) + + for _, row := range qr.Rows { + var bls binlogdatapb.BinlogSource + if err := proto.UnmarshalText(row[0].ToString(), &bls); err != nil { + return err + } + pos, err := mysql.DecodePosition(row[1].ToString()) + if err != nil { + return err + } + func() { + mu.Lock() + defer mu.Unlock() + + prev, ok := stoppedPositions[bls.Shard] + if ok && prev.AtLeast(pos) { + return + } + stoppedPositions[bls.Shard] = pos + }() + } + return nil + }) + if err != nil { + return nil, err + } + return stoppedPositions, nil +} + +func (df *vdiff) waitForSourceStreams(ctx context.Context) (map[string]mysql.Position, error) { + var mu sync.Mutex + stoppedPositions := make(map[string]mysql.Position) + + err := df.mi.forAllTargets(func(target *miTarget) error { + query := fmt.Sprintf("update _vt.vreplication set state='Stopped', message='for vdiff' where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.mi.workflow)) + _, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) + if err != nil { + return err + } + query = fmt.Sprintf("select source, pos from _vt.vreplication where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.mi.workflow)) + p3qr, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) + if err != nil { + return err + } + qr := sqltypes.Proto3ToResult(p3qr) + + for _, row := range qr.Rows { + var bls binlogdatapb.BinlogSource + if err := proto.UnmarshalText(row[0].ToString(), &bls); err != nil { + return err + } + pos, err := mysql.DecodePosition(row[1].ToString()) + if err != nil { + return err + } + func() { + mu.Lock() + defer mu.Unlock() + + prev, ok := stoppedPositions[bls.Shard] + if ok && prev.AtLeast(pos) { + return + } + stoppedPositions[bls.Shard] = pos + }() + } + return nil + }) + if err != nil { + return nil, err + } + return stoppedPositions, nil +} + func removeKeyrange(where *sqlparser.Where) *sqlparser.Where { if where == nil { return nil From c581f0e31425b30962835d2036782425fed1e194 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 6 Oct 2019 07:40:44 -0700 Subject: [PATCH 07/28] discovery: move tabletpicker from vreplication Signed-off-by: Sugu Sougoumarane --- go/vt/discovery/healthcheck_test.go | 49 +++++-- go/vt/discovery/tablet_picker.go | 105 ++++++++++++++ go/vt/discovery/tablet_picker_test.go | 198 ++++++++++++++++++++++++++ 3 files changed, 337 insertions(+), 15 deletions(-) create mode 100644 go/vt/discovery/tablet_picker.go create mode 100644 go/vt/discovery/tablet_picker_test.go diff --git a/go/vt/discovery/healthcheck_test.go b/go/vt/discovery/healthcheck_test.go index 5969f44b3de..29afa001aac 100644 --- a/go/vt/discovery/healthcheck_test.go +++ b/go/vt/discovery/healthcheck_test.go @@ -656,6 +656,22 @@ func (l *listener) StatsUpdate(ts *TabletStats) { l.output <- ts } +type fakeConn struct { + queryservice.QueryService + tablet *topodatapb.Tablet + // If fixedResult is set, the channels are not used. + fixedResult *querypb.StreamHealthResponse + // hcChan should be an unbuffered channel which holds the tablet's next health response. + hcChan chan *querypb.StreamHealthResponse + // errCh is either an unbuffered channel which holds the stream error to return, or nil. + errCh chan error + // cbErrCh is a channel which receives errors returned from the supplied callback. + cbErrCh chan error + + mu sync.Mutex + canceled bool +} + func createFakeConn(tablet *topodatapb.Tablet, c chan *querypb.StreamHealthResponse) *fakeConn { key := TabletToMapKey(tablet) conn := &fakeConn{ @@ -668,27 +684,27 @@ func createFakeConn(tablet *topodatapb.Tablet, c chan *querypb.StreamHealthRespo return conn } -func discoveryDialer(tablet *topodatapb.Tablet, failFast grpcclient.FailFast) (queryservice.QueryService, error) { +func createFixedHealthConn(tablet *topodatapb.Tablet, fixedResult *querypb.StreamHealthResponse) *fakeConn { key := TabletToMapKey(tablet) - return connMap[key], nil + conn := &fakeConn{ + QueryService: fakes.ErrorQueryService, + tablet: tablet, + fixedResult: fixedResult, + } + connMap[key] = conn + return conn } -type fakeConn struct { - queryservice.QueryService - tablet *topodatapb.Tablet - // hcChan should be an unbuffered channel which holds the tablet's next health response. - hcChan chan *querypb.StreamHealthResponse - // errCh is either an unbuffered channel which holds the stream error to return, or nil. - errCh chan error - // cbErrCh is a channel which receives errors returned from the supplied callback. - cbErrCh chan error - - mu sync.Mutex - canceled bool +func discoveryDialer(tablet *topodatapb.Tablet, failFast grpcclient.FailFast) (queryservice.QueryService, error) { + key := TabletToMapKey(tablet) + return connMap[key], nil } // StreamHealth implements queryservice.QueryService. func (fc *fakeConn) StreamHealth(ctx context.Context, callback func(shr *querypb.StreamHealthResponse) error) error { + if fc.fixedResult != nil { + return callback(fc.fixedResult) + } for { select { case shr := <-fc.hcChan: @@ -696,7 +712,10 @@ func (fc *fakeConn) StreamHealth(ctx context.Context, callback func(shr *querypb if err == io.EOF { return nil } - fc.cbErrCh <- err + select { + case fc.cbErrCh <- err: + case <-ctx.Done(): + } return err } case err := <-fc.errCh: diff --git a/go/vt/discovery/tablet_picker.go b/go/vt/discovery/tablet_picker.go new file mode 100644 index 00000000000..6434df3f873 --- /dev/null +++ b/go/vt/discovery/tablet_picker.go @@ -0,0 +1,105 @@ +/* +Copyright 2019 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package discovery + +import ( + "fmt" + "math/rand" + "time" + + "golang.org/x/net/context" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/vterrors" +) + +// These are vars because they need to be overridden for testing. +var ( + healthCheckTopologyRefresh = 30 * time.Second + healthcheckRetryDelay = 5 * time.Second + healthCheckTimeout = 1 * time.Minute +) + +// TabletPicker gives a simplified API for picking tablets. +type TabletPicker struct { + ts *topo.Server + cell string + keyspace string + shard string + tabletTypes []topodatapb.TabletType + + healthCheck HealthCheck + watcher *TopologyWatcher + statsCache *TabletStatsCache +} + +// NewTabletPicker returns a TabletPicker. +func NewTabletPicker(ctx context.Context, ts *topo.Server, cell, keyspace, shard, tabletTypesStr string) (*TabletPicker, error) { + tabletTypes, err := topoproto.ParseTabletTypes(tabletTypesStr) + if err != nil { + return nil, fmt.Errorf("failed to parse list of tablet types: %v", tabletTypesStr) + } + + // These have to be initialized in the following sequence (watcher must be last). + healthCheck := NewHealthCheck(healthcheckRetryDelay, healthCheckTimeout) + statsCache := NewTabletStatsCache(healthCheck, ts, cell) + watcher := NewShardReplicationWatcher(ctx, ts, healthCheck, cell, keyspace, shard, healthCheckTopologyRefresh, DefaultTopoReadConcurrency) + + return &TabletPicker{ + ts: ts, + cell: cell, + keyspace: keyspace, + shard: shard, + tabletTypes: tabletTypes, + healthCheck: healthCheck, + watcher: watcher, + statsCache: statsCache, + }, nil +} + +// PickForStreaming picks all healthy tablets including the non-serving ones. +func (tp *TabletPicker) PickForStreaming(ctx context.Context) (*topodatapb.Tablet, error) { + // wait for any of required the tablets (useful for the first run at least, fast for next runs) + if err := tp.statsCache.WaitForAnyTablet(ctx, tp.cell, tp.keyspace, tp.shard, tp.tabletTypes); err != nil { + return nil, vterrors.Wrapf(err, "error waiting for tablets for %v %v %v", tp.cell, tp.keyspace, tp.shard) + } + + // Find the server list from the health check. + // Note: We cannot use statsCache.GetHealthyTabletStats() here because it does + // not return non-serving tablets. We must include non-serving tablets because + // some tablets may not be serving if their traffic was already migrated to the + // destination shards. + for _, tabletType := range tp.tabletTypes { + addrs := RemoveUnhealthyTablets(tp.statsCache.GetTabletStats(tp.keyspace, tp.shard, tabletType)) + if len(addrs) > 0 { + return addrs[rand.Intn(len(addrs))].Tablet, nil + } + } + return nil, fmt.Errorf("can't find any healthy source tablet for %v %v %v", tp.keyspace, tp.shard, tp.tabletTypes) +} + +// Close shuts down TabletPicker. +func (tp *TabletPicker) Close() { + tp.watcher.Stop() + tp.healthCheck.Close() +} + +func init() { + // TODO(sougou): consolidate this call to be once per process. + rand.Seed(time.Now().UnixNano()) +} diff --git a/go/vt/discovery/tablet_picker_test.go b/go/vt/discovery/tablet_picker_test.go new file mode 100644 index 00000000000..21b76e4d418 --- /dev/null +++ b/go/vt/discovery/tablet_picker_test.go @@ -0,0 +1,198 @@ +/* +Copyright 2019 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package discovery + +import ( + "fmt" + "testing" + + "github.com/golang/protobuf/proto" + "golang.org/x/net/context" + querypb "vitess.io/vitess/go/vt/proto/query" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/memorytopo" +) + +func TestPickSimple(t *testing.T) { + te := newPickerTestEnv(t) + want := addTablet(te, 100, topodatapb.TabletType_REPLICA, true, true) + defer deleteTablet(te, want) + + tp, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "replica") + if err != nil { + t.Fatal(err) + } + defer tp.Close() + + tablet, err := tp.PickForStreaming(context.Background()) + if err != nil { + t.Fatal(err) + } + if !proto.Equal(want, tablet) { + t.Errorf("Pick: %v, want %v", tablet, want) + } +} + +func TestPickFromTwoHealthy(t *testing.T) { + te := newPickerTestEnv(t) + want1 := addTablet(te, 100, topodatapb.TabletType_REPLICA, true, true) + defer deleteTablet(te, want1) + want2 := addTablet(te, 101, topodatapb.TabletType_RDONLY, true, true) + defer deleteTablet(te, want2) + + tp, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "replica,rdonly") + if err != nil { + t.Fatal(err) + } + defer tp.Close() + + tablet, err := tp.PickForStreaming(context.Background()) + if err != nil { + t.Fatal(err) + } + if !proto.Equal(tablet, want1) { + t.Errorf("Pick:\n%v, want\n%v", tablet, want1) + } + + tp, err = NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "rdonly,replica") + if err != nil { + t.Fatal(err) + } + defer tp.Close() + + tablet, err = tp.PickForStreaming(context.Background()) + if err != nil { + t.Fatal(err) + } + if !proto.Equal(tablet, want2) { + t.Errorf("Pick:\n%v, want\n%v", tablet, want2) + } +} + +func TestPickFromSomeUnhealthy(t *testing.T) { + te := newPickerTestEnv(t) + defer deleteTablet(te, addTablet(te, 100, topodatapb.TabletType_REPLICA, false, false)) + want := addTablet(te, 101, topodatapb.TabletType_RDONLY, false, true) + defer deleteTablet(te, want) + + tp, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "replica,rdonly") + if err != nil { + t.Fatal(err) + } + defer tp.Close() + + tablet, err := tp.PickForStreaming(context.Background()) + if err != nil { + t.Fatal(err) + } + if !proto.Equal(tablet, want) { + t.Errorf("Pick:\n%v, want\n%v", tablet, want) + } +} + +func TestPickError(t *testing.T) { + te := newPickerTestEnv(t) + defer deleteTablet(te, addTablet(te, 100, topodatapb.TabletType_REPLICA, false, false)) + + _, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "badtype") + want := "failed to parse list of tablet types: badtype" + if err == nil || err.Error() != want { + t.Errorf("NewTabletPicker err: %v, want %v", err, want) + } + + tp, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "replica,rdonly") + if err != nil { + t.Fatal(err) + } + defer tp.Close() + + _, err = tp.PickForStreaming(context.Background()) + want = fmt.Sprintf("can't find any healthy source tablet for %s 0 [REPLICA RDONLY]", te.keyspace) + if err == nil || err.Error() != want { + t.Errorf("Pick err: %v, want %v", err, want) + } +} + +type pickerTestEnv struct { + t *testing.T + keyspace string + shard string + cell string + + topoServ *topo.Server +} + +func newPickerTestEnv(t *testing.T) *pickerTestEnv { + ctx := context.Background() + + te := &pickerTestEnv{ + t: t, + keyspace: "ks", + shard: "0", + cell: "cell", + topoServ: memorytopo.NewServer("cell"), + } + if err := te.topoServ.CreateKeyspace(ctx, te.keyspace, &topodatapb.Keyspace{}); err != nil { + t.Fatal(err) + } + if err := te.topoServ.CreateShard(ctx, te.keyspace, te.shard); err != nil { + t.Fatal(err) + } + return te +} + +func addTablet(te *pickerTestEnv, id int, tabletType topodatapb.TabletType, serving, healthy bool) *topodatapb.Tablet { + tablet := &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: te.cell, + Uid: uint32(id), + }, + Keyspace: te.keyspace, + Shard: te.shard, + KeyRange: &topodatapb.KeyRange{}, + Type: tabletType, + PortMap: map[string]int32{ + "test": int32(id), + }, + } + if err := te.topoServ.CreateTablet(context.Background(), tablet); err != nil { + te.t.Fatal(err) + } + + var herr string + if !healthy { + herr = "err" + } + _ = createFixedHealthConn(tablet, &querypb.StreamHealthResponse{ + Serving: serving, + Target: &querypb.Target{ + Keyspace: te.keyspace, + Shard: te.shard, + TabletType: tabletType, + }, + RealtimeStats: &querypb.RealtimeStats{HealthError: herr}, + }) + + return tablet +} + +func deleteTablet(te *pickerTestEnv, tablet *topodatapb.Tablet) { + te.topoServ.DeleteTablet(context.Background(), tablet.Alias) + // This is not automatically removed from shard replication, which results in log spam. + topo.DeleteTabletReplicationData(context.Background(), te.topoServ, tablet) +} From c6b7e30499724246583c23c5d802416315756140 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 6 Oct 2019 09:15:46 -0700 Subject: [PATCH 08/28] vreplication: use discovery.TabletPicker Signed-off-by: Sugu Sougoumarane --- .../tabletmanager/vreplication/controller.go | 7 +- .../vreplication/controller_test.go | 12 +- .../tabletmanager/vreplication/engine_test.go | 11 +- .../vreplication/framework_test.go | 73 ++++------- .../vreplication/tablet_picker.go | 105 --------------- .../vreplication/tablet_picker_test.go | 122 ------------------ .../vreplication/vcopier_test.go | 15 +-- .../vreplication/vplayer_test.go | 33 +++-- 8 files changed, 60 insertions(+), 318 deletions(-) delete mode 100644 go/vt/vttablet/tabletmanager/vreplication/tablet_picker.go delete mode 100644 go/vt/vttablet/tabletmanager/vreplication/tablet_picker_test.go diff --git a/go/vt/vttablet/tabletmanager/vreplication/controller.go b/go/vt/vttablet/tabletmanager/vreplication/controller.go index 24fe76ed521..ecdad00f55c 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/controller.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller.go @@ -22,6 +22,7 @@ import ( "strconv" "time" + "vitess.io/vitess/go/vt/discovery" "vitess.io/vitess/go/vt/vterrors" "github.com/golang/protobuf/proto" @@ -50,7 +51,7 @@ type controller struct { id uint32 source binlogdatapb.BinlogSource stopPos string - tabletPicker *tabletPicker + tabletPicker *discovery.TabletPicker cancel context.CancelFunc done chan struct{} @@ -99,7 +100,7 @@ func newController(ctx context.Context, params map[string]string, dbClientFactor if v, ok := params["tablet_types"]; ok { tabletTypesStr = v } - tp, err := newTabletPicker(ctx, ts, cell, ct.source.Keyspace, ct.source.Shard, tabletTypesStr) + tp, err := discovery.NewTabletPicker(ctx, ts, cell, ct.source.Keyspace, ct.source.Shard, tabletTypesStr) if err != nil { return nil, err } @@ -169,7 +170,7 @@ func (ct *controller) runBlp(ctx context.Context) (err error) { } defer dbClient.Close() - tablet, err := ct.tabletPicker.Pick(ctx) + tablet, err := ct.tabletPicker.PickForStreaming(ctx) if err != nil { return err } diff --git a/go/vt/vttablet/tabletmanager/vreplication/controller_test.go b/go/vt/vttablet/tabletmanager/vreplication/controller_test.go index df33417fc3c..b6cf8a3ba11 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/controller_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller_test.go @@ -56,7 +56,7 @@ var ( func TestControllerKeyRange(t *testing.T) { resetBinlogClient() - wantTablet := addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true) + wantTablet := addTablet(100) defer deleteTablet(wantTablet) params := map[string]string{ @@ -90,7 +90,7 @@ func TestControllerKeyRange(t *testing.T) { } func TestControllerTables(t *testing.T) { - wantTablet := addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true) + wantTablet := addTablet(100) defer deleteTablet(wantTablet) resetBinlogClient() @@ -181,7 +181,7 @@ func TestControllerStopped(t *testing.T) { func TestControllerOverrides(t *testing.T) { resetBinlogClient() - wantTablet := addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true) + wantTablet := addTablet(100) defer deleteTablet(wantTablet) params := map[string]string{ @@ -217,7 +217,7 @@ func TestControllerOverrides(t *testing.T) { } func TestControllerCanceledContext(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) params := map[string]string{ "id": "1", @@ -246,7 +246,7 @@ func TestControllerRetry(t *testing.T) { *retryDelay = 10 * time.Millisecond resetBinlogClient() - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) params := map[string]string{ "id": "1", @@ -280,7 +280,7 @@ func TestControllerRetry(t *testing.T) { func TestControllerStopPosition(t *testing.T) { resetBinlogClient() - wantTablet := addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true) + wantTablet := addTablet(100) defer deleteTablet(wantTablet) params := map[string]string{ diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine_test.go b/go/vt/vttablet/tabletmanager/vreplication/engine_test.go index d93791d8a75..6377be170a1 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/engine_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/engine_test.go @@ -28,13 +28,12 @@ import ( "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/binlog/binlogplayer" "vitess.io/vitess/go/vt/mysqlctl/fakemysqldaemon" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) func TestEngineOpen(t *testing.T) { defer func() { globalStats = &vrStats{} }() - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) resetBinlogClient() dbClient := binlogplayer.NewMockDBClient(t) dbClientFactory := func() binlogplayer.DBClient { return dbClient } @@ -82,7 +81,7 @@ func TestEngineOpen(t *testing.T) { func TestEngineExec(t *testing.T) { defer func() { globalStats = &vrStats{} }() - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) resetBinlogClient() dbClient := binlogplayer.NewMockDBClient(t) dbClientFactory := func() binlogplayer.DBClient { return dbClient } @@ -243,7 +242,7 @@ func TestEngineExec(t *testing.T) { func TestEngineBadInsert(t *testing.T) { defer func() { globalStats = &vrStats{} }() - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) resetBinlogClient() dbClient := binlogplayer.NewMockDBClient(t) @@ -273,7 +272,7 @@ func TestEngineBadInsert(t *testing.T) { } func TestEngineSelect(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) resetBinlogClient() dbClient := binlogplayer.NewMockDBClient(t) @@ -427,7 +426,7 @@ func TestWaitForPosCancel(t *testing.T) { func TestCreateDBAndTable(t *testing.T) { defer func() { globalStats = &vrStats{} }() - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) resetBinlogClient() dbClient := binlogplayer.NewMockDBClient(t) dbClientFactory := func() binlogplayer.DBClient { return dbClient } diff --git a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go index 92d4aaf33a3..36b3e55c693 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go @@ -125,50 +125,30 @@ func resetBinlogClient() { //-------------------------------------- // Topos and tablets -func addTablet(id int, shard string, tabletType topodatapb.TabletType, serving, healthy bool) *topodatapb.Tablet { - t := newTablet(id, shard, tabletType, serving, healthy) - if err := env.TopoServ.CreateTablet(context.Background(), t); err != nil { - panic(err) - } - return t -} - -func deleteTablet(t *topodatapb.Tablet) { - env.TopoServ.DeleteTablet(context.Background(), t.Alias) - // This is not automatically removed from shard replication, which results in log spam. - topo.DeleteTabletReplicationData(context.Background(), env.TopoServ, t) -} - -func newTablet(id int, shard string, tabletType topodatapb.TabletType, serving, healthy bool) *topodatapb.Tablet { - stag := "not_serving" - if serving { - stag = "serving" - } - htag := "not_healthy" - if healthy { - htag = "healthy" - } - _, kr, err := topo.ValidateShardName(shard) - if err != nil { - panic(err) - } - return &topodatapb.Tablet{ +func addTablet(id int) *topodatapb.Tablet { + tablet := &topodatapb.Tablet{ Alias: &topodatapb.TabletAlias{ Cell: env.Cells[0], Uid: uint32(id), }, Keyspace: env.KeyspaceName, Shard: env.ShardName, - KeyRange: kr, - Type: tabletType, - Tags: map[string]string{ - "serving": stag, - "healthy": htag, - }, + KeyRange: &topodatapb.KeyRange{}, + Type: topodatapb.TabletType_REPLICA, PortMap: map[string]int32{ "test": int32(id), }, } + if err := env.TopoServ.CreateTablet(context.Background(), tablet); err != nil { + panic(err) + } + return tablet +} + +func deleteTablet(tablet *topodatapb.Tablet) { + env.TopoServ.DeleteTablet(context.Background(), tablet.Alias) + // This is not automatically removed from shard replication, which results in log spam. + topo.DeleteTabletReplicationData(context.Background(), env.TopoServ, tablet) } // fakeTabletConn implement TabletConn interface. We only care about the @@ -181,24 +161,15 @@ type fakeTabletConn struct { // StreamHealth is part of queryservice.QueryService. func (ftc *fakeTabletConn) StreamHealth(ctx context.Context, callback func(*querypb.StreamHealthResponse) error) error { - serving := true - if s, ok := ftc.tablet.Tags["serving"]; ok { - serving = (s == "serving") - } - var herr string - if s, ok := ftc.tablet.Tags["healthy"]; ok && s != "healthy" { - herr = "err" - } - callback(&querypb.StreamHealthResponse{ - Serving: serving, + return callback(&querypb.StreamHealthResponse{ + Serving: true, Target: &querypb.Target{ Keyspace: ftc.tablet.Keyspace, Shard: ftc.tablet.Shard, TabletType: ftc.tablet.Type, }, - RealtimeStats: &querypb.RealtimeStats{HealthError: herr}, + RealtimeStats: &querypb.RealtimeStats{}, }) - return nil } // VStream directly calls into the pre-initialized engine. @@ -274,9 +245,9 @@ type btStream struct { sent bool } -func (t *btStream) Recv() (*binlogdatapb.BinlogTransaction, error) { - if !t.sent { - t.sent = true +func (bts *btStream) Recv() (*binlogdatapb.BinlogTransaction, error) { + if !bts.sent { + bts.sent = true return &binlogdatapb.BinlogTransaction{ Statements: []*binlogdatapb.BinlogTransaction_Statement{ { @@ -290,8 +261,8 @@ func (t *btStream) Recv() (*binlogdatapb.BinlogTransaction, error) { }, }, nil } - <-t.ctx.Done() - return nil, t.ctx.Err() + <-bts.ctx.Done() + return nil, bts.ctx.Err() } func expectFBCRequest(t *testing.T, tablet *topodatapb.Tablet, pos string, tables []string, kr *topodatapb.KeyRange) { diff --git a/go/vt/vttablet/tabletmanager/vreplication/tablet_picker.go b/go/vt/vttablet/tabletmanager/vreplication/tablet_picker.go deleted file mode 100644 index 5bf012733fc..00000000000 --- a/go/vt/vttablet/tabletmanager/vreplication/tablet_picker.go +++ /dev/null @@ -1,105 +0,0 @@ -/* -Copyright 2019 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package vreplication - -import ( - "flag" - "fmt" - "math/rand" - "time" - - "vitess.io/vitess/go/vt/vterrors" - - "golang.org/x/net/context" - - "vitess.io/vitess/go/vt/discovery" - "vitess.io/vitess/go/vt/topo" - "vitess.io/vitess/go/vt/topo/topoproto" - - topodatapb "vitess.io/vitess/go/vt/proto/topodata" -) - -var ( - healthCheckTopologyRefresh = flag.Duration("vreplication_healthcheck_topology_refresh", 30*time.Second, "refresh interval for re-reading the topology") - healthcheckRetryDelay = flag.Duration("vreplication_healthcheck_retry_delay", 5*time.Second, "delay before retrying a failed healthcheck") - healthCheckTimeout = flag.Duration("vreplication_healthcheck_timeout", time.Minute, "the health check timeout period") -) - -type tabletPicker struct { - ts *topo.Server - cell string - keyspace string - shard string - tabletTypes []topodatapb.TabletType - - healthCheck discovery.HealthCheck - watcher *discovery.TopologyWatcher - statsCache *discovery.TabletStatsCache -} - -func newTabletPicker(ctx context.Context, ts *topo.Server, cell, keyspace, shard, tabletTypesStr string) (*tabletPicker, error) { - tabletTypes, err := topoproto.ParseTabletTypes(tabletTypesStr) - if err != nil { - return nil, fmt.Errorf("failed to parse list of tablet types: %v", tabletTypesStr) - } - - // These have to be initialized in the following sequence (watcher must be last). - healthCheck := discovery.NewHealthCheck(*healthcheckRetryDelay, *healthCheckTimeout) - statsCache := discovery.NewTabletStatsCache(healthCheck, ts, cell) - watcher := discovery.NewShardReplicationWatcher(ctx, ts, healthCheck, cell, keyspace, shard, *healthCheckTopologyRefresh, discovery.DefaultTopoReadConcurrency) - - return &tabletPicker{ - ts: ts, - cell: cell, - keyspace: keyspace, - shard: shard, - tabletTypes: tabletTypes, - healthCheck: healthCheck, - watcher: watcher, - statsCache: statsCache, - }, nil -} - -func (tp *tabletPicker) Pick(ctx context.Context) (*topodatapb.Tablet, error) { - // wait for any of required the tablets (useful for the first run at least, fast for next runs) - if err := tp.statsCache.WaitForAnyTablet(ctx, tp.cell, tp.keyspace, tp.shard, tp.tabletTypes); err != nil { - return nil, vterrors.Wrapf(err, "error waiting for tablets for %v %v %v", tp.cell, tp.keyspace, tp.shard) - } - - // Find the server list from the health check. - // Note: We cannot use statsCache.GetHealthyTabletStats() here because it does - // not return non-serving tablets. We must include non-serving tablets because - // some tablets may not be serving if their traffic was already migrated to the - // destination shards. - for _, tabletType := range tp.tabletTypes { - addrs := discovery.RemoveUnhealthyTablets(tp.statsCache.GetTabletStats(tp.keyspace, tp.shard, tabletType)) - if len(addrs) > 0 { - return addrs[rand.Intn(len(addrs))].Tablet, nil - } - } - return nil, fmt.Errorf("can't find any healthy source tablet for %v %v %v", tp.keyspace, tp.shard, tp.tabletTypes) -} - -func (tp *tabletPicker) Close() { - tp.watcher.Stop() - tp.healthCheck.Close() -} - -func init() { - // TODO(sougou): consolidate this call to be once per process. - rand.Seed(time.Now().UnixNano()) -} diff --git a/go/vt/vttablet/tabletmanager/vreplication/tablet_picker_test.go b/go/vt/vttablet/tabletmanager/vreplication/tablet_picker_test.go deleted file mode 100644 index e43030031be..00000000000 --- a/go/vt/vttablet/tabletmanager/vreplication/tablet_picker_test.go +++ /dev/null @@ -1,122 +0,0 @@ -/* -Copyright 2019 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package vreplication - -import ( - "fmt" - "testing" - - "github.com/golang/protobuf/proto" - "golang.org/x/net/context" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" -) - -func TestPickSimple(t *testing.T) { - want := addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true) - defer deleteTablet(want) - - tp, err := newTabletPicker(context.Background(), env.TopoServ, env.Cells[0], env.KeyspaceName, env.ShardName, "replica") - if err != nil { - t.Fatal(err) - } - defer tp.Close() - - tablet, err := tp.Pick(context.Background()) - if err != nil { - t.Fatal(err) - } - if !proto.Equal(want, tablet) { - t.Errorf("Pick: %v, want %v", tablet, want) - } -} - -func TestPickFromTwoHealthy(t *testing.T) { - want1 := addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true) - defer deleteTablet(want1) - want2 := addTablet(101, "0", topodatapb.TabletType_RDONLY, true, true) - defer deleteTablet(want2) - - tp, err := newTabletPicker(context.Background(), env.TopoServ, env.Cells[0], env.KeyspaceName, env.ShardName, "replica,rdonly") - if err != nil { - t.Fatal(err) - } - defer tp.Close() - - tablet, err := tp.Pick(context.Background()) - if err != nil { - t.Fatal(err) - } - if !proto.Equal(tablet, want1) { - t.Errorf("Pick:\n%v, want\n%v", tablet, want1) - } - - tp, err = newTabletPicker(context.Background(), env.TopoServ, env.Cells[0], env.KeyspaceName, env.ShardName, "rdonly,replica") - if err != nil { - t.Fatal(err) - } - defer tp.Close() - - tablet, err = tp.Pick(context.Background()) - if err != nil { - t.Fatal(err) - } - if !proto.Equal(tablet, want2) { - t.Errorf("Pick:\n%v, want\n%v", tablet, want2) - } -} - -func TestPickFromSomeUnhealthy(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, false, false)) - want := addTablet(101, "0", topodatapb.TabletType_RDONLY, false, true) - defer deleteTablet(want) - - tp, err := newTabletPicker(context.Background(), env.TopoServ, env.Cells[0], env.KeyspaceName, env.ShardName, "replica,rdonly") - if err != nil { - t.Fatal(err) - } - defer tp.Close() - - tablet, err := tp.Pick(context.Background()) - if err != nil { - t.Fatal(err) - } - if !proto.Equal(tablet, want) { - t.Errorf("Pick:\n%v, want\n%v", tablet, want) - } -} - -func TestPickError(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, false, false)) - - _, err := newTabletPicker(context.Background(), env.TopoServ, env.Cells[0], env.KeyspaceName, env.ShardName, "badtype") - want := "failed to parse list of tablet types: badtype" - if err == nil || err.Error() != want { - t.Errorf("newTabletPicker err: %v, want %v", err, want) - } - - tp, err := newTabletPicker(context.Background(), env.TopoServ, env.Cells[0], env.KeyspaceName, env.ShardName, "replica,rdonly") - if err != nil { - t.Fatal(err) - } - defer tp.Close() - - _, err = tp.Pick(context.Background()) - want = fmt.Sprintf("can't find any healthy source tablet for %s 0 [REPLICA RDONLY]", env.KeyspaceName) - if err == nil || err.Error() != want { - t.Errorf("Pick err: %v, want %v", err, want) - } -} diff --git a/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go b/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go index 0a40d5a98dd..c0d2cf10326 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go @@ -26,12 +26,11 @@ import ( "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/binlog/binlogplayer" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/vttablet/tabletserver/vstreamer" ) func TestPlayerCopyTables(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table src1(id int, val varbinary(128), primary key(id))", @@ -114,7 +113,7 @@ func TestPlayerCopyTables(t *testing.T) { // TestPlayerCopyBigTable ensures the copy-catchup back-and-forth loop works correctly. func TestPlayerCopyBigTable(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) savedPacketSize := *vstreamer.PacketSize // PacketSize of 1 byte will send at most one row at a time. @@ -245,7 +244,7 @@ func TestPlayerCopyBigTable(t *testing.T) { // TestPlayerCopyWildcardRule ensures the copy-catchup back-and-forth loop works correctly // when the filter uses a wildcard rule func TestPlayerCopyWildcardRule(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) savedPacketSize := *vstreamer.PacketSize // PacketSize of 1 byte will send at most one row at a time. @@ -375,7 +374,7 @@ func TestPlayerCopyWildcardRule(t *testing.T) { // TestPlayerCopyTableContinuation tests the copy workflow where tables have been partially copied. func TestPlayerCopyTableContinuation(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ // src1 is initialized as partially copied. @@ -539,7 +538,7 @@ func TestPlayerCopyTableContinuation(t *testing.T) { // TestPlayerCopyWildcardTableContinuation tests the copy workflow where tables have been partially copied. func TestPlayerCopyWildcardTableContinuation(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ // src is initialized as partially copied. @@ -622,7 +621,7 @@ func TestPlayerCopyWildcardTableContinuation(t *testing.T) { } func TestPlayerCopyTablesNone(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) filter := &binlogdatapb.Filter{ Rules: []*binlogdatapb.Rule{{ @@ -660,7 +659,7 @@ func TestPlayerCopyTablesNone(t *testing.T) { } func TestPlayerCopyTableCancel(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table src1(id int, val varbinary(128), primary key(id))", diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go index 110e5bc8775..10f66487e05 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go @@ -31,11 +31,10 @@ import ( "vitess.io/vitess/go/vt/binlog/binlogplayer" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) func TestPlayerFilters(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table src1(id int, val varbinary(128), primary key(id))", @@ -283,7 +282,7 @@ func TestPlayerFilters(t *testing.T) { } func TestPlayerKeywordNames(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table `begin`(`primary` int, `column` varbinary(128), primary key(`primary`))", @@ -449,7 +448,7 @@ func TestPlayerKeywordNames(t *testing.T) { } } func TestUnicode(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table src1(id int, val varchar(128) COLLATE utf8_unicode_ci, primary key(id))", @@ -516,7 +515,7 @@ func TestUnicode(t *testing.T) { } func TestPlayerUpdates(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table t1(id int, grouped int, ungrouped int, summed int, primary key(id))", @@ -625,7 +624,7 @@ func TestPlayerUpdates(t *testing.T) { } func TestPlayerRowMove(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table src(id int, val1 int, val2 int, primary key(id))", @@ -679,7 +678,7 @@ func TestPlayerRowMove(t *testing.T) { } func TestPlayerTypes(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table vitess_ints(tiny tinyint, tinyu tinyint unsigned, small smallint, smallu smallint unsigned, medium mediumint, mediumu mediumint unsigned, normal int, normalu int unsigned, big bigint, bigu bigint unsigned, y year, primary key(tiny))", @@ -793,7 +792,7 @@ func TestPlayerTypes(t *testing.T) { } func TestPlayerDDL(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table t1(id int, primary key(id))", fmt.Sprintf("create table %s.t1(id int, primary key(id))", vrepldb), @@ -895,7 +894,7 @@ func TestPlayerDDL(t *testing.T) { } func TestPlayerStopPos(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table yes(id int, val varbinary(128), primary key(id))", @@ -992,7 +991,7 @@ func TestPlayerStopPos(t *testing.T) { } func TestPlayerIdleUpdate(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) savedIdleTimeout := idleTimeout defer func() { idleTimeout = savedIdleTimeout }() @@ -1040,7 +1039,7 @@ func TestPlayerIdleUpdate(t *testing.T) { } func TestPlayerSplitTransaction(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) flag.Set("vstream_packet_size", "10") defer flag.Set("vstream_packet_size", "10000") @@ -1080,7 +1079,7 @@ func TestPlayerSplitTransaction(t *testing.T) { } func TestPlayerLockErrors(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table t1(id int, val varbinary(128), primary key(id))", @@ -1154,7 +1153,7 @@ func TestPlayerLockErrors(t *testing.T) { } func TestPlayerCancelOnLock(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table t1(id int, val varbinary(128), primary key(id))", @@ -1226,7 +1225,7 @@ func TestPlayerCancelOnLock(t *testing.T) { } func TestPlayerBatching(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table t1(id int, val varbinary(128), primary key(id))", @@ -1309,7 +1308,7 @@ func TestPlayerBatching(t *testing.T) { } func TestPlayerRelayLogMaxSize(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) for i := 0; i < 2; i++ { // First iteration checks max size, second checks max items @@ -1408,7 +1407,7 @@ func TestPlayerRelayLogMaxSize(t *testing.T) { } func TestRestartOnVStreamEnd(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) savedDelay := *retryDelay defer func() { *retryDelay = savedDelay }() @@ -1463,7 +1462,7 @@ func TestRestartOnVStreamEnd(t *testing.T) { } func TestTimestamp(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table t1(id int, ts timestamp, dt datetime)", From d6063d9a1cd6e6c001be8eca8dc4b799f50243ff Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 6 Oct 2019 10:15:33 -0700 Subject: [PATCH 09/28] discovery: refactor TabletPicker It now waits indefinitely until at least one tablet is available. Signed-off-by: Sugu Sougoumarane --- go/vt/discovery/tablet_picker.go | 9 +++------ go/vt/discovery/tablet_picker_test.go | 13 ++++++++----- go/vt/discovery/tablet_stats_cache_wait.go | 17 ++++++----------- go/vt/discovery/tablet_stats_cache_wait_test.go | 6 +++--- go/vt/worker/legacy_split_clone.go | 2 +- go/vt/worker/split_clone.go | 2 +- go/vt/worker/topo_utils.go | 2 +- go/vt/wrangler/keyspace.go | 2 +- 8 files changed, 24 insertions(+), 29 deletions(-) diff --git a/go/vt/discovery/tablet_picker.go b/go/vt/discovery/tablet_picker.go index 6434df3f873..39014c93953 100644 --- a/go/vt/discovery/tablet_picker.go +++ b/go/vt/discovery/tablet_picker.go @@ -75,21 +75,18 @@ func NewTabletPicker(ctx context.Context, ts *topo.Server, cell, keyspace, shard // PickForStreaming picks all healthy tablets including the non-serving ones. func (tp *TabletPicker) PickForStreaming(ctx context.Context) (*topodatapb.Tablet, error) { // wait for any of required the tablets (useful for the first run at least, fast for next runs) - if err := tp.statsCache.WaitForAnyTablet(ctx, tp.cell, tp.keyspace, tp.shard, tp.tabletTypes); err != nil { + if err := tp.statsCache.WaitByFilter(ctx, tp.keyspace, tp.shard, tp.tabletTypes, RemoveUnhealthyTablets); err != nil { return nil, vterrors.Wrapf(err, "error waiting for tablets for %v %v %v", tp.cell, tp.keyspace, tp.shard) } - // Find the server list from the health check. - // Note: We cannot use statsCache.GetHealthyTabletStats() here because it does - // not return non-serving tablets. We must include non-serving tablets because - // some tablets may not be serving if their traffic was already migrated to the - // destination shards. + // Refilter the tablets list based on the same criteria. for _, tabletType := range tp.tabletTypes { addrs := RemoveUnhealthyTablets(tp.statsCache.GetTabletStats(tp.keyspace, tp.shard, tabletType)) if len(addrs) > 0 { return addrs[rand.Intn(len(addrs))].Tablet, nil } } + // Unreachable. return nil, fmt.Errorf("can't find any healthy source tablet for %v %v %v", tp.keyspace, tp.shard, tp.tabletTypes) } diff --git a/go/vt/discovery/tablet_picker_test.go b/go/vt/discovery/tablet_picker_test.go index 21b76e4d418..81267f040ba 100644 --- a/go/vt/discovery/tablet_picker_test.go +++ b/go/vt/discovery/tablet_picker_test.go @@ -17,8 +17,9 @@ limitations under the License. package discovery import ( - "fmt" + "strings" "testing" + "time" "github.com/golang/protobuf/proto" "golang.org/x/net/context" @@ -121,10 +122,12 @@ func TestPickError(t *testing.T) { } defer tp.Close() - _, err = tp.PickForStreaming(context.Background()) - want = fmt.Sprintf("can't find any healthy source tablet for %s 0 [REPLICA RDONLY]", te.keyspace) - if err == nil || err.Error() != want { - t.Errorf("Pick err: %v, want %v", err, want) + ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond) + defer cancel() + _, err = tp.PickForStreaming(ctx) + want = "error waiting for tablets" + if err == nil || !strings.Contains(err.Error(), want) { + t.Errorf("Pick err: %v, must contain %v", err, want) } } diff --git a/go/vt/discovery/tablet_stats_cache_wait.go b/go/vt/discovery/tablet_stats_cache_wait.go index 00ffff0b71f..1b1123a7439 100644 --- a/go/vt/discovery/tablet_stats_cache_wait.go +++ b/go/vt/discovery/tablet_stats_cache_wait.go @@ -30,10 +30,10 @@ var ( waitAvailableTabletInterval = 100 * time.Millisecond ) -// WaitForTablets waits for at least one tablet in the given cell / +// WaitForTablets waits for at least one tablet in the given // keyspace / shard / tablet type before returning. The tablets do not // have to be healthy. It will return ctx.Err() if the context is canceled. -func (tc *TabletStatsCache) WaitForTablets(ctx context.Context, cell, keyspace, shard string, tabletType topodatapb.TabletType) error { +func (tc *TabletStatsCache) WaitForTablets(ctx context.Context, keyspace, shard string, tabletType topodatapb.TabletType) error { targets := []*querypb.Target{ { Keyspace: keyspace, @@ -44,12 +44,6 @@ func (tc *TabletStatsCache) WaitForTablets(ctx context.Context, cell, keyspace, return tc.waitForTablets(ctx, targets, false) } -// WaitForAnyTablet waits for a single tablet of any of the types. -// It doesn't have to be serving. -func (tc *TabletStatsCache) WaitForAnyTablet(ctx context.Context, cell, keyspace, shard string, tabletTypes []topodatapb.TabletType) error { - return tc.waitForAnyTablet(ctx, keyspace, shard, tabletTypes) -} - // WaitForAllServingTablets waits for at least one healthy serving tablet in // each given target before returning. // It will return ctx.Err() if the context is canceled. @@ -97,11 +91,12 @@ func (tc *TabletStatsCache) waitForTablets(ctx context.Context, targets []*query } } -// waitForAnyTablet is the internal method that polls for any tablet of required type -func (tc *TabletStatsCache) waitForAnyTablet(ctx context.Context, keyspace, shard string, types []topodatapb.TabletType) error { +// WaitByFilter waits for at least one tablet based on the filter function. +func (tc *TabletStatsCache) WaitByFilter(ctx context.Context, keyspace, shard string, tabletTypes []topodatapb.TabletType, filter func([]TabletStats) []TabletStats) error { for { - for _, tt := range types { + for _, tt := range tabletTypes { stats := tc.GetTabletStats(keyspace, shard, tt) + stats = filter(stats) if len(stats) > 0 { return nil } diff --git a/go/vt/discovery/tablet_stats_cache_wait_test.go b/go/vt/discovery/tablet_stats_cache_wait_test.go index 458bb779225..0cf309931c1 100644 --- a/go/vt/discovery/tablet_stats_cache_wait_test.go +++ b/go/vt/discovery/tablet_stats_cache_wait_test.go @@ -43,14 +43,14 @@ func TestWaitForTablets(t *testing.T) { hc.AddTablet(tablet, "") // this should time out - if err := tsc.WaitForTablets(shortCtx, "cell", "keyspace", "shard", topodatapb.TabletType_REPLICA); err != context.DeadlineExceeded { + if err := tsc.WaitForTablets(shortCtx, "keyspace", "shard", topodatapb.TabletType_REPLICA); err != context.DeadlineExceeded { t.Errorf("got wrong error: %v", err) } // this should fail, but return a non-timeout error cancelledCtx, cancel := context.WithCancel(context.Background()) cancel() - if err := tsc.WaitForTablets(cancelledCtx, "cell", "keyspace", "shard", topodatapb.TabletType_REPLICA); err == nil || err == context.DeadlineExceeded { + if err := tsc.WaitForTablets(cancelledCtx, "keyspace", "shard", topodatapb.TabletType_REPLICA); err == nil || err == context.DeadlineExceeded { t.Errorf("want: non-timeout error, got: %v", err) } @@ -70,7 +70,7 @@ func TestWaitForTablets(t *testing.T) { longCtx, longCancel := context.WithTimeout(context.Background(), 10*time.Second) defer longCancel() waitAvailableTabletInterval = 10 * time.Millisecond - if err := tsc.WaitForTablets(longCtx, "cell", "keyspace", "shard", topodatapb.TabletType_REPLICA); err != nil { + if err := tsc.WaitForTablets(longCtx, "keyspace", "shard", topodatapb.TabletType_REPLICA); err != nil { t.Errorf("got error: %v", err) } } diff --git a/go/vt/worker/legacy_split_clone.go b/go/vt/worker/legacy_split_clone.go index 0bfa68f6afc..dd9e568e47a 100644 --- a/go/vt/worker/legacy_split_clone.go +++ b/go/vt/worker/legacy_split_clone.go @@ -400,7 +400,7 @@ func (scw *LegacySplitCloneWorker) findTargets(ctx context.Context) error { for _, si := range scw.destinationShards { waitCtx, waitCancel := context.WithTimeout(ctx, 10*time.Second) defer waitCancel() - if err := scw.tsc.WaitForTablets(waitCtx, scw.cell, si.Keyspace(), si.ShardName(), topodatapb.TabletType_MASTER); err != nil { + if err := scw.tsc.WaitForTablets(waitCtx, si.Keyspace(), si.ShardName(), topodatapb.TabletType_MASTER); err != nil { return vterrors.Wrapf(err, "cannot find MASTER tablet for destination shard for %v/%v", si.Keyspace(), si.ShardName()) } masters := scw.tsc.GetHealthyTabletStats(si.Keyspace(), si.ShardName(), topodatapb.TabletType_MASTER) diff --git a/go/vt/worker/split_clone.go b/go/vt/worker/split_clone.go index f0b800f1f99..ce042c7d351 100644 --- a/go/vt/worker/split_clone.go +++ b/go/vt/worker/split_clone.go @@ -844,7 +844,7 @@ func (scw *SplitCloneWorker) findDestinationMasters(ctx context.Context) error { scw.wr.Logger().Infof("Finding a MASTER tablet for each destination shard...") for _, si := range scw.destinationShards { waitCtx, waitCancel := context.WithTimeout(ctx, *waitForHealthyTabletsTimeout) - err := scw.tsc.WaitForTablets(waitCtx, scw.cell, si.Keyspace(), si.ShardName(), topodatapb.TabletType_MASTER) + err := scw.tsc.WaitForTablets(waitCtx, si.Keyspace(), si.ShardName(), topodatapb.TabletType_MASTER) waitCancel() if err != nil { return vterrors.Wrapf(err, "cannot find MASTER tablet for destination shard for %v/%v (in cell: %v)", si.Keyspace(), si.ShardName(), scw.cell) diff --git a/go/vt/worker/topo_utils.go b/go/vt/worker/topo_utils.go index e078f2c0f12..c83f90a2fa1 100644 --- a/go/vt/worker/topo_utils.go +++ b/go/vt/worker/topo_utils.go @@ -77,7 +77,7 @@ func waitForHealthyTablets(ctx context.Context, wr *wrangler.Wrangler, tsc *disc cell, keyspace, shard, minHealthyRdonlyTablets, time.Until(deadlineForLog).Seconds()) // Wait for at least one RDONLY tablet initially before checking the list. - if err := tsc.WaitForTablets(busywaitCtx, cell, keyspace, shard, tabletType); err != nil { + if err := tsc.WaitForTablets(busywaitCtx, keyspace, shard, tabletType); err != nil { return nil, vterrors.Wrapf(err, "error waiting for %v tablets for (%v,%v/%v)", tabletType, cell, keyspace, shard) } diff --git a/go/vt/wrangler/keyspace.go b/go/vt/wrangler/keyspace.go index 1b8378097f7..25e266df0dd 100644 --- a/go/vt/wrangler/keyspace.go +++ b/go/vt/wrangler/keyspace.go @@ -958,7 +958,7 @@ func (wr *Wrangler) waitForDrainInCell(ctx context.Context, cell, keyspace, shar defer watcher.Stop() // Wait for at least one tablet. - if err := tsc.WaitForTablets(ctx, cell, keyspace, shard, servedType); err != nil { + if err := tsc.WaitForTablets(ctx, keyspace, shard, servedType); err != nil { return fmt.Errorf("%v: error waiting for initial %v tablets for %v/%v: %v", cell, servedType, keyspace, shard, err) } From 3bdafdebdb00980f68348361d4cd19f13273c215 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 19 Oct 2019 12:26:45 -0700 Subject: [PATCH 10/28] discovery: improve TabletPicker algorithm It now picks equally from all tablet types. Signed-off-by: Sugu Sougoumarane --- go/vt/discovery/tablet_picker.go | 10 +-- go/vt/discovery/tablet_picker_test.go | 88 ++++++++++----------------- 2 files changed, 37 insertions(+), 61 deletions(-) diff --git a/go/vt/discovery/tablet_picker.go b/go/vt/discovery/tablet_picker.go index 39014c93953..32f71316bc3 100644 --- a/go/vt/discovery/tablet_picker.go +++ b/go/vt/discovery/tablet_picker.go @@ -80,11 +80,13 @@ func (tp *TabletPicker) PickForStreaming(ctx context.Context) (*topodatapb.Table } // Refilter the tablets list based on the same criteria. + var addrs []TabletStats for _, tabletType := range tp.tabletTypes { - addrs := RemoveUnhealthyTablets(tp.statsCache.GetTabletStats(tp.keyspace, tp.shard, tabletType)) - if len(addrs) > 0 { - return addrs[rand.Intn(len(addrs))].Tablet, nil - } + list := RemoveUnhealthyTablets(tp.statsCache.GetTabletStats(tp.keyspace, tp.shard, tabletType)) + addrs = append(addrs, list...) + } + if len(addrs) > 0 { + return addrs[rand.Intn(len(addrs))].Tablet, nil } // Unreachable. return nil, fmt.Errorf("can't find any healthy source tablet for %v %v %v", tp.keyspace, tp.shard, tp.tabletTypes) diff --git a/go/vt/discovery/tablet_picker_test.go b/go/vt/discovery/tablet_picker_test.go index 81267f040ba..d73dd83af9f 100644 --- a/go/vt/discovery/tablet_picker_test.go +++ b/go/vt/discovery/tablet_picker_test.go @@ -17,11 +17,12 @@ limitations under the License. package discovery import ( - "strings" "testing" "time" "github.com/golang/protobuf/proto" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "golang.org/x/net/context" querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" @@ -35,15 +36,11 @@ func TestPickSimple(t *testing.T) { defer deleteTablet(te, want) tp, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "replica") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) defer tp.Close() tablet, err := tp.PickForStreaming(context.Background()) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) if !proto.Equal(want, tablet) { t.Errorf("Pick: %v, want %v", tablet, want) } @@ -57,32 +54,23 @@ func TestPickFromTwoHealthy(t *testing.T) { defer deleteTablet(te, want2) tp, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "replica,rdonly") - if err != nil { - t.Fatal(err) - } - defer tp.Close() - - tablet, err := tp.PickForStreaming(context.Background()) - if err != nil { - t.Fatal(err) - } - if !proto.Equal(tablet, want1) { - t.Errorf("Pick:\n%v, want\n%v", tablet, want1) - } - - tp, err = NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "rdonly,replica") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) defer tp.Close() - tablet, err = tp.PickForStreaming(context.Background()) - if err != nil { - t.Fatal(err) - } - if !proto.Equal(tablet, want2) { - t.Errorf("Pick:\n%v, want\n%v", tablet, want2) - } + // In 20 attempts, both tablet types must be picked at least once. + var picked1, picked2 bool + for i := 0; i < 20; i++ { + tablet, err := tp.PickForStreaming(context.Background()) + require.NoError(t, err) + if proto.Equal(tablet, want1) { + picked1 = true + } + if proto.Equal(tablet, want2) { + picked2 = true + } + } + assert.True(t, picked1) + assert.True(t, picked2) } func TestPickFromSomeUnhealthy(t *testing.T) { @@ -92,15 +80,11 @@ func TestPickFromSomeUnhealthy(t *testing.T) { defer deleteTablet(te, want) tp, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "replica,rdonly") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) defer tp.Close() tablet, err := tp.PickForStreaming(context.Background()) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) if !proto.Equal(tablet, want) { t.Errorf("Pick:\n%v, want\n%v", tablet, want) } @@ -111,24 +95,17 @@ func TestPickError(t *testing.T) { defer deleteTablet(te, addTablet(te, 100, topodatapb.TabletType_REPLICA, false, false)) _, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "badtype") - want := "failed to parse list of tablet types: badtype" - if err == nil || err.Error() != want { - t.Errorf("NewTabletPicker err: %v, want %v", err, want) - } + assert.EqualError(t, err, "failed to parse list of tablet types: badtype") tp, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "replica,rdonly") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) defer tp.Close() ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond) defer cancel() _, err = tp.PickForStreaming(ctx) - want = "error waiting for tablets" - if err == nil || !strings.Contains(err.Error(), want) { - t.Errorf("Pick err: %v, must contain %v", err, want) - } + require.Error(t, err) + assert.Contains(t, err.Error(), "error waiting for tablets") } type pickerTestEnv struct { @@ -150,12 +127,10 @@ func newPickerTestEnv(t *testing.T) *pickerTestEnv { cell: "cell", topoServ: memorytopo.NewServer("cell"), } - if err := te.topoServ.CreateKeyspace(ctx, te.keyspace, &topodatapb.Keyspace{}); err != nil { - t.Fatal(err) - } - if err := te.topoServ.CreateShard(ctx, te.keyspace, te.shard); err != nil { - t.Fatal(err) - } + err := te.topoServ.CreateKeyspace(ctx, te.keyspace, &topodatapb.Keyspace{}) + require.NoError(t, err) + err = te.topoServ.CreateShard(ctx, te.keyspace, te.shard) + require.NoError(t, err) return te } @@ -173,9 +148,8 @@ func addTablet(te *pickerTestEnv, id int, tabletType topodatapb.TabletType, serv "test": int32(id), }, } - if err := te.topoServ.CreateTablet(context.Background(), tablet); err != nil { - te.t.Fatal(err) - } + err := te.topoServ.CreateTablet(context.Background(), tablet) + require.NoError(te.t, err) var herr string if !healthy { From 297c5d1cc48409c6d801509fcd8237d4c67c8423 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 6 Oct 2019 16:12:58 -0700 Subject: [PATCH 11/28] vdiff: new data structures Signed-off-by: Sugu Sougoumarane --- go/vt/wrangler/vdiff.go | 120 ++++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index 230b76f4358..d544a017b59 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -26,18 +26,24 @@ import ( "golang.org/x/net/context" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/concurrency" "vitess.io/vitess/go/vt/key" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vttablet/tabletmanager/vreplication" ) type vdiff struct { - mi *migrater - differs map[string]*tableDiffer + wr *Wrangler + workflow string + differs map[string]*tableDiffer + sources map[string]*dfParams + targets map[string]*dfParams } type tableDiffer struct { @@ -48,6 +54,12 @@ type tableDiffer struct { orderBy []engine.OrderbyParams } +type dfParams struct { + master *topo.TabletInfo + tablet *topo.TabletInfo + position mysql.Position +} + // VDiff reports differences between the sources and targets of a vreplication workflow. func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow string, filteredReplicationWaitTime time.Duration) error { mi, err := wr.buildMigrater(ctx, targetKeyspace, workflow) @@ -59,10 +71,23 @@ func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow string, mi.wr.Logger().Errorf("validate failed: %v", err) return err } + df := &vdiff{ + wr: wr, + workflow: workflow, + sources: make(map[string]*dfParams), + targets: make(map[string]*dfParams), + } + for shard, source := range mi.sources { + df.sources[shard] = &dfParams{ + master: source.master, + } + } var oneTarget *miTarget - for _, target := range mi.targets { + for shard, target := range mi.targets { + df.targets[shard] = &dfParams{ + master: target.master, + } oneTarget = target - break } var oneFilter *binlogdatapb.Filter for _, bls := range oneTarget.sources { @@ -73,12 +98,12 @@ func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow string, if err != nil { return err } - _, err = buildVDiffPlan(ctx, oneFilter, schm) + df.differs, err = buildVDiffPlan(ctx, oneFilter, schm) return err } func buildVDiffPlan(ctx context.Context, filter *binlogdatapb.Filter, schm *tabletmanagerdatapb.SchemaDefinition) (map[string]*tableDiffer, error) { - tableDiffers := make(map[string]*tableDiffer) + differs := make(map[string]*tableDiffer) for _, table := range schm.TableDefinitions { rule, err := vreplication.MatchTable(table.Name, filter) if err != nil { @@ -93,12 +118,12 @@ func buildVDiffPlan(ctx context.Context, filter *binlogdatapb.Filter, schm *tabl buf.Myprintf("select * from %v", sqlparser.NewTableIdent(table.Name)) query = buf.String() } - tableDiffers[table.Name], err = buildDifferPlan(table, query) + differs[table.Name], err = buildDifferPlan(table, query) if err != nil { return nil, err } } - return tableDiffers, nil + return differs, nil } func buildDifferPlan(table *tabletmanagerdatapb.TableDefinition, query string) (*tableDiffer, error) { @@ -195,18 +220,17 @@ func buildDifferPlan(table *tabletmanagerdatapb.TableDefinition, query string) ( return td, nil } -func (df *vdiff) stopTargetStreams(ctx context.Context) (map[string]mysql.Position, error) { +func (df *vdiff) stopTargetStreams(ctx context.Context) error { var mu sync.Mutex - stoppedPositions := make(map[string]mysql.Position) - err := df.mi.forAllTargets(func(target *miTarget) error { - query := fmt.Sprintf("update _vt.vreplication set state='Stopped', message='for vdiff' where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.mi.workflow)) - _, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) + err := df.forAll(df.targets, func(target *dfParams) error { + query := fmt.Sprintf("update _vt.vreplication set state='Stopped', message='for vdiff' where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.workflow)) + _, err := df.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) if err != nil { return err } - query = fmt.Sprintf("select source, pos from _vt.vreplication where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.mi.workflow)) - p3qr, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) + query = fmt.Sprintf("select source, pos from _vt.vreplication where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.workflow)) + p3qr, err := df.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) if err != nil { return err } @@ -225,64 +249,40 @@ func (df *vdiff) stopTargetStreams(ctx context.Context) (map[string]mysql.Positi mu.Lock() defer mu.Unlock() - prev, ok := stoppedPositions[bls.Shard] - if ok && prev.AtLeast(pos) { + source, ok := df.sources[bls.Shard] + if !ok { + // Unreachable. return } - stoppedPositions[bls.Shard] = pos + if !source.position.IsZero() && source.position.AtLeast(pos) { + return + } + source.position = pos }() } return nil }) if err != nil { - return nil, err + return err } - return stoppedPositions, nil + return nil } -func (df *vdiff) waitForSourceStreams(ctx context.Context) (map[string]mysql.Position, error) { - var mu sync.Mutex - stoppedPositions := make(map[string]mysql.Position) - - err := df.mi.forAllTargets(func(target *miTarget) error { - query := fmt.Sprintf("update _vt.vreplication set state='Stopped', message='for vdiff' where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.mi.workflow)) - _, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) - if err != nil { - return err - } - query = fmt.Sprintf("select source, pos from _vt.vreplication where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.mi.workflow)) - p3qr, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) - if err != nil { - return err - } - qr := sqltypes.Proto3ToResult(p3qr) +func (df *vdiff) forAll(participants map[string]*dfParams, f func(*dfParams) error) error { + var wg sync.WaitGroup + allErrors := &concurrency.AllErrorRecorder{} + for _, participant := range participants { + wg.Add(1) + go func(participant *dfParams) { + defer wg.Done() - for _, row := range qr.Rows { - var bls binlogdatapb.BinlogSource - if err := proto.UnmarshalText(row[0].ToString(), &bls); err != nil { - return err - } - pos, err := mysql.DecodePosition(row[1].ToString()) - if err != nil { - return err + if err := f(participant); err != nil { + allErrors.RecordError(err) } - func() { - mu.Lock() - defer mu.Unlock() - - prev, ok := stoppedPositions[bls.Shard] - if ok && prev.AtLeast(pos) { - return - } - stoppedPositions[bls.Shard] = pos - }() - } - return nil - }) - if err != nil { - return nil, err + }(participant) } - return stoppedPositions, nil + wg.Wait() + return allErrors.AggrError(vterrors.Aggregate) } func removeKeyrange(where *sqlparser.Where) *sqlparser.Where { From 2ef29629d7b8a389e7d783cb969009b75316bc2a Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 6 Oct 2019 18:30:34 -0700 Subject: [PATCH 12/28] tabletmanager: WaitForPosition Signed-off-by: Sugu Sougoumarane --- .../tabletmanagerdata/tabletmanagerdata.pb.go | 428 ++++++++++-------- .../tabletmanagerservice.pb.go | 167 ++++--- go/vt/vtcombo/tablet_map.go | 4 + go/vt/vttablet/agentrpctest/test_agent_rpc.go | 4 + go/vt/vttablet/faketmclient/fake_client.go | 5 + go/vt/vttablet/grpctmclient/client.go | 11 + go/vt/vttablet/grpctmserver/server.go | 7 + go/vt/vttablet/tabletmanager/rpc_agent.go | 2 + .../vttablet/tabletmanager/rpc_replication.go | 9 + go/vt/vttablet/tmclient/rpc_client_api.go | 3 + proto/tabletmanagerdata.proto | 7 + proto/tabletmanagerservice.proto | 3 + py/vtproto/tabletmanagerdata_pb2.py | 271 ++++++++--- py/vtproto/tabletmanagerservice_pb2.py | 59 ++- py/vtproto/tabletmanagerservice_pb2_grpc.py | 17 + 15 files changed, 662 insertions(+), 335 deletions(-) diff --git a/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go b/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go index 5ce79557270..fd1f76410e8 100644 --- a/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go +++ b/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go @@ -2056,6 +2056,76 @@ func (m *MasterPositionResponse) GetPosition() string { return "" } +type WaitForPositionRequest struct { + Position string `protobuf:"bytes,1,opt,name=position,proto3" json:"position,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *WaitForPositionRequest) Reset() { *m = WaitForPositionRequest{} } +func (m *WaitForPositionRequest) String() string { return proto.CompactTextString(m) } +func (*WaitForPositionRequest) ProtoMessage() {} +func (*WaitForPositionRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_ff9ac4f89e61ffa4, []int{48} +} + +func (m *WaitForPositionRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_WaitForPositionRequest.Unmarshal(m, b) +} +func (m *WaitForPositionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_WaitForPositionRequest.Marshal(b, m, deterministic) +} +func (m *WaitForPositionRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_WaitForPositionRequest.Merge(m, src) +} +func (m *WaitForPositionRequest) XXX_Size() int { + return xxx_messageInfo_WaitForPositionRequest.Size(m) +} +func (m *WaitForPositionRequest) XXX_DiscardUnknown() { + xxx_messageInfo_WaitForPositionRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_WaitForPositionRequest proto.InternalMessageInfo + +func (m *WaitForPositionRequest) GetPosition() string { + if m != nil { + return m.Position + } + return "" +} + +type WaitForPositionResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *WaitForPositionResponse) Reset() { *m = WaitForPositionResponse{} } +func (m *WaitForPositionResponse) String() string { return proto.CompactTextString(m) } +func (*WaitForPositionResponse) ProtoMessage() {} +func (*WaitForPositionResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_ff9ac4f89e61ffa4, []int{49} +} + +func (m *WaitForPositionResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_WaitForPositionResponse.Unmarshal(m, b) +} +func (m *WaitForPositionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_WaitForPositionResponse.Marshal(b, m, deterministic) +} +func (m *WaitForPositionResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_WaitForPositionResponse.Merge(m, src) +} +func (m *WaitForPositionResponse) XXX_Size() int { + return xxx_messageInfo_WaitForPositionResponse.Size(m) +} +func (m *WaitForPositionResponse) XXX_DiscardUnknown() { + xxx_messageInfo_WaitForPositionResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_WaitForPositionResponse proto.InternalMessageInfo + type StopSlaveRequest struct { XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -2066,7 +2136,7 @@ func (m *StopSlaveRequest) Reset() { *m = StopSlaveRequest{} } func (m *StopSlaveRequest) String() string { return proto.CompactTextString(m) } func (*StopSlaveRequest) ProtoMessage() {} func (*StopSlaveRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{48} + return fileDescriptor_ff9ac4f89e61ffa4, []int{50} } func (m *StopSlaveRequest) XXX_Unmarshal(b []byte) error { @@ -2097,7 +2167,7 @@ func (m *StopSlaveResponse) Reset() { *m = StopSlaveResponse{} } func (m *StopSlaveResponse) String() string { return proto.CompactTextString(m) } func (*StopSlaveResponse) ProtoMessage() {} func (*StopSlaveResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{49} + return fileDescriptor_ff9ac4f89e61ffa4, []int{51} } func (m *StopSlaveResponse) XXX_Unmarshal(b []byte) error { @@ -2130,7 +2200,7 @@ func (m *StopSlaveMinimumRequest) Reset() { *m = StopSlaveMinimumRequest func (m *StopSlaveMinimumRequest) String() string { return proto.CompactTextString(m) } func (*StopSlaveMinimumRequest) ProtoMessage() {} func (*StopSlaveMinimumRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{50} + return fileDescriptor_ff9ac4f89e61ffa4, []int{52} } func (m *StopSlaveMinimumRequest) XXX_Unmarshal(b []byte) error { @@ -2176,7 +2246,7 @@ func (m *StopSlaveMinimumResponse) Reset() { *m = StopSlaveMinimumRespon func (m *StopSlaveMinimumResponse) String() string { return proto.CompactTextString(m) } func (*StopSlaveMinimumResponse) ProtoMessage() {} func (*StopSlaveMinimumResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{51} + return fileDescriptor_ff9ac4f89e61ffa4, []int{53} } func (m *StopSlaveMinimumResponse) XXX_Unmarshal(b []byte) error { @@ -2214,7 +2284,7 @@ func (m *StartSlaveRequest) Reset() { *m = StartSlaveRequest{} } func (m *StartSlaveRequest) String() string { return proto.CompactTextString(m) } func (*StartSlaveRequest) ProtoMessage() {} func (*StartSlaveRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{52} + return fileDescriptor_ff9ac4f89e61ffa4, []int{54} } func (m *StartSlaveRequest) XXX_Unmarshal(b []byte) error { @@ -2245,7 +2315,7 @@ func (m *StartSlaveResponse) Reset() { *m = StartSlaveResponse{} } func (m *StartSlaveResponse) String() string { return proto.CompactTextString(m) } func (*StartSlaveResponse) ProtoMessage() {} func (*StartSlaveResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{53} + return fileDescriptor_ff9ac4f89e61ffa4, []int{55} } func (m *StartSlaveResponse) XXX_Unmarshal(b []byte) error { @@ -2278,7 +2348,7 @@ func (m *StartSlaveUntilAfterRequest) Reset() { *m = StartSlaveUntilAfte func (m *StartSlaveUntilAfterRequest) String() string { return proto.CompactTextString(m) } func (*StartSlaveUntilAfterRequest) ProtoMessage() {} func (*StartSlaveUntilAfterRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{54} + return fileDescriptor_ff9ac4f89e61ffa4, []int{56} } func (m *StartSlaveUntilAfterRequest) XXX_Unmarshal(b []byte) error { @@ -2323,7 +2393,7 @@ func (m *StartSlaveUntilAfterResponse) Reset() { *m = StartSlaveUntilAft func (m *StartSlaveUntilAfterResponse) String() string { return proto.CompactTextString(m) } func (*StartSlaveUntilAfterResponse) ProtoMessage() {} func (*StartSlaveUntilAfterResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{55} + return fileDescriptor_ff9ac4f89e61ffa4, []int{57} } func (m *StartSlaveUntilAfterResponse) XXX_Unmarshal(b []byte) error { @@ -2358,7 +2428,7 @@ func (m *TabletExternallyReparentedRequest) Reset() { *m = TabletExterna func (m *TabletExternallyReparentedRequest) String() string { return proto.CompactTextString(m) } func (*TabletExternallyReparentedRequest) ProtoMessage() {} func (*TabletExternallyReparentedRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{56} + return fileDescriptor_ff9ac4f89e61ffa4, []int{58} } func (m *TabletExternallyReparentedRequest) XXX_Unmarshal(b []byte) error { @@ -2396,7 +2466,7 @@ func (m *TabletExternallyReparentedResponse) Reset() { *m = TabletExtern func (m *TabletExternallyReparentedResponse) String() string { return proto.CompactTextString(m) } func (*TabletExternallyReparentedResponse) ProtoMessage() {} func (*TabletExternallyReparentedResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{57} + return fileDescriptor_ff9ac4f89e61ffa4, []int{59} } func (m *TabletExternallyReparentedResponse) XXX_Unmarshal(b []byte) error { @@ -2427,7 +2497,7 @@ func (m *TabletExternallyElectedRequest) Reset() { *m = TabletExternally func (m *TabletExternallyElectedRequest) String() string { return proto.CompactTextString(m) } func (*TabletExternallyElectedRequest) ProtoMessage() {} func (*TabletExternallyElectedRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{58} + return fileDescriptor_ff9ac4f89e61ffa4, []int{60} } func (m *TabletExternallyElectedRequest) XXX_Unmarshal(b []byte) error { @@ -2458,7 +2528,7 @@ func (m *TabletExternallyElectedResponse) Reset() { *m = TabletExternall func (m *TabletExternallyElectedResponse) String() string { return proto.CompactTextString(m) } func (*TabletExternallyElectedResponse) ProtoMessage() {} func (*TabletExternallyElectedResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{59} + return fileDescriptor_ff9ac4f89e61ffa4, []int{61} } func (m *TabletExternallyElectedResponse) XXX_Unmarshal(b []byte) error { @@ -2489,7 +2559,7 @@ func (m *GetSlavesRequest) Reset() { *m = GetSlavesRequest{} } func (m *GetSlavesRequest) String() string { return proto.CompactTextString(m) } func (*GetSlavesRequest) ProtoMessage() {} func (*GetSlavesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{60} + return fileDescriptor_ff9ac4f89e61ffa4, []int{62} } func (m *GetSlavesRequest) XXX_Unmarshal(b []byte) error { @@ -2521,7 +2591,7 @@ func (m *GetSlavesResponse) Reset() { *m = GetSlavesResponse{} } func (m *GetSlavesResponse) String() string { return proto.CompactTextString(m) } func (*GetSlavesResponse) ProtoMessage() {} func (*GetSlavesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{61} + return fileDescriptor_ff9ac4f89e61ffa4, []int{63} } func (m *GetSlavesResponse) XXX_Unmarshal(b []byte) error { @@ -2559,7 +2629,7 @@ func (m *ResetReplicationRequest) Reset() { *m = ResetReplicationRequest func (m *ResetReplicationRequest) String() string { return proto.CompactTextString(m) } func (*ResetReplicationRequest) ProtoMessage() {} func (*ResetReplicationRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{62} + return fileDescriptor_ff9ac4f89e61ffa4, []int{64} } func (m *ResetReplicationRequest) XXX_Unmarshal(b []byte) error { @@ -2590,7 +2660,7 @@ func (m *ResetReplicationResponse) Reset() { *m = ResetReplicationRespon func (m *ResetReplicationResponse) String() string { return proto.CompactTextString(m) } func (*ResetReplicationResponse) ProtoMessage() {} func (*ResetReplicationResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{63} + return fileDescriptor_ff9ac4f89e61ffa4, []int{65} } func (m *ResetReplicationResponse) XXX_Unmarshal(b []byte) error { @@ -2622,7 +2692,7 @@ func (m *VReplicationExecRequest) Reset() { *m = VReplicationExecRequest func (m *VReplicationExecRequest) String() string { return proto.CompactTextString(m) } func (*VReplicationExecRequest) ProtoMessage() {} func (*VReplicationExecRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{64} + return fileDescriptor_ff9ac4f89e61ffa4, []int{66} } func (m *VReplicationExecRequest) XXX_Unmarshal(b []byte) error { @@ -2661,7 +2731,7 @@ func (m *VReplicationExecResponse) Reset() { *m = VReplicationExecRespon func (m *VReplicationExecResponse) String() string { return proto.CompactTextString(m) } func (*VReplicationExecResponse) ProtoMessage() {} func (*VReplicationExecResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{65} + return fileDescriptor_ff9ac4f89e61ffa4, []int{67} } func (m *VReplicationExecResponse) XXX_Unmarshal(b []byte) error { @@ -2701,7 +2771,7 @@ func (m *VReplicationWaitForPosRequest) Reset() { *m = VReplicationWaitF func (m *VReplicationWaitForPosRequest) String() string { return proto.CompactTextString(m) } func (*VReplicationWaitForPosRequest) ProtoMessage() {} func (*VReplicationWaitForPosRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{66} + return fileDescriptor_ff9ac4f89e61ffa4, []int{68} } func (m *VReplicationWaitForPosRequest) XXX_Unmarshal(b []byte) error { @@ -2746,7 +2816,7 @@ func (m *VReplicationWaitForPosResponse) Reset() { *m = VReplicationWait func (m *VReplicationWaitForPosResponse) String() string { return proto.CompactTextString(m) } func (*VReplicationWaitForPosResponse) ProtoMessage() {} func (*VReplicationWaitForPosResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{67} + return fileDescriptor_ff9ac4f89e61ffa4, []int{69} } func (m *VReplicationWaitForPosResponse) XXX_Unmarshal(b []byte) error { @@ -2777,7 +2847,7 @@ func (m *InitMasterRequest) Reset() { *m = InitMasterRequest{} } func (m *InitMasterRequest) String() string { return proto.CompactTextString(m) } func (*InitMasterRequest) ProtoMessage() {} func (*InitMasterRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{68} + return fileDescriptor_ff9ac4f89e61ffa4, []int{70} } func (m *InitMasterRequest) XXX_Unmarshal(b []byte) error { @@ -2809,7 +2879,7 @@ func (m *InitMasterResponse) Reset() { *m = InitMasterResponse{} } func (m *InitMasterResponse) String() string { return proto.CompactTextString(m) } func (*InitMasterResponse) ProtoMessage() {} func (*InitMasterResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{69} + return fileDescriptor_ff9ac4f89e61ffa4, []int{71} } func (m *InitMasterResponse) XXX_Unmarshal(b []byte) error { @@ -2851,7 +2921,7 @@ func (m *PopulateReparentJournalRequest) Reset() { *m = PopulateReparent func (m *PopulateReparentJournalRequest) String() string { return proto.CompactTextString(m) } func (*PopulateReparentJournalRequest) ProtoMessage() {} func (*PopulateReparentJournalRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{70} + return fileDescriptor_ff9ac4f89e61ffa4, []int{72} } func (m *PopulateReparentJournalRequest) XXX_Unmarshal(b []byte) error { @@ -2910,7 +2980,7 @@ func (m *PopulateReparentJournalResponse) Reset() { *m = PopulateReparen func (m *PopulateReparentJournalResponse) String() string { return proto.CompactTextString(m) } func (*PopulateReparentJournalResponse) ProtoMessage() {} func (*PopulateReparentJournalResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{71} + return fileDescriptor_ff9ac4f89e61ffa4, []int{73} } func (m *PopulateReparentJournalResponse) XXX_Unmarshal(b []byte) error { @@ -2944,7 +3014,7 @@ func (m *InitSlaveRequest) Reset() { *m = InitSlaveRequest{} } func (m *InitSlaveRequest) String() string { return proto.CompactTextString(m) } func (*InitSlaveRequest) ProtoMessage() {} func (*InitSlaveRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{72} + return fileDescriptor_ff9ac4f89e61ffa4, []int{74} } func (m *InitSlaveRequest) XXX_Unmarshal(b []byte) error { @@ -2996,7 +3066,7 @@ func (m *InitSlaveResponse) Reset() { *m = InitSlaveResponse{} } func (m *InitSlaveResponse) String() string { return proto.CompactTextString(m) } func (*InitSlaveResponse) ProtoMessage() {} func (*InitSlaveResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{73} + return fileDescriptor_ff9ac4f89e61ffa4, []int{75} } func (m *InitSlaveResponse) XXX_Unmarshal(b []byte) error { @@ -3027,7 +3097,7 @@ func (m *DemoteMasterRequest) Reset() { *m = DemoteMasterRequest{} } func (m *DemoteMasterRequest) String() string { return proto.CompactTextString(m) } func (*DemoteMasterRequest) ProtoMessage() {} func (*DemoteMasterRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{74} + return fileDescriptor_ff9ac4f89e61ffa4, []int{76} } func (m *DemoteMasterRequest) XXX_Unmarshal(b []byte) error { @@ -3059,7 +3129,7 @@ func (m *DemoteMasterResponse) Reset() { *m = DemoteMasterResponse{} } func (m *DemoteMasterResponse) String() string { return proto.CompactTextString(m) } func (*DemoteMasterResponse) ProtoMessage() {} func (*DemoteMasterResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{75} + return fileDescriptor_ff9ac4f89e61ffa4, []int{77} } func (m *DemoteMasterResponse) XXX_Unmarshal(b []byte) error { @@ -3097,7 +3167,7 @@ func (m *UndoDemoteMasterRequest) Reset() { *m = UndoDemoteMasterRequest func (m *UndoDemoteMasterRequest) String() string { return proto.CompactTextString(m) } func (*UndoDemoteMasterRequest) ProtoMessage() {} func (*UndoDemoteMasterRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{76} + return fileDescriptor_ff9ac4f89e61ffa4, []int{78} } func (m *UndoDemoteMasterRequest) XXX_Unmarshal(b []byte) error { @@ -3128,7 +3198,7 @@ func (m *UndoDemoteMasterResponse) Reset() { *m = UndoDemoteMasterRespon func (m *UndoDemoteMasterResponse) String() string { return proto.CompactTextString(m) } func (*UndoDemoteMasterResponse) ProtoMessage() {} func (*UndoDemoteMasterResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{77} + return fileDescriptor_ff9ac4f89e61ffa4, []int{79} } func (m *UndoDemoteMasterResponse) XXX_Unmarshal(b []byte) error { @@ -3160,7 +3230,7 @@ func (m *PromoteSlaveWhenCaughtUpRequest) Reset() { *m = PromoteSlaveWhe func (m *PromoteSlaveWhenCaughtUpRequest) String() string { return proto.CompactTextString(m) } func (*PromoteSlaveWhenCaughtUpRequest) ProtoMessage() {} func (*PromoteSlaveWhenCaughtUpRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{78} + return fileDescriptor_ff9ac4f89e61ffa4, []int{80} } func (m *PromoteSlaveWhenCaughtUpRequest) XXX_Unmarshal(b []byte) error { @@ -3199,7 +3269,7 @@ func (m *PromoteSlaveWhenCaughtUpResponse) Reset() { *m = PromoteSlaveWh func (m *PromoteSlaveWhenCaughtUpResponse) String() string { return proto.CompactTextString(m) } func (*PromoteSlaveWhenCaughtUpResponse) ProtoMessage() {} func (*PromoteSlaveWhenCaughtUpResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{79} + return fileDescriptor_ff9ac4f89e61ffa4, []int{81} } func (m *PromoteSlaveWhenCaughtUpResponse) XXX_Unmarshal(b []byte) error { @@ -3237,7 +3307,7 @@ func (m *SlaveWasPromotedRequest) Reset() { *m = SlaveWasPromotedRequest func (m *SlaveWasPromotedRequest) String() string { return proto.CompactTextString(m) } func (*SlaveWasPromotedRequest) ProtoMessage() {} func (*SlaveWasPromotedRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{80} + return fileDescriptor_ff9ac4f89e61ffa4, []int{82} } func (m *SlaveWasPromotedRequest) XXX_Unmarshal(b []byte) error { @@ -3268,7 +3338,7 @@ func (m *SlaveWasPromotedResponse) Reset() { *m = SlaveWasPromotedRespon func (m *SlaveWasPromotedResponse) String() string { return proto.CompactTextString(m) } func (*SlaveWasPromotedResponse) ProtoMessage() {} func (*SlaveWasPromotedResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{81} + return fileDescriptor_ff9ac4f89e61ffa4, []int{83} } func (m *SlaveWasPromotedResponse) XXX_Unmarshal(b []byte) error { @@ -3303,7 +3373,7 @@ func (m *SetMasterRequest) Reset() { *m = SetMasterRequest{} } func (m *SetMasterRequest) String() string { return proto.CompactTextString(m) } func (*SetMasterRequest) ProtoMessage() {} func (*SetMasterRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{82} + return fileDescriptor_ff9ac4f89e61ffa4, []int{84} } func (m *SetMasterRequest) XXX_Unmarshal(b []byte) error { @@ -3362,7 +3432,7 @@ func (m *SetMasterResponse) Reset() { *m = SetMasterResponse{} } func (m *SetMasterResponse) String() string { return proto.CompactTextString(m) } func (*SetMasterResponse) ProtoMessage() {} func (*SetMasterResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{83} + return fileDescriptor_ff9ac4f89e61ffa4, []int{85} } func (m *SetMasterResponse) XXX_Unmarshal(b []byte) error { @@ -3395,7 +3465,7 @@ func (m *SlaveWasRestartedRequest) Reset() { *m = SlaveWasRestartedReque func (m *SlaveWasRestartedRequest) String() string { return proto.CompactTextString(m) } func (*SlaveWasRestartedRequest) ProtoMessage() {} func (*SlaveWasRestartedRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{84} + return fileDescriptor_ff9ac4f89e61ffa4, []int{86} } func (m *SlaveWasRestartedRequest) XXX_Unmarshal(b []byte) error { @@ -3433,7 +3503,7 @@ func (m *SlaveWasRestartedResponse) Reset() { *m = SlaveWasRestartedResp func (m *SlaveWasRestartedResponse) String() string { return proto.CompactTextString(m) } func (*SlaveWasRestartedResponse) ProtoMessage() {} func (*SlaveWasRestartedResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{85} + return fileDescriptor_ff9ac4f89e61ffa4, []int{87} } func (m *SlaveWasRestartedResponse) XXX_Unmarshal(b []byte) error { @@ -3464,7 +3534,7 @@ func (m *StopReplicationAndGetStatusRequest) Reset() { *m = StopReplicat func (m *StopReplicationAndGetStatusRequest) String() string { return proto.CompactTextString(m) } func (*StopReplicationAndGetStatusRequest) ProtoMessage() {} func (*StopReplicationAndGetStatusRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{86} + return fileDescriptor_ff9ac4f89e61ffa4, []int{88} } func (m *StopReplicationAndGetStatusRequest) XXX_Unmarshal(b []byte) error { @@ -3496,7 +3566,7 @@ func (m *StopReplicationAndGetStatusResponse) Reset() { *m = StopReplica func (m *StopReplicationAndGetStatusResponse) String() string { return proto.CompactTextString(m) } func (*StopReplicationAndGetStatusResponse) ProtoMessage() {} func (*StopReplicationAndGetStatusResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{87} + return fileDescriptor_ff9ac4f89e61ffa4, []int{89} } func (m *StopReplicationAndGetStatusResponse) XXX_Unmarshal(b []byte) error { @@ -3534,7 +3604,7 @@ func (m *PromoteSlaveRequest) Reset() { *m = PromoteSlaveRequest{} } func (m *PromoteSlaveRequest) String() string { return proto.CompactTextString(m) } func (*PromoteSlaveRequest) ProtoMessage() {} func (*PromoteSlaveRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{88} + return fileDescriptor_ff9ac4f89e61ffa4, []int{90} } func (m *PromoteSlaveRequest) XXX_Unmarshal(b []byte) error { @@ -3566,7 +3636,7 @@ func (m *PromoteSlaveResponse) Reset() { *m = PromoteSlaveResponse{} } func (m *PromoteSlaveResponse) String() string { return proto.CompactTextString(m) } func (*PromoteSlaveResponse) ProtoMessage() {} func (*PromoteSlaveResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{89} + return fileDescriptor_ff9ac4f89e61ffa4, []int{91} } func (m *PromoteSlaveResponse) XXX_Unmarshal(b []byte) error { @@ -3606,7 +3676,7 @@ func (m *BackupRequest) Reset() { *m = BackupRequest{} } func (m *BackupRequest) String() string { return proto.CompactTextString(m) } func (*BackupRequest) ProtoMessage() {} func (*BackupRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{90} + return fileDescriptor_ff9ac4f89e61ffa4, []int{92} } func (m *BackupRequest) XXX_Unmarshal(b []byte) error { @@ -3652,7 +3722,7 @@ func (m *BackupResponse) Reset() { *m = BackupResponse{} } func (m *BackupResponse) String() string { return proto.CompactTextString(m) } func (*BackupResponse) ProtoMessage() {} func (*BackupResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{91} + return fileDescriptor_ff9ac4f89e61ffa4, []int{93} } func (m *BackupResponse) XXX_Unmarshal(b []byte) error { @@ -3690,7 +3760,7 @@ func (m *RestoreFromBackupRequest) Reset() { *m = RestoreFromBackupReque func (m *RestoreFromBackupRequest) String() string { return proto.CompactTextString(m) } func (*RestoreFromBackupRequest) ProtoMessage() {} func (*RestoreFromBackupRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{92} + return fileDescriptor_ff9ac4f89e61ffa4, []int{94} } func (m *RestoreFromBackupRequest) XXX_Unmarshal(b []byte) error { @@ -3722,7 +3792,7 @@ func (m *RestoreFromBackupResponse) Reset() { *m = RestoreFromBackupResp func (m *RestoreFromBackupResponse) String() string { return proto.CompactTextString(m) } func (*RestoreFromBackupResponse) ProtoMessage() {} func (*RestoreFromBackupResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ff9ac4f89e61ffa4, []int{93} + return fileDescriptor_ff9ac4f89e61ffa4, []int{95} } func (m *RestoreFromBackupResponse) XXX_Unmarshal(b []byte) error { @@ -3802,6 +3872,8 @@ func init() { proto.RegisterType((*SlaveStatusResponse)(nil), "tabletmanagerdata.SlaveStatusResponse") proto.RegisterType((*MasterPositionRequest)(nil), "tabletmanagerdata.MasterPositionRequest") proto.RegisterType((*MasterPositionResponse)(nil), "tabletmanagerdata.MasterPositionResponse") + proto.RegisterType((*WaitForPositionRequest)(nil), "tabletmanagerdata.WaitForPositionRequest") + proto.RegisterType((*WaitForPositionResponse)(nil), "tabletmanagerdata.WaitForPositionResponse") proto.RegisterType((*StopSlaveRequest)(nil), "tabletmanagerdata.StopSlaveRequest") proto.RegisterType((*StopSlaveResponse)(nil), "tabletmanagerdata.StopSlaveResponse") proto.RegisterType((*StopSlaveMinimumRequest)(nil), "tabletmanagerdata.StopSlaveMinimumRequest") @@ -3853,137 +3925,137 @@ func init() { func init() { proto.RegisterFile("tabletmanagerdata.proto", fileDescriptor_ff9ac4f89e61ffa4) } var fileDescriptor_ff9ac4f89e61ffa4 = []byte{ - // 2102 bytes of a gzipped FileDescriptorProto + // 2108 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x59, 0x5b, 0x6f, 0x1b, 0xc7, - 0xf5, 0x07, 0x49, 0x49, 0xa6, 0x0e, 0x2f, 0x22, 0x97, 0x94, 0x48, 0xc9, 0xff, 0xe8, 0xb2, 0x76, - 0xfe, 0x51, 0x5d, 0x94, 0x4a, 0x94, 0x34, 0x08, 0x52, 0xa4, 0xa8, 0xac, 0x8b, 0xed, 0x44, 0x89, - 0x95, 0x95, 0x65, 0x17, 0x41, 0x81, 0xc5, 0x90, 0x3b, 0x22, 0x17, 0x5a, 0xee, 0xac, 0x67, 0x66, - 0x29, 0xf1, 0x4b, 0xf4, 0x13, 0xf4, 0xad, 0x40, 0xfb, 0xde, 0xc7, 0x7e, 0x90, 0xf4, 0xa3, 0xf4, - 0xa1, 0x0f, 0x2d, 0xe6, 0xb2, 0xe4, 0x2c, 0x2f, 0xb6, 0x24, 0xb8, 0x40, 0x5f, 0x04, 0x9e, 0xdf, - 0x39, 0x73, 0x6e, 0x73, 0xce, 0x99, 0xb3, 0x10, 0x34, 0x38, 0x6a, 0x07, 0x98, 0xf7, 0x51, 0x88, - 0xba, 0x98, 0x7a, 0x88, 0xa3, 0x56, 0x44, 0x09, 0x27, 0x56, 0x75, 0x8a, 0xb1, 0x51, 0x78, 0x1b, - 0x63, 0x3a, 0x54, 0xfc, 0x8d, 0x32, 0x27, 0x11, 0x19, 0xcb, 0x6f, 0xac, 0x52, 0x1c, 0x05, 0x7e, - 0x07, 0x71, 0x9f, 0x84, 0x06, 0x5c, 0x0a, 0x48, 0x37, 0xe6, 0x7e, 0xa0, 0x48, 0xfb, 0xdf, 0x19, - 0x58, 0x79, 0x25, 0x14, 0x1f, 0xe1, 0x4b, 0x3f, 0xf4, 0x85, 0xb0, 0x65, 0xc1, 0x42, 0x88, 0xfa, - 0xb8, 0x99, 0xd9, 0xce, 0xec, 0x2e, 0x3b, 0xf2, 0xb7, 0xb5, 0x06, 0x4b, 0xac, 0xd3, 0xc3, 0x7d, - 0xd4, 0xcc, 0x4a, 0x54, 0x53, 0x56, 0x13, 0x1e, 0x74, 0x48, 0x10, 0xf7, 0x43, 0xd6, 0xcc, 0x6d, - 0xe7, 0x76, 0x97, 0x9d, 0x84, 0xb4, 0x5a, 0x50, 0x8b, 0xa8, 0xdf, 0x47, 0x74, 0xe8, 0x5e, 0xe1, - 0xa1, 0x9b, 0x48, 0x2d, 0x48, 0xa9, 0xaa, 0x66, 0x7d, 0x87, 0x87, 0x87, 0x5a, 0xde, 0x82, 0x05, - 0x3e, 0x8c, 0x70, 0x73, 0x51, 0x59, 0x15, 0xbf, 0xad, 0x2d, 0x28, 0x08, 0xd7, 0xdd, 0x00, 0x87, - 0x5d, 0xde, 0x6b, 0x2e, 0x6d, 0x67, 0x76, 0x17, 0x1c, 0x10, 0xd0, 0xa9, 0x44, 0xac, 0x87, 0xb0, - 0x4c, 0xc9, 0xb5, 0xdb, 0x21, 0x71, 0xc8, 0x9b, 0x0f, 0x24, 0x3b, 0x4f, 0xc9, 0xf5, 0xa1, 0xa0, - 0xad, 0xc7, 0xb0, 0x74, 0xe9, 0xe3, 0xc0, 0x63, 0xcd, 0xfc, 0x76, 0x6e, 0xb7, 0xb0, 0x5f, 0x6c, - 0xa9, 0x7c, 0x9d, 0x08, 0xd0, 0xd1, 0x3c, 0xfb, 0x2f, 0x19, 0xa8, 0x9c, 0xcb, 0x60, 0x8c, 0x14, - 0x7c, 0x02, 0x2b, 0xc2, 0x4a, 0x1b, 0x31, 0xec, 0xea, 0xb8, 0x55, 0x36, 0xca, 0x09, 0xac, 0x8e, - 0x58, 0x2f, 0x41, 0xdd, 0x8b, 0xeb, 0x8d, 0x0e, 0xb3, 0x66, 0x56, 0x9a, 0xb3, 0x5b, 0xd3, 0x57, - 0x39, 0x91, 0x6a, 0xa7, 0xc2, 0xd3, 0x00, 0x13, 0x09, 0x1d, 0x60, 0xca, 0x7c, 0x12, 0x36, 0x73, - 0xd2, 0x62, 0x42, 0x0a, 0x47, 0x2d, 0x65, 0xf5, 0xb0, 0x87, 0xc2, 0x2e, 0x76, 0x30, 0x8b, 0x03, - 0x6e, 0x3d, 0x87, 0x52, 0x1b, 0x5f, 0x12, 0x9a, 0x72, 0xb4, 0xb0, 0xff, 0x68, 0x86, 0xf5, 0xc9, - 0x30, 0x9d, 0xa2, 0x3a, 0xa9, 0x63, 0x39, 0x81, 0x22, 0xba, 0xe4, 0x98, 0xba, 0xc6, 0x4d, 0xdf, - 0x52, 0x51, 0x41, 0x1e, 0x54, 0xb0, 0xfd, 0xcf, 0x0c, 0x94, 0x2f, 0x18, 0xa6, 0x67, 0x98, 0xf6, - 0x7d, 0xc6, 0x74, 0x49, 0xf5, 0x08, 0xe3, 0x49, 0x49, 0x89, 0xdf, 0x02, 0x8b, 0x19, 0xa6, 0xba, - 0xa0, 0xe4, 0x6f, 0xeb, 0x97, 0x50, 0x8d, 0x10, 0x63, 0xd7, 0x84, 0x7a, 0x6e, 0xa7, 0x87, 0x3b, - 0x57, 0x2c, 0xee, 0xcb, 0x3c, 0x2c, 0x38, 0x95, 0x84, 0x71, 0xa8, 0x71, 0xeb, 0x47, 0x80, 0x88, - 0xfa, 0x03, 0x3f, 0xc0, 0x5d, 0xac, 0x0a, 0xab, 0xb0, 0xff, 0xd9, 0x0c, 0x6f, 0xd3, 0xbe, 0xb4, - 0xce, 0x46, 0x67, 0x8e, 0x43, 0x4e, 0x87, 0x8e, 0xa1, 0x64, 0xe3, 0x1b, 0x58, 0x99, 0x60, 0x5b, - 0x15, 0xc8, 0x5d, 0xe1, 0xa1, 0xf6, 0x5c, 0xfc, 0xb4, 0xea, 0xb0, 0x38, 0x40, 0x41, 0x8c, 0xb5, - 0xe7, 0x8a, 0xf8, 0x3a, 0xfb, 0x55, 0xc6, 0xfe, 0x39, 0x03, 0xc5, 0xa3, 0xf6, 0x7b, 0xe2, 0x2e, - 0x43, 0xd6, 0x6b, 0xeb, 0xb3, 0x59, 0xaf, 0x3d, 0xca, 0x43, 0xce, 0xc8, 0xc3, 0xcb, 0x19, 0xa1, - 0xed, 0xcd, 0x08, 0xcd, 0x34, 0xf6, 0xdf, 0x0c, 0xec, 0xcf, 0x19, 0x28, 0x8c, 0x2d, 0x31, 0xeb, - 0x14, 0x2a, 0xc2, 0x4f, 0x37, 0x1a, 0x63, 0xcd, 0x8c, 0xf4, 0x72, 0xe7, 0xbd, 0x17, 0xe0, 0xac, - 0xc4, 0x29, 0x9a, 0x59, 0x27, 0x50, 0xf6, 0xda, 0x29, 0x5d, 0xaa, 0x83, 0xb6, 0xde, 0x13, 0xb1, - 0x53, 0xf2, 0x0c, 0x8a, 0xd9, 0x9f, 0x40, 0xe1, 0xcc, 0x0f, 0xbb, 0x0e, 0x7e, 0x1b, 0x63, 0xc6, - 0x45, 0x2b, 0x45, 0x68, 0x18, 0x10, 0xe4, 0xe9, 0x20, 0x13, 0xd2, 0xde, 0x85, 0xa2, 0x12, 0x64, - 0x11, 0x09, 0x19, 0x7e, 0x87, 0xe4, 0x13, 0x28, 0x9e, 0x07, 0x18, 0x47, 0x89, 0xce, 0x0d, 0xc8, - 0x7b, 0x31, 0x95, 0x43, 0x55, 0x8a, 0xe6, 0x9c, 0x11, 0x6d, 0xaf, 0x40, 0x49, 0xcb, 0x2a, 0xb5, - 0xf6, 0x3f, 0x32, 0x60, 0x1d, 0xdf, 0xe0, 0x4e, 0xcc, 0xf1, 0x73, 0x42, 0xae, 0x12, 0x1d, 0xb3, - 0xe6, 0xeb, 0x26, 0x40, 0x84, 0x28, 0xea, 0x63, 0x8e, 0xa9, 0x0a, 0x7f, 0xd9, 0x31, 0x10, 0xeb, - 0x0c, 0x96, 0xf1, 0x0d, 0xa7, 0xc8, 0xc5, 0xe1, 0x40, 0x4e, 0xda, 0xc2, 0xfe, 0xe7, 0x33, 0xb2, - 0x33, 0x6d, 0xad, 0x75, 0x2c, 0x8e, 0x1d, 0x87, 0x03, 0x55, 0x13, 0x79, 0xac, 0xc9, 0x8d, 0xdf, - 0x40, 0x29, 0xc5, 0xba, 0x53, 0x3d, 0x5c, 0x42, 0x2d, 0x65, 0x4a, 0xe7, 0x71, 0x0b, 0x0a, 0xf8, - 0xc6, 0xe7, 0x2e, 0xe3, 0x88, 0xc7, 0x4c, 0x27, 0x08, 0x04, 0x74, 0x2e, 0x11, 0xf9, 0x8c, 0x70, - 0x8f, 0xc4, 0x7c, 0xf4, 0x8c, 0x48, 0x4a, 0xe3, 0x98, 0x26, 0x5d, 0xa0, 0x29, 0x7b, 0x00, 0x95, - 0x67, 0x98, 0xab, 0xb9, 0x92, 0xa4, 0x6f, 0x0d, 0x96, 0x64, 0xe0, 0xaa, 0xe2, 0x96, 0x1d, 0x4d, - 0x59, 0x8f, 0xa0, 0xe4, 0x87, 0x9d, 0x20, 0xf6, 0xb0, 0x3b, 0xf0, 0xf1, 0x35, 0x93, 0x26, 0xf2, - 0x4e, 0x51, 0x83, 0xaf, 0x05, 0x66, 0x7d, 0x0c, 0x65, 0x7c, 0xa3, 0x84, 0xb4, 0x12, 0xf5, 0x6c, - 0x95, 0x34, 0x2a, 0x07, 0x34, 0xb3, 0x31, 0x54, 0x0d, 0xbb, 0x3a, 0xba, 0x33, 0xa8, 0xaa, 0xc9, - 0x68, 0x0c, 0xfb, 0xbb, 0x4c, 0xdb, 0x0a, 0x9b, 0x40, 0xec, 0x06, 0xac, 0x3e, 0xc3, 0xdc, 0x28, - 0x61, 0x1d, 0xa3, 0xfd, 0x13, 0xac, 0x4d, 0x32, 0xb4, 0x13, 0xbf, 0x83, 0x42, 0xba, 0xe9, 0x84, - 0xf9, 0xcd, 0x19, 0xe6, 0xcd, 0xc3, 0xe6, 0x11, 0xbb, 0x0e, 0xd6, 0x39, 0xe6, 0x0e, 0x46, 0xde, - 0xcb, 0x30, 0x18, 0x26, 0x16, 0x57, 0xa1, 0x96, 0x42, 0x75, 0x09, 0x8f, 0xe1, 0x37, 0xd4, 0xe7, - 0x38, 0x91, 0x5e, 0x83, 0x7a, 0x1a, 0xd6, 0xe2, 0xdf, 0x42, 0x55, 0x3d, 0x4e, 0xaf, 0x86, 0x51, - 0x22, 0x6c, 0xfd, 0x1a, 0x0a, 0xca, 0x3d, 0x57, 0x3e, 0xf0, 0xc2, 0xe5, 0xf2, 0x7e, 0xbd, 0x35, - 0xda, 0x57, 0x64, 0xce, 0xb9, 0x3c, 0x01, 0x7c, 0xf4, 0x5b, 0xf8, 0x69, 0xea, 0x1a, 0x3b, 0xe4, - 0xe0, 0x4b, 0x8a, 0x59, 0x4f, 0x94, 0x94, 0xe9, 0x50, 0x1a, 0xd6, 0xe2, 0x0d, 0x58, 0x75, 0xe2, - 0xf0, 0x39, 0x46, 0x01, 0xef, 0xc9, 0x87, 0x23, 0x39, 0xd0, 0x84, 0xb5, 0x49, 0x86, 0x3e, 0xf2, - 0x05, 0x34, 0x5f, 0x74, 0x43, 0x42, 0xb1, 0x62, 0x1e, 0x53, 0x4a, 0x68, 0x6a, 0xa4, 0x70, 0x8e, - 0x69, 0x38, 0x1e, 0x14, 0x92, 0xb4, 0x1f, 0xc2, 0xfa, 0x8c, 0x53, 0x5a, 0xe5, 0xd7, 0xc2, 0x69, - 0x31, 0x4f, 0xd2, 0x95, 0xfc, 0x08, 0x4a, 0xd7, 0xc8, 0xe7, 0x6e, 0x44, 0xd8, 0xb8, 0x98, 0x96, - 0x9d, 0xa2, 0x00, 0xcf, 0x34, 0xa6, 0x22, 0x33, 0xcf, 0x6a, 0x9d, 0xfb, 0xb0, 0x76, 0x46, 0xf1, - 0x65, 0xe0, 0x77, 0x7b, 0x13, 0x0d, 0x22, 0x76, 0x32, 0x99, 0xb8, 0xa4, 0x43, 0x12, 0xd2, 0xee, - 0x42, 0x63, 0xea, 0x8c, 0xae, 0xab, 0x53, 0x28, 0x2b, 0x29, 0x97, 0xca, 0xbd, 0x22, 0x99, 0xe7, - 0x1f, 0xcf, 0xad, 0x6c, 0x73, 0x0b, 0x71, 0x4a, 0x1d, 0x83, 0x62, 0xf6, 0xbf, 0x32, 0x60, 0x1d, - 0x44, 0x51, 0x30, 0x4c, 0x7b, 0x56, 0x81, 0x1c, 0x7b, 0x1b, 0x24, 0x23, 0x86, 0xbd, 0x0d, 0xc4, - 0x88, 0xb9, 0x24, 0xb4, 0x83, 0x75, 0xb3, 0x2a, 0x42, 0xac, 0x01, 0x28, 0x08, 0xc8, 0xb5, 0x6b, - 0xec, 0xb0, 0x72, 0x32, 0xe4, 0x9d, 0x8a, 0x64, 0x38, 0x63, 0x7c, 0x7a, 0x01, 0x5a, 0xf8, 0x50, - 0x0b, 0xd0, 0xe2, 0x3d, 0x17, 0xa0, 0xbf, 0x66, 0xa0, 0x96, 0x8a, 0x5e, 0xe7, 0xf8, 0x7f, 0x6f, - 0x55, 0xab, 0x41, 0xf5, 0x94, 0x74, 0xae, 0xd4, 0xd4, 0x4b, 0x5a, 0xa3, 0x0e, 0x96, 0x09, 0x8e, - 0x1b, 0xef, 0x22, 0x0c, 0xa6, 0x84, 0xd7, 0xa0, 0x9e, 0x86, 0xb5, 0xf8, 0xdf, 0x32, 0xd0, 0xd4, - 0x4f, 0xc4, 0x09, 0xe6, 0x9d, 0xde, 0x01, 0x3b, 0x6a, 0x8f, 0xea, 0xa0, 0x0e, 0x8b, 0x72, 0x15, - 0x97, 0x09, 0x28, 0x3a, 0x8a, 0xb0, 0x1a, 0xf0, 0xc0, 0x6b, 0xbb, 0xf2, 0x69, 0xd4, 0xaf, 0x83, - 0xd7, 0xfe, 0x41, 0x3c, 0x8e, 0xeb, 0x90, 0xef, 0xa3, 0x1b, 0x97, 0x92, 0x6b, 0xa6, 0x97, 0xc1, - 0x07, 0x7d, 0x74, 0xe3, 0x90, 0x6b, 0x26, 0x17, 0x75, 0x9f, 0xc9, 0x0d, 0xbc, 0xed, 0x87, 0x01, - 0xe9, 0x32, 0x79, 0xfd, 0x79, 0xa7, 0xac, 0xe1, 0xa7, 0x0a, 0x15, 0xbd, 0x46, 0x65, 0x1b, 0x99, - 0x97, 0x9b, 0x77, 0x8a, 0xd4, 0xe8, 0x2d, 0xfb, 0x19, 0xac, 0xcf, 0xf0, 0x59, 0xdf, 0xde, 0x13, - 0x58, 0x52, 0xad, 0xa1, 0xaf, 0xcd, 0xd2, 0x9f, 0x13, 0x3f, 0x8a, 0xbf, 0xba, 0x0d, 0xb4, 0x84, - 0xfd, 0xc7, 0x0c, 0x7c, 0x94, 0xd6, 0x74, 0x10, 0x04, 0x62, 0x01, 0x63, 0x1f, 0x3e, 0x05, 0x53, - 0x91, 0x2d, 0xcc, 0x88, 0xec, 0x14, 0x36, 0xe7, 0xf9, 0x73, 0x8f, 0xf0, 0xbe, 0x9b, 0xbc, 0xdb, - 0x83, 0x28, 0x7a, 0x77, 0x60, 0xa6, 0xff, 0xd9, 0x94, 0xff, 0xd3, 0x49, 0x97, 0xca, 0xee, 0xe1, - 0x95, 0x78, 0xd8, 0x02, 0x34, 0xc0, 0x6a, 0xd7, 0x48, 0x0a, 0xf4, 0x04, 0x6a, 0x29, 0x54, 0x2b, - 0xde, 0x13, 0x1b, 0xc7, 0x68, 0x4b, 0x29, 0xec, 0x37, 0x5a, 0x93, 0xdf, 0xcb, 0xfa, 0x80, 0x16, - 0x13, 0x2f, 0xc9, 0xf7, 0x88, 0x71, 0x4c, 0x93, 0xc9, 0x9c, 0x18, 0xf8, 0x02, 0xd6, 0x26, 0x19, - 0xda, 0xc6, 0x06, 0xe4, 0x27, 0x46, 0xfb, 0x88, 0xb6, 0x2d, 0xa8, 0x9c, 0x73, 0x12, 0x49, 0xd7, - 0x12, 0x4d, 0x35, 0xa8, 0x1a, 0x98, 0x6e, 0xa4, 0xdf, 0x43, 0x63, 0x04, 0x7e, 0xef, 0x87, 0x7e, - 0x3f, 0xee, 0x1b, 0xcb, 0xe8, 0x3c, 0xfd, 0xd6, 0x0e, 0xc8, 0x67, 0xc4, 0xe5, 0x7e, 0x1f, 0x27, - 0xfb, 0x56, 0xce, 0x29, 0x08, 0xec, 0x95, 0x82, 0xec, 0x2f, 0xa1, 0x39, 0xad, 0xf9, 0x16, 0xae, - 0x4b, 0x37, 0x11, 0xe5, 0x29, 0xdf, 0x45, 0xf2, 0x0d, 0x50, 0x3b, 0xff, 0x07, 0x78, 0x38, 0x46, - 0x2f, 0x42, 0xee, 0x07, 0x07, 0x62, 0xfa, 0x7c, 0xa0, 0x00, 0x36, 0xe1, 0xff, 0x66, 0x6b, 0xd7, - 0xd6, 0x8f, 0x60, 0x47, 0xed, 0x16, 0xc7, 0x37, 0xe2, 0x8d, 0x46, 0x81, 0x58, 0x6c, 0x22, 0x44, - 0x71, 0xc8, 0xb1, 0x97, 0xf8, 0x20, 0x77, 0x56, 0xc5, 0x76, 0xfd, 0x64, 0xff, 0x87, 0x04, 0x7a, - 0xe1, 0xd9, 0x8f, 0xc1, 0x7e, 0x97, 0x16, 0x6d, 0x6b, 0x1b, 0x36, 0x27, 0xa5, 0x8e, 0x03, 0xdc, - 0x19, 0x1b, 0xb2, 0x77, 0x60, 0x6b, 0xae, 0x84, 0x56, 0x62, 0xa9, 0x75, 0x57, 0x84, 0x33, 0xaa, - 0xdf, 0x5f, 0xa8, 0x55, 0x54, 0x63, 0xfa, 0x7a, 0xea, 0xb0, 0x88, 0x3c, 0x8f, 0x26, 0x0f, 0xbc, - 0x22, 0xec, 0x75, 0x68, 0x38, 0x98, 0x89, 0xbd, 0x6c, 0x54, 0xc9, 0x89, 0x96, 0x0d, 0x68, 0x4e, - 0xb3, 0xb4, 0xd5, 0x3d, 0x68, 0xbc, 0x36, 0x70, 0xd1, 0x8c, 0x33, 0x9b, 0x79, 0x59, 0x37, 0xb3, - 0x7d, 0x02, 0xcd, 0xe9, 0x03, 0xf7, 0x1a, 0x23, 0x1f, 0x99, 0x7a, 0xde, 0x20, 0x9f, 0x9f, 0x10, - 0xd1, 0x46, 0x89, 0xf9, 0x32, 0x64, 0xf5, 0x95, 0xe4, 0x9c, 0xac, 0xef, 0xa5, 0xea, 0x25, 0x3b, - 0x51, 0x95, 0xdb, 0xb0, 0x39, 0x4f, 0x99, 0x8e, 0xb3, 0x06, 0xd5, 0x17, 0xa1, 0xcf, 0x55, 0xb3, - 0x26, 0x89, 0xf9, 0x14, 0x2c, 0x13, 0xbc, 0x45, 0xf9, 0xff, 0x9c, 0x81, 0xcd, 0x33, 0x12, 0xc5, - 0x81, 0xdc, 0x33, 0x55, 0x21, 0x7c, 0x4b, 0x62, 0x71, 0xa3, 0x89, 0xdf, 0xff, 0x0f, 0x2b, 0xa2, - 0x6c, 0xdd, 0x0e, 0xc5, 0x88, 0x63, 0xcf, 0x0d, 0x93, 0x6f, 0xa1, 0x92, 0x80, 0x0f, 0x15, 0xfa, - 0x03, 0x13, 0xb5, 0x87, 0x3a, 0x42, 0xa9, 0x39, 0xf2, 0x41, 0x41, 0x72, 0xec, 0x7f, 0x05, 0xc5, - 0xbe, 0xf4, 0xcc, 0x45, 0x81, 0x8f, 0xd4, 0xe8, 0x2f, 0xec, 0xaf, 0x4e, 0xee, 0xce, 0x07, 0x82, - 0xe9, 0x14, 0x94, 0xa8, 0x24, 0xac, 0xcf, 0xa0, 0x6e, 0x0c, 0xb4, 0xf1, 0x8a, 0xb9, 0x20, 0x6d, - 0xd4, 0x0c, 0xde, 0x68, 0xd3, 0xdc, 0x81, 0xad, 0xb9, 0x71, 0xe9, 0x14, 0xfe, 0x29, 0x03, 0x15, - 0x91, 0x2e, 0xb3, 0xf5, 0xad, 0x5f, 0xc1, 0x92, 0x92, 0xd6, 0x57, 0x3e, 0xc7, 0x3d, 0x2d, 0x34, - 0xd7, 0xb3, 0xec, 0x5c, 0xcf, 0x66, 0xe5, 0x33, 0x37, 0x23, 0x9f, 0xc9, 0x0d, 0xa7, 0x67, 0xd0, - 0x2a, 0xd4, 0x8e, 0x70, 0x9f, 0x70, 0x9c, 0xbe, 0xf8, 0x7d, 0xa8, 0xa7, 0xe1, 0x5b, 0x5c, 0xfd, - 0x3a, 0x34, 0x2e, 0x42, 0x8f, 0xcc, 0x52, 0xb7, 0x01, 0xcd, 0x69, 0x96, 0xf6, 0xe0, 0x1b, 0xd8, - 0x3a, 0xa3, 0x44, 0x30, 0xa4, 0x67, 0x6f, 0x7a, 0x38, 0x3c, 0x44, 0x71, 0xb7, 0xc7, 0x2f, 0xa2, - 0x5b, 0x4c, 0x42, 0xfb, 0xb7, 0xb0, 0x3d, 0xff, 0xf8, 0xed, 0xbc, 0x56, 0x07, 0x11, 0xd3, 0x7a, - 0x3c, 0xc3, 0xeb, 0x69, 0x96, 0xf6, 0xfa, 0xef, 0x19, 0xa8, 0x9c, 0xe3, 0x74, 0xbb, 0xdc, 0xf5, - 0xae, 0x67, 0x5c, 0x5c, 0x76, 0x56, 0x23, 0x4c, 0x7d, 0x09, 0x2d, 0x4c, 0x7f, 0x09, 0x59, 0x4f, - 0xa0, 0x2a, 0x3f, 0x0f, 0x5c, 0x26, 0x86, 0xbe, 0xcb, 0x84, 0xe3, 0xfa, 0xab, 0x60, 0x45, 0x32, - 0xc6, 0x8f, 0x81, 0x7c, 0xa3, 0xf0, 0x44, 0x57, 0xdb, 0x2f, 0xc6, 0xd1, 0x3a, 0x58, 0x2a, 0x19, - 0x3f, 0x03, 0x77, 0x0b, 0x4c, 0x7c, 0xee, 0xcd, 0x50, 0xa5, 0xed, 0x3c, 0x06, 0x5b, 0x3c, 0xac, - 0xc6, 0x34, 0x3a, 0x08, 0x3d, 0x31, 0xc4, 0x53, 0x8b, 0xc9, 0x6b, 0x78, 0xf4, 0x4e, 0xa9, 0xfb, - 0x2e, 0x2a, 0xab, 0x50, 0x33, 0xcb, 0xc5, 0xa8, 0xf7, 0x34, 0x7c, 0x8b, 0xca, 0x39, 0x87, 0xd2, - 0x53, 0xd4, 0xb9, 0x8a, 0x47, 0x65, 0xba, 0x0d, 0x85, 0x0e, 0x09, 0x3b, 0x31, 0xa5, 0x38, 0xec, - 0x0c, 0xf5, 0x50, 0x33, 0x21, 0x21, 0x21, 0xbf, 0xd0, 0x54, 0xea, 0xf5, 0x67, 0x9d, 0x09, 0xd9, - 0x5f, 0x42, 0x39, 0x51, 0xaa, 0x5d, 0x78, 0x0c, 0x8b, 0x78, 0x30, 0x4e, 0x7d, 0xb9, 0x95, 0xfc, - 0x8f, 0xe2, 0x58, 0xa0, 0x8e, 0x62, 0xea, 0x27, 0x8c, 0x13, 0x8a, 0x4f, 0x28, 0xe9, 0xa7, 0xfc, - 0xb2, 0x0f, 0x60, 0x7d, 0x06, 0xef, 0x2e, 0xea, 0x9f, 0x7e, 0xfa, 0x53, 0x6b, 0xe0, 0x73, 0xcc, - 0x58, 0xcb, 0x27, 0x7b, 0xea, 0xd7, 0x5e, 0x97, 0xec, 0x0d, 0xf8, 0x9e, 0xfc, 0x4f, 0xc9, 0xde, - 0xd4, 0xa7, 0x55, 0x7b, 0x49, 0x32, 0x3e, 0xff, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xab, 0x03, - 0x4a, 0x1d, 0xb3, 0x19, 0x00, 0x00, + 0x15, 0x06, 0x49, 0x49, 0xa6, 0x0e, 0x2f, 0x22, 0x97, 0x94, 0x48, 0xc9, 0x8d, 0x2e, 0x6b, 0xa7, + 0x51, 0x5d, 0x94, 0x4a, 0x94, 0x34, 0x08, 0x52, 0xa4, 0xa8, 0xac, 0x8b, 0xed, 0x44, 0x89, 0x95, + 0x95, 0x65, 0x17, 0x41, 0x81, 0xc5, 0x90, 0x3b, 0x22, 0x17, 0x5a, 0xee, 0xac, 0x67, 0x66, 0x29, + 0xf1, 0x4f, 0xf4, 0x17, 0xf4, 0xad, 0x40, 0xfb, 0xde, 0xc7, 0xfe, 0x10, 0xf7, 0xa7, 0xf4, 0xa1, + 0x0f, 0x2d, 0xe6, 0xb2, 0xe4, 0x2c, 0x49, 0xc9, 0x92, 0xe0, 0x02, 0x79, 0x11, 0x38, 0xdf, 0x39, + 0x73, 0x6e, 0x73, 0x6e, 0x0b, 0x41, 0x83, 0xa3, 0x76, 0x80, 0x79, 0x1f, 0x85, 0xa8, 0x8b, 0xa9, + 0x87, 0x38, 0x6a, 0x45, 0x94, 0x70, 0x62, 0x55, 0xa7, 0x08, 0x6b, 0x85, 0xb7, 0x31, 0xa6, 0x43, + 0x45, 0x5f, 0x2b, 0x73, 0x12, 0x91, 0x31, 0xff, 0xda, 0x32, 0xc5, 0x51, 0xe0, 0x77, 0x10, 0xf7, + 0x49, 0x68, 0xc0, 0xa5, 0x80, 0x74, 0x63, 0xee, 0x07, 0xea, 0x68, 0xff, 0x37, 0x03, 0x4b, 0xaf, + 0x84, 0xe0, 0x03, 0x7c, 0xee, 0x87, 0xbe, 0x60, 0xb6, 0x2c, 0x98, 0x0b, 0x51, 0x1f, 0x37, 0x33, + 0x9b, 0x99, 0xed, 0x45, 0x47, 0xfe, 0xb6, 0x56, 0x60, 0x81, 0x75, 0x7a, 0xb8, 0x8f, 0x9a, 0x59, + 0x89, 0xea, 0x93, 0xd5, 0x84, 0x07, 0x1d, 0x12, 0xc4, 0xfd, 0x90, 0x35, 0x73, 0x9b, 0xb9, 0xed, + 0x45, 0x27, 0x39, 0x5a, 0x2d, 0xa8, 0x45, 0xd4, 0xef, 0x23, 0x3a, 0x74, 0x2f, 0xf0, 0xd0, 0x4d, + 0xb8, 0xe6, 0x24, 0x57, 0x55, 0x93, 0xbe, 0xc3, 0xc3, 0x7d, 0xcd, 0x6f, 0xc1, 0x1c, 0x1f, 0x46, + 0xb8, 0x39, 0xaf, 0xb4, 0x8a, 0xdf, 0xd6, 0x06, 0x14, 0x84, 0xe9, 0x6e, 0x80, 0xc3, 0x2e, 0xef, + 0x35, 0x17, 0x36, 0x33, 0xdb, 0x73, 0x0e, 0x08, 0xe8, 0x58, 0x22, 0xd6, 0x43, 0x58, 0xa4, 0xe4, + 0xd2, 0xed, 0x90, 0x38, 0xe4, 0xcd, 0x07, 0x92, 0x9c, 0xa7, 0xe4, 0x72, 0x5f, 0x9c, 0xad, 0xc7, + 0xb0, 0x70, 0xee, 0xe3, 0xc0, 0x63, 0xcd, 0xfc, 0x66, 0x6e, 0xbb, 0xb0, 0x5b, 0x6c, 0xa9, 0x78, + 0x1d, 0x09, 0xd0, 0xd1, 0x34, 0xfb, 0x6f, 0x19, 0xa8, 0x9c, 0x4a, 0x67, 0x8c, 0x10, 0x7c, 0x02, + 0x4b, 0x42, 0x4b, 0x1b, 0x31, 0xec, 0x6a, 0xbf, 0x55, 0x34, 0xca, 0x09, 0xac, 0xae, 0x58, 0x2f, + 0x41, 0xbd, 0x8b, 0xeb, 0x8d, 0x2e, 0xb3, 0x66, 0x56, 0xaa, 0xb3, 0x5b, 0xd3, 0x4f, 0x39, 0x11, + 0x6a, 0xa7, 0xc2, 0xd3, 0x00, 0x13, 0x01, 0x1d, 0x60, 0xca, 0x7c, 0x12, 0x36, 0x73, 0x52, 0x63, + 0x72, 0x14, 0x86, 0x5a, 0x4a, 0xeb, 0x7e, 0x0f, 0x85, 0x5d, 0xec, 0x60, 0x16, 0x07, 0xdc, 0x7a, + 0x0e, 0xa5, 0x36, 0x3e, 0x27, 0x34, 0x65, 0x68, 0x61, 0xf7, 0xd1, 0x0c, 0xed, 0x93, 0x6e, 0x3a, + 0x45, 0x75, 0x53, 0xfb, 0x72, 0x04, 0x45, 0x74, 0xce, 0x31, 0x75, 0x8d, 0x97, 0xbe, 0xa5, 0xa0, + 0x82, 0xbc, 0xa8, 0x60, 0xfb, 0xdf, 0x19, 0x28, 0x9f, 0x31, 0x4c, 0x4f, 0x30, 0xed, 0xfb, 0x8c, + 0xe9, 0x94, 0xea, 0x11, 0xc6, 0x93, 0x94, 0x12, 0xbf, 0x05, 0x16, 0x33, 0x4c, 0x75, 0x42, 0xc9, + 0xdf, 0xd6, 0xaf, 0xa1, 0x1a, 0x21, 0xc6, 0x2e, 0x09, 0xf5, 0xdc, 0x4e, 0x0f, 0x77, 0x2e, 0x58, + 0xdc, 0x97, 0x71, 0x98, 0x73, 0x2a, 0x09, 0x61, 0x5f, 0xe3, 0xd6, 0x8f, 0x00, 0x11, 0xf5, 0x07, + 0x7e, 0x80, 0xbb, 0x58, 0x25, 0x56, 0x61, 0xf7, 0xb3, 0x19, 0xd6, 0xa6, 0x6d, 0x69, 0x9d, 0x8c, + 0xee, 0x1c, 0x86, 0x9c, 0x0e, 0x1d, 0x43, 0xc8, 0xda, 0x37, 0xb0, 0x34, 0x41, 0xb6, 0x2a, 0x90, + 0xbb, 0xc0, 0x43, 0x6d, 0xb9, 0xf8, 0x69, 0xd5, 0x61, 0x7e, 0x80, 0x82, 0x18, 0x6b, 0xcb, 0xd5, + 0xe1, 0xeb, 0xec, 0x57, 0x19, 0xfb, 0x5d, 0x06, 0x8a, 0x07, 0xed, 0xf7, 0xf8, 0x5d, 0x86, 0xac, + 0xd7, 0xd6, 0x77, 0xb3, 0x5e, 0x7b, 0x14, 0x87, 0x9c, 0x11, 0x87, 0x97, 0x33, 0x5c, 0xdb, 0x99, + 0xe1, 0x9a, 0xa9, 0xec, 0xff, 0xe9, 0xd8, 0x5f, 0x33, 0x50, 0x18, 0x6b, 0x62, 0xd6, 0x31, 0x54, + 0x84, 0x9d, 0x6e, 0x34, 0xc6, 0x9a, 0x19, 0x69, 0xe5, 0xd6, 0x7b, 0x1f, 0xc0, 0x59, 0x8a, 0x53, + 0x67, 0x66, 0x1d, 0x41, 0xd9, 0x6b, 0xa7, 0x64, 0xa9, 0x0a, 0xda, 0x78, 0x8f, 0xc7, 0x4e, 0xc9, + 0x33, 0x4e, 0xcc, 0xfe, 0x04, 0x0a, 0x27, 0x7e, 0xd8, 0x75, 0xf0, 0xdb, 0x18, 0x33, 0x2e, 0x4a, + 0x29, 0x42, 0xc3, 0x80, 0x20, 0x4f, 0x3b, 0x99, 0x1c, 0xed, 0x6d, 0x28, 0x2a, 0x46, 0x16, 0x91, + 0x90, 0xe1, 0x1b, 0x38, 0x9f, 0x40, 0xf1, 0x34, 0xc0, 0x38, 0x4a, 0x64, 0xae, 0x41, 0xde, 0x8b, + 0xa9, 0x6c, 0xaa, 0x92, 0x35, 0xe7, 0x8c, 0xce, 0xf6, 0x12, 0x94, 0x34, 0xaf, 0x12, 0x6b, 0xff, + 0x2b, 0x03, 0xd6, 0xe1, 0x15, 0xee, 0xc4, 0x1c, 0x3f, 0x27, 0xe4, 0x22, 0x91, 0x31, 0xab, 0xbf, + 0xae, 0x03, 0x44, 0x88, 0xa2, 0x3e, 0xe6, 0x98, 0x2a, 0xf7, 0x17, 0x1d, 0x03, 0xb1, 0x4e, 0x60, + 0x11, 0x5f, 0x71, 0x8a, 0x5c, 0x1c, 0x0e, 0x64, 0xa7, 0x2d, 0xec, 0x7e, 0x3e, 0x23, 0x3a, 0xd3, + 0xda, 0x5a, 0x87, 0xe2, 0xda, 0x61, 0x38, 0x50, 0x39, 0x91, 0xc7, 0xfa, 0xb8, 0xf6, 0x3b, 0x28, + 0xa5, 0x48, 0x77, 0xca, 0x87, 0x73, 0xa8, 0xa5, 0x54, 0xe9, 0x38, 0x6e, 0x40, 0x01, 0x5f, 0xf9, + 0xdc, 0x65, 0x1c, 0xf1, 0x98, 0xe9, 0x00, 0x81, 0x80, 0x4e, 0x25, 0x22, 0xc7, 0x08, 0xf7, 0x48, + 0xcc, 0x47, 0x63, 0x44, 0x9e, 0x34, 0x8e, 0x69, 0x52, 0x05, 0xfa, 0x64, 0x0f, 0xa0, 0xf2, 0x0c, + 0x73, 0xd5, 0x57, 0x92, 0xf0, 0xad, 0xc0, 0x82, 0x74, 0x5c, 0x65, 0xdc, 0xa2, 0xa3, 0x4f, 0xd6, + 0x23, 0x28, 0xf9, 0x61, 0x27, 0x88, 0x3d, 0xec, 0x0e, 0x7c, 0x7c, 0xc9, 0xa4, 0x8a, 0xbc, 0x53, + 0xd4, 0xe0, 0x6b, 0x81, 0x59, 0x1f, 0x43, 0x19, 0x5f, 0x29, 0x26, 0x2d, 0x44, 0x8d, 0xad, 0x92, + 0x46, 0x65, 0x83, 0x66, 0x36, 0x86, 0xaa, 0xa1, 0x57, 0x7b, 0x77, 0x02, 0x55, 0xd5, 0x19, 0x8d, + 0x66, 0x7f, 0x97, 0x6e, 0x5b, 0x61, 0x13, 0x88, 0xdd, 0x80, 0xe5, 0x67, 0x98, 0x1b, 0x29, 0xac, + 0x7d, 0xb4, 0x7f, 0x82, 0x95, 0x49, 0x82, 0x36, 0xe2, 0x0f, 0x50, 0x48, 0x17, 0x9d, 0x50, 0xbf, + 0x3e, 0x43, 0xbd, 0x79, 0xd9, 0xbc, 0x62, 0xd7, 0xc1, 0x3a, 0xc5, 0xdc, 0xc1, 0xc8, 0x7b, 0x19, + 0x06, 0xc3, 0x44, 0xe3, 0x32, 0xd4, 0x52, 0xa8, 0x4e, 0xe1, 0x31, 0xfc, 0x86, 0xfa, 0x1c, 0x27, + 0xdc, 0x2b, 0x50, 0x4f, 0xc3, 0x9a, 0xfd, 0x5b, 0xa8, 0xaa, 0xe1, 0xf4, 0x6a, 0x18, 0x25, 0xcc, + 0xd6, 0x6f, 0xa1, 0xa0, 0xcc, 0x73, 0xe5, 0x80, 0x17, 0x26, 0x97, 0x77, 0xeb, 0xad, 0xd1, 0xbe, + 0x22, 0x63, 0xce, 0xe5, 0x0d, 0xe0, 0xa3, 0xdf, 0xc2, 0x4e, 0x53, 0xd6, 0xd8, 0x20, 0x07, 0x9f, + 0x53, 0xcc, 0x7a, 0x22, 0xa5, 0x4c, 0x83, 0xd2, 0xb0, 0x66, 0x6f, 0xc0, 0xb2, 0x13, 0x87, 0xcf, + 0x31, 0x0a, 0x78, 0x4f, 0x0e, 0x8e, 0xe4, 0x42, 0x13, 0x56, 0x26, 0x09, 0xfa, 0xca, 0x17, 0xd0, + 0x7c, 0xd1, 0x0d, 0x09, 0xc5, 0x8a, 0x78, 0x48, 0x29, 0xa1, 0xa9, 0x96, 0xc2, 0x39, 0xa6, 0xe1, + 0xb8, 0x51, 0xc8, 0xa3, 0xfd, 0x10, 0x56, 0x67, 0xdc, 0xd2, 0x22, 0xbf, 0x16, 0x46, 0x8b, 0x7e, + 0x92, 0xce, 0xe4, 0x47, 0x50, 0xba, 0x44, 0x3e, 0x77, 0x23, 0xc2, 0xc6, 0xc9, 0xb4, 0xe8, 0x14, + 0x05, 0x78, 0xa2, 0x31, 0xe5, 0x99, 0x79, 0x57, 0xcb, 0xdc, 0x85, 0x95, 0x13, 0x8a, 0xcf, 0x03, + 0xbf, 0xdb, 0x9b, 0x28, 0x10, 0xb1, 0x93, 0xc9, 0xc0, 0x25, 0x15, 0x92, 0x1c, 0xed, 0x2e, 0x34, + 0xa6, 0xee, 0xe8, 0xbc, 0x3a, 0x86, 0xb2, 0xe2, 0x72, 0xa9, 0xdc, 0x2b, 0x92, 0x7e, 0xfe, 0xf1, + 0xb5, 0x99, 0x6d, 0x6e, 0x21, 0x4e, 0xa9, 0x63, 0x9c, 0x98, 0xfd, 0x9f, 0x0c, 0x58, 0x7b, 0x51, + 0x14, 0x0c, 0xd3, 0x96, 0x55, 0x20, 0xc7, 0xde, 0x06, 0x49, 0x8b, 0x61, 0x6f, 0x03, 0xd1, 0x62, + 0xce, 0x09, 0xed, 0x60, 0x5d, 0xac, 0xea, 0x20, 0xd6, 0x00, 0x14, 0x04, 0xe4, 0xd2, 0x35, 0x76, + 0x58, 0xd9, 0x19, 0xf2, 0x4e, 0x45, 0x12, 0x9c, 0x31, 0x3e, 0xbd, 0x00, 0xcd, 0x7d, 0xa8, 0x05, + 0x68, 0xfe, 0x9e, 0x0b, 0xd0, 0xdf, 0x33, 0x50, 0x4b, 0x79, 0xaf, 0x63, 0xfc, 0xf3, 0x5b, 0xd5, + 0x6a, 0x50, 0x3d, 0x26, 0x9d, 0x0b, 0xd5, 0xf5, 0x92, 0xd2, 0xa8, 0x83, 0x65, 0x82, 0xe3, 0xc2, + 0x3b, 0x0b, 0x83, 0x29, 0xe6, 0x15, 0xa8, 0xa7, 0x61, 0xcd, 0xfe, 0x8f, 0x0c, 0x34, 0xf5, 0x88, + 0x38, 0xc2, 0xbc, 0xd3, 0xdb, 0x63, 0x07, 0xed, 0x51, 0x1e, 0xd4, 0x61, 0x5e, 0xae, 0xe2, 0x32, + 0x00, 0x45, 0x47, 0x1d, 0xac, 0x06, 0x3c, 0xf0, 0xda, 0xae, 0x1c, 0x8d, 0x7a, 0x3a, 0x78, 0xed, + 0x1f, 0xc4, 0x70, 0x5c, 0x85, 0x7c, 0x1f, 0x5d, 0xb9, 0x94, 0x5c, 0x32, 0xbd, 0x0c, 0x3e, 0xe8, + 0xa3, 0x2b, 0x87, 0x5c, 0x32, 0xb9, 0xa8, 0xfb, 0x4c, 0x6e, 0xe0, 0x6d, 0x3f, 0x0c, 0x48, 0x97, + 0xc9, 0xe7, 0xcf, 0x3b, 0x65, 0x0d, 0x3f, 0x55, 0xa8, 0xa8, 0x35, 0x2a, 0xcb, 0xc8, 0x7c, 0xdc, + 0xbc, 0x53, 0xa4, 0x46, 0x6d, 0xd9, 0xcf, 0x60, 0x75, 0x86, 0xcd, 0xfa, 0xf5, 0x9e, 0xc0, 0x82, + 0x2a, 0x0d, 0xfd, 0x6c, 0x96, 0xfe, 0x9c, 0xf8, 0x51, 0xfc, 0xd5, 0x65, 0xa0, 0x39, 0xec, 0x3f, + 0x67, 0xe0, 0xa3, 0xb4, 0xa4, 0xbd, 0x20, 0x10, 0x0b, 0x18, 0xfb, 0xf0, 0x21, 0x98, 0xf2, 0x6c, + 0x6e, 0x86, 0x67, 0xc7, 0xb0, 0x7e, 0x9d, 0x3d, 0xf7, 0x70, 0xef, 0xbb, 0xc9, 0xb7, 0xdd, 0x8b, + 0xa2, 0x9b, 0x1d, 0x33, 0xed, 0xcf, 0xa6, 0xec, 0x9f, 0x0e, 0xba, 0x14, 0x76, 0x0f, 0xab, 0xc4, + 0x60, 0x0b, 0xd0, 0x00, 0xab, 0x5d, 0x23, 0x49, 0xd0, 0x23, 0xa8, 0xa5, 0x50, 0x2d, 0x78, 0x47, + 0x6c, 0x1c, 0xa3, 0x2d, 0xa5, 0xb0, 0xdb, 0x68, 0x4d, 0x7e, 0x2f, 0xeb, 0x0b, 0x9a, 0x4d, 0x4c, + 0x92, 0xef, 0x11, 0xe3, 0x98, 0x26, 0x9d, 0x39, 0x51, 0xf0, 0x05, 0xac, 0x4c, 0x12, 0xb4, 0x8e, + 0x35, 0xc8, 0x4f, 0xb4, 0xf6, 0xd1, 0x59, 0xdc, 0x7a, 0x83, 0x7c, 0x7e, 0x44, 0x26, 0xe5, 0xdd, + 0x78, 0x6b, 0x15, 0x1a, 0x53, 0xb7, 0x74, 0xc1, 0x59, 0x50, 0x39, 0xe5, 0x24, 0x92, 0xbe, 0x26, + 0xa6, 0xd5, 0xa0, 0x6a, 0x60, 0x9a, 0xf1, 0x8f, 0xd0, 0x18, 0x81, 0xdf, 0xfb, 0xa1, 0xdf, 0x8f, + 0xfb, 0xb7, 0x50, 0x6d, 0x6d, 0x81, 0x9c, 0x4b, 0x2e, 0xf7, 0xfb, 0x38, 0x59, 0xe0, 0x72, 0x4e, + 0x41, 0x60, 0xaf, 0x14, 0x64, 0x7f, 0x09, 0xcd, 0x69, 0xc9, 0xb7, 0x88, 0x85, 0x34, 0x13, 0x51, + 0x9e, 0xb2, 0x5d, 0xbc, 0xa6, 0x01, 0x6a, 0xe3, 0xff, 0x04, 0x0f, 0xc7, 0xe8, 0x59, 0xc8, 0xfd, + 0x60, 0x4f, 0xb4, 0xb3, 0x0f, 0xe4, 0xc0, 0x3a, 0xfc, 0x62, 0xb6, 0x74, 0xad, 0xfd, 0x00, 0xb6, + 0xd4, 0xb2, 0x72, 0x78, 0x25, 0x86, 0x3e, 0x0a, 0xc4, 0xa6, 0x14, 0x21, 0x8a, 0x43, 0x8e, 0xbd, + 0xc4, 0x06, 0xb9, 0x04, 0x2b, 0xb2, 0xeb, 0x27, 0x1f, 0x14, 0x90, 0x40, 0x2f, 0x3c, 0xfb, 0x31, + 0xd8, 0x37, 0x49, 0xd1, 0xba, 0x36, 0x61, 0x7d, 0x92, 0xeb, 0x30, 0xc0, 0x9d, 0xb1, 0x22, 0x7b, + 0x0b, 0x36, 0xae, 0xe5, 0x18, 0x27, 0x85, 0xd8, 0x63, 0x85, 0x3b, 0xa3, 0x82, 0xf8, 0x95, 0xda, + 0x6d, 0x35, 0xa6, 0x9f, 0xa7, 0x0e, 0xf3, 0xc8, 0xf3, 0x68, 0xb2, 0x31, 0xa8, 0x83, 0x48, 0x37, + 0x07, 0x33, 0xb1, 0xe8, 0x8d, 0x4a, 0x23, 0x91, 0xb2, 0x06, 0xcd, 0x69, 0x92, 0xd6, 0xba, 0x03, + 0x8d, 0xd7, 0x06, 0x2e, 0xaa, 0x7b, 0x66, 0x77, 0x58, 0xd4, 0xdd, 0xc1, 0x3e, 0x82, 0xe6, 0xf4, + 0x85, 0x7b, 0xf5, 0xa5, 0x8f, 0x4c, 0x39, 0xe3, 0x52, 0x49, 0xd4, 0x97, 0x21, 0xab, 0x9f, 0x24, + 0xe7, 0x64, 0x7d, 0x2f, 0x95, 0x2f, 0xd9, 0x89, 0xac, 0xdc, 0x84, 0xf5, 0xeb, 0x84, 0x69, 0x3f, + 0x6b, 0x50, 0x7d, 0x11, 0xfa, 0x5c, 0x55, 0x7f, 0x12, 0x98, 0x4f, 0xc1, 0x32, 0xc1, 0x5b, 0xa4, + 0xff, 0xbb, 0x0c, 0xac, 0x9f, 0x90, 0x28, 0x0e, 0xe4, 0xe2, 0xaa, 0x12, 0xe1, 0x5b, 0x12, 0x8b, + 0x17, 0x4d, 0xec, 0xfe, 0x25, 0x2c, 0x89, 0xb4, 0x75, 0x3b, 0x14, 0x23, 0x8e, 0x3d, 0x37, 0x4c, + 0x3e, 0xae, 0x4a, 0x02, 0xde, 0x57, 0xe8, 0x0f, 0x4c, 0xe4, 0x1e, 0xea, 0x08, 0xa1, 0xe6, 0x0c, + 0x01, 0x05, 0xc9, 0x39, 0xf2, 0x15, 0x14, 0xfb, 0xd2, 0x32, 0x17, 0x05, 0x3e, 0x52, 0xb3, 0xa4, + 0xb0, 0xbb, 0x3c, 0xb9, 0x8c, 0xef, 0x09, 0xa2, 0x53, 0x50, 0xac, 0xf2, 0x60, 0x7d, 0x06, 0x75, + 0xa3, 0x43, 0x8e, 0x77, 0xd6, 0x39, 0xa9, 0xa3, 0x66, 0xd0, 0x46, 0xab, 0xeb, 0x16, 0x6c, 0x5c, + 0xeb, 0x97, 0x0e, 0xe1, 0x5f, 0x32, 0x50, 0x11, 0xe1, 0x32, 0x4b, 0xdf, 0xfa, 0x0d, 0x2c, 0x28, + 0x6e, 0xfd, 0xe4, 0xd7, 0x98, 0xa7, 0x99, 0xae, 0xb5, 0x2c, 0x7b, 0xad, 0x65, 0xb3, 0xe2, 0x99, + 0x9b, 0x11, 0xcf, 0xe4, 0x85, 0xd3, 0x3d, 0x68, 0x19, 0x6a, 0x07, 0xb8, 0x4f, 0x38, 0x4e, 0x3f, + 0xfc, 0x2e, 0xd4, 0xd3, 0xf0, 0x2d, 0x9e, 0x7e, 0x15, 0x1a, 0x67, 0xa1, 0x47, 0x66, 0x89, 0x5b, + 0x83, 0xe6, 0x34, 0x49, 0x5b, 0xf0, 0x0d, 0x6c, 0x9c, 0x50, 0x22, 0x08, 0xd2, 0xb2, 0x37, 0x3d, + 0x1c, 0xee, 0xa3, 0xb8, 0xdb, 0xe3, 0x67, 0xd1, 0x6d, 0xa6, 0xc8, 0xef, 0x61, 0xf3, 0xfa, 0xeb, + 0xb7, 0xb3, 0x5a, 0x5d, 0x44, 0x4c, 0xcb, 0xf1, 0x0c, 0xab, 0xa7, 0x49, 0xda, 0xea, 0x7f, 0x66, + 0xa0, 0x72, 0x8a, 0xd3, 0xe5, 0x72, 0xd7, 0xb7, 0x9e, 0xf1, 0x70, 0xd9, 0x59, 0x85, 0x30, 0xf5, + 0x69, 0x35, 0x37, 0xfd, 0x69, 0x65, 0x3d, 0x81, 0xaa, 0xfc, 0xde, 0x70, 0x99, 0x68, 0xfa, 0x2e, + 0x13, 0x86, 0xeb, 0xcf, 0x8c, 0x25, 0x49, 0x18, 0x0f, 0x03, 0x39, 0xa3, 0xf0, 0x44, 0x55, 0xdb, + 0x2f, 0xc6, 0xde, 0x3a, 0x58, 0x0a, 0x19, 0x8f, 0x81, 0xbb, 0x39, 0x26, 0xbe, 0x1f, 0x67, 0x88, + 0xd2, 0x7a, 0x1e, 0x83, 0x2d, 0x06, 0xab, 0xd1, 0x8d, 0xf6, 0x42, 0x4f, 0x34, 0xf1, 0xd4, 0xa6, + 0xf3, 0x1a, 0x1e, 0xdd, 0xc8, 0x75, 0xdf, 0xcd, 0x67, 0x19, 0x6a, 0x66, 0xba, 0x18, 0xf9, 0x9e, + 0x86, 0x6f, 0x91, 0x39, 0xa7, 0x50, 0x7a, 0x8a, 0x3a, 0x17, 0xf1, 0x28, 0x4d, 0x37, 0xa1, 0xd0, + 0x21, 0x61, 0x27, 0xa6, 0x14, 0x87, 0x9d, 0xa1, 0x6e, 0x6a, 0x26, 0x24, 0x38, 0xe4, 0x27, 0x9f, + 0x0a, 0xbd, 0xfe, 0x4e, 0x34, 0x21, 0xfb, 0x4b, 0x28, 0x27, 0x42, 0xb5, 0x09, 0x8f, 0x61, 0x1e, + 0x0f, 0xc6, 0xa1, 0x2f, 0xb7, 0x92, 0x7f, 0x7a, 0x1c, 0x0a, 0xd4, 0x51, 0x44, 0x3d, 0xc2, 0x38, + 0xa1, 0xf8, 0x88, 0x92, 0x7e, 0xca, 0x2e, 0x7b, 0x0f, 0x56, 0x67, 0xd0, 0xee, 0x22, 0xfe, 0xe9, + 0xa7, 0x3f, 0xb5, 0x06, 0x3e, 0xc7, 0x8c, 0xb5, 0x7c, 0xb2, 0xa3, 0x7e, 0xed, 0x74, 0xc9, 0xce, + 0x80, 0xef, 0xc8, 0x7f, 0xbd, 0xec, 0x4c, 0x7d, 0xab, 0xb5, 0x17, 0x24, 0xe1, 0xf3, 0xff, 0x05, + 0x00, 0x00, 0xff, 0xff, 0x05, 0x80, 0x1f, 0x06, 0x04, 0x1a, 0x00, 0x00, } diff --git a/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go b/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go index 11699a3fbf3..1f494400a18 100644 --- a/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go +++ b/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go @@ -29,72 +29,73 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package func init() { proto.RegisterFile("tabletmanagerservice.proto", fileDescriptor_9ee75fe63cfd9360) } var fileDescriptor_9ee75fe63cfd9360 = []byte{ - // 1030 bytes of a gzipped FileDescriptorProto + // 1041 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x98, 0x6d, 0x6f, 0x1b, 0x45, - 0x10, 0xc7, 0xb1, 0x04, 0x95, 0x58, 0x1e, 0xbb, 0xaa, 0x28, 0x0a, 0x12, 0x4f, 0x4d, 0x79, 0x48, + 0x10, 0xc7, 0xb1, 0x04, 0x95, 0x58, 0x1e, 0xbb, 0xaa, 0x28, 0x0a, 0x12, 0x4f, 0x6d, 0x78, 0x48, 0x51, 0xdc, 0x34, 0x94, 0xf7, 0x6e, 0x9a, 0xb4, 0x41, 0x8d, 0x30, 0x76, 0x43, 0x10, 0x48, 0x48, - 0x1b, 0x7b, 0xe2, 0x3b, 0x72, 0xde, 0x3d, 0x76, 0xf7, 0xac, 0xe6, 0x15, 0x12, 0x12, 0xaf, 0x90, - 0xf8, 0x4a, 0x7c, 0x35, 0x74, 0x0f, 0xbb, 0x37, 0x6b, 0xcf, 0xad, 0xed, 0x77, 0x91, 0xff, 0xbf, - 0x9d, 0x99, 0x9d, 0x9d, 0x99, 0xdd, 0x1c, 0xdb, 0xb1, 0xe2, 0x32, 0x03, 0x3b, 0x17, 0x52, 0xcc, - 0x40, 0x1b, 0xd0, 0x8b, 0x74, 0x02, 0xfb, 0xb9, 0x56, 0x56, 0xf1, 0x3b, 0x94, 0xb6, 0x73, 0x37, - 0xf8, 0x75, 0x2a, 0xac, 0xa8, 0xf1, 0x47, 0xff, 0xed, 0xb2, 0x77, 0x5e, 0x56, 0xda, 0x59, 0xad, - 0xf1, 0x53, 0xf6, 0xfa, 0x30, 0x95, 0x33, 0xfe, 0xf1, 0xfe, 0xea, 0x9a, 0x52, 0x18, 0xc1, 0x1f, - 0x05, 0x18, 0xbb, 0xf3, 0x49, 0xa7, 0x6e, 0x72, 0x25, 0x0d, 0x7c, 0xfe, 0x1a, 0x7f, 0xc1, 0xde, - 0x18, 0x67, 0x00, 0x39, 0xa7, 0xd8, 0x4a, 0x71, 0xc6, 0x3e, 0xed, 0x06, 0xbc, 0xb5, 0xdf, 0xd8, - 0x5b, 0xc7, 0xaf, 0x60, 0x52, 0x58, 0x78, 0xae, 0xd4, 0x35, 0xbf, 0x4f, 0x2c, 0x41, 0xba, 0xb3, - 0xfc, 0xc5, 0x3a, 0xcc, 0xdb, 0xff, 0x99, 0xbd, 0xf9, 0x0c, 0xec, 0x78, 0x92, 0xc0, 0x5c, 0xf0, - 0x7b, 0xc4, 0x32, 0xaf, 0x3a, 0xdb, 0xbb, 0x71, 0xc8, 0x5b, 0x9e, 0xb1, 0x77, 0x9f, 0x81, 0x1d, - 0x82, 0x9e, 0xa7, 0xc6, 0xa4, 0x4a, 0x1a, 0xfe, 0x15, 0xbd, 0x12, 0x21, 0xce, 0xc7, 0xd7, 0x1b, - 0x90, 0x38, 0x45, 0x63, 0xb0, 0x23, 0x10, 0xd3, 0x1f, 0x64, 0x76, 0x43, 0xa6, 0x08, 0xe9, 0xb1, - 0x14, 0x05, 0x98, 0xb7, 0x2f, 0xd8, 0xdb, 0x8d, 0x70, 0xa1, 0x53, 0x0b, 0x3c, 0xb2, 0xb2, 0x02, - 0x9c, 0x87, 0x2f, 0xd7, 0x72, 0xde, 0xc5, 0xaf, 0x8c, 0x1d, 0x25, 0x42, 0xce, 0xe0, 0xe5, 0x4d, - 0x0e, 0x9c, 0xca, 0x70, 0x2b, 0x3b, 0xf3, 0xf7, 0xd7, 0x50, 0x38, 0xfe, 0x11, 0x5c, 0x69, 0x30, - 0xc9, 0xd8, 0x8a, 0x8e, 0xf8, 0x31, 0x10, 0x8b, 0x3f, 0xe4, 0xf0, 0x59, 0x8f, 0x0a, 0xf9, 0x1c, - 0x44, 0x66, 0x93, 0xa3, 0x04, 0x26, 0xd7, 0xe4, 0x59, 0x87, 0x48, 0xec, 0xac, 0x97, 0x49, 0xef, - 0x28, 0x67, 0xb7, 0x4f, 0x67, 0x52, 0x69, 0xa8, 0xe5, 0x63, 0xad, 0x95, 0xe6, 0x0f, 0x08, 0x0b, - 0x2b, 0x94, 0x73, 0xf7, 0xcd, 0x66, 0x70, 0x98, 0xbd, 0x4c, 0x89, 0x69, 0xd3, 0x23, 0x74, 0xf6, - 0x5a, 0x20, 0x9e, 0x3d, 0xcc, 0x79, 0x17, 0xbf, 0xb3, 0xf7, 0x86, 0x1a, 0xae, 0xb2, 0x74, 0x96, - 0xb8, 0x4e, 0xa4, 0x92, 0xb2, 0xc4, 0x38, 0x47, 0x7b, 0x9b, 0xa0, 0xb8, 0x59, 0x06, 0x79, 0x9e, - 0xdd, 0x34, 0x7e, 0xa8, 0x22, 0x42, 0x7a, 0xac, 0x59, 0x02, 0x0c, 0x57, 0xf2, 0x0b, 0x35, 0xb9, - 0xae, 0xa6, 0xab, 0x21, 0x2b, 0xb9, 0x95, 0x63, 0x95, 0x8c, 0x29, 0x7c, 0x16, 0xe7, 0x32, 0x6b, - 0xcd, 0x53, 0x61, 0x61, 0x20, 0x76, 0x16, 0x21, 0x87, 0x0b, 0xac, 0x19, 0x94, 0x27, 0x60, 0x27, - 0xc9, 0xc0, 0x3c, 0xbd, 0x14, 0x64, 0x81, 0xad, 0x50, 0xb1, 0x02, 0x23, 0x60, 0xef, 0xf1, 0x4f, - 0xf6, 0x41, 0x28, 0x0f, 0xb2, 0x6c, 0xa8, 0xd3, 0x85, 0xe1, 0x0f, 0xd7, 0x5a, 0x72, 0xa8, 0xf3, - 0x7d, 0xb0, 0xc5, 0x8a, 0xee, 0x2d, 0x0f, 0xf2, 0x7c, 0x83, 0x2d, 0x0f, 0xf2, 0x7c, 0xf3, 0x2d, - 0x57, 0x70, 0x30, 0xb1, 0x33, 0xb1, 0x80, 0x72, 0x8c, 0x14, 0x86, 0x9e, 0xd8, 0xad, 0x1e, 0x9d, - 0xd8, 0x18, 0xc3, 0xe3, 0xe8, 0x4c, 0x18, 0x0b, 0x7a, 0xa8, 0x4c, 0x6a, 0x53, 0x25, 0xc9, 0x71, - 0x14, 0x22, 0xb1, 0x71, 0xb4, 0x4c, 0xe2, 0xdb, 0x73, 0x6c, 0x55, 0x5e, 0x45, 0x41, 0xde, 0x9e, - 0x5e, 0x8d, 0xdd, 0x9e, 0x08, 0xf2, 0x96, 0xe7, 0xec, 0x7d, 0xff, 0xf3, 0x59, 0x2a, 0xd3, 0x79, - 0x31, 0xe7, 0x7b, 0xb1, 0xb5, 0x0d, 0xe4, 0xfc, 0x3c, 0xd8, 0x88, 0xc5, 0x6d, 0x3b, 0xb6, 0x42, - 0xdb, 0x7a, 0x27, 0x74, 0x90, 0x4e, 0x8e, 0xb5, 0x2d, 0xa6, 0xbc, 0xf1, 0x1b, 0x76, 0xa7, 0xfd, - 0xfd, 0x5c, 0xda, 0x34, 0x1b, 0x5c, 0x59, 0xd0, 0x7c, 0x3f, 0x6a, 0xa0, 0x05, 0x9d, 0xc3, 0xfe, - 0xc6, 0xbc, 0x77, 0xfd, 0x4f, 0x8f, 0xed, 0xd4, 0x2f, 0xbd, 0xe3, 0x57, 0x16, 0xb4, 0x14, 0x59, - 0x79, 0xb5, 0xe7, 0x42, 0x83, 0xb4, 0x30, 0xe5, 0xdf, 0x12, 0x16, 0xbb, 0x71, 0x17, 0xc7, 0xe3, - 0x2d, 0x57, 0xf9, 0x68, 0xfe, 0xea, 0xb1, 0xbb, 0xcb, 0xe0, 0x71, 0x06, 0x93, 0x32, 0x94, 0x83, - 0x0d, 0x8c, 0x36, 0xac, 0x8b, 0xe3, 0xd1, 0x36, 0x4b, 0x96, 0x5f, 0x7c, 0x65, 0xca, 0x4c, 0xe7, - 0x8b, 0xaf, 0x52, 0xd7, 0xbd, 0xf8, 0x1a, 0x08, 0xd7, 0xec, 0x4f, 0x23, 0xc8, 0xb3, 0x74, 0x22, - 0xca, 0x3e, 0x29, 0x27, 0x00, 0x59, 0xb3, 0xcb, 0x50, 0xac, 0x66, 0x57, 0x59, 0x3c, 0x38, 0xb1, - 0x7a, 0x21, 0x52, 0x7b, 0xa2, 0xca, 0x2e, 0x25, 0x07, 0x27, 0x8d, 0xc6, 0x06, 0x67, 0xd7, 0x0a, - 0xbc, 0xdf, 0x11, 0x98, 0xf2, 0x45, 0xe7, 0x39, 0x72, 0xbf, 0xcb, 0x50, 0x6c, 0xbf, 0xab, 0x2c, - 0xee, 0xd1, 0x53, 0x99, 0xda, 0x7a, 0x18, 0x91, 0x3d, 0xda, 0xca, 0xb1, 0x1e, 0xc5, 0x54, 0x50, - 0x9a, 0x43, 0x95, 0x17, 0x59, 0xf5, 0xb0, 0xab, 0x6b, 0xf7, 0x7b, 0x55, 0x94, 0x45, 0x44, 0x96, - 0x66, 0x07, 0x1b, 0x2b, 0xcd, 0xce, 0x25, 0xb8, 0x34, 0xcb, 0xe0, 0xba, 0xc7, 0xa9, 0x57, 0x63, - 0xa5, 0x89, 0x20, 0xfc, 0x72, 0x78, 0x0a, 0x73, 0x65, 0xa1, 0xc9, 0x1e, 0x75, 0x97, 0x60, 0x20, - 0xf6, 0x72, 0x08, 0x39, 0x5c, 0x0d, 0xe7, 0x72, 0xaa, 0x02, 0x37, 0x7b, 0xe4, 0xc3, 0x23, 0x84, - 0x62, 0xd5, 0xb0, 0xca, 0x7a, 0x77, 0x7f, 0xf7, 0xd8, 0x87, 0x43, 0xad, 0x4a, 0xad, 0xda, 0xec, - 0x45, 0x02, 0xf2, 0x48, 0x14, 0xb3, 0xc4, 0x9e, 0xe7, 0x9c, 0x4c, 0x7f, 0x07, 0xec, 0xfc, 0x1f, - 0x6e, 0xb5, 0x26, 0xb8, 0xa8, 0x2a, 0x59, 0x98, 0x86, 0x9e, 0xd2, 0x17, 0xd5, 0x12, 0x14, 0xbd, - 0xa8, 0x56, 0xd8, 0xe0, 0xc6, 0x05, 0xd7, 0x03, 0xf7, 0xe8, 0xff, 0xb0, 0xc2, 0xbc, 0xee, 0xc6, - 0x21, 0xfc, 0x0c, 0x72, 0x7e, 0x47, 0x60, 0xca, 0x6b, 0x05, 0xa6, 0x3c, 0x16, 0x9d, 0xa7, 0x62, - 0xcf, 0x20, 0x02, 0xf6, 0x1e, 0xff, 0xed, 0xb1, 0x8f, 0xca, 0x3b, 0x19, 0xb5, 0xfb, 0x40, 0x4e, - 0xcb, 0xc9, 0x5a, 0xbf, 0x8b, 0x1e, 0x77, 0xdc, 0xe1, 0x1d, 0xbc, 0x0b, 0xe3, 0xbb, 0x6d, 0x97, - 0xe1, 0x2e, 0xc1, 0x27, 0x4e, 0x76, 0x09, 0x06, 0x62, 0x5d, 0x12, 0x72, 0xde, 0xc5, 0x8f, 0xec, - 0xd6, 0x13, 0x31, 0xb9, 0x2e, 0x72, 0x4e, 0x7d, 0xfd, 0xa8, 0x25, 0x67, 0xf6, 0xb3, 0x08, 0xe1, - 0x0c, 0x3e, 0xec, 0x71, 0xcd, 0x6e, 0x97, 0xd9, 0x55, 0x1a, 0x4e, 0xb4, 0x9a, 0x37, 0xd6, 0x3b, - 0x66, 0x6b, 0x48, 0xc5, 0x0e, 0x8e, 0x80, 0x5b, 0x9f, 0x4f, 0x0e, 0x7f, 0x39, 0x58, 0xa4, 0x16, - 0x8c, 0xd9, 0x4f, 0x55, 0xbf, 0xfe, 0xab, 0x3f, 0x53, 0xfd, 0x85, 0xed, 0x57, 0x5f, 0x98, 0xfa, - 0xd4, 0xf7, 0xa8, 0xcb, 0x5b, 0x95, 0x76, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xae, 0x75, - 0xbb, 0x5f, 0xca, 0x12, 0x00, 0x00, + 0x1b, 0x7b, 0x62, 0x1f, 0x39, 0xef, 0x1e, 0xbb, 0x7b, 0x56, 0xf3, 0x0a, 0x09, 0x89, 0x57, 0x48, + 0x7c, 0x11, 0xbe, 0x24, 0xba, 0x87, 0xdd, 0x9b, 0x3d, 0xcf, 0xad, 0xed, 0x77, 0x91, 0xff, 0xbf, + 0x99, 0xd9, 0x87, 0x99, 0xd9, 0xc9, 0xb1, 0x1d, 0x2b, 0x2e, 0x53, 0xb0, 0x0b, 0x21, 0xc5, 0x0c, + 0xb4, 0x01, 0xbd, 0x4c, 0x26, 0xb0, 0x9f, 0x69, 0x65, 0x15, 0xbf, 0x43, 0x69, 0x3b, 0x77, 0x83, + 0x5f, 0xa7, 0xc2, 0x8a, 0x0a, 0x7f, 0xf4, 0xdf, 0x2e, 0x7b, 0xe7, 0x65, 0xa9, 0x9d, 0x55, 0x1a, + 0x3f, 0x65, 0xaf, 0x0f, 0x13, 0x39, 0xe3, 0x1f, 0xef, 0xaf, 0xda, 0x14, 0xc2, 0x08, 0xfe, 0xc8, + 0xc1, 0xd8, 0x9d, 0x4f, 0x3a, 0x75, 0x93, 0x29, 0x69, 0xe0, 0xf3, 0xd7, 0xf8, 0x0b, 0xf6, 0xc6, + 0x38, 0x05, 0xc8, 0x38, 0xc5, 0x96, 0x8a, 0x73, 0xf6, 0x69, 0x37, 0xe0, 0xbd, 0xfd, 0xc6, 0xde, + 0x3a, 0x7e, 0x05, 0x93, 0xdc, 0xc2, 0x73, 0xa5, 0xae, 0xf9, 0x2e, 0x61, 0x82, 0x74, 0xe7, 0xf9, + 0x8b, 0x75, 0x98, 0xf7, 0xff, 0x33, 0x7b, 0xf3, 0x19, 0xd8, 0xf1, 0x64, 0x0e, 0x0b, 0xc1, 0xef, + 0x11, 0x66, 0x5e, 0x75, 0xbe, 0xef, 0xc7, 0x21, 0xef, 0x79, 0xc6, 0xde, 0x7d, 0x06, 0x76, 0x08, + 0x7a, 0x91, 0x18, 0x93, 0x28, 0x69, 0xf8, 0x57, 0xb4, 0x25, 0x42, 0x5c, 0x8c, 0xaf, 0x37, 0x20, + 0xf1, 0x11, 0x8d, 0xc1, 0x8e, 0x40, 0x4c, 0x7f, 0x90, 0xe9, 0x0d, 0x79, 0x44, 0x48, 0x8f, 0x1d, + 0x51, 0x80, 0x79, 0xff, 0x82, 0xbd, 0x5d, 0x0b, 0x17, 0x3a, 0xb1, 0xc0, 0x23, 0x96, 0x25, 0xe0, + 0x22, 0x7c, 0xb9, 0x96, 0xf3, 0x21, 0x7e, 0x65, 0xec, 0x68, 0x2e, 0xe4, 0x0c, 0x5e, 0xde, 0x64, + 0xc0, 0xa9, 0x13, 0x6e, 0x64, 0xe7, 0x7e, 0x77, 0x0d, 0x85, 0xd7, 0x3f, 0x82, 0x2b, 0x0d, 0x66, + 0x3e, 0xb6, 0xa2, 0x63, 0xfd, 0x18, 0x88, 0xad, 0x3f, 0xe4, 0xf0, 0x5d, 0x8f, 0x72, 0xf9, 0x1c, + 0x44, 0x6a, 0xe7, 0x47, 0x73, 0x98, 0x5c, 0x93, 0x77, 0x1d, 0x22, 0xb1, 0xbb, 0x6e, 0x93, 0x3e, + 0x50, 0xc6, 0x6e, 0x9f, 0xce, 0xa4, 0xd2, 0x50, 0xc9, 0xc7, 0x5a, 0x2b, 0xcd, 0x1f, 0x10, 0x1e, + 0x56, 0x28, 0x17, 0xee, 0x9b, 0xcd, 0xe0, 0xf0, 0xf4, 0x52, 0x25, 0xa6, 0x75, 0x8d, 0xd0, 0xa7, + 0xd7, 0x00, 0xf1, 0xd3, 0xc3, 0x9c, 0x0f, 0xf1, 0x3b, 0x7b, 0x6f, 0xa8, 0xe1, 0x2a, 0x4d, 0x66, + 0x73, 0x57, 0x89, 0xd4, 0xa1, 0xb4, 0x18, 0x17, 0x68, 0x6f, 0x13, 0x14, 0x17, 0xcb, 0x20, 0xcb, + 0xd2, 0x9b, 0x3a, 0x0e, 0x95, 0x44, 0x48, 0x8f, 0x15, 0x4b, 0x80, 0xe1, 0x4c, 0x7e, 0xa1, 0x26, + 0xd7, 0x65, 0x77, 0x35, 0x64, 0x26, 0x37, 0x72, 0x2c, 0x93, 0x31, 0x85, 0xef, 0xe2, 0x5c, 0xa6, + 0x8d, 0x7b, 0x6a, 0x59, 0x18, 0x88, 0xdd, 0x45, 0xc8, 0xe1, 0x04, 0xab, 0x1b, 0xe5, 0x09, 0xd8, + 0xc9, 0x7c, 0x60, 0x9e, 0x5e, 0x0a, 0x32, 0xc1, 0x56, 0xa8, 0x58, 0x82, 0x11, 0xb0, 0x8f, 0xf8, + 0x27, 0xfb, 0x20, 0x94, 0x07, 0x69, 0x3a, 0xd4, 0xc9, 0xd2, 0xf0, 0x87, 0x6b, 0x3d, 0x39, 0xd4, + 0xc5, 0x3e, 0xd8, 0xc2, 0xa2, 0x7b, 0xcb, 0x83, 0x2c, 0xdb, 0x60, 0xcb, 0x83, 0x2c, 0xdb, 0x7c, + 0xcb, 0x25, 0x1c, 0x74, 0xec, 0x54, 0x2c, 0xa1, 0x68, 0x23, 0xb9, 0xa1, 0x3b, 0x76, 0xa3, 0x47, + 0x3b, 0x36, 0xc6, 0x70, 0x3b, 0x3a, 0x13, 0xc6, 0x82, 0x1e, 0x2a, 0x93, 0xd8, 0x44, 0x49, 0xb2, + 0x1d, 0x85, 0x48, 0xac, 0x1d, 0xb5, 0x49, 0x5c, 0xb9, 0x17, 0x22, 0xb1, 0x27, 0xaa, 0x89, 0x44, + 0xd9, 0xb7, 0x98, 0x58, 0xe5, 0xae, 0xa0, 0xf8, 0xa5, 0x1e, 0x5b, 0x95, 0x95, 0x3b, 0x26, 0x5f, + 0x6a, 0xaf, 0xc6, 0x5e, 0x6a, 0x04, 0x79, 0xcf, 0x0b, 0xf6, 0xbe, 0xff, 0xf9, 0x2c, 0x91, 0xc9, + 0x22, 0x5f, 0xf0, 0xbd, 0x98, 0x6d, 0x0d, 0xb9, 0x38, 0x0f, 0x36, 0x62, 0x71, 0x8b, 0x18, 0x5b, + 0xa1, 0x6d, 0xb5, 0x13, 0x7a, 0x91, 0x4e, 0x8e, 0xb5, 0x08, 0x4c, 0x79, 0xe7, 0x37, 0xec, 0x4e, + 0xf3, 0xfb, 0xb9, 0xb4, 0x49, 0x3a, 0xb8, 0xb2, 0xa0, 0xf9, 0x7e, 0xd4, 0x41, 0x03, 0xba, 0x80, + 0xfd, 0x8d, 0x79, 0x1f, 0xfa, 0x9f, 0x1e, 0xdb, 0xa9, 0xa6, 0xca, 0xe3, 0x57, 0x16, 0xb4, 0x14, + 0x69, 0x31, 0x46, 0x64, 0x42, 0x83, 0xb4, 0x30, 0xe5, 0xdf, 0x12, 0x1e, 0xbb, 0x71, 0xb7, 0x8e, + 0xc7, 0x5b, 0x5a, 0xf9, 0xd5, 0xfc, 0xd5, 0x63, 0x77, 0xdb, 0xe0, 0x71, 0x0a, 0x93, 0x62, 0x29, + 0x07, 0x1b, 0x38, 0xad, 0x59, 0xb7, 0x8e, 0x47, 0xdb, 0x98, 0xb4, 0xa7, 0xcb, 0xe2, 0xc8, 0x4c, + 0xe7, 0x74, 0x59, 0xaa, 0xeb, 0xa6, 0xcb, 0x1a, 0xc2, 0x39, 0xfb, 0xd3, 0x08, 0xb2, 0x34, 0x99, + 0x88, 0xa2, 0x4e, 0x8a, 0x6e, 0x43, 0xe6, 0x6c, 0x1b, 0x8a, 0xe5, 0xec, 0x2a, 0x8b, 0x9b, 0x34, + 0x56, 0x9b, 0x2a, 0x25, 0x9b, 0x34, 0x8d, 0xc6, 0x9a, 0x74, 0x97, 0x05, 0xde, 0xef, 0x08, 0x4c, + 0x31, 0x3d, 0x7a, 0x8e, 0xdc, 0x6f, 0x1b, 0x8a, 0xed, 0x77, 0x95, 0xc5, 0x35, 0x7a, 0x2a, 0x13, + 0x5b, 0x35, 0x3e, 0xb2, 0x46, 0x1b, 0x39, 0x56, 0xa3, 0x98, 0x0a, 0x52, 0x73, 0xa8, 0xb2, 0x3c, + 0x2d, 0x87, 0xc8, 0x2a, 0x77, 0xbf, 0x57, 0x79, 0x91, 0x44, 0x64, 0x6a, 0x76, 0xb0, 0xb1, 0xd4, + 0xec, 0x34, 0xc1, 0xa9, 0x59, 0x2c, 0xae, 0xbb, 0x9d, 0x7a, 0x35, 0x96, 0x9a, 0x08, 0xc2, 0x53, + 0xca, 0x53, 0x58, 0x28, 0x0b, 0xf5, 0xe9, 0x51, 0xef, 0x16, 0x06, 0x62, 0x53, 0x4a, 0xc8, 0xe1, + 0x6c, 0x38, 0x97, 0x53, 0x15, 0x84, 0xd9, 0x23, 0x87, 0x9c, 0x10, 0x8a, 0x65, 0xc3, 0x2a, 0xeb, + 0xc3, 0xfd, 0xdd, 0x63, 0x1f, 0x0e, 0xb5, 0x2a, 0xb4, 0x72, 0xb3, 0x17, 0x73, 0x90, 0x47, 0x22, + 0x9f, 0xcd, 0xed, 0x79, 0xc6, 0xc9, 0xe3, 0xef, 0x80, 0x5d, 0xfc, 0xc3, 0xad, 0x6c, 0x82, 0x87, + 0xaa, 0x94, 0x85, 0xa9, 0xe9, 0x29, 0xfd, 0x50, 0xb5, 0xa0, 0xe8, 0x43, 0xb5, 0xc2, 0x06, 0x2f, + 0x2e, 0xb8, 0x1a, 0xb8, 0x47, 0xff, 0x37, 0x17, 0x9e, 0xeb, 0xfd, 0x38, 0x84, 0x47, 0x2e, 0x17, + 0x77, 0x04, 0xa6, 0x78, 0x56, 0x60, 0xca, 0x63, 0xab, 0xf3, 0x54, 0x6c, 0xe4, 0x22, 0x60, 0x1f, + 0xf1, 0xdf, 0x1e, 0xfb, 0xa8, 0x78, 0x93, 0x51, 0xb9, 0x0f, 0xe4, 0xb4, 0xe8, 0xac, 0xd5, 0x0c, + 0xf6, 0xb8, 0xe3, 0x0d, 0xef, 0xe0, 0xdd, 0x32, 0xbe, 0xdb, 0xd6, 0x0c, 0x57, 0x09, 0xbe, 0x71, + 0xb2, 0x4a, 0x30, 0x10, 0xab, 0x92, 0x90, 0xf3, 0x21, 0x7e, 0x64, 0xb7, 0x9e, 0x88, 0xc9, 0x75, + 0x9e, 0x71, 0xea, 0x4b, 0x4b, 0x25, 0x39, 0xb7, 0x9f, 0x45, 0x08, 0xe7, 0xf0, 0x61, 0x8f, 0x6b, + 0x76, 0xbb, 0x38, 0x5d, 0xa5, 0xe1, 0x44, 0xab, 0x45, 0xed, 0xbd, 0xa3, 0xb7, 0x86, 0x54, 0xec, + 0xe2, 0x08, 0xb8, 0x89, 0xf9, 0xe4, 0xf0, 0x97, 0x83, 0x65, 0x62, 0xc1, 0x98, 0xfd, 0x44, 0xf5, + 0xab, 0xbf, 0xfa, 0x33, 0xd5, 0x5f, 0xda, 0x7e, 0xf9, 0x35, 0xab, 0x4f, 0x7d, 0xfb, 0xba, 0xbc, + 0x55, 0x6a, 0x87, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, 0xcf, 0xa2, 0x81, 0x89, 0x36, 0x13, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -138,6 +139,8 @@ type TabletManagerClient interface { SlaveStatus(ctx context.Context, in *tabletmanagerdata.SlaveStatusRequest, opts ...grpc.CallOption) (*tabletmanagerdata.SlaveStatusResponse, error) // MasterPosition returns the current master position MasterPosition(ctx context.Context, in *tabletmanagerdata.MasterPositionRequest, opts ...grpc.CallOption) (*tabletmanagerdata.MasterPositionResponse, error) + // WaitForPosition waits for the position to be reached + WaitForPosition(ctx context.Context, in *tabletmanagerdata.WaitForPositionRequest, opts ...grpc.CallOption) (*tabletmanagerdata.WaitForPositionResponse, error) // StopSlave makes mysql stop its replication StopSlave(ctx context.Context, in *tabletmanagerdata.StopSlaveRequest, opts ...grpc.CallOption) (*tabletmanagerdata.StopSlaveResponse, error) // StopSlaveMinimum stops the mysql replication after it reaches @@ -408,6 +411,15 @@ func (c *tabletManagerClient) MasterPosition(ctx context.Context, in *tabletmana return out, nil } +func (c *tabletManagerClient) WaitForPosition(ctx context.Context, in *tabletmanagerdata.WaitForPositionRequest, opts ...grpc.CallOption) (*tabletmanagerdata.WaitForPositionResponse, error) { + out := new(tabletmanagerdata.WaitForPositionResponse) + err := c.cc.Invoke(ctx, "/tabletmanagerservice.TabletManager/WaitForPosition", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *tabletManagerClient) StopSlave(ctx context.Context, in *tabletmanagerdata.StopSlaveRequest, opts ...grpc.CallOption) (*tabletmanagerdata.StopSlaveResponse, error) { out := new(tabletmanagerdata.StopSlaveResponse) err := c.cc.Invoke(ctx, "/tabletmanagerservice.TabletManager/StopSlave", in, out, opts...) @@ -692,6 +704,8 @@ type TabletManagerServer interface { SlaveStatus(context.Context, *tabletmanagerdata.SlaveStatusRequest) (*tabletmanagerdata.SlaveStatusResponse, error) // MasterPosition returns the current master position MasterPosition(context.Context, *tabletmanagerdata.MasterPositionRequest) (*tabletmanagerdata.MasterPositionResponse, error) + // WaitForPosition waits for the position to be reached + WaitForPosition(context.Context, *tabletmanagerdata.WaitForPositionRequest) (*tabletmanagerdata.WaitForPositionResponse, error) // StopSlave makes mysql stop its replication StopSlave(context.Context, *tabletmanagerdata.StopSlaveRequest) (*tabletmanagerdata.StopSlaveResponse, error) // StopSlaveMinimum stops the mysql replication after it reaches @@ -832,6 +846,9 @@ func (*UnimplementedTabletManagerServer) SlaveStatus(ctx context.Context, req *t func (*UnimplementedTabletManagerServer) MasterPosition(ctx context.Context, req *tabletmanagerdata.MasterPositionRequest) (*tabletmanagerdata.MasterPositionResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method MasterPosition not implemented") } +func (*UnimplementedTabletManagerServer) WaitForPosition(ctx context.Context, req *tabletmanagerdata.WaitForPositionRequest) (*tabletmanagerdata.WaitForPositionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method WaitForPosition not implemented") +} func (*UnimplementedTabletManagerServer) StopSlave(ctx context.Context, req *tabletmanagerdata.StopSlaveRequest) (*tabletmanagerdata.StopSlaveResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method StopSlave not implemented") } @@ -1284,6 +1301,24 @@ func _TabletManager_MasterPosition_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } +func _TabletManager_WaitForPosition_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(tabletmanagerdata.WaitForPositionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TabletManagerServer).WaitForPosition(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tabletmanagerservice.TabletManager/WaitForPosition", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TabletManagerServer).WaitForPosition(ctx, req.(*tabletmanagerdata.WaitForPositionRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _TabletManager_StopSlave_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(tabletmanagerdata.StopSlaveRequest) if err := dec(in); err != nil { @@ -1792,6 +1827,10 @@ var _TabletManager_serviceDesc = grpc.ServiceDesc{ MethodName: "MasterPosition", Handler: _TabletManager_MasterPosition_Handler, }, + { + MethodName: "WaitForPosition", + Handler: _TabletManager_WaitForPosition_Handler, + }, { MethodName: "StopSlave", Handler: _TabletManager_StopSlave_Handler, diff --git a/go/vt/vtcombo/tablet_map.go b/go/vt/vtcombo/tablet_map.go index ca93afa61ac..49d0454270d 100644 --- a/go/vt/vtcombo/tablet_map.go +++ b/go/vt/vtcombo/tablet_map.go @@ -636,6 +636,10 @@ func (itmc *internalTabletManagerClient) MasterPosition(ctx context.Context, tab return "", fmt.Errorf("not implemented in vtcombo") } +func (itmc *internalTabletManagerClient) WaitForPosition(ctx context.Context, tablet *topodatapb.Tablet, pos string) error { + return fmt.Errorf("not implemented in vtcombo") +} + func (itmc *internalTabletManagerClient) StopSlave(ctx context.Context, tablet *topodatapb.Tablet) error { return fmt.Errorf("not implemented in vtcombo") } diff --git a/go/vt/vttablet/agentrpctest/test_agent_rpc.go b/go/vt/vttablet/agentrpctest/test_agent_rpc.go index 6cc5350b9b9..de059c9ee5c 100644 --- a/go/vt/vttablet/agentrpctest/test_agent_rpc.go +++ b/go/vt/vttablet/agentrpctest/test_agent_rpc.go @@ -728,6 +728,10 @@ func (fra *fakeRPCAgent) MasterPosition(ctx context.Context) (string, error) { return testReplicationPosition, nil } +func (fra *fakeRPCAgent) WaitForPosition(ctx context.Context, pos string) error { + panic("unimplemented") +} + func agentRPCTestMasterPosition(ctx context.Context, t *testing.T, client tmclient.TabletManagerClient, tablet *topodatapb.Tablet) { rs, err := client.MasterPosition(ctx, tablet) compareError(t, "MasterPosition", err, rs, testReplicationPosition) diff --git a/go/vt/vttablet/faketmclient/fake_client.go b/go/vt/vttablet/faketmclient/fake_client.go index cab6a1b3a48..60658787f72 100644 --- a/go/vt/vttablet/faketmclient/fake_client.go +++ b/go/vt/vttablet/faketmclient/fake_client.go @@ -181,6 +181,11 @@ func (client *FakeTabletManagerClient) MasterPosition(ctx context.Context, table return "", nil } +// WaitForPosition is part of the tmclient.TabletManagerClient interface. +func (client *FakeTabletManagerClient) WaitForPosition(ctx context.Context, tablet *topodatapb.Tablet, pos string) error { + return nil +} + // StopSlave is part of the tmclient.TabletManagerClient interface. func (client *FakeTabletManagerClient) StopSlave(ctx context.Context, tablet *topodatapb.Tablet) error { return nil diff --git a/go/vt/vttablet/grpctmclient/client.go b/go/vt/vttablet/grpctmclient/client.go index 945ee954ea8..d79e8003da3 100644 --- a/go/vt/vttablet/grpctmclient/client.go +++ b/go/vt/vttablet/grpctmclient/client.go @@ -482,6 +482,17 @@ func (client *Client) MasterPosition(ctx context.Context, tablet *topodatapb.Tab return response.Position, nil } +// WaitForPosition is part of the tmclient.TabletManagerClient interface. +func (client *Client) WaitForPosition(ctx context.Context, tablet *topodatapb.Tablet, pos string) error { + cc, c, err := client.dial(tablet) + if err != nil { + return err + } + defer cc.Close() + _, err = c.WaitForPosition(ctx, &tabletmanagerdatapb.WaitForPositionRequest{Position: pos}) + return err +} + // StopSlave is part of the tmclient.TabletManagerClient interface. func (client *Client) StopSlave(ctx context.Context, tablet *topodatapb.Tablet) error { cc, c, err := client.dial(tablet) diff --git a/go/vt/vttablet/grpctmserver/server.go b/go/vt/vttablet/grpctmserver/server.go index e850b745364..8d2d6b0c297 100644 --- a/go/vt/vttablet/grpctmserver/server.go +++ b/go/vt/vttablet/grpctmserver/server.go @@ -256,6 +256,13 @@ func (s *server) MasterPosition(ctx context.Context, request *tabletmanagerdatap return response, err } +func (s *server) WaitForPosition(ctx context.Context, request *tabletmanagerdatapb.WaitForPositionRequest) (response *tabletmanagerdatapb.WaitForPositionResponse, err error) { + defer s.agent.HandleRPCPanic(ctx, "WaitForPosition", request, response, false /*verbose*/, &err) + ctx = callinfo.GRPCCallInfo(ctx) + response = &tabletmanagerdatapb.WaitForPositionResponse{} + return response, s.agent.WaitForPosition(ctx, request.Position) +} + func (s *server) StopSlave(ctx context.Context, request *tabletmanagerdatapb.StopSlaveRequest) (response *tabletmanagerdatapb.StopSlaveResponse, err error) { defer s.agent.HandleRPCPanic(ctx, "StopSlave", request, response, true /*verbose*/, &err) ctx = callinfo.GRPCCallInfo(ctx) diff --git a/go/vt/vttablet/tabletmanager/rpc_agent.go b/go/vt/vttablet/tabletmanager/rpc_agent.go index 2b5faf8a9b1..eedcbf96c17 100644 --- a/go/vt/vttablet/tabletmanager/rpc_agent.go +++ b/go/vt/vttablet/tabletmanager/rpc_agent.go @@ -82,6 +82,8 @@ type RPCAgent interface { MasterPosition(ctx context.Context) (string, error) + WaitForPosition(ctx context.Context, pos string) error + StopSlave(ctx context.Context) error StopSlaveMinimum(ctx context.Context, position string, waitTime time.Duration) (string, error) diff --git a/go/vt/vttablet/tabletmanager/rpc_replication.go b/go/vt/vttablet/tabletmanager/rpc_replication.go index 92c3cdc91e9..f0eea772f6f 100644 --- a/go/vt/vttablet/tabletmanager/rpc_replication.go +++ b/go/vt/vttablet/tabletmanager/rpc_replication.go @@ -60,6 +60,15 @@ func (agent *ActionAgent) MasterPosition(ctx context.Context) (string, error) { return mysql.EncodePosition(pos), nil } +// WaitForPosition returns the master position +func (agent *ActionAgent) WaitForPosition(ctx context.Context, pos string) error { + mpos, err := mysql.DecodePosition(pos) + if err != nil { + return err + } + return agent.MysqlDaemon.WaitMasterPos(ctx, mpos) +} + // StopSlave will stop the mysql. Works both when Vitess manages // replication or not (using hook if not). func (agent *ActionAgent) StopSlave(ctx context.Context) error { diff --git a/go/vt/vttablet/tmclient/rpc_client_api.go b/go/vt/vttablet/tmclient/rpc_client_api.go index 17cf1770a99..6e2ed4e4f20 100644 --- a/go/vt/vttablet/tmclient/rpc_client_api.go +++ b/go/vt/vttablet/tmclient/rpc_client_api.go @@ -116,6 +116,9 @@ type TabletManagerClient interface { // MasterPosition returns the tablet's master position MasterPosition(ctx context.Context, tablet *topodatapb.Tablet) (string, error) + // WaitForPosition waits for the position to be reached + WaitForPosition(ctx context.Context, tablet *topodatapb.Tablet, pos string) error + // StopSlave stops the mysql replication StopSlave(ctx context.Context, tablet *topodatapb.Tablet) error diff --git a/proto/tabletmanagerdata.proto b/proto/tabletmanagerdata.proto index 740f544ec14..9f05f103553 100644 --- a/proto/tabletmanagerdata.proto +++ b/proto/tabletmanagerdata.proto @@ -275,6 +275,13 @@ message MasterPositionResponse { string position = 1; } +message WaitForPositionRequest { + string position = 1; +} + +message WaitForPositionResponse { +} + message StopSlaveRequest { } diff --git a/proto/tabletmanagerservice.proto b/proto/tabletmanagerservice.proto index 24f20204d9e..f1351f63e35 100644 --- a/proto/tabletmanagerservice.proto +++ b/proto/tabletmanagerservice.proto @@ -88,6 +88,9 @@ service TabletManager { // MasterPosition returns the current master position rpc MasterPosition(tabletmanagerdata.MasterPositionRequest) returns (tabletmanagerdata.MasterPositionResponse) {}; + // WaitForPosition waits for the position to be reached + rpc WaitForPosition(tabletmanagerdata.WaitForPositionRequest) returns (tabletmanagerdata.WaitForPositionResponse) {}; + // StopSlave makes mysql stop its replication rpc StopSlave(tabletmanagerdata.StopSlaveRequest) returns (tabletmanagerdata.StopSlaveResponse) {}; diff --git a/py/vtproto/tabletmanagerdata_pb2.py b/py/vtproto/tabletmanagerdata_pb2.py index 4fcd650d929..ac459f35a93 100644 --- a/py/vtproto/tabletmanagerdata_pb2.py +++ b/py/vtproto/tabletmanagerdata_pb2.py @@ -23,7 +23,11 @@ package='tabletmanagerdata', syntax='proto3', serialized_options=_b('Z.vitess.io/vitess/go/vt/proto/tabletmanagerdata'), +<<<<<<< HEAD serialized_pb=_b('\n\x17tabletmanagerdata.proto\x12\x11tabletmanagerdata\x1a\x0bquery.proto\x1a\x0etopodata.proto\x1a\x15replicationdata.proto\x1a\rlogutil.proto\"\xb1\x01\n\x0fTableDefinition\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06schema\x18\x02 \x01(\t\x12\x0f\n\x07\x63olumns\x18\x03 \x03(\t\x12\x1b\n\x13primary_key_columns\x18\x04 \x03(\t\x12\x0c\n\x04type\x18\x05 \x01(\t\x12\x13\n\x0b\x64\x61ta_length\x18\x06 \x01(\x04\x12\x11\n\trow_count\x18\x07 \x01(\x04\x12\x1c\n\x06\x66ields\x18\x08 \x03(\x0b\x32\x0c.query.Field\"{\n\x10SchemaDefinition\x12\x17\n\x0f\x64\x61tabase_schema\x18\x01 \x01(\t\x12=\n\x11table_definitions\x18\x02 \x03(\x0b\x32\".tabletmanagerdata.TableDefinition\x12\x0f\n\x07version\x18\x03 \x01(\t\"\x8b\x01\n\x12SchemaChangeResult\x12:\n\rbefore_schema\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x02 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\xc1\x01\n\x0eUserPermission\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x0c\n\x04user\x18\x02 \x01(\t\x12\x19\n\x11password_checksum\x18\x03 \x01(\x04\x12\x45\n\nprivileges\x18\x04 \x03(\x0b\x32\x31.tabletmanagerdata.UserPermission.PrivilegesEntry\x1a\x31\n\x0fPrivilegesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xae\x01\n\x0c\x44\x62Permission\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\n\n\x02\x64\x62\x18\x02 \x01(\t\x12\x0c\n\x04user\x18\x03 \x01(\t\x12\x43\n\nprivileges\x18\x04 \x03(\x0b\x32/.tabletmanagerdata.DbPermission.PrivilegesEntry\x1a\x31\n\x0fPrivilegesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x83\x01\n\x0bPermissions\x12;\n\x10user_permissions\x18\x01 \x03(\x0b\x32!.tabletmanagerdata.UserPermission\x12\x37\n\x0e\x64\x62_permissions\x18\x02 \x03(\x0b\x32\x1f.tabletmanagerdata.DbPermission\"\x1e\n\x0bPingRequest\x12\x0f\n\x07payload\x18\x01 \x01(\t\"\x1f\n\x0cPingResponse\x12\x0f\n\x07payload\x18\x01 \x01(\t\" \n\x0cSleepRequest\x12\x10\n\x08\x64uration\x18\x01 \x01(\x03\"\x0f\n\rSleepResponse\"\xaf\x01\n\x12\x45xecuteHookRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\nparameters\x18\x02 \x03(\t\x12\x46\n\textra_env\x18\x03 \x03(\x0b\x32\x33.tabletmanagerdata.ExecuteHookRequest.ExtraEnvEntry\x1a/\n\rExtraEnvEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"J\n\x13\x45xecuteHookResponse\x12\x13\n\x0b\x65xit_status\x18\x01 \x01(\x03\x12\x0e\n\x06stdout\x18\x02 \x01(\t\x12\x0e\n\x06stderr\x18\x03 \x01(\t\"Q\n\x10GetSchemaRequest\x12\x0e\n\x06tables\x18\x01 \x03(\t\x12\x15\n\rinclude_views\x18\x02 \x01(\x08\x12\x16\n\x0e\x65xclude_tables\x18\x03 \x03(\t\"S\n\x11GetSchemaResponse\x12>\n\x11schema_definition\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x17\n\x15GetPermissionsRequest\"M\n\x16GetPermissionsResponse\x12\x33\n\x0bpermissions\x18\x01 \x01(\x0b\x32\x1e.tabletmanagerdata.Permissions\"\x14\n\x12SetReadOnlyRequest\"\x15\n\x13SetReadOnlyResponse\"\x15\n\x13SetReadWriteRequest\"\x16\n\x14SetReadWriteResponse\">\n\x11\x43hangeTypeRequest\x12)\n\x0btablet_type\x18\x01 \x01(\x0e\x32\x14.topodata.TabletType\"\x14\n\x12\x43hangeTypeResponse\"\x15\n\x13RefreshStateRequest\"\x16\n\x14RefreshStateResponse\"\x17\n\x15RunHealthCheckRequest\"\x18\n\x16RunHealthCheckResponse\"+\n\x18IgnoreHealthErrorRequest\x12\x0f\n\x07pattern\x18\x01 \x01(\t\"\x1b\n\x19IgnoreHealthErrorResponse\",\n\x13ReloadSchemaRequest\x12\x15\n\rwait_position\x18\x01 \x01(\t\"\x16\n\x14ReloadSchemaResponse\")\n\x16PreflightSchemaRequest\x12\x0f\n\x07\x63hanges\x18\x01 \x03(\t\"X\n\x17PreflightSchemaResponse\x12=\n\x0e\x63hange_results\x18\x01 \x03(\x0b\x32%.tabletmanagerdata.SchemaChangeResult\"\xc2\x01\n\x12\x41pplySchemaRequest\x12\x0b\n\x03sql\x18\x01 \x01(\t\x12\r\n\x05\x66orce\x18\x02 \x01(\x08\x12\x19\n\x11\x61llow_replication\x18\x03 \x01(\x08\x12:\n\rbefore_schema\x18\x04 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x05 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x8c\x01\n\x13\x41pplySchemaResponse\x12:\n\rbefore_schema\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x02 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x13\n\x11LockTablesRequest\"\x14\n\x12LockTablesResponse\"\x15\n\x13UnlockTablesRequest\"\x16\n\x14UnlockTablesResponse\"|\n\x18\x45xecuteFetchAsDbaRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x0f\n\x07\x64\x62_name\x18\x02 \x01(\t\x12\x10\n\x08max_rows\x18\x03 \x01(\x04\x12\x17\n\x0f\x64isable_binlogs\x18\x04 \x01(\x08\x12\x15\n\rreload_schema\x18\x05 \x01(\x08\"?\n\x19\x45xecuteFetchAsDbaResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"h\n\x1d\x45xecuteFetchAsAllPrivsRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x0f\n\x07\x64\x62_name\x18\x02 \x01(\t\x12\x10\n\x08max_rows\x18\x03 \x01(\x04\x12\x15\n\rreload_schema\x18\x04 \x01(\x08\"D\n\x1e\x45xecuteFetchAsAllPrivsResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\";\n\x18\x45xecuteFetchAsAppRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x10\n\x08max_rows\x18\x02 \x01(\x04\"?\n\x19\x45xecuteFetchAsAppResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"\x14\n\x12SlaveStatusRequest\">\n\x13SlaveStatusResponse\x12\'\n\x06status\x18\x01 \x01(\x0b\x32\x17.replicationdata.Status\"\x17\n\x15MasterPositionRequest\"*\n\x16MasterPositionResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x12\n\x10StopSlaveRequest\"\x13\n\x11StopSlaveResponse\"A\n\x17StopSlaveMinimumRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x14\n\x0cwait_timeout\x18\x02 \x01(\x03\",\n\x18StopSlaveMinimumResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x13\n\x11StartSlaveRequest\"\x14\n\x12StartSlaveResponse\"E\n\x1bStartSlaveUntilAfterRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x14\n\x0cwait_timeout\x18\x02 \x01(\x03\"\x1e\n\x1cStartSlaveUntilAfterResponse\"8\n!TabletExternallyReparentedRequest\x12\x13\n\x0b\x65xternal_id\x18\x01 \x01(\t\"$\n\"TabletExternallyReparentedResponse\" \n\x1eTabletExternallyElectedRequest\"!\n\x1fTabletExternallyElectedResponse\"\x12\n\x10GetSlavesRequest\"\"\n\x11GetSlavesResponse\x12\r\n\x05\x61\x64\x64rs\x18\x01 \x03(\t\"\x19\n\x17ResetReplicationRequest\"\x1a\n\x18ResetReplicationResponse\"(\n\x17VReplicationExecRequest\x12\r\n\x05query\x18\x01 \x01(\t\">\n\x18VReplicationExecResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"=\n\x1dVReplicationWaitForPosRequest\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08position\x18\x02 \x01(\t\" \n\x1eVReplicationWaitForPosResponse\"\x13\n\x11InitMasterRequest\"&\n\x12InitMasterResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x99\x01\n\x1ePopulateReparentJournalRequest\x12\x17\n\x0ftime_created_ns\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63tion_name\x18\x02 \x01(\t\x12+\n\x0cmaster_alias\x18\x03 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x1c\n\x14replication_position\x18\x04 \x01(\t\"!\n\x1fPopulateReparentJournalResponse\"p\n\x10InitSlaveRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x1c\n\x14replication_position\x18\x02 \x01(\t\x12\x17\n\x0ftime_created_ns\x18\x03 \x01(\x03\"\x13\n\x11InitSlaveResponse\"\x15\n\x13\x44\x65moteMasterRequest\"(\n\x14\x44\x65moteMasterResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17UndoDemoteMasterRequest\"\x1a\n\x18UndoDemoteMasterResponse\"3\n\x1fPromoteSlaveWhenCaughtUpRequest\x12\x10\n\x08position\x18\x01 \x01(\t\"4\n PromoteSlaveWhenCaughtUpResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17SlaveWasPromotedRequest\"\x1a\n\x18SlaveWasPromotedResponse\"\x84\x01\n\x10SetMasterRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x17\n\x0ftime_created_ns\x18\x02 \x01(\x03\x12\x15\n\rwait_position\x18\x04 \x01(\t\x12\x19\n\x11\x66orce_start_slave\x18\x03 \x01(\x08\"\x13\n\x11SetMasterResponse\"A\n\x18SlaveWasRestartedRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\"\x1b\n\x19SlaveWasRestartedResponse\"$\n\"StopReplicationAndGetStatusRequest\"N\n#StopReplicationAndGetStatusResponse\x12\'\n\x06status\x18\x01 \x01(\x0b\x32\x17.replicationdata.Status\"\x15\n\x13PromoteSlaveRequest\"(\n\x14PromoteSlaveResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"9\n\rBackupRequest\x12\x13\n\x0b\x63oncurrency\x18\x01 \x01(\x03\x12\x13\n\x0b\x61llowMaster\x18\x02 \x01(\x08\"/\n\x0e\x42\x61\x63kupResponse\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.logutil.Event\"\x1a\n\x18RestoreFromBackupRequest\":\n\x19RestoreFromBackupResponse\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.logutil.EventB0Z.vitess.io/vitess/go/vt/proto/tabletmanagerdatab\x06proto3') +======= + serialized_pb=_b('\n\x17tabletmanagerdata.proto\x12\x11tabletmanagerdata\x1a\x0bquery.proto\x1a\x0etopodata.proto\x1a\x15replicationdata.proto\x1a\rlogutil.proto\"\xb1\x01\n\x0fTableDefinition\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06schema\x18\x02 \x01(\t\x12\x0f\n\x07\x63olumns\x18\x03 \x03(\t\x12\x1b\n\x13primary_key_columns\x18\x04 \x03(\t\x12\x0c\n\x04type\x18\x05 \x01(\t\x12\x13\n\x0b\x64\x61ta_length\x18\x06 \x01(\x04\x12\x11\n\trow_count\x18\x07 \x01(\x04\x12\x1c\n\x06\x66ields\x18\x08 \x03(\x0b\x32\x0c.query.Field\"{\n\x10SchemaDefinition\x12\x17\n\x0f\x64\x61tabase_schema\x18\x01 \x01(\t\x12=\n\x11table_definitions\x18\x02 \x03(\x0b\x32\".tabletmanagerdata.TableDefinition\x12\x0f\n\x07version\x18\x03 \x01(\t\"\x8b\x01\n\x12SchemaChangeResult\x12:\n\rbefore_schema\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x02 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\xc1\x01\n\x0eUserPermission\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x0c\n\x04user\x18\x02 \x01(\t\x12\x19\n\x11password_checksum\x18\x03 \x01(\x04\x12\x45\n\nprivileges\x18\x04 \x03(\x0b\x32\x31.tabletmanagerdata.UserPermission.PrivilegesEntry\x1a\x31\n\x0fPrivilegesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xae\x01\n\x0c\x44\x62Permission\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\n\n\x02\x64\x62\x18\x02 \x01(\t\x12\x0c\n\x04user\x18\x03 \x01(\t\x12\x43\n\nprivileges\x18\x04 \x03(\x0b\x32/.tabletmanagerdata.DbPermission.PrivilegesEntry\x1a\x31\n\x0fPrivilegesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x83\x01\n\x0bPermissions\x12;\n\x10user_permissions\x18\x01 \x03(\x0b\x32!.tabletmanagerdata.UserPermission\x12\x37\n\x0e\x64\x62_permissions\x18\x02 \x03(\x0b\x32\x1f.tabletmanagerdata.DbPermission\"\x1e\n\x0bPingRequest\x12\x0f\n\x07payload\x18\x01 \x01(\t\"\x1f\n\x0cPingResponse\x12\x0f\n\x07payload\x18\x01 \x01(\t\" \n\x0cSleepRequest\x12\x10\n\x08\x64uration\x18\x01 \x01(\x03\"\x0f\n\rSleepResponse\"\xaf\x01\n\x12\x45xecuteHookRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\nparameters\x18\x02 \x03(\t\x12\x46\n\textra_env\x18\x03 \x03(\x0b\x32\x33.tabletmanagerdata.ExecuteHookRequest.ExtraEnvEntry\x1a/\n\rExtraEnvEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"J\n\x13\x45xecuteHookResponse\x12\x13\n\x0b\x65xit_status\x18\x01 \x01(\x03\x12\x0e\n\x06stdout\x18\x02 \x01(\t\x12\x0e\n\x06stderr\x18\x03 \x01(\t\"Q\n\x10GetSchemaRequest\x12\x0e\n\x06tables\x18\x01 \x03(\t\x12\x15\n\rinclude_views\x18\x02 \x01(\x08\x12\x16\n\x0e\x65xclude_tables\x18\x03 \x03(\t\"S\n\x11GetSchemaResponse\x12>\n\x11schema_definition\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x17\n\x15GetPermissionsRequest\"M\n\x16GetPermissionsResponse\x12\x33\n\x0bpermissions\x18\x01 \x01(\x0b\x32\x1e.tabletmanagerdata.Permissions\"\x14\n\x12SetReadOnlyRequest\"\x15\n\x13SetReadOnlyResponse\"\x15\n\x13SetReadWriteRequest\"\x16\n\x14SetReadWriteResponse\">\n\x11\x43hangeTypeRequest\x12)\n\x0btablet_type\x18\x01 \x01(\x0e\x32\x14.topodata.TabletType\"\x14\n\x12\x43hangeTypeResponse\"\x15\n\x13RefreshStateRequest\"\x16\n\x14RefreshStateResponse\"\x17\n\x15RunHealthCheckRequest\"\x18\n\x16RunHealthCheckResponse\"+\n\x18IgnoreHealthErrorRequest\x12\x0f\n\x07pattern\x18\x01 \x01(\t\"\x1b\n\x19IgnoreHealthErrorResponse\",\n\x13ReloadSchemaRequest\x12\x15\n\rwait_position\x18\x01 \x01(\t\"\x16\n\x14ReloadSchemaResponse\")\n\x16PreflightSchemaRequest\x12\x0f\n\x07\x63hanges\x18\x01 \x03(\t\"X\n\x17PreflightSchemaResponse\x12=\n\x0e\x63hange_results\x18\x01 \x03(\x0b\x32%.tabletmanagerdata.SchemaChangeResult\"\xc2\x01\n\x12\x41pplySchemaRequest\x12\x0b\n\x03sql\x18\x01 \x01(\t\x12\r\n\x05\x66orce\x18\x02 \x01(\x08\x12\x19\n\x11\x61llow_replication\x18\x03 \x01(\x08\x12:\n\rbefore_schema\x18\x04 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x05 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x8c\x01\n\x13\x41pplySchemaResponse\x12:\n\rbefore_schema\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x02 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x13\n\x11LockTablesRequest\"\x14\n\x12LockTablesResponse\"\x15\n\x13UnlockTablesRequest\"\x16\n\x14UnlockTablesResponse\"|\n\x18\x45xecuteFetchAsDbaRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x0f\n\x07\x64\x62_name\x18\x02 \x01(\t\x12\x10\n\x08max_rows\x18\x03 \x01(\x04\x12\x17\n\x0f\x64isable_binlogs\x18\x04 \x01(\x08\x12\x15\n\rreload_schema\x18\x05 \x01(\x08\"?\n\x19\x45xecuteFetchAsDbaResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"h\n\x1d\x45xecuteFetchAsAllPrivsRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x0f\n\x07\x64\x62_name\x18\x02 \x01(\t\x12\x10\n\x08max_rows\x18\x03 \x01(\x04\x12\x15\n\rreload_schema\x18\x04 \x01(\x08\"D\n\x1e\x45xecuteFetchAsAllPrivsResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\";\n\x18\x45xecuteFetchAsAppRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x10\n\x08max_rows\x18\x02 \x01(\x04\"?\n\x19\x45xecuteFetchAsAppResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"\x14\n\x12SlaveStatusRequest\">\n\x13SlaveStatusResponse\x12\'\n\x06status\x18\x01 \x01(\x0b\x32\x17.replicationdata.Status\"\x17\n\x15MasterPositionRequest\"*\n\x16MasterPositionResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"*\n\x16WaitForPositionRequest\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17WaitForPositionResponse\"\x12\n\x10StopSlaveRequest\"\x13\n\x11StopSlaveResponse\"A\n\x17StopSlaveMinimumRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x14\n\x0cwait_timeout\x18\x02 \x01(\x03\",\n\x18StopSlaveMinimumResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x13\n\x11StartSlaveRequest\"\x14\n\x12StartSlaveResponse\"E\n\x1bStartSlaveUntilAfterRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x14\n\x0cwait_timeout\x18\x02 \x01(\x03\"\x1e\n\x1cStartSlaveUntilAfterResponse\"8\n!TabletExternallyReparentedRequest\x12\x13\n\x0b\x65xternal_id\x18\x01 \x01(\t\"$\n\"TabletExternallyReparentedResponse\" \n\x1eTabletExternallyElectedRequest\"!\n\x1fTabletExternallyElectedResponse\"\x12\n\x10GetSlavesRequest\"\"\n\x11GetSlavesResponse\x12\r\n\x05\x61\x64\x64rs\x18\x01 \x03(\t\"\x19\n\x17ResetReplicationRequest\"\x1a\n\x18ResetReplicationResponse\"(\n\x17VReplicationExecRequest\x12\r\n\x05query\x18\x01 \x01(\t\">\n\x18VReplicationExecResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"=\n\x1dVReplicationWaitForPosRequest\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08position\x18\x02 \x01(\t\" \n\x1eVReplicationWaitForPosResponse\"\x13\n\x11InitMasterRequest\"&\n\x12InitMasterResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x99\x01\n\x1ePopulateReparentJournalRequest\x12\x17\n\x0ftime_created_ns\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63tion_name\x18\x02 \x01(\t\x12+\n\x0cmaster_alias\x18\x03 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x1c\n\x14replication_position\x18\x04 \x01(\t\"!\n\x1fPopulateReparentJournalResponse\"p\n\x10InitSlaveRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x1c\n\x14replication_position\x18\x02 \x01(\t\x12\x17\n\x0ftime_created_ns\x18\x03 \x01(\x03\"\x13\n\x11InitSlaveResponse\"\x15\n\x13\x44\x65moteMasterRequest\"(\n\x14\x44\x65moteMasterResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17UndoDemoteMasterRequest\"\x1a\n\x18UndoDemoteMasterResponse\"3\n\x1fPromoteSlaveWhenCaughtUpRequest\x12\x10\n\x08position\x18\x01 \x01(\t\"4\n PromoteSlaveWhenCaughtUpResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17SlaveWasPromotedRequest\"\x1a\n\x18SlaveWasPromotedResponse\"m\n\x10SetMasterRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x17\n\x0ftime_created_ns\x18\x02 \x01(\x03\x12\x19\n\x11\x66orce_start_slave\x18\x03 \x01(\x08\"\x13\n\x11SetMasterResponse\"A\n\x18SlaveWasRestartedRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\"\x1b\n\x19SlaveWasRestartedResponse\"$\n\"StopReplicationAndGetStatusRequest\"N\n#StopReplicationAndGetStatusResponse\x12\'\n\x06status\x18\x01 \x01(\x0b\x32\x17.replicationdata.Status\"\x15\n\x13PromoteSlaveRequest\"(\n\x14PromoteSlaveResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"9\n\rBackupRequest\x12\x13\n\x0b\x63oncurrency\x18\x01 \x01(\x03\x12\x13\n\x0b\x61llowMaster\x18\x02 \x01(\x08\"/\n\x0e\x42\x61\x63kupResponse\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.logutil.Event\"\x1a\n\x18RestoreFromBackupRequest\":\n\x19RestoreFromBackupResponse\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.logutil.EventB0Z.vitess.io/vitess/go/vt/proto/tabletmanagerdatab\x06proto3') +>>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition , dependencies=[query__pb2.DESCRIPTOR,topodata__pb2.DESCRIPTOR,replicationdata__pb2.DESCRIPTOR,logutil__pb2.DESCRIPTOR,]) @@ -1748,6 +1752,61 @@ ) +_WAITFORPOSITIONREQUEST = _descriptor.Descriptor( + name='WaitForPositionRequest', + full_name='tabletmanagerdata.WaitForPositionRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='position', full_name='tabletmanagerdata.WaitForPositionRequest.position', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=3340, + serialized_end=3382, +) + + +_WAITFORPOSITIONRESPONSE = _descriptor.Descriptor( + name='WaitForPositionResponse', + full_name='tabletmanagerdata.WaitForPositionResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=3384, + serialized_end=3409, +) + + _STOPSLAVEREQUEST = _descriptor.Descriptor( name='StopSlaveRequest', full_name='tabletmanagerdata.StopSlaveRequest', @@ -1767,8 +1826,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3340, - serialized_end=3358, + serialized_start=3411, + serialized_end=3429, ) @@ -1791,8 +1850,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3360, - serialized_end=3379, + serialized_start=3431, + serialized_end=3450, ) @@ -1829,8 +1888,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3381, - serialized_end=3446, + serialized_start=3452, + serialized_end=3517, ) @@ -1860,8 +1919,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3448, - serialized_end=3492, + serialized_start=3519, + serialized_end=3563, ) @@ -1884,8 +1943,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3494, - serialized_end=3513, + serialized_start=3565, + serialized_end=3584, ) @@ -1908,8 +1967,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3515, - serialized_end=3535, + serialized_start=3586, + serialized_end=3606, ) @@ -1946,8 +2005,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3537, - serialized_end=3606, + serialized_start=3608, + serialized_end=3677, ) @@ -1970,8 +2029,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3608, - serialized_end=3638, + serialized_start=3679, + serialized_end=3709, ) @@ -2001,8 +2060,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3640, - serialized_end=3696, + serialized_start=3711, + serialized_end=3767, ) @@ -2025,8 +2084,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3698, - serialized_end=3734, + serialized_start=3769, + serialized_end=3805, ) @@ -2049,8 +2108,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3736, - serialized_end=3768, + serialized_start=3807, + serialized_end=3839, ) @@ -2073,8 +2132,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3770, - serialized_end=3803, + serialized_start=3841, + serialized_end=3874, ) @@ -2097,8 +2156,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3805, - serialized_end=3823, + serialized_start=3876, + serialized_end=3894, ) @@ -2128,8 +2187,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3825, - serialized_end=3859, + serialized_start=3896, + serialized_end=3930, ) @@ -2152,8 +2211,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3861, - serialized_end=3886, + serialized_start=3932, + serialized_end=3957, ) @@ -2176,8 +2235,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3888, - serialized_end=3914, + serialized_start=3959, + serialized_end=3985, ) @@ -2207,8 +2266,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3916, - serialized_end=3956, + serialized_start=3987, + serialized_end=4027, ) @@ -2238,8 +2297,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3958, - serialized_end=4020, + serialized_start=4029, + serialized_end=4091, ) @@ -2276,8 +2335,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4022, - serialized_end=4083, + serialized_start=4093, + serialized_end=4154, ) @@ -2300,8 +2359,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4085, - serialized_end=4117, + serialized_start=4156, + serialized_end=4188, ) @@ -2324,8 +2383,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4119, - serialized_end=4138, + serialized_start=4190, + serialized_end=4209, ) @@ -2355,8 +2414,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4140, - serialized_end=4178, + serialized_start=4211, + serialized_end=4249, ) @@ -2407,8 +2466,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4181, - serialized_end=4334, + serialized_start=4252, + serialized_end=4405, ) @@ -2431,8 +2490,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4336, - serialized_end=4369, + serialized_start=4407, + serialized_end=4440, ) @@ -2476,8 +2535,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4371, - serialized_end=4483, + serialized_start=4442, + serialized_end=4554, ) @@ -2500,8 +2559,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4485, - serialized_end=4504, + serialized_start=4556, + serialized_end=4575, ) @@ -2524,8 +2583,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4506, - serialized_end=4527, + serialized_start=4577, + serialized_end=4598, ) @@ -2555,8 +2614,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4529, - serialized_end=4569, + serialized_start=4600, + serialized_end=4640, ) @@ -2579,8 +2638,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4571, - serialized_end=4596, + serialized_start=4642, + serialized_end=4667, ) @@ -2603,8 +2662,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4598, - serialized_end=4624, + serialized_start=4669, + serialized_end=4695, ) @@ -2634,8 +2693,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4626, - serialized_end=4677, + serialized_start=4697, + serialized_end=4748, ) @@ -2665,8 +2724,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4679, - serialized_end=4731, + serialized_start=4750, + serialized_end=4802, ) @@ -2689,8 +2748,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4733, - serialized_end=4758, + serialized_start=4804, + serialized_end=4829, ) @@ -2713,8 +2772,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4760, - serialized_end=4786, + serialized_start=4831, + serialized_end=4857, ) @@ -2765,8 +2824,13 @@ extension_ranges=[], oneofs=[ ], +<<<<<<< HEAD serialized_start=4789, serialized_end=4921, +======= + serialized_start=4859, + serialized_end=4968, +>>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition ) @@ -2789,8 +2853,13 @@ extension_ranges=[], oneofs=[ ], +<<<<<<< HEAD serialized_start=4923, serialized_end=4942, +======= + serialized_start=4970, + serialized_end=4989, +>>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition ) @@ -2820,8 +2889,13 @@ extension_ranges=[], oneofs=[ ], +<<<<<<< HEAD serialized_start=4944, serialized_end=5009, +======= + serialized_start=4991, + serialized_end=5056, +>>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition ) @@ -2844,8 +2918,13 @@ extension_ranges=[], oneofs=[ ], +<<<<<<< HEAD serialized_start=5011, serialized_end=5038, +======= + serialized_start=5058, + serialized_end=5085, +>>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition ) @@ -2868,8 +2947,13 @@ extension_ranges=[], oneofs=[ ], +<<<<<<< HEAD serialized_start=5040, serialized_end=5076, +======= + serialized_start=5087, + serialized_end=5123, +>>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition ) @@ -2899,8 +2983,13 @@ extension_ranges=[], oneofs=[ ], +<<<<<<< HEAD serialized_start=5078, serialized_end=5156, +======= + serialized_start=5125, + serialized_end=5203, +>>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition ) @@ -2923,8 +3012,13 @@ extension_ranges=[], oneofs=[ ], +<<<<<<< HEAD serialized_start=5158, serialized_end=5179, +======= + serialized_start=5205, + serialized_end=5226, +>>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition ) @@ -2954,8 +3048,13 @@ extension_ranges=[], oneofs=[ ], +<<<<<<< HEAD serialized_start=5181, serialized_end=5221, +======= + serialized_start=5228, + serialized_end=5268, +>>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition ) @@ -2992,8 +3091,13 @@ extension_ranges=[], oneofs=[ ], +<<<<<<< HEAD serialized_start=5223, serialized_end=5280, +======= + serialized_start=5270, + serialized_end=5327, +>>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition ) @@ -3023,8 +3127,13 @@ extension_ranges=[], oneofs=[ ], +<<<<<<< HEAD serialized_start=5282, serialized_end=5329, +======= + serialized_start=5329, + serialized_end=5376, +>>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition ) @@ -3047,8 +3156,13 @@ extension_ranges=[], oneofs=[ ], +<<<<<<< HEAD serialized_start=5331, serialized_end=5357, +======= + serialized_start=5378, + serialized_end=5404, +>>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition ) @@ -3078,8 +3192,13 @@ extension_ranges=[], oneofs=[ ], +<<<<<<< HEAD serialized_start=5359, serialized_end=5417, +======= + serialized_start=5406, + serialized_end=5464, +>>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition ) _TABLEDEFINITION.fields_by_name['fields'].message_type = query__pb2._FIELD @@ -3162,6 +3281,8 @@ DESCRIPTOR.message_types_by_name['SlaveStatusResponse'] = _SLAVESTATUSRESPONSE DESCRIPTOR.message_types_by_name['MasterPositionRequest'] = _MASTERPOSITIONREQUEST DESCRIPTOR.message_types_by_name['MasterPositionResponse'] = _MASTERPOSITIONRESPONSE +DESCRIPTOR.message_types_by_name['WaitForPositionRequest'] = _WAITFORPOSITIONREQUEST +DESCRIPTOR.message_types_by_name['WaitForPositionResponse'] = _WAITFORPOSITIONRESPONSE DESCRIPTOR.message_types_by_name['StopSlaveRequest'] = _STOPSLAVEREQUEST DESCRIPTOR.message_types_by_name['StopSlaveResponse'] = _STOPSLAVERESPONSE DESCRIPTOR.message_types_by_name['StopSlaveMinimumRequest'] = _STOPSLAVEMINIMUMREQUEST @@ -3570,6 +3691,20 @@ )) _sym_db.RegisterMessage(MasterPositionResponse) +WaitForPositionRequest = _reflection.GeneratedProtocolMessageType('WaitForPositionRequest', (_message.Message,), dict( + DESCRIPTOR = _WAITFORPOSITIONREQUEST, + __module__ = 'tabletmanagerdata_pb2' + # @@protoc_insertion_point(class_scope:tabletmanagerdata.WaitForPositionRequest) + )) +_sym_db.RegisterMessage(WaitForPositionRequest) + +WaitForPositionResponse = _reflection.GeneratedProtocolMessageType('WaitForPositionResponse', (_message.Message,), dict( + DESCRIPTOR = _WAITFORPOSITIONRESPONSE, + __module__ = 'tabletmanagerdata_pb2' + # @@protoc_insertion_point(class_scope:tabletmanagerdata.WaitForPositionResponse) + )) +_sym_db.RegisterMessage(WaitForPositionResponse) + StopSlaveRequest = _reflection.GeneratedProtocolMessageType('StopSlaveRequest', (_message.Message,), dict( DESCRIPTOR = _STOPSLAVEREQUEST, __module__ = 'tabletmanagerdata_pb2' diff --git a/py/vtproto/tabletmanagerservice_pb2.py b/py/vtproto/tabletmanagerservice_pb2.py index d9f607b5ada..56729dea692 100644 --- a/py/vtproto/tabletmanagerservice_pb2.py +++ b/py/vtproto/tabletmanagerservice_pb2.py @@ -20,7 +20,7 @@ package='tabletmanagerservice', syntax='proto3', serialized_options=_b('Z1vitess.io/vitess/go/vt/proto/tabletmanagerservice'), - serialized_pb=_b('\n\x1atabletmanagerservice.proto\x12\x14tabletmanagerservice\x1a\x17tabletmanagerdata.proto2\xbf$\n\rTabletManager\x12I\n\x04Ping\x12\x1e.tabletmanagerdata.PingRequest\x1a\x1f.tabletmanagerdata.PingResponse\"\x00\x12L\n\x05Sleep\x12\x1f.tabletmanagerdata.SleepRequest\x1a .tabletmanagerdata.SleepResponse\"\x00\x12^\n\x0b\x45xecuteHook\x12%.tabletmanagerdata.ExecuteHookRequest\x1a&.tabletmanagerdata.ExecuteHookResponse\"\x00\x12X\n\tGetSchema\x12#.tabletmanagerdata.GetSchemaRequest\x1a$.tabletmanagerdata.GetSchemaResponse\"\x00\x12g\n\x0eGetPermissions\x12(.tabletmanagerdata.GetPermissionsRequest\x1a).tabletmanagerdata.GetPermissionsResponse\"\x00\x12^\n\x0bSetReadOnly\x12%.tabletmanagerdata.SetReadOnlyRequest\x1a&.tabletmanagerdata.SetReadOnlyResponse\"\x00\x12\x61\n\x0cSetReadWrite\x12&.tabletmanagerdata.SetReadWriteRequest\x1a\'.tabletmanagerdata.SetReadWriteResponse\"\x00\x12[\n\nChangeType\x12$.tabletmanagerdata.ChangeTypeRequest\x1a%.tabletmanagerdata.ChangeTypeResponse\"\x00\x12\x61\n\x0cRefreshState\x12&.tabletmanagerdata.RefreshStateRequest\x1a\'.tabletmanagerdata.RefreshStateResponse\"\x00\x12g\n\x0eRunHealthCheck\x12(.tabletmanagerdata.RunHealthCheckRequest\x1a).tabletmanagerdata.RunHealthCheckResponse\"\x00\x12p\n\x11IgnoreHealthError\x12+.tabletmanagerdata.IgnoreHealthErrorRequest\x1a,.tabletmanagerdata.IgnoreHealthErrorResponse\"\x00\x12\x61\n\x0cReloadSchema\x12&.tabletmanagerdata.ReloadSchemaRequest\x1a\'.tabletmanagerdata.ReloadSchemaResponse\"\x00\x12j\n\x0fPreflightSchema\x12).tabletmanagerdata.PreflightSchemaRequest\x1a*.tabletmanagerdata.PreflightSchemaResponse\"\x00\x12^\n\x0b\x41pplySchema\x12%.tabletmanagerdata.ApplySchemaRequest\x1a&.tabletmanagerdata.ApplySchemaResponse\"\x00\x12[\n\nLockTables\x12$.tabletmanagerdata.LockTablesRequest\x1a%.tabletmanagerdata.LockTablesResponse\"\x00\x12\x61\n\x0cUnlockTables\x12&.tabletmanagerdata.UnlockTablesRequest\x1a\'.tabletmanagerdata.UnlockTablesResponse\"\x00\x12p\n\x11\x45xecuteFetchAsDba\x12+.tabletmanagerdata.ExecuteFetchAsDbaRequest\x1a,.tabletmanagerdata.ExecuteFetchAsDbaResponse\"\x00\x12\x7f\n\x16\x45xecuteFetchAsAllPrivs\x12\x30.tabletmanagerdata.ExecuteFetchAsAllPrivsRequest\x1a\x31.tabletmanagerdata.ExecuteFetchAsAllPrivsResponse\"\x00\x12p\n\x11\x45xecuteFetchAsApp\x12+.tabletmanagerdata.ExecuteFetchAsAppRequest\x1a,.tabletmanagerdata.ExecuteFetchAsAppResponse\"\x00\x12^\n\x0bSlaveStatus\x12%.tabletmanagerdata.SlaveStatusRequest\x1a&.tabletmanagerdata.SlaveStatusResponse\"\x00\x12g\n\x0eMasterPosition\x12(.tabletmanagerdata.MasterPositionRequest\x1a).tabletmanagerdata.MasterPositionResponse\"\x00\x12X\n\tStopSlave\x12#.tabletmanagerdata.StopSlaveRequest\x1a$.tabletmanagerdata.StopSlaveResponse\"\x00\x12m\n\x10StopSlaveMinimum\x12*.tabletmanagerdata.StopSlaveMinimumRequest\x1a+.tabletmanagerdata.StopSlaveMinimumResponse\"\x00\x12[\n\nStartSlave\x12$.tabletmanagerdata.StartSlaveRequest\x1a%.tabletmanagerdata.StartSlaveResponse\"\x00\x12y\n\x14StartSlaveUntilAfter\x12..tabletmanagerdata.StartSlaveUntilAfterRequest\x1a/.tabletmanagerdata.StartSlaveUntilAfterResponse\"\x00\x12\x8b\x01\n\x1aTabletExternallyReparented\x12\x34.tabletmanagerdata.TabletExternallyReparentedRequest\x1a\x35.tabletmanagerdata.TabletExternallyReparentedResponse\"\x00\x12\x82\x01\n\x17TabletExternallyElected\x12\x31.tabletmanagerdata.TabletExternallyElectedRequest\x1a\x32.tabletmanagerdata.TabletExternallyElectedResponse\"\x00\x12X\n\tGetSlaves\x12#.tabletmanagerdata.GetSlavesRequest\x1a$.tabletmanagerdata.GetSlavesResponse\"\x00\x12m\n\x10VReplicationExec\x12*.tabletmanagerdata.VReplicationExecRequest\x1a+.tabletmanagerdata.VReplicationExecResponse\"\x00\x12\x7f\n\x16VReplicationWaitForPos\x12\x30.tabletmanagerdata.VReplicationWaitForPosRequest\x1a\x31.tabletmanagerdata.VReplicationWaitForPosResponse\"\x00\x12m\n\x10ResetReplication\x12*.tabletmanagerdata.ResetReplicationRequest\x1a+.tabletmanagerdata.ResetReplicationResponse\"\x00\x12[\n\nInitMaster\x12$.tabletmanagerdata.InitMasterRequest\x1a%.tabletmanagerdata.InitMasterResponse\"\x00\x12\x82\x01\n\x17PopulateReparentJournal\x12\x31.tabletmanagerdata.PopulateReparentJournalRequest\x1a\x32.tabletmanagerdata.PopulateReparentJournalResponse\"\x00\x12X\n\tInitSlave\x12#.tabletmanagerdata.InitSlaveRequest\x1a$.tabletmanagerdata.InitSlaveResponse\"\x00\x12\x61\n\x0c\x44\x65moteMaster\x12&.tabletmanagerdata.DemoteMasterRequest\x1a\'.tabletmanagerdata.DemoteMasterResponse\"\x00\x12m\n\x10UndoDemoteMaster\x12*.tabletmanagerdata.UndoDemoteMasterRequest\x1a+.tabletmanagerdata.UndoDemoteMasterResponse\"\x00\x12\x85\x01\n\x18PromoteSlaveWhenCaughtUp\x12\x32.tabletmanagerdata.PromoteSlaveWhenCaughtUpRequest\x1a\x33.tabletmanagerdata.PromoteSlaveWhenCaughtUpResponse\"\x00\x12m\n\x10SlaveWasPromoted\x12*.tabletmanagerdata.SlaveWasPromotedRequest\x1a+.tabletmanagerdata.SlaveWasPromotedResponse\"\x00\x12X\n\tSetMaster\x12#.tabletmanagerdata.SetMasterRequest\x1a$.tabletmanagerdata.SetMasterResponse\"\x00\x12p\n\x11SlaveWasRestarted\x12+.tabletmanagerdata.SlaveWasRestartedRequest\x1a,.tabletmanagerdata.SlaveWasRestartedResponse\"\x00\x12\x8e\x01\n\x1bStopReplicationAndGetStatus\x12\x35.tabletmanagerdata.StopReplicationAndGetStatusRequest\x1a\x36.tabletmanagerdata.StopReplicationAndGetStatusResponse\"\x00\x12\x61\n\x0cPromoteSlave\x12&.tabletmanagerdata.PromoteSlaveRequest\x1a\'.tabletmanagerdata.PromoteSlaveResponse\"\x00\x12Q\n\x06\x42\x61\x63kup\x12 .tabletmanagerdata.BackupRequest\x1a!.tabletmanagerdata.BackupResponse\"\x00\x30\x01\x12r\n\x11RestoreFromBackup\x12+.tabletmanagerdata.RestoreFromBackupRequest\x1a,.tabletmanagerdata.RestoreFromBackupResponse\"\x00\x30\x01\x42\x33Z1vitess.io/vitess/go/vt/proto/tabletmanagerserviceb\x06proto3') + serialized_pb=_b('\n\x1atabletmanagerservice.proto\x12\x14tabletmanagerservice\x1a\x17tabletmanagerdata.proto2\xab%\n\rTabletManager\x12I\n\x04Ping\x12\x1e.tabletmanagerdata.PingRequest\x1a\x1f.tabletmanagerdata.PingResponse\"\x00\x12L\n\x05Sleep\x12\x1f.tabletmanagerdata.SleepRequest\x1a .tabletmanagerdata.SleepResponse\"\x00\x12^\n\x0b\x45xecuteHook\x12%.tabletmanagerdata.ExecuteHookRequest\x1a&.tabletmanagerdata.ExecuteHookResponse\"\x00\x12X\n\tGetSchema\x12#.tabletmanagerdata.GetSchemaRequest\x1a$.tabletmanagerdata.GetSchemaResponse\"\x00\x12g\n\x0eGetPermissions\x12(.tabletmanagerdata.GetPermissionsRequest\x1a).tabletmanagerdata.GetPermissionsResponse\"\x00\x12^\n\x0bSetReadOnly\x12%.tabletmanagerdata.SetReadOnlyRequest\x1a&.tabletmanagerdata.SetReadOnlyResponse\"\x00\x12\x61\n\x0cSetReadWrite\x12&.tabletmanagerdata.SetReadWriteRequest\x1a\'.tabletmanagerdata.SetReadWriteResponse\"\x00\x12[\n\nChangeType\x12$.tabletmanagerdata.ChangeTypeRequest\x1a%.tabletmanagerdata.ChangeTypeResponse\"\x00\x12\x61\n\x0cRefreshState\x12&.tabletmanagerdata.RefreshStateRequest\x1a\'.tabletmanagerdata.RefreshStateResponse\"\x00\x12g\n\x0eRunHealthCheck\x12(.tabletmanagerdata.RunHealthCheckRequest\x1a).tabletmanagerdata.RunHealthCheckResponse\"\x00\x12p\n\x11IgnoreHealthError\x12+.tabletmanagerdata.IgnoreHealthErrorRequest\x1a,.tabletmanagerdata.IgnoreHealthErrorResponse\"\x00\x12\x61\n\x0cReloadSchema\x12&.tabletmanagerdata.ReloadSchemaRequest\x1a\'.tabletmanagerdata.ReloadSchemaResponse\"\x00\x12j\n\x0fPreflightSchema\x12).tabletmanagerdata.PreflightSchemaRequest\x1a*.tabletmanagerdata.PreflightSchemaResponse\"\x00\x12^\n\x0b\x41pplySchema\x12%.tabletmanagerdata.ApplySchemaRequest\x1a&.tabletmanagerdata.ApplySchemaResponse\"\x00\x12[\n\nLockTables\x12$.tabletmanagerdata.LockTablesRequest\x1a%.tabletmanagerdata.LockTablesResponse\"\x00\x12\x61\n\x0cUnlockTables\x12&.tabletmanagerdata.UnlockTablesRequest\x1a\'.tabletmanagerdata.UnlockTablesResponse\"\x00\x12p\n\x11\x45xecuteFetchAsDba\x12+.tabletmanagerdata.ExecuteFetchAsDbaRequest\x1a,.tabletmanagerdata.ExecuteFetchAsDbaResponse\"\x00\x12\x7f\n\x16\x45xecuteFetchAsAllPrivs\x12\x30.tabletmanagerdata.ExecuteFetchAsAllPrivsRequest\x1a\x31.tabletmanagerdata.ExecuteFetchAsAllPrivsResponse\"\x00\x12p\n\x11\x45xecuteFetchAsApp\x12+.tabletmanagerdata.ExecuteFetchAsAppRequest\x1a,.tabletmanagerdata.ExecuteFetchAsAppResponse\"\x00\x12^\n\x0bSlaveStatus\x12%.tabletmanagerdata.SlaveStatusRequest\x1a&.tabletmanagerdata.SlaveStatusResponse\"\x00\x12g\n\x0eMasterPosition\x12(.tabletmanagerdata.MasterPositionRequest\x1a).tabletmanagerdata.MasterPositionResponse\"\x00\x12j\n\x0fWaitForPosition\x12).tabletmanagerdata.WaitForPositionRequest\x1a*.tabletmanagerdata.WaitForPositionResponse\"\x00\x12X\n\tStopSlave\x12#.tabletmanagerdata.StopSlaveRequest\x1a$.tabletmanagerdata.StopSlaveResponse\"\x00\x12m\n\x10StopSlaveMinimum\x12*.tabletmanagerdata.StopSlaveMinimumRequest\x1a+.tabletmanagerdata.StopSlaveMinimumResponse\"\x00\x12[\n\nStartSlave\x12$.tabletmanagerdata.StartSlaveRequest\x1a%.tabletmanagerdata.StartSlaveResponse\"\x00\x12y\n\x14StartSlaveUntilAfter\x12..tabletmanagerdata.StartSlaveUntilAfterRequest\x1a/.tabletmanagerdata.StartSlaveUntilAfterResponse\"\x00\x12\x8b\x01\n\x1aTabletExternallyReparented\x12\x34.tabletmanagerdata.TabletExternallyReparentedRequest\x1a\x35.tabletmanagerdata.TabletExternallyReparentedResponse\"\x00\x12\x82\x01\n\x17TabletExternallyElected\x12\x31.tabletmanagerdata.TabletExternallyElectedRequest\x1a\x32.tabletmanagerdata.TabletExternallyElectedResponse\"\x00\x12X\n\tGetSlaves\x12#.tabletmanagerdata.GetSlavesRequest\x1a$.tabletmanagerdata.GetSlavesResponse\"\x00\x12m\n\x10VReplicationExec\x12*.tabletmanagerdata.VReplicationExecRequest\x1a+.tabletmanagerdata.VReplicationExecResponse\"\x00\x12\x7f\n\x16VReplicationWaitForPos\x12\x30.tabletmanagerdata.VReplicationWaitForPosRequest\x1a\x31.tabletmanagerdata.VReplicationWaitForPosResponse\"\x00\x12m\n\x10ResetReplication\x12*.tabletmanagerdata.ResetReplicationRequest\x1a+.tabletmanagerdata.ResetReplicationResponse\"\x00\x12[\n\nInitMaster\x12$.tabletmanagerdata.InitMasterRequest\x1a%.tabletmanagerdata.InitMasterResponse\"\x00\x12\x82\x01\n\x17PopulateReparentJournal\x12\x31.tabletmanagerdata.PopulateReparentJournalRequest\x1a\x32.tabletmanagerdata.PopulateReparentJournalResponse\"\x00\x12X\n\tInitSlave\x12#.tabletmanagerdata.InitSlaveRequest\x1a$.tabletmanagerdata.InitSlaveResponse\"\x00\x12\x61\n\x0c\x44\x65moteMaster\x12&.tabletmanagerdata.DemoteMasterRequest\x1a\'.tabletmanagerdata.DemoteMasterResponse\"\x00\x12m\n\x10UndoDemoteMaster\x12*.tabletmanagerdata.UndoDemoteMasterRequest\x1a+.tabletmanagerdata.UndoDemoteMasterResponse\"\x00\x12\x85\x01\n\x18PromoteSlaveWhenCaughtUp\x12\x32.tabletmanagerdata.PromoteSlaveWhenCaughtUpRequest\x1a\x33.tabletmanagerdata.PromoteSlaveWhenCaughtUpResponse\"\x00\x12m\n\x10SlaveWasPromoted\x12*.tabletmanagerdata.SlaveWasPromotedRequest\x1a+.tabletmanagerdata.SlaveWasPromotedResponse\"\x00\x12X\n\tSetMaster\x12#.tabletmanagerdata.SetMasterRequest\x1a$.tabletmanagerdata.SetMasterResponse\"\x00\x12p\n\x11SlaveWasRestarted\x12+.tabletmanagerdata.SlaveWasRestartedRequest\x1a,.tabletmanagerdata.SlaveWasRestartedResponse\"\x00\x12\x8e\x01\n\x1bStopReplicationAndGetStatus\x12\x35.tabletmanagerdata.StopReplicationAndGetStatusRequest\x1a\x36.tabletmanagerdata.StopReplicationAndGetStatusResponse\"\x00\x12\x61\n\x0cPromoteSlave\x12&.tabletmanagerdata.PromoteSlaveRequest\x1a\'.tabletmanagerdata.PromoteSlaveResponse\"\x00\x12Q\n\x06\x42\x61\x63kup\x12 .tabletmanagerdata.BackupRequest\x1a!.tabletmanagerdata.BackupResponse\"\x00\x30\x01\x12r\n\x11RestoreFromBackup\x12+.tabletmanagerdata.RestoreFromBackupRequest\x1a,.tabletmanagerdata.RestoreFromBackupResponse\"\x00\x30\x01\x42\x33Z1vitess.io/vitess/go/vt/proto/tabletmanagerserviceb\x06proto3') , dependencies=[tabletmanagerdata__pb2.DESCRIPTOR,]) @@ -38,7 +38,7 @@ index=0, serialized_options=None, serialized_start=78, - serialized_end=4749, + serialized_end=4857, methods=[ _descriptor.MethodDescriptor( name='Ping', @@ -229,10 +229,19 @@ output_type=tabletmanagerdata__pb2._MASTERPOSITIONRESPONSE, serialized_options=None, ), + _descriptor.MethodDescriptor( + name='WaitForPosition', + full_name='tabletmanagerservice.TabletManager.WaitForPosition', + index=21, + containing_service=None, + input_type=tabletmanagerdata__pb2._WAITFORPOSITIONREQUEST, + output_type=tabletmanagerdata__pb2._WAITFORPOSITIONRESPONSE, + serialized_options=None, + ), _descriptor.MethodDescriptor( name='StopSlave', full_name='tabletmanagerservice.TabletManager.StopSlave', - index=21, + index=22, containing_service=None, input_type=tabletmanagerdata__pb2._STOPSLAVEREQUEST, output_type=tabletmanagerdata__pb2._STOPSLAVERESPONSE, @@ -241,7 +250,7 @@ _descriptor.MethodDescriptor( name='StopSlaveMinimum', full_name='tabletmanagerservice.TabletManager.StopSlaveMinimum', - index=22, + index=23, containing_service=None, input_type=tabletmanagerdata__pb2._STOPSLAVEMINIMUMREQUEST, output_type=tabletmanagerdata__pb2._STOPSLAVEMINIMUMRESPONSE, @@ -250,7 +259,7 @@ _descriptor.MethodDescriptor( name='StartSlave', full_name='tabletmanagerservice.TabletManager.StartSlave', - index=23, + index=24, containing_service=None, input_type=tabletmanagerdata__pb2._STARTSLAVEREQUEST, output_type=tabletmanagerdata__pb2._STARTSLAVERESPONSE, @@ -259,7 +268,7 @@ _descriptor.MethodDescriptor( name='StartSlaveUntilAfter', full_name='tabletmanagerservice.TabletManager.StartSlaveUntilAfter', - index=24, + index=25, containing_service=None, input_type=tabletmanagerdata__pb2._STARTSLAVEUNTILAFTERREQUEST, output_type=tabletmanagerdata__pb2._STARTSLAVEUNTILAFTERRESPONSE, @@ -268,7 +277,7 @@ _descriptor.MethodDescriptor( name='TabletExternallyReparented', full_name='tabletmanagerservice.TabletManager.TabletExternallyReparented', - index=25, + index=26, containing_service=None, input_type=tabletmanagerdata__pb2._TABLETEXTERNALLYREPARENTEDREQUEST, output_type=tabletmanagerdata__pb2._TABLETEXTERNALLYREPARENTEDRESPONSE, @@ -277,7 +286,7 @@ _descriptor.MethodDescriptor( name='TabletExternallyElected', full_name='tabletmanagerservice.TabletManager.TabletExternallyElected', - index=26, + index=27, containing_service=None, input_type=tabletmanagerdata__pb2._TABLETEXTERNALLYELECTEDREQUEST, output_type=tabletmanagerdata__pb2._TABLETEXTERNALLYELECTEDRESPONSE, @@ -286,7 +295,7 @@ _descriptor.MethodDescriptor( name='GetSlaves', full_name='tabletmanagerservice.TabletManager.GetSlaves', - index=27, + index=28, containing_service=None, input_type=tabletmanagerdata__pb2._GETSLAVESREQUEST, output_type=tabletmanagerdata__pb2._GETSLAVESRESPONSE, @@ -295,7 +304,7 @@ _descriptor.MethodDescriptor( name='VReplicationExec', full_name='tabletmanagerservice.TabletManager.VReplicationExec', - index=28, + index=29, containing_service=None, input_type=tabletmanagerdata__pb2._VREPLICATIONEXECREQUEST, output_type=tabletmanagerdata__pb2._VREPLICATIONEXECRESPONSE, @@ -304,7 +313,7 @@ _descriptor.MethodDescriptor( name='VReplicationWaitForPos', full_name='tabletmanagerservice.TabletManager.VReplicationWaitForPos', - index=29, + index=30, containing_service=None, input_type=tabletmanagerdata__pb2._VREPLICATIONWAITFORPOSREQUEST, output_type=tabletmanagerdata__pb2._VREPLICATIONWAITFORPOSRESPONSE, @@ -313,7 +322,7 @@ _descriptor.MethodDescriptor( name='ResetReplication', full_name='tabletmanagerservice.TabletManager.ResetReplication', - index=30, + index=31, containing_service=None, input_type=tabletmanagerdata__pb2._RESETREPLICATIONREQUEST, output_type=tabletmanagerdata__pb2._RESETREPLICATIONRESPONSE, @@ -322,7 +331,7 @@ _descriptor.MethodDescriptor( name='InitMaster', full_name='tabletmanagerservice.TabletManager.InitMaster', - index=31, + index=32, containing_service=None, input_type=tabletmanagerdata__pb2._INITMASTERREQUEST, output_type=tabletmanagerdata__pb2._INITMASTERRESPONSE, @@ -331,7 +340,7 @@ _descriptor.MethodDescriptor( name='PopulateReparentJournal', full_name='tabletmanagerservice.TabletManager.PopulateReparentJournal', - index=32, + index=33, containing_service=None, input_type=tabletmanagerdata__pb2._POPULATEREPARENTJOURNALREQUEST, output_type=tabletmanagerdata__pb2._POPULATEREPARENTJOURNALRESPONSE, @@ -340,7 +349,7 @@ _descriptor.MethodDescriptor( name='InitSlave', full_name='tabletmanagerservice.TabletManager.InitSlave', - index=33, + index=34, containing_service=None, input_type=tabletmanagerdata__pb2._INITSLAVEREQUEST, output_type=tabletmanagerdata__pb2._INITSLAVERESPONSE, @@ -349,7 +358,7 @@ _descriptor.MethodDescriptor( name='DemoteMaster', full_name='tabletmanagerservice.TabletManager.DemoteMaster', - index=34, + index=35, containing_service=None, input_type=tabletmanagerdata__pb2._DEMOTEMASTERREQUEST, output_type=tabletmanagerdata__pb2._DEMOTEMASTERRESPONSE, @@ -358,7 +367,7 @@ _descriptor.MethodDescriptor( name='UndoDemoteMaster', full_name='tabletmanagerservice.TabletManager.UndoDemoteMaster', - index=35, + index=36, containing_service=None, input_type=tabletmanagerdata__pb2._UNDODEMOTEMASTERREQUEST, output_type=tabletmanagerdata__pb2._UNDODEMOTEMASTERRESPONSE, @@ -367,7 +376,7 @@ _descriptor.MethodDescriptor( name='PromoteSlaveWhenCaughtUp', full_name='tabletmanagerservice.TabletManager.PromoteSlaveWhenCaughtUp', - index=36, + index=37, containing_service=None, input_type=tabletmanagerdata__pb2._PROMOTESLAVEWHENCAUGHTUPREQUEST, output_type=tabletmanagerdata__pb2._PROMOTESLAVEWHENCAUGHTUPRESPONSE, @@ -376,7 +385,7 @@ _descriptor.MethodDescriptor( name='SlaveWasPromoted', full_name='tabletmanagerservice.TabletManager.SlaveWasPromoted', - index=37, + index=38, containing_service=None, input_type=tabletmanagerdata__pb2._SLAVEWASPROMOTEDREQUEST, output_type=tabletmanagerdata__pb2._SLAVEWASPROMOTEDRESPONSE, @@ -385,7 +394,7 @@ _descriptor.MethodDescriptor( name='SetMaster', full_name='tabletmanagerservice.TabletManager.SetMaster', - index=38, + index=39, containing_service=None, input_type=tabletmanagerdata__pb2._SETMASTERREQUEST, output_type=tabletmanagerdata__pb2._SETMASTERRESPONSE, @@ -394,7 +403,7 @@ _descriptor.MethodDescriptor( name='SlaveWasRestarted', full_name='tabletmanagerservice.TabletManager.SlaveWasRestarted', - index=39, + index=40, containing_service=None, input_type=tabletmanagerdata__pb2._SLAVEWASRESTARTEDREQUEST, output_type=tabletmanagerdata__pb2._SLAVEWASRESTARTEDRESPONSE, @@ -403,7 +412,7 @@ _descriptor.MethodDescriptor( name='StopReplicationAndGetStatus', full_name='tabletmanagerservice.TabletManager.StopReplicationAndGetStatus', - index=40, + index=41, containing_service=None, input_type=tabletmanagerdata__pb2._STOPREPLICATIONANDGETSTATUSREQUEST, output_type=tabletmanagerdata__pb2._STOPREPLICATIONANDGETSTATUSRESPONSE, @@ -412,7 +421,7 @@ _descriptor.MethodDescriptor( name='PromoteSlave', full_name='tabletmanagerservice.TabletManager.PromoteSlave', - index=41, + index=42, containing_service=None, input_type=tabletmanagerdata__pb2._PROMOTESLAVEREQUEST, output_type=tabletmanagerdata__pb2._PROMOTESLAVERESPONSE, @@ -421,7 +430,7 @@ _descriptor.MethodDescriptor( name='Backup', full_name='tabletmanagerservice.TabletManager.Backup', - index=42, + index=43, containing_service=None, input_type=tabletmanagerdata__pb2._BACKUPREQUEST, output_type=tabletmanagerdata__pb2._BACKUPRESPONSE, @@ -430,7 +439,7 @@ _descriptor.MethodDescriptor( name='RestoreFromBackup', full_name='tabletmanagerservice.TabletManager.RestoreFromBackup', - index=43, + index=44, containing_service=None, input_type=tabletmanagerdata__pb2._RESTOREFROMBACKUPREQUEST, output_type=tabletmanagerdata__pb2._RESTOREFROMBACKUPRESPONSE, diff --git a/py/vtproto/tabletmanagerservice_pb2_grpc.py b/py/vtproto/tabletmanagerservice_pb2_grpc.py index 0cdae4b3898..95019dd89ed 100644 --- a/py/vtproto/tabletmanagerservice_pb2_grpc.py +++ b/py/vtproto/tabletmanagerservice_pb2_grpc.py @@ -122,6 +122,11 @@ def __init__(self, channel): request_serializer=tabletmanagerdata__pb2.MasterPositionRequest.SerializeToString, response_deserializer=tabletmanagerdata__pb2.MasterPositionResponse.FromString, ) + self.WaitForPosition = channel.unary_unary( + '/tabletmanagerservice.TabletManager/WaitForPosition', + request_serializer=tabletmanagerdata__pb2.WaitForPositionRequest.SerializeToString, + response_deserializer=tabletmanagerdata__pb2.WaitForPositionResponse.FromString, + ) self.StopSlave = channel.unary_unary( '/tabletmanagerservice.TabletManager/StopSlave', request_serializer=tabletmanagerdata__pb2.StopSlaveRequest.SerializeToString, @@ -400,6 +405,13 @@ def MasterPosition(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def WaitForPosition(self, request, context): + """WaitForPosition waits for the position to be reached + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def StopSlave(self, request, context): """StopSlave makes mysql stop its replication """ @@ -703,6 +715,11 @@ def add_TabletManagerServicer_to_server(servicer, server): request_deserializer=tabletmanagerdata__pb2.MasterPositionRequest.FromString, response_serializer=tabletmanagerdata__pb2.MasterPositionResponse.SerializeToString, ), + 'WaitForPosition': grpc.unary_unary_rpc_method_handler( + servicer.WaitForPosition, + request_deserializer=tabletmanagerdata__pb2.WaitForPositionRequest.FromString, + response_serializer=tabletmanagerdata__pb2.WaitForPositionResponse.SerializeToString, + ), 'StopSlave': grpc.unary_unary_rpc_method_handler( servicer.StopSlave, request_deserializer=tabletmanagerdata__pb2.StopSlaveRequest.FromString, From ea2a5c08003863b318ae78a7027c037bd69cb06e Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 6 Oct 2019 19:56:13 -0700 Subject: [PATCH 13/28] vdiff: selectTablets Signed-off-by: Sugu Sougoumarane --- go/vt/wrangler/vdiff.go | 96 +++++++++++++++++++++++++++++++++-------- 1 file changed, 79 insertions(+), 17 deletions(-) diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index d544a017b59..44d8f965e9a 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -27,10 +27,12 @@ import ( "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/concurrency" + "vitess.io/vitess/go/vt/discovery" "vitess.io/vitess/go/vt/key" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/vterrors" @@ -39,11 +41,16 @@ import ( ) type vdiff struct { - wr *Wrangler - workflow string - differs map[string]*tableDiffer - sources map[string]*dfParams - targets map[string]*dfParams + wr *Wrangler + workflow string + sourceKeyspace string + targetKeyspace string + sourceCell string + targetCell string + tabletTypesStr string + differs map[string]*tableDiffer + sources map[string]*dfParams + targets map[string]*dfParams } type tableDiffer struct { @@ -56,12 +63,12 @@ type tableDiffer struct { type dfParams struct { master *topo.TabletInfo - tablet *topo.TabletInfo + tablet *topodatapb.Tablet position mysql.Position } // VDiff reports differences between the sources and targets of a vreplication workflow. -func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow string, filteredReplicationWaitTime time.Duration) error { +func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow, sourceCell, targetCell, tabletTypesStr string, filteredReplicationWaitTime time.Duration) error { mi, err := wr.buildMigrater(ctx, targetKeyspace, workflow) if err != nil { wr.Logger().Errorf("buildMigrater failed: %v", err) @@ -72,10 +79,15 @@ func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow string, return err } df := &vdiff{ - wr: wr, - workflow: workflow, - sources: make(map[string]*dfParams), - targets: make(map[string]*dfParams), + wr: wr, + workflow: workflow, + sourceKeyspace: mi.sourceKeyspace, + targetKeyspace: mi.targetKeyspace, + sourceCell: sourceCell, + targetCell: targetCell, + tabletTypesStr: tabletTypesStr, + sources: make(map[string]*dfParams), + targets: make(map[string]*dfParams), } for shard, source := range mi.sources { df.sources[shard] = &dfParams{ @@ -223,7 +235,7 @@ func buildDifferPlan(table *tabletmanagerdatapb.TableDefinition, query string) ( func (df *vdiff) stopTargetStreams(ctx context.Context) error { var mu sync.Mutex - err := df.forAll(df.targets, func(target *dfParams) error { + err := df.forAll(df.targets, func(shard string, target *dfParams) error { query := fmt.Sprintf("update _vt.vreplication set state='Stopped', message='for vdiff' where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.workflow)) _, err := df.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) if err != nil { @@ -268,18 +280,68 @@ func (df *vdiff) stopTargetStreams(ctx context.Context) error { return nil } -func (df *vdiff) forAll(participants map[string]*dfParams, f func(*dfParams) error) error { +func (df *vdiff) selectTablets(ctx context.Context) error { + var wg sync.WaitGroup + var err1, err2 error + + // Parallelize all discovery. + wg.Add(1) + go func() { + defer wg.Done() + err1 = df.forAll(df.sources, func(shard string, source *dfParams) error { + tp, err := discovery.NewTabletPicker(ctx, df.wr.ts, df.targetCell, df.targetKeyspace, shard, df.tabletTypesStr) + if err != nil { + return err + } + defer tp.Close() + + tablet, err := tp.PickForStreaming(ctx) + if err != nil { + return err + } + df.sources[shard].tablet = tablet + return nil + }) + }() + + wg.Add(1) + go func() { + defer wg.Done() + err2 = df.forAll(df.targets, func(shard string, target *dfParams) error { + tp, err := discovery.NewTabletPicker(ctx, df.wr.ts, df.targetCell, df.targetKeyspace, shard, df.tabletTypesStr) + if err != nil { + return err + } + defer tp.Close() + + tablet, err := tp.PickForStreaming(ctx) + if err != nil { + return err + } + df.targets[shard].tablet = tablet + return nil + }) + }() + + wg.Wait() + if err1 != nil { + return err1 + } + return err2 +} + +func (df *vdiff) forAll(participants map[string]*dfParams, f func(string, *dfParams) error) error { var wg sync.WaitGroup allErrors := &concurrency.AllErrorRecorder{} - for _, participant := range participants { + for shard, participant := range participants { wg.Add(1) - go func(participant *dfParams) { + go func(shard string, participant *dfParams) { defer wg.Done() - if err := f(participant); err != nil { + if err := f(shard, participant); err != nil { allErrors.RecordError(err) } - }(participant) + }(shard, participant) } wg.Wait() return allErrors.AggrError(vterrors.Aggregate) From d37fd4fa068881fe802090e4e0959964d5bd8789 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 6 Oct 2019 21:04:07 -0700 Subject: [PATCH 14/28] vdiff: streamFromSources Signed-off-by: Sugu Sougoumarane --- go/vt/wrangler/vdiff.go | 86 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 5 deletions(-) diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index 44d8f965e9a..d0a24e6b61a 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -18,6 +18,7 @@ package wrangler import ( "fmt" + "io" "strings" "sync" "time" @@ -28,6 +29,7 @@ import ( "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/concurrency" "vitess.io/vitess/go/vt/discovery" + "vitess.io/vitess/go/vt/grpcclient" "vitess.io/vitess/go/vt/key" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" @@ -37,6 +39,7 @@ import ( "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" + "vitess.io/vitess/go/vt/vttablet/tabletconn" "vitess.io/vitess/go/vt/vttablet/tabletmanager/vreplication" ) @@ -62,9 +65,12 @@ type tableDiffer struct { } type dfParams struct { - master *topo.TabletInfo - tablet *topodatapb.Tablet - position mysql.Position + master *topo.TabletInfo + tablet *topodatapb.Tablet + position mysql.Position + snapshotPosition string + result chan *sqltypes.Result + err error } // VDiff reports differences between the sources and targets of a vreplication workflow. @@ -299,7 +305,7 @@ func (df *vdiff) selectTablets(ctx context.Context) error { if err != nil { return err } - df.sources[shard].tablet = tablet + source.tablet = tablet return nil }) }() @@ -318,7 +324,7 @@ func (df *vdiff) selectTablets(ctx context.Context) error { if err != nil { return err } - df.targets[shard].tablet = tablet + target.tablet = tablet return nil }) }() @@ -330,6 +336,76 @@ func (df *vdiff) selectTablets(ctx context.Context) error { return err2 } +func (df *vdiff) streamFromSources(ctx context.Context, td *tableDiffer) error { + err := df.forAll(df.sources, func(shard string, source *dfParams) error { + // Iteration for each source. + if err := df.wr.tmc.WaitForPosition(ctx, source.tablet, mysql.EncodePosition(source.position)); err != nil { + return err + } + source.result = make(chan *sqltypes.Result, 1) + gtidch := make(chan string, 1) + + // Start the stream in a separate goroutine. + go df.streamOneSource(ctx, shard, source, td, gtidch) + + // Wait for the gtid to be sent. If it's not received, there was an error + // which would be stored in source.err. + gtid, ok := <-gtidch + if !ok { + return source.err + } + // Save the new position, as of when the query executed. + source.snapshotPosition = gtid + return nil + }) + return err +} + +// streamOneSource is called as a goroutine, and communicates its results through channels. +// It first sends the snapshot gtid to gtidch. +// Then it streams results to source.result. +// Before returning, it sets source.err, and closes all channels. +// If any channel is closed, then source.err can be checked if there was an error. +func (df *vdiff) streamOneSource(ctx context.Context, shard string, source *dfParams, td *tableDiffer, gtidch chan string) { + defer close(source.result) + defer close(gtidch) + + // Wrap the streaming in a separate function so we can capture the error. + // This shows that the error will be set before the channels are closed. + source.err = func() error { + conn, err := tabletconn.GetDialer()(source.tablet, grpcclient.FailFast(false)) + if err != nil { + return err + } + defer conn.Close(ctx) + + target := &querypb.Target{ + Keyspace: df.sourceKeyspace, + Shard: shard, + TabletType: source.tablet.Type, + } + var fields []*querypb.Field + err = conn.VStreamResults(ctx, target, td.sourceExpression, func(vrs *binlogdatapb.VStreamResultsResponse) error { + if vrs.Fields != nil { + fields = vrs.Fields + gtidch <- vrs.Gtid + } + p3qr := &querypb.QueryResult{ + Fields: fields, + Rows: vrs.Rows, + } + result := sqltypes.Proto3ToResult(p3qr) + select { + case source.result <- result: + case <-ctx.Done(): + return io.EOF + } + return nil + }) + return err + }() +} + func (df *vdiff) forAll(participants map[string]*dfParams, f func(string, *dfParams) error) error { var wg sync.WaitGroup allErrors := &concurrency.AllErrorRecorder{} From 3a9aa89484e29fd9b44b19100b7993a705fc76d7 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Mon, 7 Oct 2019 17:11:04 -0700 Subject: [PATCH 15/28] vdiff: syncTargets and restartTargets Signed-off-by: Sugu Sougoumarane --- go/vt/wrangler/vdiff.go | 101 ++++++++++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 35 deletions(-) diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index d0a24e6b61a..10e5ac5395c 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -44,10 +44,7 @@ import ( ) type vdiff struct { - wr *Wrangler - workflow string - sourceKeyspace string - targetKeyspace string + mi *migrater sourceCell string targetCell string tabletTypesStr string @@ -85,10 +82,7 @@ func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow, sourceC return err } df := &vdiff{ - wr: wr, - workflow: workflow, - sourceKeyspace: mi.sourceKeyspace, - targetKeyspace: mi.targetKeyspace, + mi: mi, sourceCell: sourceCell, targetCell: targetCell, tabletTypesStr: tabletTypesStr, @@ -242,13 +236,13 @@ func (df *vdiff) stopTargetStreams(ctx context.Context) error { var mu sync.Mutex err := df.forAll(df.targets, func(shard string, target *dfParams) error { - query := fmt.Sprintf("update _vt.vreplication set state='Stopped', message='for vdiff' where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.workflow)) - _, err := df.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) + query := fmt.Sprintf("update _vt.vreplication set state='Stopped', message='for vdiff' where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.mi.workflow)) + _, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) if err != nil { return err } - query = fmt.Sprintf("select source, pos from _vt.vreplication where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.workflow)) - p3qr, err := df.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) + query = fmt.Sprintf("select source, pos from _vt.vreplication where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.mi.workflow)) + p3qr, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) if err != nil { return err } @@ -295,7 +289,7 @@ func (df *vdiff) selectTablets(ctx context.Context) error { go func() { defer wg.Done() err1 = df.forAll(df.sources, func(shard string, source *dfParams) error { - tp, err := discovery.NewTabletPicker(ctx, df.wr.ts, df.targetCell, df.targetKeyspace, shard, df.tabletTypesStr) + tp, err := discovery.NewTabletPicker(ctx, df.mi.wr.ts, df.targetCell, df.mi.targetKeyspace, shard, df.tabletTypesStr) if err != nil { return err } @@ -314,7 +308,7 @@ func (df *vdiff) selectTablets(ctx context.Context) error { go func() { defer wg.Done() err2 = df.forAll(df.targets, func(shard string, target *dfParams) error { - tp, err := discovery.NewTabletPicker(ctx, df.wr.ts, df.targetCell, df.targetKeyspace, shard, df.tabletTypesStr) + tp, err := discovery.NewTabletPicker(ctx, df.mi.wr.ts, df.targetCell, df.mi.targetKeyspace, shard, df.tabletTypesStr) if err != nil { return err } @@ -336,56 +330,56 @@ func (df *vdiff) selectTablets(ctx context.Context) error { return err2 } -func (df *vdiff) streamFromSources(ctx context.Context, td *tableDiffer) error { - err := df.forAll(df.sources, func(shard string, source *dfParams) error { - // Iteration for each source. - if err := df.wr.tmc.WaitForPosition(ctx, source.tablet, mysql.EncodePosition(source.position)); err != nil { +func (df *vdiff) startStreams(ctx context.Context, participans map[string]*dfParams, query string) error { + err := df.forAll(participans, func(shard string, participant *dfParams) error { + // Iteration for each participant. + if err := df.mi.wr.tmc.WaitForPosition(ctx, participant.tablet, mysql.EncodePosition(participant.position)); err != nil { return err } - source.result = make(chan *sqltypes.Result, 1) + participant.result = make(chan *sqltypes.Result, 1) gtidch := make(chan string, 1) // Start the stream in a separate goroutine. - go df.streamOneSource(ctx, shard, source, td, gtidch) + go df.streamOne(ctx, shard, participant, query, gtidch) // Wait for the gtid to be sent. If it's not received, there was an error - // which would be stored in source.err. + // which would be stored in participant.err. gtid, ok := <-gtidch if !ok { - return source.err + return participant.err } // Save the new position, as of when the query executed. - source.snapshotPosition = gtid + participant.snapshotPosition = gtid return nil }) return err } -// streamOneSource is called as a goroutine, and communicates its results through channels. +// streamOne is called as a goroutine, and communicates its results through channels. // It first sends the snapshot gtid to gtidch. -// Then it streams results to source.result. -// Before returning, it sets source.err, and closes all channels. -// If any channel is closed, then source.err can be checked if there was an error. -func (df *vdiff) streamOneSource(ctx context.Context, shard string, source *dfParams, td *tableDiffer, gtidch chan string) { - defer close(source.result) +// Then it streams results to participant.result. +// Before returning, it sets participant.err, and closes all channels. +// If any channel is closed, then participant.err can be checked if there was an error. +func (df *vdiff) streamOne(ctx context.Context, shard string, participant *dfParams, query string, gtidch chan string) { + defer close(participant.result) defer close(gtidch) // Wrap the streaming in a separate function so we can capture the error. // This shows that the error will be set before the channels are closed. - source.err = func() error { - conn, err := tabletconn.GetDialer()(source.tablet, grpcclient.FailFast(false)) + participant.err = func() error { + conn, err := tabletconn.GetDialer()(participant.tablet, grpcclient.FailFast(false)) if err != nil { return err } defer conn.Close(ctx) target := &querypb.Target{ - Keyspace: df.sourceKeyspace, + Keyspace: df.mi.sourceKeyspace, Shard: shard, - TabletType: source.tablet.Type, + TabletType: participant.tablet.Type, } var fields []*querypb.Field - err = conn.VStreamResults(ctx, target, td.sourceExpression, func(vrs *binlogdatapb.VStreamResultsResponse) error { + err = conn.VStreamResults(ctx, target, query, func(vrs *binlogdatapb.VStreamResultsResponse) error { if vrs.Fields != nil { fields = vrs.Fields gtidch <- vrs.Gtid @@ -396,7 +390,7 @@ func (df *vdiff) streamOneSource(ctx context.Context, shard string, source *dfPa } result := sqltypes.Proto3ToResult(p3qr) select { - case source.result <- result: + case participant.result <- result: case <-ctx.Done(): return io.EOF } @@ -406,6 +400,43 @@ func (df *vdiff) streamOneSource(ctx context.Context, shard string, source *dfPa }() } +func (df *vdiff) syncTargets(ctx context.Context) error { + err := df.mi.forAllUids(func(target *miTarget, uid uint32) error { + bls := target.sources[uid] + pos := df.sources[bls.Shard].snapshotPosition + query := fmt.Sprintf("update _vt.vreplication set state='Running', stop_pos='%s', message='synchronizing for vdiff' where id=%d", pos, uid) + if _, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query); err != nil { + return err + } + return df.mi.wr.tmc.VReplicationWaitForPos(ctx, target.master.Tablet, int(uid), pos) + }) + if err != nil { + return err + } + + err = df.forAll(df.targets, func(shard string, target *dfParams) error { + pos, err := df.mi.wr.tmc.MasterPosition(ctx, target.master.Tablet) + if err != nil { + return err + } + mpos, err := mysql.DecodePosition(pos) + if err != nil { + return err + } + target.position = mpos + return nil + }) + return err +} + +func (df *vdiff) restartTargets(ctx context.Context) error { + return df.forAll(df.targets, func(shard string, target *dfParams) error { + query := fmt.Sprintf("update _vt.vreplication set state='Running', message='' where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.mi.workflow)) + _, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) + return err + }) +} + func (df *vdiff) forAll(participants map[string]*dfParams, f func(string, *dfParams) error) error { var wg sync.WaitGroup allErrors := &concurrency.AllErrorRecorder{} From 51ce2c57b0a42befd7917e9b9246eb9d8f405b65 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Wed, 9 Oct 2019 19:41:33 -0700 Subject: [PATCH 16/28] vdiff: resultReader that uses engine.MergeSort Signed-off-by: Sugu Sougoumarane --- go/vt/vtgate/engine/merge_sort.go | 6 +- go/vt/vtgate/engine/merge_sort_test.go | 34 ++++---- go/vt/vtgate/engine/route.go | 2 +- go/vt/wrangler/vdiff.go | 104 ++++++++++++++++++++++++- 4 files changed, 124 insertions(+), 22 deletions(-) diff --git a/go/vt/vtgate/engine/merge_sort.go b/go/vt/vtgate/engine/merge_sort.go index 1572e4d1837..e55f213b89d 100644 --- a/go/vt/vtgate/engine/merge_sort.go +++ b/go/vt/vtgate/engine/merge_sort.go @@ -30,13 +30,13 @@ import ( "vitess.io/vitess/go/vt/srvtopo" ) -// mergeSort performs a merge-sort of rows returned by a streaming scatter query. +// MergeSort performs a merge-sort of rows returned by a streaming scatter query. // Each shard of the scatter query is treated as a stream. One row from each stream // is added to the merge-sorter heap. Every time a value is pulled out of the heap, // a new value is added to it from the stream that was the source of the value that // was pulled out. Since the input streams are sorted the same way that the heap is // sorted, this guarantees that the merged stream will also be sorted the same way. -func mergeSort(vcursor VCursor, query string, orderBy []OrderbyParams, rss []*srvtopo.ResolvedShard, bvs []map[string]*querypb.BindVariable, callback func(*sqltypes.Result) error) error { +func MergeSort(vcursor VCursor, query string, orderBy []OrderbyParams, rss []*srvtopo.ResolvedShard, bvs []map[string]*querypb.BindVariable, callback func(*sqltypes.Result) error) error { ctx, cancel := context.WithCancel(vcursor.Context()) defer cancel() @@ -123,7 +123,7 @@ func mergeSort(vcursor VCursor, query string, orderBy []OrderbyParams, rss []*sr // The fields channel is used by the stream to transmit the field info, which // is the first packet. Following this, the stream sends each row to the row // channel. At the end of the stream, fields and row are closed. If there -// was an error, err is set before the channels are closed. The mergeSort +// was an error, err is set before the channels are closed. The MergeSort // routine that pulls the rows out of each streamHandle can abort the stream // by calling canceling the context. type streamHandle struct { diff --git a/go/vt/vtgate/engine/merge_sort_test.go b/go/vt/vtgate/engine/merge_sort_test.go index 6d30072e0eb..b1c74c903b2 100644 --- a/go/vt/vtgate/engine/merge_sort_test.go +++ b/go/vt/vtgate/engine/merge_sort_test.go @@ -65,7 +65,7 @@ func TestMergeSortNormal(t *testing.T) { bvs := []map[string]*querypb.BindVariable{nil, nil, nil, nil} var results []*sqltypes.Result - err := mergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { + err := MergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { results = append(results, qr) return nil }) @@ -92,7 +92,7 @@ func TestMergeSortNormal(t *testing.T) { "8|h", ) if !reflect.DeepEqual(results, wantResults) { - t.Errorf("mergeSort:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(wantResults)) + t.Errorf("MergeSort:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(wantResults)) } } @@ -135,7 +135,7 @@ func TestMergeSortDescending(t *testing.T) { bvs := []map[string]*querypb.BindVariable{nil, nil, nil, nil} var results []*sqltypes.Result - err := mergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { + err := MergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { results = append(results, qr) return nil }) @@ -162,7 +162,7 @@ func TestMergeSortDescending(t *testing.T) { "1|a", ) if !reflect.DeepEqual(results, wantResults) { - t.Errorf("mergeSort:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(wantResults)) + t.Errorf("MergeSort:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(wantResults)) } } @@ -194,7 +194,7 @@ func TestMergeSortEmptyResults(t *testing.T) { bvs := []map[string]*querypb.BindVariable{nil, nil, nil, nil} var results []*sqltypes.Result - err := mergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { + err := MergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { results = append(results, qr) return nil }) @@ -213,7 +213,7 @@ func TestMergeSortEmptyResults(t *testing.T) { "7|g", ) if !reflect.DeepEqual(results, wantResults) { - t.Errorf("mergeSort:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(wantResults)) + t.Errorf("MergeSort:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(wantResults)) } } @@ -235,10 +235,10 @@ func TestMergeSortResultFailures(t *testing.T) { vc.shardResults["0"] = &shardResult{ sendErr: errors.New("early error"), } - err := mergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { return nil }) + err := MergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { return nil }) want := "early error" if err == nil || err.Error() != want { - t.Errorf("mergeSort(): %v, want %v", err, want) + t.Errorf("MergeSort(): %v, want %v", err, want) } // Test fail after fields. @@ -247,10 +247,10 @@ func TestMergeSortResultFailures(t *testing.T) { results: sqltypes.MakeTestStreamingResults(idFields), sendErr: errors.New("fail after fields"), } - err = mergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { return nil }) + err = MergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { return nil }) want = "fail after fields" if err == nil || err.Error() != want { - t.Errorf("mergeSort(): %v, want %v", err, want) + t.Errorf("MergeSort(): %v, want %v", err, want) } // Test fail after first row. @@ -258,10 +258,10 @@ func TestMergeSortResultFailures(t *testing.T) { results: sqltypes.MakeTestStreamingResults(idFields, "1"), sendErr: errors.New("fail after first row"), } - err = mergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { return nil }) + err = MergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { return nil }) want = "fail after first row" if err == nil || err.Error() != want { - t.Errorf("mergeSort(): %v, want %v", err, want) + t.Errorf("MergeSort(): %v, want %v", err, want) } } @@ -288,13 +288,13 @@ func TestMergeSortDataFailures(t *testing.T) { } bvs := []map[string]*querypb.BindVariable{nil, nil} - err := mergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { return nil }) + err := MergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { return nil }) want := `strconv.ParseInt: parsing "2.1": invalid syntax` if err == nil || err.Error() != want { - t.Errorf("mergeSort(): %v, want %v", err, want) + t.Errorf("MergeSort(): %v, want %v", err, want) } - // Create a new VCursor because the previous mergeSort will still + // Create a new VCursor because the previous MergeSort will still // have lingering goroutines that can cause data race. vc = &streamVCursor{ shardResults: map[string]*shardResult{ @@ -307,10 +307,10 @@ func TestMergeSortDataFailures(t *testing.T) { )}, }, } - err = mergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { return nil }) + err = MergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { return nil }) want = `strconv.ParseInt: parsing "1.1": invalid syntax` if err == nil || err.Error() != want { - t.Errorf("mergeSort(): %v, want %v", err, want) + t.Errorf("MergeSort(): %v, want %v", err, want) } } diff --git a/go/vt/vtgate/engine/route.go b/go/vt/vtgate/engine/route.go index 4b62d766a74..2ad95038820 100644 --- a/go/vt/vtgate/engine/route.go +++ b/go/vt/vtgate/engine/route.go @@ -331,7 +331,7 @@ func (route *Route) StreamExecute(vcursor VCursor, bindVars map[string]*querypb. }) } - return mergeSort(vcursor, route.Query, route.OrderBy, rss, bvs, func(qr *sqltypes.Result) error { + return MergeSort(vcursor, route.Query, route.OrderBy, rss, bvs, func(qr *sqltypes.Result) error { return callback(qr.Truncate(route.TruncateColumnCount)) }) } diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index 10e5ac5395c..11a4665b7a8 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -35,7 +35,9 @@ import ( querypb "vitess.io/vitess/go/vt/proto/query" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/srvtopo" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" @@ -330,7 +332,7 @@ func (df *vdiff) selectTablets(ctx context.Context) error { return err2 } -func (df *vdiff) startStreams(ctx context.Context, participans map[string]*dfParams, query string) error { +func (df *vdiff) startQueryStreams(ctx context.Context, participans map[string]*dfParams, query string) error { err := df.forAll(participans, func(shard string, participant *dfParams) error { // Iteration for each participant. if err := df.mi.wr.tmc.WaitForPosition(ctx, participant.tablet, mysql.EncodePosition(participant.position)); err != nil { @@ -454,6 +456,106 @@ func (df *vdiff) forAll(participants map[string]*dfParams, f func(string, *dfPar return allErrors.AggrError(vterrors.Aggregate) } +var _ engine.VCursor = (*resultReader)(nil) + +// resultReader performs a merge-sorted read from the participants. +type resultReader struct { + ctx context.Context + cancel func() + participants map[string]*dfParams + orderBy []engine.OrderbyParams + result chan *sqltypes.Result +} + +func newResultReader(ctx context.Context, participants map[string]*dfParams, orderBy []engine.OrderbyParams) *resultReader { + ctx, cancel := context.WithCancel(ctx) + rr := &resultReader{ + ctx: ctx, + cancel: cancel, + participants: participants, + orderBy: orderBy, + result: make(chan *sqltypes.Result, 1), + } + rss := make([]*srvtopo.ResolvedShard, 0, len(participants)) + for shard := range participants { + rss = append(rss, &srvtopo.ResolvedShard{ + Target: &querypb.Target{ + Shard: shard, + }, + }) + } + go engine.MergeSort(rr, "", rr.orderBy, rss, nil, func(qr *sqltypes.Result) error { + select { + case rr.result <- qr: + case <-rr.ctx.Done(): + return io.EOF + } + return nil + }) + return rr +} + +func (rr *resultReader) Next() (*sqltypes.Result, error) { + select { + case qr := <-rr.result: + return qr, nil + case <-rr.ctx.Done(): + return nil, io.EOF + } +} + +func (rr *resultReader) Close() { + rr.cancel() +} + +func (rr *resultReader) Context() context.Context { + return nil +} + +func (rr *resultReader) MaxMemoryRows() int { + return 0 +} + +func (rr *resultReader) SetContextTimeout(timeout time.Duration) context.CancelFunc { + return nil +} + +func (rr *resultReader) RecordWarning(warning *querypb.QueryWarning) { +} + +func (rr *resultReader) Execute(method string, query string, bindvars map[string]*querypb.BindVariable, isDML bool, co vtgatepb.CommitOrder) (*sqltypes.Result, error) { + return nil, nil +} + +func (rr *resultReader) AutocommitApproval() bool { + return false +} + +func (rr *resultReader) ExecuteMultiShard(rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, isDML, canAutocommit bool) (*sqltypes.Result, []error) { + return nil, nil +} + +func (rr *resultReader) ExecuteStandalone(query string, bindvars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard) (*sqltypes.Result, error) { + return nil, nil +} + +func (rr *resultReader) StreamExecuteMulti(query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, callback func(reply *sqltypes.Result) error) error { + for result := range rr.participants[rss[0].Target.Shard].result { + if err := callback(result); err != nil { + return err + } + } + return rr.participants[rss[0].Target.Shard].err +} + +func (rr *resultReader) ExecuteKeyspaceID(keyspace string, ksid []byte, query string, bindVars map[string]*querypb.BindVariable, isDML, autocommit bool) (*sqltypes.Result, error) { + return nil, nil +} + +func (rr *resultReader) ResolveDestinations(keyspace string, ids []*querypb.Value, destinations []key.Destination) ([]*srvtopo.ResolvedShard, [][]*querypb.Value, error) { + return nil, nil, nil +} + func removeKeyrange(where *sqlparser.Where) *sqlparser.Where { if where == nil { return nil From 798fedbb385e657e162a24c91c74b74bd8ccd7f5 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 12 Oct 2019 12:58:16 -0700 Subject: [PATCH 17/28] vdiff: diff function Signed-off-by: Sugu Sougoumarane --- go/vt/wrangler/vdiff.go | 198 ++++++++++++++++++++++++++++++++-------- 1 file changed, 161 insertions(+), 37 deletions(-) diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index 11a4665b7a8..d680d374339 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -18,7 +18,6 @@ package wrangler import ( "fmt" - "io" "strings" "sync" "time" @@ -60,7 +59,14 @@ type tableDiffer struct { targetExpression string sourceExpression string compareCols []int + comparePKs []int orderBy []engine.OrderbyParams + + processedRows int + matchingRows int + mismatchedRows int + extraRowsSource int + extraRowsTarget int } type dfParams struct { @@ -213,6 +219,9 @@ func buildDifferPlan(table *tabletmanagerdatapb.TableDefinition, query string) ( colname := selExpr.(*sqlparser.AliasedExpr).Expr.(*sqlparser.ColName).Name.Lowered() if pk == colname { td.orderBy = append(td.orderBy, engine.OrderbyParams{Col: td.compareCols[i]}) + td.comparePKs = append(td.comparePKs, td.compareCols[i]) + // We'll be comparing pks seperately. So, remove them from compareCols. + td.compareCols[i] = -1 found = true break } @@ -394,7 +403,7 @@ func (df *vdiff) streamOne(ctx context.Context, shard string, participant *dfPar select { case participant.result <- result: case <-ctx.Done(): - return io.EOF + return fmt.Errorf("VStreamResults: %v", ctx.Err()) } return nil }) @@ -460,18 +469,15 @@ var _ engine.VCursor = (*resultReader)(nil) // resultReader performs a merge-sorted read from the participants. type resultReader struct { - ctx context.Context - cancel func() participants map[string]*dfParams orderBy []engine.OrderbyParams + rows [][]sqltypes.Value result chan *sqltypes.Result + err error } func newResultReader(ctx context.Context, participants map[string]*dfParams, orderBy []engine.OrderbyParams) *resultReader { - ctx, cancel := context.WithCancel(ctx) rr := &resultReader{ - ctx: ctx, - cancel: cancel, participants: participants, orderBy: orderBy, result: make(chan *sqltypes.Result, 1), @@ -484,52 +490,66 @@ func newResultReader(ctx context.Context, participants map[string]*dfParams, ord }, }) } - go engine.MergeSort(rr, "", rr.orderBy, rss, nil, func(qr *sqltypes.Result) error { - select { - case rr.result <- qr: - case <-rr.ctx.Done(): - return io.EOF - } - return nil - }) + go func() { + defer close(rr.result) + + rr.err = engine.MergeSort(rr, "", rr.orderBy, rss, nil, func(qr *sqltypes.Result) error { + select { + case rr.result <- qr: + case <-ctx.Done(): + return fmt.Errorf("MergeSort: %v", ctx.Err()) + } + return nil + }) + }() return rr } -func (rr *resultReader) Next() (*sqltypes.Result, error) { - select { - case qr := <-rr.result: - return qr, nil - case <-rr.ctx.Done(): - return nil, io.EOF +func (rr *resultReader) next(ctx context.Context) ([]sqltypes.Value, error) { + for len(rr.rows) == 0 { + select { + case qr, ok := <-rr.result: + if !ok { + return nil, rr.err + } + rr.rows = qr.Rows + case <-ctx.Done(): + return nil, fmt.Errorf("next: %v", ctx.Err()) + } } -} -func (rr *resultReader) Close() { - rr.cancel() + row := rr.rows[0] + rr.rows = rr.rows[1:] + return row, nil } -func (rr *resultReader) Context() context.Context { - return nil +func (rr *resultReader) drain(ctx context.Context) (int, error) { + count := 0 + for { + row, err := rr.next(ctx) + if err != nil { + return 0, err + } + if row == nil { + return count, nil + } + count++ + } } -func (rr *resultReader) MaxMemoryRows() int { - return 0 -} +func (rr *resultReader) Context() context.Context { return nil } -func (rr *resultReader) SetContextTimeout(timeout time.Duration) context.CancelFunc { - return nil -} +func (rr *resultReader) MaxMemoryRows() int { return 0 } -func (rr *resultReader) RecordWarning(warning *querypb.QueryWarning) { -} +func (rr *resultReader) SetContextTimeout(timeout time.Duration) context.CancelFunc { return nil } + +func (rr *resultReader) RecordWarning(warning *querypb.QueryWarning) {} func (rr *resultReader) Execute(method string, query string, bindvars map[string]*querypb.BindVariable, isDML bool, co vtgatepb.CommitOrder) (*sqltypes.Result, error) { return nil, nil } -func (rr *resultReader) AutocommitApproval() bool { - return false -} +func (rr *resultReader) AutocommitApproval() bool { return false } func (rr *resultReader) ExecuteMultiShard(rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, isDML, canAutocommit bool) (*sqltypes.Result, []error) { return nil, nil @@ -556,6 +576,110 @@ func (rr *resultReader) ResolveDestinations(keyspace string, ids []*querypb.Valu return nil, nil, nil } +func (td *tableDiffer) diff(ctx context.Context, wr *Wrangler, source, target *resultReader) error { + var sourceRow, targetRow []sqltypes.Value + var err error + advanceSource := true + advanceTarget := true + for { + if advanceSource { + sourceRow, err = source.next(ctx) + if err != nil { + return err + } + advanceSource = false + } + if advanceTarget { + targetRow, err = target.next(ctx) + if err != nil { + return err + } + advanceTarget = false + } + td.processedRows++ + if sourceRow == nil { + // no more rows from the source + if targetRow == nil { + // no more rows from target either, we're done + return nil + } + + // drain target, update count + wr.Logger().Errorf("Draining extra row(s) found on the target starting with: %v", targetRow) + count, err := target.drain(ctx) + if err != nil { + return err + } + td.extraRowsTarget += 1 + count + return nil + } + if targetRow == nil { + // no more rows from the target + // we know we have rows from source, drain, update count + wr.Logger().Errorf("Draining extra row(s) found on the source starting with: %v", sourceRow) + count, err := source.drain(ctx) + if err != nil { + return err + } + td.extraRowsSource += 1 + count + return nil + } + + // Compare pk values. + c, err := td.compare(sourceRow, targetRow, td.comparePKs) + switch { + case err != nil: + return err + case c < 0: + if td.extraRowsSource < 10 { + wr.Logger().Errorf("[table=%v] Extra row %v on source: %v", td.targetTable, td.extraRowsSource, sourceRow) + } + td.extraRowsSource++ + advanceSource = true + continue + case c > 0: + if td.extraRowsTarget < 10 { + wr.Logger().Errorf("[table=%v] Extra row %v on target: %v", td.targetTable, td.extraRowsTarget, targetRow) + } + td.extraRowsTarget++ + advanceTarget = true + continue + } + + // c == 0 + advanceSource = true + advanceTarget = true + + // Compare non-pk values. + c, err = td.compare(sourceRow, targetRow, td.compareCols) + switch { + case err != nil: + return err + case c != 0: + if td.mismatchedRows < 10 { + wr.Logger().Errorf("[table=%v] Different content %v in same PK: %v != %v", td.targetTable, td.mismatchedRows, sourceRow, targetRow) + } + td.mismatchedRows++ + } + } +} + +func (td *tableDiffer) compare(sourceRow, targetRow []sqltypes.Value, cols []int) (int, error) { + for _, col := range cols { + if col == -1 { + continue + } + c, err := sqltypes.NullsafeCompare(sourceRow[col], targetRow[col]) + if err != nil { + return 0, err + } + if c != 0 { + return c, nil + } + } + return 0, nil +} + func removeKeyrange(where *sqlparser.Where) *sqlparser.Where { if where == nil { return nil From 8e231daa4937444aae20c3aad7c448fae7a0bfd1 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 12 Oct 2019 17:37:28 -0700 Subject: [PATCH 18/28] vdiff: main function and start of testing Signed-off-by: Sugu Sougoumarane --- go/vt/wrangler/vdiff.go | 244 +++++++++++++++++++++-------------- go/vt/wrangler/vdiff_test.go | 92 +++++++++++-- 2 files changed, 224 insertions(+), 112 deletions(-) diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index d680d374339..78c16c68100 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -44,6 +44,15 @@ import ( "vitess.io/vitess/go/vt/vttablet/tabletmanager/vreplication" ) +// DiffSummary is the summary of differences for one table. +type DiffSummary struct { + ProcessedRows int + MatchingRows int + MismatchedRows int + ExtraRowsSource int + ExtraRowsTarget int +} + type vdiff struct { mi *migrater sourceCell string @@ -56,17 +65,10 @@ type vdiff struct { type tableDiffer struct { targetTable string - targetExpression string sourceExpression string + targetExpression string compareCols []int comparePKs []int - orderBy []engine.OrderbyParams - - processedRows int - matchingRows int - mismatchedRows int - extraRowsSource int - extraRowsTarget int } type dfParams struct { @@ -119,7 +121,40 @@ func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow, sourceC return err } df.differs, err = buildVDiffPlan(ctx, oneFilter, schm) - return err + if err != nil { + return err + } + if err := df.selectTablets(ctx); err != nil { + return err + } + ctx, cancel := context.WithCancel(ctx) + defer cancel() + // TODO(sougou): parallelize + for _, td := range df.differs { + if err := df.stopTargetStreams(ctx); err != nil { + return err + } + sourceReader, err := df.startQueryStreams(ctx, df.sources, td.sourceExpression, td.orderbyParams()) + if err != nil { + return err + } + if err := df.syncTargets(ctx); err != nil { + return err + } + targetReader, err := df.startQueryStreams(ctx, df.targets, td.targetExpression, td.orderbyParams()) + if err != nil { + return err + } + if err := df.restartTargets(ctx); err != nil { + return err + } + dr, err := td.diff(ctx, df.mi.wr, sourceReader, targetReader) + if err != nil { + return err + } + fmt.Printf("Summary for %v: %+v\n", td.targetTable, dr) + } + return nil } func buildVDiffPlan(ctx context.Context, filter *binlogdatapb.Filter, schm *tabletmanagerdatapb.SchemaDefinition) (map[string]*tableDiffer, error) { @@ -190,7 +225,7 @@ func buildDifferPlan(table *tabletmanagerdatapb.TableDefinition, query string) ( td.compareCols = make([]int, len(sourceSelect.SelectExprs)) for i := range td.compareCols { - colname := sourceSelect.SelectExprs[i].(*sqlparser.AliasedExpr).Expr.(*sqlparser.ColName).Name.Lowered() + colname := targetSelect.SelectExprs[i].(*sqlparser.AliasedExpr).Expr.(*sqlparser.ColName).Name.Lowered() typ, ok := fields[colname] if !ok { return nil, fmt.Errorf("column %v not found in table %v", colname, table.Name) @@ -218,7 +253,6 @@ func buildDifferPlan(table *tabletmanagerdatapb.TableDefinition, query string) ( for i, selExpr := range targetSelect.SelectExprs { colname := selExpr.(*sqlparser.AliasedExpr).Expr.(*sqlparser.ColName).Name.Lowered() if pk == colname { - td.orderBy = append(td.orderBy, engine.OrderbyParams{Col: td.compareCols[i]}) td.comparePKs = append(td.comparePKs, td.compareCols[i]) // We'll be comparing pks seperately. So, remove them from compareCols. td.compareCols[i] = -1 @@ -230,7 +264,10 @@ func buildDifferPlan(table *tabletmanagerdatapb.TableDefinition, query string) ( // Unreachable. return nil, fmt.Errorf("column %v not found in table %v", pk, table.Name) } - orderby = append(orderby, &sqlparser.Order{Expr: &sqlparser.ColName{Name: sqlparser.NewColIdent(pk)}}) + orderby = append(orderby, &sqlparser.Order{ + Expr: &sqlparser.ColName{Name: sqlparser.NewColIdent(pk)}, + Direction: sqlparser.AscScr, + }) } targetSelect.OrderBy = orderby @@ -243,54 +280,6 @@ func buildDifferPlan(table *tabletmanagerdatapb.TableDefinition, query string) ( return td, nil } -func (df *vdiff) stopTargetStreams(ctx context.Context) error { - var mu sync.Mutex - - err := df.forAll(df.targets, func(shard string, target *dfParams) error { - query := fmt.Sprintf("update _vt.vreplication set state='Stopped', message='for vdiff' where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.mi.workflow)) - _, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) - if err != nil { - return err - } - query = fmt.Sprintf("select source, pos from _vt.vreplication where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.mi.workflow)) - p3qr, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) - if err != nil { - return err - } - qr := sqltypes.Proto3ToResult(p3qr) - - for _, row := range qr.Rows { - var bls binlogdatapb.BinlogSource - if err := proto.UnmarshalText(row[0].ToString(), &bls); err != nil { - return err - } - pos, err := mysql.DecodePosition(row[1].ToString()) - if err != nil { - return err - } - func() { - mu.Lock() - defer mu.Unlock() - - source, ok := df.sources[bls.Shard] - if !ok { - // Unreachable. - return - } - if !source.position.IsZero() && source.position.AtLeast(pos) { - return - } - source.position = pos - }() - } - return nil - }) - if err != nil { - return err - } - return nil -} - func (df *vdiff) selectTablets(ctx context.Context) error { var wg sync.WaitGroup var err1, err2 error @@ -341,8 +330,56 @@ func (df *vdiff) selectTablets(ctx context.Context) error { return err2 } -func (df *vdiff) startQueryStreams(ctx context.Context, participans map[string]*dfParams, query string) error { - err := df.forAll(participans, func(shard string, participant *dfParams) error { +func (df *vdiff) stopTargetStreams(ctx context.Context) error { + var mu sync.Mutex + + err := df.forAll(df.targets, func(shard string, target *dfParams) error { + query := fmt.Sprintf("update _vt.vreplication set state='Stopped', message='for vdiff' where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.mi.workflow)) + _, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) + if err != nil { + return err + } + query = fmt.Sprintf("select source, pos from _vt.vreplication where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.mi.workflow)) + p3qr, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) + if err != nil { + return err + } + qr := sqltypes.Proto3ToResult(p3qr) + + for _, row := range qr.Rows { + var bls binlogdatapb.BinlogSource + if err := proto.UnmarshalText(row[0].ToString(), &bls); err != nil { + return err + } + pos, err := mysql.DecodePosition(row[1].ToString()) + if err != nil { + return err + } + func() { + mu.Lock() + defer mu.Unlock() + + source, ok := df.sources[bls.Shard] + if !ok { + // Unreachable. + return + } + if !source.position.IsZero() && source.position.AtLeast(pos) { + return + } + source.position = pos + }() + } + return nil + }) + if err != nil { + return err + } + return nil +} + +func (df *vdiff) startQueryStreams(ctx context.Context, participants map[string]*dfParams, query string, orderBy []engine.OrderbyParams) (*resultReader, error) { + err := df.forAll(participants, func(shard string, participant *dfParams) error { // Iteration for each participant. if err := df.mi.wr.tmc.WaitForPosition(ctx, participant.tablet, mysql.EncodePosition(participant.position)); err != nil { return err @@ -363,7 +400,10 @@ func (df *vdiff) startQueryStreams(ctx context.Context, participans map[string]* participant.snapshotPosition = gtid return nil }) - return err + if err != nil { + return nil, err + } + return newResultReader(ctx, participants, orderBy), nil } // streamOne is called as a goroutine, and communicates its results through channels. @@ -470,7 +510,6 @@ var _ engine.VCursor = (*resultReader)(nil) // resultReader performs a merge-sorted read from the participants. type resultReader struct { participants map[string]*dfParams - orderBy []engine.OrderbyParams rows [][]sqltypes.Value result chan *sqltypes.Result err error @@ -479,7 +518,6 @@ type resultReader struct { func newResultReader(ctx context.Context, participants map[string]*dfParams, orderBy []engine.OrderbyParams) *resultReader { rr := &resultReader{ participants: participants, - orderBy: orderBy, result: make(chan *sqltypes.Result, 1), } rss := make([]*srvtopo.ResolvedShard, 0, len(participants)) @@ -493,7 +531,7 @@ func newResultReader(ctx context.Context, participants map[string]*dfParams, ord go func() { defer close(rr.result) - rr.err = engine.MergeSort(rr, "", rr.orderBy, rss, nil, func(qr *sqltypes.Result) error { + rr.err = engine.MergeSort(rr, "", orderBy, rss, nil, func(qr *sqltypes.Result) error { select { case rr.result <- qr: case <-ctx.Done(): @@ -576,90 +614,90 @@ func (rr *resultReader) ResolveDestinations(keyspace string, ids []*querypb.Valu return nil, nil, nil } -func (td *tableDiffer) diff(ctx context.Context, wr *Wrangler, source, target *resultReader) error { +func (td *tableDiffer) diff(ctx context.Context, wr *Wrangler, sourceReader, targetReader *resultReader) (*DiffSummary, error) { + dr := &DiffSummary{} var sourceRow, targetRow []sqltypes.Value var err error advanceSource := true advanceTarget := true for { if advanceSource { - sourceRow, err = source.next(ctx) + sourceRow, err = sourceReader.next(ctx) if err != nil { - return err + return nil, err } - advanceSource = false } if advanceTarget { - targetRow, err = target.next(ctx) + targetRow, err = targetReader.next(ctx) if err != nil { - return err + return nil, err } - advanceTarget = false } - td.processedRows++ + + advanceSource = true + advanceTarget = true + + dr.ProcessedRows++ if sourceRow == nil { // no more rows from the source if targetRow == nil { // no more rows from target either, we're done - return nil + return dr, nil } // drain target, update count wr.Logger().Errorf("Draining extra row(s) found on the target starting with: %v", targetRow) - count, err := target.drain(ctx) + count, err := targetReader.drain(ctx) if err != nil { - return err + return nil, err } - td.extraRowsTarget += 1 + count - return nil + dr.ExtraRowsTarget += 1 + count + return dr, nil } if targetRow == nil { // no more rows from the target // we know we have rows from source, drain, update count wr.Logger().Errorf("Draining extra row(s) found on the source starting with: %v", sourceRow) - count, err := source.drain(ctx) + count, err := sourceReader.drain(ctx) if err != nil { - return err + return nil, err } - td.extraRowsSource += 1 + count - return nil + dr.ExtraRowsSource += 1 + count + return dr, nil } // Compare pk values. c, err := td.compare(sourceRow, targetRow, td.comparePKs) switch { case err != nil: - return err + return nil, err case c < 0: - if td.extraRowsSource < 10 { - wr.Logger().Errorf("[table=%v] Extra row %v on source: %v", td.targetTable, td.extraRowsSource, sourceRow) + if dr.ExtraRowsSource < 10 { + wr.Logger().Errorf("[table=%v] Extra row %v on source: %v", td.targetTable, dr.ExtraRowsSource, sourceRow) } - td.extraRowsSource++ - advanceSource = true + dr.ExtraRowsSource++ + advanceTarget = false continue case c > 0: - if td.extraRowsTarget < 10 { - wr.Logger().Errorf("[table=%v] Extra row %v on target: %v", td.targetTable, td.extraRowsTarget, targetRow) + if dr.ExtraRowsTarget < 10 { + wr.Logger().Errorf("[table=%v] Extra row %v on target: %v", td.targetTable, dr.ExtraRowsTarget, targetRow) } - td.extraRowsTarget++ - advanceTarget = true + dr.ExtraRowsTarget++ + advanceSource = false continue } // c == 0 - advanceSource = true - advanceTarget = true - // Compare non-pk values. c, err = td.compare(sourceRow, targetRow, td.compareCols) switch { case err != nil: - return err + return nil, err case c != 0: - if td.mismatchedRows < 10 { - wr.Logger().Errorf("[table=%v] Different content %v in same PK: %v != %v", td.targetTable, td.mismatchedRows, sourceRow, targetRow) + if dr.MismatchedRows < 10 { + wr.Logger().Errorf("[table=%v] Different content %v in same PK: %v != %v", td.targetTable, dr.MismatchedRows, sourceRow, targetRow) } - td.mismatchedRows++ + dr.MismatchedRows++ } } } @@ -680,6 +718,14 @@ func (td *tableDiffer) compare(sourceRow, targetRow []sqltypes.Value, cols []int return 0, nil } +func (td *tableDiffer) orderbyParams() []engine.OrderbyParams { + ob := make([]engine.OrderbyParams, 0, len(td.comparePKs)) + for _, col := range td.comparePKs { + ob = append(ob, engine.OrderbyParams{Col: col}) + } + return ob +} + func removeKeyrange(where *sqlparser.Where) *sqlparser.Where { if where == nil { return nil diff --git a/go/vt/wrangler/vdiff_test.go b/go/vt/wrangler/vdiff_test.go index 177561c0c53..8311ead63a6 100644 --- a/go/vt/wrangler/vdiff_test.go +++ b/go/vt/wrangler/vdiff_test.go @@ -17,23 +17,17 @@ limitations under the License. package wrangler import ( - "fmt" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "golang.org/x/net/context" "vitess.io/vitess/go/sqltypes" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" ) -func TestVDiffPlan(t *testing.T) { - filter := &binlogdatapb.Filter{ - Rules: []*binlogdatapb.Rule{{ - Match: "t1", - Filter: fmt.Sprintf("select * from t1 where in_keyrange('-80')"), - }}, - } - +func TestVDiffPlanSuccess(t *testing.T) { schm := &tabletmanagerdatapb.SchemaDefinition{ TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ Name: "t1", @@ -42,9 +36,81 @@ func TestVDiffPlan(t *testing.T) { Fields: sqltypes.MakeTestFields("c1|c2", "int64|int64"), }}, } - differs, err := buildVDiffPlan(context.Background(), filter, schm) - if err != nil { - t.Fatal(err) + + testcases := []struct { + input *binlogdatapb.Rule + table string + td *tableDiffer + }{{ + input: &binlogdatapb.Rule{ + Match: "t1", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c1, c2 from t1 order by c1 asc", + targetExpression: "select c1, c2 from t1 order by c1 asc", + compareCols: []int{-1, 1}, + comparePKs: []int{0}, + }, + }, { + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "-80", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c1, c2 from t1 order by c1 asc", + targetExpression: "select c1, c2 from t1 order by c1 asc", + compareCols: []int{-1, 1}, + comparePKs: []int{0}, + }, + }, { + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select * from t1", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c1, c2 from t1 order by c1 asc", + targetExpression: "select c1, c2 from t1 order by c1 asc", + compareCols: []int{-1, 1}, + comparePKs: []int{0}, + }, + }, { + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select c2, c1 from t1", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c2, c1 from t1 order by c1 asc", + targetExpression: "select c2, c1 from t1 order by c1 asc", + compareCols: []int{0, -1}, + comparePKs: []int{1}, + }, + }, { + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select c0 as c1, c2 from t2", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c0 as c1, c2 from t2 order by c1 asc", + targetExpression: "select c1, c2 from t1 order by c1 asc", + compareCols: []int{-1, 1}, + comparePKs: []int{0}, + }, + }} + for _, tcase := range testcases { + filter := &binlogdatapb.Filter{Rules: []*binlogdatapb.Rule{tcase.input}} + differs, err := buildVDiffPlan(context.Background(), filter, schm) + require.NoError(t, err, tcase.input) + require.Equal(t, 1, len(differs), tcase.input) + assert.Equal(t, tcase.td, differs[tcase.table], tcase.input) } - fmt.Printf("%+v\n", differs["t1"]) } From 65a0051333925c2bdb2869b2f680943be5c380f7 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 12 Oct 2019 21:22:12 -0700 Subject: [PATCH 19/28] vdiff: all plan builder tests Signed-off-by: Sugu Sougoumarane --- go/vt/wrangler/vdiff.go | 10 +- go/vt/wrangler/vdiff_test.go | 191 +++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+), 4 deletions(-) diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index 78c16c68100..470c25a6e21 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -131,7 +131,7 @@ func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow, sourceC defer cancel() // TODO(sougou): parallelize for _, td := range df.differs { - if err := df.stopTargetStreams(ctx); err != nil { + if err := df.stopTargets(ctx); err != nil { return err } sourceReader, err := df.startQueryStreams(ctx, df.sources, td.sourceExpression, td.orderbyParams()) @@ -216,6 +216,8 @@ func buildDifferPlan(table *tabletmanagerdatapb.TableDefinition, query string) ( } sourceSelect.SelectExprs = append(sourceSelect.SelectExprs, selExpr) targetSelect.SelectExprs = append(targetSelect.SelectExprs, &sqlparser.AliasedExpr{Expr: targetCol}) + default: + return nil, fmt.Errorf("unexpected: %v", sqlparser.String(statement)) } } fields := make(map[string]querypb.Type) @@ -269,12 +271,12 @@ func buildDifferPlan(table *tabletmanagerdatapb.TableDefinition, query string) ( Direction: sqlparser.AscScr, }) } - targetSelect.OrderBy = orderby - sourceSelect.Where = removeKeyrange(sel.Where) sourceSelect.GroupBy = sel.GroupBy sourceSelect.OrderBy = orderby + targetSelect.OrderBy = orderby + td.sourceExpression = sqlparser.String(sourceSelect) td.targetExpression = sqlparser.String(targetSelect) return td, nil @@ -330,7 +332,7 @@ func (df *vdiff) selectTablets(ctx context.Context) error { return err2 } -func (df *vdiff) stopTargetStreams(ctx context.Context) error { +func (df *vdiff) stopTargets(ctx context.Context) error { var mu sync.Mutex err := df.forAll(df.targets, func(shard string, target *dfParams) error { diff --git a/go/vt/wrangler/vdiff_test.go b/go/vt/wrangler/vdiff_test.go index 8311ead63a6..28502f7be16 100644 --- a/go/vt/wrangler/vdiff_test.go +++ b/go/vt/wrangler/vdiff_test.go @@ -34,6 +34,21 @@ func TestVDiffPlanSuccess(t *testing.T) { Columns: []string{"c1", "c2"}, PrimaryKeyColumns: []string{"c1"}, Fields: sqltypes.MakeTestFields("c1|c2", "int64|int64"), + }, { + Name: "nonpktext", + Columns: []string{"c1", "textcol"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|textcol", "int64|varchar"), + }, { + Name: "pktext", + Columns: []string{"textcol", "c2"}, + PrimaryKeyColumns: []string{"textcol"}, + Fields: sqltypes.MakeTestFields("textcol|c2", "varchar|int64"), + }, { + Name: "multipk", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1", "c2"}, + Fields: sqltypes.MakeTestFields("c1|c2", "int64|int64"), }}, } @@ -105,6 +120,131 @@ func TestVDiffPlanSuccess(t *testing.T) { compareCols: []int{-1, 1}, comparePKs: []int{0}, }, + }, { + // non-pk text column. + input: &binlogdatapb.Rule{ + Match: "nonpktext", + Filter: "select c1, textcol from nonpktext", + }, + table: "nonpktext", + td: &tableDiffer{ + targetTable: "nonpktext", + sourceExpression: "select c1, textcol, weight_string(textcol) from nonpktext order by c1 asc", + targetExpression: "select c1, textcol, weight_string(textcol) from nonpktext order by c1 asc", + compareCols: []int{-1, 2}, + comparePKs: []int{0}, + }, + }, { + // non-pk text column, different order. + input: &binlogdatapb.Rule{ + Match: "nonpktext", + Filter: "select textcol, c1 from nonpktext", + }, + table: "nonpktext", + td: &tableDiffer{ + targetTable: "nonpktext", + sourceExpression: "select textcol, c1, weight_string(textcol) from nonpktext order by c1 asc", + targetExpression: "select textcol, c1, weight_string(textcol) from nonpktext order by c1 asc", + compareCols: []int{2, -1}, + comparePKs: []int{1}, + }, + }, { + // pk text column. + input: &binlogdatapb.Rule{ + Match: "pktext", + Filter: "select textcol, c2 from pktext", + }, + table: "pktext", + td: &tableDiffer{ + targetTable: "pktext", + sourceExpression: "select textcol, c2, weight_string(textcol) from pktext order by textcol asc", + targetExpression: "select textcol, c2, weight_string(textcol) from pktext order by textcol asc", + compareCols: []int{-1, 1}, + comparePKs: []int{2}, + }, + }, { + // pk text column, different order. + input: &binlogdatapb.Rule{ + Match: "pktext", + Filter: "select c2, textcol from pktext", + }, + table: "pktext", + td: &tableDiffer{ + targetTable: "pktext", + sourceExpression: "select c2, textcol, weight_string(textcol) from pktext order by textcol asc", + targetExpression: "select c2, textcol, weight_string(textcol) from pktext order by textcol asc", + compareCols: []int{0, -1}, + comparePKs: []int{2}, + }, + }, { + // text column as expression. + input: &binlogdatapb.Rule{ + Match: "pktext", + Filter: "select c2, a+b as textcol from pktext", + }, + table: "pktext", + td: &tableDiffer{ + targetTable: "pktext", + sourceExpression: "select c2, a + b as textcol, weight_string(a + b) from pktext order by textcol asc", + targetExpression: "select c2, textcol, weight_string(textcol) from pktext order by textcol asc", + compareCols: []int{0, -1}, + comparePKs: []int{2}, + }, + }, { + input: &binlogdatapb.Rule{ + Match: "multipk", + }, + table: "multipk", + td: &tableDiffer{ + targetTable: "multipk", + sourceExpression: "select c1, c2 from multipk order by c1 asc, c2 asc", + targetExpression: "select c1, c2 from multipk order by c1 asc, c2 asc", + compareCols: []int{-1, -1}, + comparePKs: []int{0, 1}, + }, + }, { + // in_keyrange + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select * from t1 where in_keyrange('-80')", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c1, c2 from t1 order by c1 asc", + targetExpression: "select c1, c2 from t1 order by c1 asc", + compareCols: []int{-1, 1}, + comparePKs: []int{0}, + }, + }, { + // in_keyrange with other expressions. + // This is currently not a valid construct, but will be supported in the future. + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select * from t1 where c2 = 2 and in_keyrange('-80')", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c1, c2 from t1 where c2 = 2 order by c1 asc", + targetExpression: "select c1, c2 from t1 order by c1 asc", + compareCols: []int{-1, 1}, + comparePKs: []int{0}, + }, + }, { + // group by + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select * from t1 group by c1", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c1, c2 from t1 group by c1 order by c1 asc", + targetExpression: "select c1, c2 from t1 order by c1 asc", + compareCols: []int{-1, 1}, + comparePKs: []int{0}, + }, }} for _, tcase := range testcases { filter := &binlogdatapb.Filter{Rules: []*binlogdatapb.Rule{tcase.input}} @@ -114,3 +254,54 @@ func TestVDiffPlanSuccess(t *testing.T) { assert.Equal(t, tcase.td, differs[tcase.table], tcase.input) } } + +func TestVDiffPlanFailure(t *testing.T) { + schm := &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ + Name: "t1", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2", "int64|int64"), + }}, + } + + testcases := []struct { + input *binlogdatapb.Rule + err string + }{{ + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "bad query", + }, + err: "syntax error at position 4 near 'bad'", + }, { + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "update t1 set c1=2", + }, + err: "unexpected: update t1 set c1 = 2", + }, { + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select c1+1 from t1", + }, + err: "expression needs an alias: c1 + 1", + }, { + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select next 2 values from t1", + }, + err: "unexpected: select next 2 values from t1", + }, { + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select c3 from t1", + }, + err: "column c3 not found in table t1", + }} + for _, tcase := range testcases { + filter := &binlogdatapb.Filter{Rules: []*binlogdatapb.Rule{tcase.input}} + _, err := buildVDiffPlan(context.Background(), filter, schm) + assert.EqualError(t, err, tcase.err, tcase.input) + } +} From 38c2ae96b2a2a4e169584830356edc83cb687e4a Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 13 Oct 2019 18:28:27 -0700 Subject: [PATCH 20/28] vdiff: test framework with a basic test Signed-off-by: Sugu Sougoumarane --- go/vt/wrangler/vdiff.go | 26 ++- go/vt/wrangler/vdiff_env_test.go | 316 +++++++++++++++++++++++++++++++ go/vt/wrangler/vdiff_test.go | 44 +++++ 3 files changed, 382 insertions(+), 4 deletions(-) create mode 100644 go/vt/wrangler/vdiff_env_test.go diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index 470c25a6e21..f5246e415d9 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -127,6 +127,11 @@ func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow, sourceC if err := df.selectTablets(ctx); err != nil { return err } + defer func() { + if err := df.restartTargets(ctx); err != nil { + wr.Logger().Errorf("Could not restart workflow %s: %v, please restart it manually", workflow, err) + } + }() ctx, cancel := context.WithCancel(ctx) defer cancel() // TODO(sougou): parallelize @@ -291,7 +296,7 @@ func (df *vdiff) selectTablets(ctx context.Context) error { go func() { defer wg.Done() err1 = df.forAll(df.sources, func(shard string, source *dfParams) error { - tp, err := discovery.NewTabletPicker(ctx, df.mi.wr.ts, df.targetCell, df.mi.targetKeyspace, shard, df.tabletTypesStr) + tp, err := discovery.NewTabletPicker(ctx, df.mi.wr.ts, df.sourceCell, df.mi.sourceKeyspace, shard, df.tabletTypesStr) if err != nil { return err } @@ -442,6 +447,9 @@ func (df *vdiff) streamOne(ctx context.Context, shard string, participant *dfPar Rows: vrs.Rows, } result := sqltypes.Proto3ToResult(p3qr) + if vrs.Fields == nil { + result.Fields = nil + } select { case participant.result <- result: case <-ctx.Done(): @@ -511,6 +519,7 @@ var _ engine.VCursor = (*resultReader)(nil) // resultReader performs a merge-sorted read from the participants. type resultReader struct { + ctx context.Context participants map[string]*dfParams rows [][]sqltypes.Value result chan *sqltypes.Result @@ -519,21 +528,24 @@ type resultReader struct { func newResultReader(ctx context.Context, participants map[string]*dfParams, orderBy []engine.OrderbyParams) *resultReader { rr := &resultReader{ + ctx: ctx, participants: participants, result: make(chan *sqltypes.Result, 1), } rss := make([]*srvtopo.ResolvedShard, 0, len(participants)) + bvs := make([]map[string]*querypb.BindVariable, 0, len(participants)) for shard := range participants { rss = append(rss, &srvtopo.ResolvedShard{ Target: &querypb.Target{ Shard: shard, }, }) + bvs = append(bvs, make(map[string]*querypb.BindVariable)) } go func() { defer close(rr.result) - rr.err = engine.MergeSort(rr, "", orderBy, rss, nil, func(qr *sqltypes.Result) error { + rr.err = engine.MergeSort(rr, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { select { case rr.result <- qr: case <-ctx.Done(): @@ -577,7 +589,9 @@ func (rr *resultReader) drain(ctx context.Context) (int, error) { } } -func (rr *resultReader) Context() context.Context { return nil } +func (rr *resultReader) Context() context.Context { + return rr.ctx +} func (rr *resultReader) MaxMemoryRows() int { return 0 } @@ -639,7 +653,6 @@ func (td *tableDiffer) diff(ctx context.Context, wr *Wrangler, sourceReader, tar advanceSource = true advanceTarget = true - dr.ProcessedRows++ if sourceRow == nil { // no more rows from the source if targetRow == nil { @@ -668,6 +681,9 @@ func (td *tableDiffer) diff(ctx context.Context, wr *Wrangler, sourceReader, tar return dr, nil } + // We have rows to process on both sides. + dr.ProcessedRows++ + // Compare pk values. c, err := td.compare(sourceRow, targetRow, td.comparePKs) switch { @@ -700,6 +716,8 @@ func (td *tableDiffer) diff(ctx context.Context, wr *Wrangler, sourceReader, tar wr.Logger().Errorf("[table=%v] Different content %v in same PK: %v != %v", td.targetTable, dr.MismatchedRows, sourceRow, targetRow) } dr.MismatchedRows++ + default: + dr.MatchingRows++ } } } diff --git a/go/vt/wrangler/vdiff_env_test.go b/go/vt/wrangler/vdiff_env_test.go new file mode 100644 index 00000000000..4052a8cc7f5 --- /dev/null +++ b/go/vt/wrangler/vdiff_env_test.go @@ -0,0 +1,316 @@ +/* +Copyright 2019 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package wrangler + +import ( + "flag" + "fmt" + + "golang.org/x/net/context" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/grpcclient" + "vitess.io/vitess/go/vt/logutil" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + querypb "vitess.io/vitess/go/vt/proto/query" + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/memorytopo" + "vitess.io/vitess/go/vt/vttablet/queryservice" + "vitess.io/vitess/go/vt/vttablet/queryservice/fakes" + "vitess.io/vitess/go/vt/vttablet/tabletconn" + "vitess.io/vitess/go/vt/vttablet/tmclient" +) + +const ( + // vdiffStopPosition is the default stop position for the target vreplication. + // It can be overridden with the positons argument to newTestVDiffEnv. + vdiffStopPosition = "MariaDB/5-456-892" + // vdiffSourceGtid should be the position reported by the source side VStreamResults. + // It's expected to be higher the vdiffStopPosition. + vdiffSourceGtid = "MariaDB/5-456-893" + // vdiffTargetMasterPosition is the master position of the target after + // vreplication has been synchronized. + vdiffTargetMasterPosition = "MariaDB/6-456-892" +) + +type testVDiffEnv struct { + wr *Wrangler + workflow string + tablets map[int]*testVDiffTablet + topoServ *topo.Server + cell string + tabletType topodatapb.TabletType + tmc *testVDiffTMClient +} + +// vdiffEnv has to be a global for RegisterDialer to work. +var vdiffEnv *testVDiffEnv + +func init() { + tabletconn.RegisterDialer("VDiffTest", func(tablet *topodatapb.Tablet, failFast grpcclient.FailFast) (queryservice.QueryService, error) { + return vdiffEnv.tablets[int(tablet.Alias.Uid)], nil + }) +} + +//---------------------------------------------- +// testVDiffEnv + +func newTestVDiffEnv(sourceShards, targetShards []string, query string, positions map[string]string) *testVDiffEnv { + flag.Set("tablet_protocol", "VDiffTest") + env := &testVDiffEnv{ + workflow: "vdiffTest", + tablets: make(map[int]*testVDiffTablet), + topoServ: memorytopo.NewServer("cell"), + cell: "cell", + tabletType: topodatapb.TabletType_REPLICA, + tmc: newTestVDiffTMClient(), + } + env.wr = New(logutil.NewConsoleLogger(), env.topoServ, env.tmc) + + tabletID := 100 + for _, shard := range sourceShards { + _ = env.addTablet(tabletID, "source", shard, topodatapb.TabletType_MASTER) + _ = env.addTablet(tabletID+1, "source", shard, topodatapb.TabletType_REPLICA) + env.tmc.waitpos[tabletID+1] = vdiffStopPosition + + tabletID += 10 + } + tabletID = 200 + for _, shard := range targetShards { + master := env.addTablet(tabletID, "target", shard, topodatapb.TabletType_MASTER) + _ = env.addTablet(tabletID+1, "target", shard, topodatapb.TabletType_REPLICA) + + var rows []string + var posRows []string + for j, sourceShard := range sourceShards { + bls := &binlogdatapb.BinlogSource{ + Keyspace: "source", + Shard: sourceShard, + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: query, + }}, + }, + } + rows = append(rows, fmt.Sprintf("%d|%v|", j+1, bls)) + position := vdiffStopPosition + if pos := positions[sourceShard+shard]; pos != "" { + position = pos + } + posRows = append(posRows, fmt.Sprintf("%v|%s", bls, position)) + + // vdiff.syncTargets. This actually happens after stopTargets. + // But this is one statement per stream. + env.tmc.setVRResults( + master.tablet, + fmt.Sprintf("update _vt.vreplication set state='Running', stop_pos='%s', message='synchronizing for vdiff' where id=%d", vdiffSourceGtid, j+1), + &sqltypes.Result{}, + ) + } + // migrater buildMigrationTargets + env.tmc.setVRResults( + master.tablet, + "select id, source, message from _vt.vreplication where workflow='vdiffTest' and db_name='vt_target'", + sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|source|message", + "int64|varchar|varchar"), + rows..., + ), + ) + + // vdiff.stopTargets + env.tmc.setVRResults(master.tablet, "update _vt.vreplication set state='Stopped', message='for vdiff' where db_name='vt_target' and workflow='vdiffTest'", &sqltypes.Result{}) + env.tmc.setVRResults( + master.tablet, + "select source, pos from _vt.vreplication where db_name='vt_target' and workflow='vdiffTest'", + sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "source|pos", + "varchar|varchar"), + posRows..., + ), + ) + + // vdiff.syncTargets (continued) + env.tmc.vrpos[tabletID] = vdiffSourceGtid + env.tmc.pos[tabletID] = vdiffTargetMasterPosition + + // vdiff.startQueryStreams + env.tmc.waitpos[tabletID+1] = vdiffTargetMasterPosition + + // vdiff.restartTargets + env.tmc.setVRResults(master.tablet, "update _vt.vreplication set state='Running', message='' where db_name='vt_target' and workflow='vdiffTest'", &sqltypes.Result{}) + + tabletID += 10 + } + vdiffEnv = env + return env +} + +func (env *testVDiffEnv) close() { + for _, t := range env.tablets { + env.deleteTablet(t.tablet) + } +} + +func (env *testVDiffEnv) addTablet(id int, keyspace, shard string, tabletType topodatapb.TabletType) *testVDiffTablet { + tablet := &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: env.cell, + Uid: uint32(id), + }, + Keyspace: keyspace, + Shard: shard, + KeyRange: &topodatapb.KeyRange{}, + Type: tabletType, + PortMap: map[string]int32{ + "test": int32(id), + }, + } + env.tablets[id] = newTestVDiffTablet(tablet) + if err := env.wr.InitTablet(context.Background(), tablet, false /* allowMasterOverride */, true /* createShardAndKeyspace */, false /* allowUpdate */); err != nil { + panic(err) + } + return env.tablets[id] +} + +func (env *testVDiffEnv) deleteTablet(tablet *topodatapb.Tablet) { + env.topoServ.DeleteTablet(context.Background(), tablet.Alias) + delete(env.tablets, int(tablet.Alias.Uid)) +} + +//---------------------------------------------- +// testVDiffTablet + +type testVDiffTablet struct { + queryservice.QueryService + tablet *topodatapb.Tablet + queries map[string][]*binlogdatapb.VStreamResultsResponse +} + +func newTestVDiffTablet(tablet *topodatapb.Tablet) *testVDiffTablet { + return &testVDiffTablet{ + QueryService: fakes.ErrorQueryService, + tablet: tablet, + queries: make(map[string][]*binlogdatapb.VStreamResultsResponse), + } +} + +func (tvt *testVDiffTablet) StreamHealth(ctx context.Context, callback func(*querypb.StreamHealthResponse) error) error { + return callback(&querypb.StreamHealthResponse{ + Serving: true, + Target: &querypb.Target{ + Keyspace: tvt.tablet.Keyspace, + Shard: tvt.tablet.Shard, + TabletType: tvt.tablet.Type, + }, + RealtimeStats: &querypb.RealtimeStats{}, + }) +} + +func (tvt *testVDiffTablet) VStreamResults(ctx context.Context, target *querypb.Target, query string, send func(*binlogdatapb.VStreamResultsResponse) error) error { + results, ok := tvt.queries[query] + if !ok { + return fmt.Errorf("query %q not in list", query) + } + for _, result := range results { + if err := send(result); err != nil { + return err + } + } + return nil +} + +func (tvt *testVDiffTablet) setResults(query string, gtid string, results []*sqltypes.Result) { + vrs := []*binlogdatapb.VStreamResultsResponse{{ + Fields: results[0].Fields, + Gtid: gtid, + }} + + for _, result := range results[1:] { + vr := &binlogdatapb.VStreamResultsResponse{ + Rows: sqltypes.RowsToProto3(result.Rows), + } + vrs = append(vrs, vr) + } + tvt.queries[query] = vrs +} + +//---------------------------------------------- +// testVDiffTMCclient + +type testVDiffTMClient struct { + tmclient.TabletManagerClient + schema *tabletmanagerdatapb.SchemaDefinition + vrQueries map[int]map[string]*querypb.QueryResult + waitpos map[int]string + vrpos map[int]string + pos map[int]string +} + +func newTestVDiffTMClient() *testVDiffTMClient { + return &testVDiffTMClient{ + vrQueries: make(map[int]map[string]*querypb.QueryResult), + waitpos: make(map[int]string), + vrpos: make(map[int]string), + pos: make(map[int]string), + } +} + +func (tmc *testVDiffTMClient) GetSchema(ctx context.Context, tablet *topodatapb.Tablet, tables, excludeTables []string, includeViews bool) (*tabletmanagerdatapb.SchemaDefinition, error) { + return tmc.schema, nil +} + +func (tmc *testVDiffTMClient) setVRResults(tablet *topodatapb.Tablet, query string, result *sqltypes.Result) { + queries, ok := tmc.vrQueries[int(tablet.Alias.Uid)] + if !ok { + queries = make(map[string]*querypb.QueryResult) + tmc.vrQueries[int(tablet.Alias.Uid)] = queries + } + queries[query] = sqltypes.ResultToProto3(result) +} + +func (tmc *testVDiffTMClient) VReplicationExec(ctx context.Context, tablet *topodatapb.Tablet, query string) (*querypb.QueryResult, error) { + result, ok := tmc.vrQueries[int(tablet.Alias.Uid)][query] + if !ok { + return nil, fmt.Errorf("query %q not found for tablet %d", query, tablet.Alias.Uid) + } + return result, nil +} + +func (tmc *testVDiffTMClient) WaitForPosition(ctx context.Context, tablet *topodatapb.Tablet, pos string) error { + if pos != tmc.waitpos[int(tablet.Alias.Uid)] { + return fmt.Errorf("waitpos %s not reached for tablet %d", pos, tablet.Alias.Uid) + } + return nil +} + +func (tmc *testVDiffTMClient) VReplicationWaitForPos(ctx context.Context, tablet *topodatapb.Tablet, id int, pos string) error { + if pos != tmc.vrpos[int(tablet.Alias.Uid)] { + return fmt.Errorf("vrpos %s not reached for tablet %d", pos, tablet.Alias.Uid) + } + return nil +} + +func (tmc *testVDiffTMClient) MasterPosition(ctx context.Context, tablet *topodatapb.Tablet) (string, error) { + pos, ok := tmc.pos[int(tablet.Alias.Uid)] + if !ok { + return "", fmt.Errorf("no master position for %d", tablet.Alias.Uid) + } + return pos, nil +} diff --git a/go/vt/wrangler/vdiff_test.go b/go/vt/wrangler/vdiff_test.go index 28502f7be16..52a05dae49d 100644 --- a/go/vt/wrangler/vdiff_test.go +++ b/go/vt/wrangler/vdiff_test.go @@ -18,6 +18,7 @@ package wrangler import ( "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -305,3 +306,46 @@ func TestVDiffPlanFailure(t *testing.T) { assert.EqualError(t, err, tcase.err, tcase.input) } } + +func TestVDiffSimple(t *testing.T) { + env := newTestVDiffEnv([]string{"0"}, []string{"0"}, "", nil) + defer env.close() + + schm := &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ + Name: "t1", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2", "int64|int64"), + }}, + } + env.tmc.schema = schm + + env.tablets[101].setResults( + "select c1, c2 from t1 order by c1 asc", + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(sqltypes.MakeTestFields( + "c1|c2", + "int64|int64"), + "1|3", + "2|4", + "---", + "3|1", + ), + ) + env.tablets[201].setResults( + "select c1, c2 from t1 order by c1 asc", + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(sqltypes.MakeTestFields( + "c1|c2", + "int64|int64"), + "1|3", + "---", + "2|4", + "3|1", + ), + ) + + err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second) + assert.NoError(t, err) +} From 7139502dc8bf8c65349c29df9c52f531d24fc520 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 13 Oct 2019 21:44:38 -0700 Subject: [PATCH 21/28] vdiff: rest of the tests Signed-off-by: Sugu Sougoumarane --- go/vt/wrangler/vdiff.go | 54 ++--- go/vt/wrangler/vdiff_test.go | 368 +++++++++++++++++++++++++++++++++-- 2 files changed, 380 insertions(+), 42 deletions(-) diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index f5246e415d9..46cfade3eab 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -44,8 +44,8 @@ import ( "vitess.io/vitess/go/vt/vttablet/tabletmanager/vreplication" ) -// DiffSummary is the summary of differences for one table. -type DiffSummary struct { +// DiffReport is the summary of differences for one table. +type DiffReport struct { ProcessedRows int MatchingRows int MismatchedRows int @@ -81,15 +81,15 @@ type dfParams struct { } // VDiff reports differences between the sources and targets of a vreplication workflow. -func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow, sourceCell, targetCell, tabletTypesStr string, filteredReplicationWaitTime time.Duration) error { +func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow, sourceCell, targetCell, tabletTypesStr string, filteredReplicationWaitTime time.Duration) (map[string]*DiffReport, error) { mi, err := wr.buildMigrater(ctx, targetKeyspace, workflow) if err != nil { wr.Logger().Errorf("buildMigrater failed: %v", err) - return err + return nil, err } if err := mi.validate(ctx, false /* isWrite */); err != nil { mi.wr.Logger().Errorf("validate failed: %v", err) - return err + return nil, err } df := &vdiff{ mi: mi, @@ -118,14 +118,14 @@ func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow, sourceC } schm, err := wr.GetSchema(ctx, oneTarget.master.Alias, nil, nil, false) if err != nil { - return err + return nil, err } df.differs, err = buildVDiffPlan(ctx, oneFilter, schm) if err != nil { - return err + return nil, err } if err := df.selectTablets(ctx); err != nil { - return err + return nil, err } defer func() { if err := df.restartTargets(ctx); err != nil { @@ -135,31 +135,33 @@ func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow, sourceC ctx, cancel := context.WithCancel(ctx) defer cancel() // TODO(sougou): parallelize - for _, td := range df.differs { + diffReports := make(map[string]*DiffReport) + for table, td := range df.differs { if err := df.stopTargets(ctx); err != nil { - return err + return nil, err } sourceReader, err := df.startQueryStreams(ctx, df.sources, td.sourceExpression, td.orderbyParams()) if err != nil { - return err + return nil, err } if err := df.syncTargets(ctx); err != nil { - return err + return nil, err } targetReader, err := df.startQueryStreams(ctx, df.targets, td.targetExpression, td.orderbyParams()) if err != nil { - return err + return nil, err } if err := df.restartTargets(ctx); err != nil { - return err + return nil, err } dr, err := td.diff(ctx, df.mi.wr, sourceReader, targetReader) if err != nil { - return err + return nil, err } - fmt.Printf("Summary for %v: %+v\n", td.targetTable, dr) + wr.Logger().Printf("Summary for %v: %+v\n", td.targetTable, *dr) + diffReports[table] = dr } - return nil + return diffReports, nil } func buildVDiffPlan(ctx context.Context, filter *binlogdatapb.Filter, schm *tabletmanagerdatapb.SchemaDefinition) (map[string]*tableDiffer, error) { @@ -447,6 +449,7 @@ func (df *vdiff) streamOne(ctx context.Context, shard string, participant *dfPar Rows: vrs.Rows, } result := sqltypes.Proto3ToResult(p3qr) + // Fields should be received only once, and sent only once. if vrs.Fields == nil { result.Fields = nil } @@ -630,8 +633,8 @@ func (rr *resultReader) ResolveDestinations(keyspace string, ids []*querypb.Valu return nil, nil, nil } -func (td *tableDiffer) diff(ctx context.Context, wr *Wrangler, sourceReader, targetReader *resultReader) (*DiffSummary, error) { - dr := &DiffSummary{} +func (td *tableDiffer) diff(ctx context.Context, wr *Wrangler, sourceReader, targetReader *resultReader) (*DiffReport, error) { + dr := &DiffReport{} var sourceRow, targetRow []sqltypes.Value var err error advanceSource := true @@ -650,16 +653,14 @@ func (td *tableDiffer) diff(ctx context.Context, wr *Wrangler, sourceReader, tar } } + if sourceRow == nil && targetRow == nil { + return dr, nil + } + advanceSource = true advanceTarget = true if sourceRow == nil { - // no more rows from the source - if targetRow == nil { - // no more rows from target either, we're done - return dr, nil - } - // drain target, update count wr.Logger().Errorf("Draining extra row(s) found on the target starting with: %v", targetRow) count, err := targetReader.drain(ctx) @@ -667,6 +668,7 @@ func (td *tableDiffer) diff(ctx context.Context, wr *Wrangler, sourceReader, tar return nil, err } dr.ExtraRowsTarget += 1 + count + dr.ProcessedRows += 1 + count return dr, nil } if targetRow == nil { @@ -678,10 +680,10 @@ func (td *tableDiffer) diff(ctx context.Context, wr *Wrangler, sourceReader, tar return nil, err } dr.ExtraRowsSource += 1 + count + dr.ProcessedRows += 1 + count return dr, nil } - // We have rows to process on both sides. dr.ProcessedRows++ // Compare pk values. diff --git a/go/vt/wrangler/vdiff_test.go b/go/vt/wrangler/vdiff_test.go index 52a05dae49d..163f31cdf69 100644 --- a/go/vt/wrangler/vdiff_test.go +++ b/go/vt/wrangler/vdiff_test.go @@ -218,7 +218,7 @@ func TestVDiffPlanSuccess(t *testing.T) { comparePKs: []int{0}, }, }, { - // in_keyrange with other expressions. + // in_keyrange on RHS of AND. // This is currently not a valid construct, but will be supported in the future. input: &binlogdatapb.Rule{ Match: "t1", @@ -232,6 +232,51 @@ func TestVDiffPlanSuccess(t *testing.T) { compareCols: []int{-1, 1}, comparePKs: []int{0}, }, + }, { + // in_keyrange on LHS of AND. + // This is currently not a valid construct, but will be supported in the future. + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select * from t1 where in_keyrange('-80') and c2 = 2", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c1, c2 from t1 where c2 = 2 order by c1 asc", + targetExpression: "select c1, c2 from t1 order by c1 asc", + compareCols: []int{-1, 1}, + comparePKs: []int{0}, + }, + }, { + // in_keyrange on cascaded AND expression + // This is currently not a valid construct, but will be supported in the future. + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select * from t1 where c2 = 2 and c1 = 1 and in_keyrange('-80')", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c1, c2 from t1 where c2 = 2 and c1 = 1 order by c1 asc", + targetExpression: "select c1, c2 from t1 order by c1 asc", + compareCols: []int{-1, 1}, + comparePKs: []int{0}, + }, + }, { + // in_keyrange parenthesized + // This is currently not a valid construct, but will be supported in the future. + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select * from t1 where (c2 = 2 and in_keyrange('-80'))", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c1, c2 from t1 where (c2 = 2) order by c1 asc", + targetExpression: "select c1, c2 from t1 order by c1 asc", + compareCols: []int{-1, 1}, + comparePKs: []int{0}, + }, }, { // group by input: &binlogdatapb.Rule{ @@ -307,7 +352,7 @@ func TestVDiffPlanFailure(t *testing.T) { } } -func TestVDiffSimple(t *testing.T) { +func TestVDiffUnsharded(t *testing.T) { env := newTestVDiffEnv([]string{"0"}, []string{"0"}, "", nil) defer env.close() @@ -321,31 +366,322 @@ func TestVDiffSimple(t *testing.T) { } env.tmc.schema = schm - env.tablets[101].setResults( - "select c1, c2 from t1 order by c1 asc", - vdiffSourceGtid, - sqltypes.MakeTestStreamingResults(sqltypes.MakeTestFields( - "c1|c2", - "int64|int64"), + fields := sqltypes.MakeTestFields( + "c1|c2", + "int64|int64", + ) + + testcases := []struct { + id string + source []*sqltypes.Result + target []*sqltypes.Result + dr *DiffReport + }{{ + id: "1", + source: sqltypes.MakeTestStreamingResults(fields, "1|3", "2|4", "---", "3|1", ), + target: sqltypes.MakeTestStreamingResults(fields, + "1|3", + "---", + "2|4", + "3|1", + ), + dr: &DiffReport{ + ProcessedRows: 3, + MatchingRows: 3, + }, + }, { + id: "2", + source: sqltypes.MakeTestStreamingResults(fields, + "1|3", + ), + target: sqltypes.MakeTestStreamingResults(fields, + "1|3", + "---", + "2|4", + "3|1", + ), + dr: &DiffReport{ + ProcessedRows: 3, + MatchingRows: 1, + ExtraRowsTarget: 2, + }, + }, { + id: "3", + source: sqltypes.MakeTestStreamingResults(fields, + "1|3", + "---", + "2|4", + "3|1", + ), + target: sqltypes.MakeTestStreamingResults(fields, + "1|3", + ), + dr: &DiffReport{ + ProcessedRows: 3, + MatchingRows: 1, + ExtraRowsSource: 2, + }, + }, { + id: "4", + source: sqltypes.MakeTestStreamingResults(fields, + "1|3", + "---", + "2|4", + "3|1", + ), + target: sqltypes.MakeTestStreamingResults(fields, + "1|3", + "---", + "3|1", + ), + dr: &DiffReport{ + ProcessedRows: 3, + MatchingRows: 2, + ExtraRowsSource: 1, + }, + }, { + id: "5", + source: sqltypes.MakeTestStreamingResults(fields, + "1|3", + "---", + "3|1", + ), + target: sqltypes.MakeTestStreamingResults(fields, + "1|3", + "---", + "2|4", + "3|1", + ), + dr: &DiffReport{ + ProcessedRows: 3, + MatchingRows: 2, + ExtraRowsTarget: 1, + }, + }, { + id: "6", + source: sqltypes.MakeTestStreamingResults(fields, + "1|3", + "---", + "2|3", + "3|1", + ), + target: sqltypes.MakeTestStreamingResults(fields, + "1|3", + "---", + "2|4", + "3|1", + ), + dr: &DiffReport{ + ProcessedRows: 3, + MatchingRows: 2, + MismatchedRows: 1, + }, + }} + + for _, tcase := range testcases { + env.tablets[101].setResults("select c1, c2 from t1 order by c1 asc", vdiffSourceGtid, tcase.source) + env.tablets[201].setResults("select c1, c2 from t1 order by c1 asc", vdiffSourceGtid, tcase.target) + + dr, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second) + require.NoError(t, err) + assert.Equal(t, tcase.dr, dr["t1"], tcase.id) + } +} + +func TestVDiffSharded(t *testing.T) { + // Also test that highest position ""MariaDB/5-456-892" will be used + // if lower positions are found. + env := newTestVDiffEnv([]string{"-40", "40-"}, []string{"-80", "80-"}, "", map[string]string{ + "-40-80": "MariaDB/5-456-890", + "40-80-": "MariaDB/5-456-891", + }) + defer env.close() + + schm := &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ + Name: "t1", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2", "int64|int64"), + }}, + } + env.tmc.schema = schm + + query := "select c1, c2 from t1 order by c1 asc" + fields := sqltypes.MakeTestFields( + "c1|c2", + "int64|int64", + ) + + env.tablets[101].setResults( + query, + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(fields, + "1|3", + "2|4", + ), + ) + env.tablets[111].setResults( + query, + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(fields, + "3|4", + ), ) env.tablets[201].setResults( - "select c1, c2 from t1 order by c1 asc", + query, vdiffSourceGtid, - sqltypes.MakeTestStreamingResults(sqltypes.MakeTestFields( - "c1|c2", - "int64|int64"), + sqltypes.MakeTestStreamingResults(fields, "1|3", - "---", + ), + ) + env.tablets[211].setResults( + query, + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(fields, "2|4", - "3|1", + "3|4", + ), + ) + + dr, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second) + require.NoError(t, err) + wantdr := &DiffReport{ + ProcessedRows: 3, + MatchingRows: 3, + } + assert.Equal(t, wantdr, dr["t1"]) +} + +func TestVDiffPKWeightString(t *testing.T) { + // Also test that highest position ""MariaDB/5-456-892" will be used + // if lower positions are found. + env := newTestVDiffEnv([]string{"-40", "40-"}, []string{"-80", "80-"}, "", nil) + defer env.close() + + schm := &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ + Name: "t1", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2", "varchar|int64"), + }}, + } + env.tmc.schema = schm + + query := "select c1, c2, weight_string(c1) from t1 order by c1 asc" + fields := sqltypes.MakeTestFields( + "c1|c2|weight_string(c1)", + "varchar|int64|varbinary", + ) + + env.tablets[101].setResults( + query, + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(fields, + "a|3|A", + "b|4|B", ), ) + env.tablets[111].setResults( + query, + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(fields, + "C|5|C", + "D|6|D", + ), + ) + env.tablets[201].setResults( + query, + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(fields, + "A|3|A", + ), + ) + env.tablets[211].setResults( + query, + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(fields, + "b|4|B", + "c|5|C", + "D|6|D", + ), + ) + + dr, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second) + require.NoError(t, err) + wantdr := &DiffReport{ + ProcessedRows: 4, + MatchingRows: 4, + } + assert.Equal(t, wantdr, dr["t1"]) +} + +func TestVDiffNoPKWeightString(t *testing.T) { + // Also test that highest position ""MariaDB/5-456-892" will be used + // if lower positions are found. + env := newTestVDiffEnv([]string{"-40", "40-"}, []string{"-80", "80-"}, "", nil) + defer env.close() - err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second) - assert.NoError(t, err) + schm := &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ + Name: "t1", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2", "int64|varchar"), + }}, + } + env.tmc.schema = schm + + query := "select c1, c2, weight_string(c2) from t1 order by c1 asc" + fields := sqltypes.MakeTestFields( + "c1|c2|weight_string(c2)", + "int64|varchar|varbinary", + ) + + env.tablets[101].setResults( + query, + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(fields, + "3|a|A", + "4|b|B", + ), + ) + env.tablets[111].setResults( + query, + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(fields, + "5|C|C", + "6|D|D", + ), + ) + env.tablets[201].setResults( + query, + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(fields, + "3|A|A", + ), + ) + env.tablets[211].setResults( + query, + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(fields, + "4|b|B", + "5|c|C", + "6|D|D", + ), + ) + + dr, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second) + require.NoError(t, err) + wantdr := &DiffReport{ + ProcessedRows: 4, + MatchingRows: 4, + } + assert.Equal(t, wantdr, dr["t1"]) } From 3891247a15e019966fdb2ddd8a76fb975d45f055 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Wed, 16 Oct 2019 12:01:58 -0700 Subject: [PATCH 22/28] vdiff: filteredReplicationWaitTime Signed-off-by: Sugu Sougoumarane --- go/vt/wrangler/vdiff.go | 24 +++++++++++++++-------- go/vt/wrangler/vdiff_env_test.go | 10 ++++++++++ go/vt/wrangler/vdiff_test.go | 33 ++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 8 deletions(-) diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index 46cfade3eab..2511574405d 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -38,6 +38,7 @@ import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/srvtopo" "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vttablet/tabletconn" @@ -140,14 +141,14 @@ func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow, sourceC if err := df.stopTargets(ctx); err != nil { return nil, err } - sourceReader, err := df.startQueryStreams(ctx, df.sources, td.sourceExpression, td.orderbyParams()) + sourceReader, err := df.startQueryStreams(ctx, df.sources, td.sourceExpression, td.orderbyParams(), filteredReplicationWaitTime) if err != nil { return nil, err } - if err := df.syncTargets(ctx); err != nil { + if err := df.syncTargets(ctx, filteredReplicationWaitTime); err != nil { return nil, err } - targetReader, err := df.startQueryStreams(ctx, df.targets, td.targetExpression, td.orderbyParams()) + targetReader, err := df.startQueryStreams(ctx, df.targets, td.targetExpression, td.orderbyParams(), filteredReplicationWaitTime) if err != nil { return nil, err } @@ -387,11 +388,13 @@ func (df *vdiff) stopTargets(ctx context.Context) error { return nil } -func (df *vdiff) startQueryStreams(ctx context.Context, participants map[string]*dfParams, query string, orderBy []engine.OrderbyParams) (*resultReader, error) { +func (df *vdiff) startQueryStreams(ctx context.Context, participants map[string]*dfParams, query string, orderBy []engine.OrderbyParams, filteredReplicationWaitTime time.Duration) (*resultReader, error) { + waitCtx, cancel := context.WithTimeout(ctx, filteredReplicationWaitTime) + defer cancel() err := df.forAll(participants, func(shard string, participant *dfParams) error { // Iteration for each participant. - if err := df.mi.wr.tmc.WaitForPosition(ctx, participant.tablet, mysql.EncodePosition(participant.position)); err != nil { - return err + if err := df.mi.wr.tmc.WaitForPosition(waitCtx, participant.tablet, mysql.EncodePosition(participant.position)); err != nil { + return fmt.Errorf("WaitForPosition for tablet %v failed: %v", topoproto.TabletAliasString(participant.tablet.Alias), err) } participant.result = make(chan *sqltypes.Result, 1) gtidch := make(chan string, 1) @@ -464,7 +467,9 @@ func (df *vdiff) streamOne(ctx context.Context, shard string, participant *dfPar }() } -func (df *vdiff) syncTargets(ctx context.Context) error { +func (df *vdiff) syncTargets(ctx context.Context, filteredReplicationWaitTime time.Duration) error { + waitCtx, cancel := context.WithTimeout(ctx, filteredReplicationWaitTime) + defer cancel() err := df.mi.forAllUids(func(target *miTarget, uid uint32) error { bls := target.sources[uid] pos := df.sources[bls.Shard].snapshotPosition @@ -472,7 +477,10 @@ func (df *vdiff) syncTargets(ctx context.Context) error { if _, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query); err != nil { return err } - return df.mi.wr.tmc.VReplicationWaitForPos(ctx, target.master.Tablet, int(uid), pos) + if err := df.mi.wr.tmc.VReplicationWaitForPos(waitCtx, target.master.Tablet, int(uid), pos); err != nil { + return fmt.Errorf("VReplicationWaitForPos for tablet %v failed: %v", topoproto.TabletAliasString(target.master.Tablet.Alias), err) + } + return nil }) if err != nil { return err diff --git a/go/vt/wrangler/vdiff_env_test.go b/go/vt/wrangler/vdiff_env_test.go index 4052a8cc7f5..a144f774b22 100644 --- a/go/vt/wrangler/vdiff_env_test.go +++ b/go/vt/wrangler/vdiff_env_test.go @@ -294,6 +294,11 @@ func (tmc *testVDiffTMClient) VReplicationExec(ctx context.Context, tablet *topo } func (tmc *testVDiffTMClient) WaitForPosition(ctx context.Context, tablet *topodatapb.Tablet, pos string) error { + select { + case <-ctx.Done(): + return ctx.Err() + default: + } if pos != tmc.waitpos[int(tablet.Alias.Uid)] { return fmt.Errorf("waitpos %s not reached for tablet %d", pos, tablet.Alias.Uid) } @@ -301,6 +306,11 @@ func (tmc *testVDiffTMClient) WaitForPosition(ctx context.Context, tablet *topod } func (tmc *testVDiffTMClient) VReplicationWaitForPos(ctx context.Context, tablet *topodatapb.Tablet, id int, pos string) error { + select { + case <-ctx.Done(): + return ctx.Err() + default: + } if pos != tmc.vrpos[int(tablet.Alias.Uid)] { return fmt.Errorf("vrpos %s not reached for tablet %d", pos, tablet.Alias.Uid) } diff --git a/go/vt/wrangler/vdiff_test.go b/go/vt/wrangler/vdiff_test.go index 163f31cdf69..277f2e6a5d7 100644 --- a/go/vt/wrangler/vdiff_test.go +++ b/go/vt/wrangler/vdiff_test.go @@ -685,3 +685,36 @@ func TestVDiffNoPKWeightString(t *testing.T) { } assert.Equal(t, wantdr, dr["t1"]) } + +func TestVDiffReplicationWait(t *testing.T) { + env := newTestVDiffEnv([]string{"0"}, []string{"0"}, "", nil) + defer env.close() + + schm := &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ + Name: "t1", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2", "int64|int64"), + }}, + } + env.tmc.schema = schm + + fields := sqltypes.MakeTestFields( + "c1|c2", + "int64|int64", + ) + + source := sqltypes.MakeTestStreamingResults(fields, + "1|3", + "2|4", + "---", + "3|1", + ) + target := source + env.tablets[101].setResults("select c1, c2 from t1 order by c1 asc", vdiffSourceGtid, source) + env.tablets[201].setResults("select c1, c2 from t1 order by c1 asc", vdiffSourceGtid, target) + + _, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 0*time.Second) + require.EqualError(t, err, "WaitForPosition for tablet cell-0000000101 failed: context deadline exceeded") +} From 78babddadde9f61f984a51838c058bb7f6a32ab8 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Wed, 16 Oct 2019 16:13:16 -0700 Subject: [PATCH 23/28] vdiff: vtctl command Signed-off-by: Sugu Sougoumarane --- go/vt/vtctl/vtctl.go | 21 ++++++++++++++++++++ go/vt/wrangler/vdiff.go | 18 ++++++++++++++++++ go/vt/wrangler/vdiff_test.go | 37 ++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+) diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index 82d1b00c24e..a94e29aeea2 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -313,6 +313,9 @@ var commands = []commandGroup{ {"VerticalSplitClone", commandVerticalSplitClone, " ", "Start the VerticalSplitClone process to perform vertical resharding. Example: SplitClone from_ks to_ks 'a,/b.*/'"}, + {"VDiff", commandVDiff, + "-workflow= [-source_cell=] [-target_cell=] [-tablet_types=REPLICA] [-filtered_replication_wait_time=30s]", + "Perform a diff of all tables in the workflow"}, {"MigrateServedTypes", commandMigrateServedTypes, "[-cells=c1,c2,...] [-reverse] [-skip-refresh-state] ", "Migrates a serving type from the source shard to the shards that it replicates to. This command also rebuilds the serving graph. The argument can specify any of the shards involved in the migration."}, @@ -1807,6 +1810,24 @@ func commandVerticalSplitClone(ctx context.Context, wr *wrangler.Wrangler, subFl return wr.VerticalSplitClone(ctx, fromKeyspace, toKeyspace, tables) } +func commandVDiff(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { + workflow := subFlags.String("workflow", "", "Specifies the workflow name") + sourceCell := subFlags.String("source_cell", "", "The source cell to compare from") + targetCell := subFlags.String("target_cell", "", "The target cell to compare with") + tabletTypes := subFlags.String("tablet_types", "", "Tablet types for source and target") + filteredReplicationWaitTime := subFlags.Duration("filtered_replication_wait_time", 30*time.Second, "Specifies the maximum time to wait, in seconds, for filtered replication to catch up on master migrations. The migration will be aborted on timeout.") + if err := subFlags.Parse(args); err != nil { + return err + } + if subFlags.NArg() != 1 { + return fmt.Errorf("the is required") + } + + targetKeyspace := subFlags.Arg(0) + _, err := wr.VDiff(ctx, targetKeyspace, *workflow, *sourceCell, *targetCell, *tabletTypes, *filteredReplicationWaitTime) + return err +} + func commandMigrateServedTypes(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { cellsStr := subFlags.String("cells", "", "Specifies a comma-separated list of cells to update") reverse := subFlags.Bool("reverse", false, "Moves the served tablet type backward instead of forward.") diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index 2511574405d..dbe7f46c57d 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -83,6 +83,24 @@ type dfParams struct { // VDiff reports differences between the sources and targets of a vreplication workflow. func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow, sourceCell, targetCell, tabletTypesStr string, filteredReplicationWaitTime time.Duration) (map[string]*DiffReport, error) { + if sourceCell == "" && targetCell == "" { + cells, err := wr.ts.GetCellInfoNames(ctx) + if err != nil { + return nil, err + } + if len(cells) == 0 { + // Unreachable + return nil, fmt.Errorf("there are no cells in the topo") + } + sourceCell = cells[0] + targetCell = sourceCell + } + if sourceCell == "" { + sourceCell = targetCell + } + if targetCell == "" { + targetCell = sourceCell + } mi, err := wr.buildMigrater(ctx, targetKeyspace, workflow) if err != nil { wr.Logger().Errorf("buildMigrater failed: %v", err) diff --git a/go/vt/wrangler/vdiff_test.go b/go/vt/wrangler/vdiff_test.go index 277f2e6a5d7..d23052094ff 100644 --- a/go/vt/wrangler/vdiff_test.go +++ b/go/vt/wrangler/vdiff_test.go @@ -686,6 +686,43 @@ func TestVDiffNoPKWeightString(t *testing.T) { assert.Equal(t, wantdr, dr["t1"]) } +func TestVDiffDefaults(t *testing.T) { + env := newTestVDiffEnv([]string{"0"}, []string{"0"}, "", nil) + defer env.close() + + schm := &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ + Name: "t1", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2", "int64|int64"), + }}, + } + env.tmc.schema = schm + + fields := sqltypes.MakeTestFields( + "c1|c2", + "int64|int64", + ) + + source := sqltypes.MakeTestStreamingResults(fields, + "1|3", + "2|4", + "---", + "3|1", + ) + target := source + env.tablets[101].setResults("select c1, c2 from t1 order by c1 asc", vdiffSourceGtid, source) + env.tablets[201].setResults("select c1, c2 from t1 order by c1 asc", vdiffSourceGtid, target) + + _, err := env.wr.VDiff(context.Background(), "target", env.workflow, "", "", "replica", 30*time.Second) + require.NoError(t, err) + _, err = env.wr.VDiff(context.Background(), "target", env.workflow, "", env.cell, "replica", 30*time.Second) + require.NoError(t, err) + _, err = env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, "", "replica", 30*time.Second) + require.NoError(t, err) +} + func TestVDiffReplicationWait(t *testing.T) { env := newTestVDiffEnv([]string{"0"}, []string{"0"}, "", nil) defer env.close() From 98429a9bc36c8a636fcb5699599a9eeafc50d693 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Thu, 17 Oct 2019 16:40:28 -0700 Subject: [PATCH 24/28] vdiff: fix two bugs * WaitForPos previously worked only for replicas. It's been updated to work correctly for masters also. * resultReader keyspace was hardcoded to source. The keyspace name is now passed as input param. Signed-off-by: Sugu Sougoumarane --- go/vt/mysqlctl/replication.go | 11 +++++++ go/vt/wrangler/vdiff.go | 50 ++++++++++++++++---------------- go/vt/wrangler/vdiff_env_test.go | 2 +- go/vt/wrangler/vdiff_test.go | 2 +- 4 files changed, 38 insertions(+), 27 deletions(-) diff --git a/go/vt/mysqlctl/replication.go b/go/vt/mysqlctl/replication.go index 85ab67452c2..67acf25ff95 100644 --- a/go/vt/mysqlctl/replication.go +++ b/go/vt/mysqlctl/replication.go @@ -181,6 +181,17 @@ func (mysqld *Mysqld) WaitMasterPos(ctx context.Context, targetPos mysql.Positio } defer conn.Recycle() + // If we are the master, WaitUntilPositionCommand will fail. + // But position is most likely reached. So, check the position + // first. + mpos, err := conn.MasterPosition() + if err != nil { + return fmt.Errorf("WaitMasterPos: MasterPosition failed: %v", err) + } + if mpos.AtLeast(targetPos) { + return nil + } + // Find the query to run, run it. query, err := conn.WaitUntilPositionCommand(ctx, targetPos) if err != nil { diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index dbe7f46c57d..4534bb13ec8 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -103,11 +103,11 @@ func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow, sourceC } mi, err := wr.buildMigrater(ctx, targetKeyspace, workflow) if err != nil { - wr.Logger().Errorf("buildMigrater failed: %v", err) + wr.Logger().Errorf("buildMigrater: %v", err) return nil, err } if err := mi.validate(ctx, false /* isWrite */); err != nil { - mi.wr.Logger().Errorf("validate failed: %v", err) + mi.wr.Logger().Errorf("validate: %v", err) return nil, err } df := &vdiff{ @@ -137,45 +137,45 @@ func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow, sourceC } schm, err := wr.GetSchema(ctx, oneTarget.master.Alias, nil, nil, false) if err != nil { - return nil, err + return nil, vterrors.Wrap(err, "GetSchema") } df.differs, err = buildVDiffPlan(ctx, oneFilter, schm) if err != nil { - return nil, err + return nil, vterrors.Wrap(err, "buildVDiffPlan") } if err := df.selectTablets(ctx); err != nil { - return nil, err + return nil, vterrors.Wrap(err, "selectTablets") } - defer func() { + defer func(ctx context.Context) { if err := df.restartTargets(ctx); err != nil { wr.Logger().Errorf("Could not restart workflow %s: %v, please restart it manually", workflow, err) } - }() + }(ctx) ctx, cancel := context.WithCancel(ctx) defer cancel() // TODO(sougou): parallelize diffReports := make(map[string]*DiffReport) for table, td := range df.differs { if err := df.stopTargets(ctx); err != nil { - return nil, err + return nil, vterrors.Wrap(err, "stopTargets") } - sourceReader, err := df.startQueryStreams(ctx, df.sources, td.sourceExpression, td.orderbyParams(), filteredReplicationWaitTime) + sourceReader, err := df.startQueryStreams(ctx, df.mi.sourceKeyspace, df.sources, td.sourceExpression, td.orderbyParams(), filteredReplicationWaitTime) if err != nil { - return nil, err + return nil, vterrors.Wrap(err, "startQueryStreams(sources)") } if err := df.syncTargets(ctx, filteredReplicationWaitTime); err != nil { - return nil, err + return nil, vterrors.Wrap(err, "syncTargets") } - targetReader, err := df.startQueryStreams(ctx, df.targets, td.targetExpression, td.orderbyParams(), filteredReplicationWaitTime) + targetReader, err := df.startQueryStreams(ctx, df.mi.targetKeyspace, df.targets, td.targetExpression, td.orderbyParams(), filteredReplicationWaitTime) if err != nil { - return nil, err + return nil, vterrors.Wrap(err, "startQueryStreams(targets)") } if err := df.restartTargets(ctx); err != nil { - return nil, err + return nil, vterrors.Wrap(err, "restartTargets") } dr, err := td.diff(ctx, df.mi.wr, sourceReader, targetReader) if err != nil { - return nil, err + return nil, vterrors.Wrap(err, "diff") } wr.Logger().Printf("Summary for %v: %+v\n", td.targetTable, *dr) diffReports[table] = dr @@ -406,19 +406,19 @@ func (df *vdiff) stopTargets(ctx context.Context) error { return nil } -func (df *vdiff) startQueryStreams(ctx context.Context, participants map[string]*dfParams, query string, orderBy []engine.OrderbyParams, filteredReplicationWaitTime time.Duration) (*resultReader, error) { +func (df *vdiff) startQueryStreams(ctx context.Context, keyspace string, participants map[string]*dfParams, query string, orderBy []engine.OrderbyParams, filteredReplicationWaitTime time.Duration) (*resultReader, error) { waitCtx, cancel := context.WithTimeout(ctx, filteredReplicationWaitTime) defer cancel() err := df.forAll(participants, func(shard string, participant *dfParams) error { // Iteration for each participant. if err := df.mi.wr.tmc.WaitForPosition(waitCtx, participant.tablet, mysql.EncodePosition(participant.position)); err != nil { - return fmt.Errorf("WaitForPosition for tablet %v failed: %v", topoproto.TabletAliasString(participant.tablet.Alias), err) + return vterrors.Wrapf(err, "WaitForPosition for tablet %v", topoproto.TabletAliasString(participant.tablet.Alias)) } participant.result = make(chan *sqltypes.Result, 1) gtidch := make(chan string, 1) // Start the stream in a separate goroutine. - go df.streamOne(ctx, shard, participant, query, gtidch) + go df.streamOne(ctx, keyspace, shard, participant, query, gtidch) // Wait for the gtid to be sent. If it's not received, there was an error // which would be stored in participant.err. @@ -441,7 +441,7 @@ func (df *vdiff) startQueryStreams(ctx context.Context, participants map[string] // Then it streams results to participant.result. // Before returning, it sets participant.err, and closes all channels. // If any channel is closed, then participant.err can be checked if there was an error. -func (df *vdiff) streamOne(ctx context.Context, shard string, participant *dfParams, query string, gtidch chan string) { +func (df *vdiff) streamOne(ctx context.Context, keyspace, shard string, participant *dfParams, query string, gtidch chan string) { defer close(participant.result) defer close(gtidch) @@ -455,7 +455,7 @@ func (df *vdiff) streamOne(ctx context.Context, shard string, participant *dfPar defer conn.Close(ctx) target := &querypb.Target{ - Keyspace: df.mi.sourceKeyspace, + Keyspace: keyspace, Shard: shard, TabletType: participant.tablet.Type, } @@ -477,7 +477,7 @@ func (df *vdiff) streamOne(ctx context.Context, shard string, participant *dfPar select { case participant.result <- result: case <-ctx.Done(): - return fmt.Errorf("VStreamResults: %v", ctx.Err()) + return vterrors.Wrap(ctx.Err(), "VStreamResults") } return nil }) @@ -496,7 +496,7 @@ func (df *vdiff) syncTargets(ctx context.Context, filteredReplicationWaitTime ti return err } if err := df.mi.wr.tmc.VReplicationWaitForPos(waitCtx, target.master.Tablet, int(uid), pos); err != nil { - return fmt.Errorf("VReplicationWaitForPos for tablet %v failed: %v", topoproto.TabletAliasString(target.master.Tablet.Alias), err) + return vterrors.Wrapf(err, "VReplicationWaitForPos for tablet %v", topoproto.TabletAliasString(target.master.Tablet.Alias)) } return nil }) @@ -521,7 +521,7 @@ func (df *vdiff) syncTargets(ctx context.Context, filteredReplicationWaitTime ti func (df *vdiff) restartTargets(ctx context.Context) error { return df.forAll(df.targets, func(shard string, target *dfParams) error { - query := fmt.Sprintf("update _vt.vreplication set state='Running', message='' where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.mi.workflow)) + query := fmt.Sprintf("update _vt.vreplication set state='Running', message='', stop_pos='' where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.mi.workflow)) _, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) return err }) @@ -578,7 +578,7 @@ func newResultReader(ctx context.Context, participants map[string]*dfParams, ord select { case rr.result <- qr: case <-ctx.Done(): - return fmt.Errorf("MergeSort: %v", ctx.Err()) + return vterrors.Wrap(ctx.Err(), "MergeSort") } return nil }) @@ -595,7 +595,7 @@ func (rr *resultReader) next(ctx context.Context) ([]sqltypes.Value, error) { } rr.rows = qr.Rows case <-ctx.Done(): - return nil, fmt.Errorf("next: %v", ctx.Err()) + return nil, vterrors.Wrap(ctx.Err(), "next") } } diff --git a/go/vt/wrangler/vdiff_env_test.go b/go/vt/wrangler/vdiff_env_test.go index a144f774b22..afebe51d7c0 100644 --- a/go/vt/wrangler/vdiff_env_test.go +++ b/go/vt/wrangler/vdiff_env_test.go @@ -154,7 +154,7 @@ func newTestVDiffEnv(sourceShards, targetShards []string, query string, position env.tmc.waitpos[tabletID+1] = vdiffTargetMasterPosition // vdiff.restartTargets - env.tmc.setVRResults(master.tablet, "update _vt.vreplication set state='Running', message='' where db_name='vt_target' and workflow='vdiffTest'", &sqltypes.Result{}) + env.tmc.setVRResults(master.tablet, "update _vt.vreplication set state='Running', message='', stop_pos='' where db_name='vt_target' and workflow='vdiffTest'", &sqltypes.Result{}) tabletID += 10 } diff --git a/go/vt/wrangler/vdiff_test.go b/go/vt/wrangler/vdiff_test.go index d23052094ff..c120e6f966f 100644 --- a/go/vt/wrangler/vdiff_test.go +++ b/go/vt/wrangler/vdiff_test.go @@ -753,5 +753,5 @@ func TestVDiffReplicationWait(t *testing.T) { env.tablets[201].setResults("select c1, c2 from t1 order by c1 asc", vdiffSourceGtid, target) _, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 0*time.Second) - require.EqualError(t, err, "WaitForPosition for tablet cell-0000000101 failed: context deadline exceeded") + require.EqualError(t, err, "startQueryStreams(sources): WaitForPosition for tablet cell-0000000101: context deadline exceeded") } From 357d070aa77ea14613b040c3fcb47792b2a1f068 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 19 Oct 2019 09:31:12 -0700 Subject: [PATCH 25/28] vdiff: handle aggregates Signed-off-by: Sugu Sougoumarane --- go/vt/wrangler/vdiff.go | 192 ++++++++++++++++++++--------------- go/vt/wrangler/vdiff_test.go | 150 +++++++++++++++++++++++++-- 2 files changed, 253 insertions(+), 89 deletions(-) diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index 4534bb13ec8..67eb4d6b004 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -34,7 +34,6 @@ import ( querypb "vitess.io/vitess/go/vt/proto/query" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" - vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/srvtopo" "vitess.io/vitess/go/vt/topo" @@ -70,6 +69,8 @@ type tableDiffer struct { targetExpression string compareCols []int comparePKs []int + sourcePrimitive engine.Primitive + targetPrimitive engine.Primitive } type dfParams struct { @@ -159,14 +160,14 @@ func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow, sourceC if err := df.stopTargets(ctx); err != nil { return nil, vterrors.Wrap(err, "stopTargets") } - sourceReader, err := df.startQueryStreams(ctx, df.mi.sourceKeyspace, df.sources, td.sourceExpression, td.orderbyParams(), filteredReplicationWaitTime) + sourceReader, err := df.startQueryStreams(ctx, df.mi.sourceKeyspace, df.sources, td.sourceExpression, filteredReplicationWaitTime) if err != nil { return nil, vterrors.Wrap(err, "startQueryStreams(sources)") } if err := df.syncTargets(ctx, filteredReplicationWaitTime); err != nil { return nil, vterrors.Wrap(err, "syncTargets") } - targetReader, err := df.startQueryStreams(ctx, df.mi.targetKeyspace, df.targets, td.targetExpression, td.orderbyParams(), filteredReplicationWaitTime) + targetReader, err := df.startQueryStreams(ctx, df.mi.targetKeyspace, df.targets, td.targetExpression, filteredReplicationWaitTime) if err != nil { return nil, vterrors.Wrap(err, "startQueryStreams(targets)") } @@ -221,6 +222,7 @@ func buildDifferPlan(table *tabletmanagerdatapb.TableDefinition, query string) ( } sourceSelect := &sqlparser.Select{} targetSelect := &sqlparser.Select{} + var aggregates []engine.AggregateParams for _, selExpr := range sel.SelectExprs { switch selExpr := selExpr.(type) { case *sqlparser.StarExpr: @@ -242,6 +244,17 @@ func buildDifferPlan(table *tabletmanagerdatapb.TableDefinition, query string) ( } sourceSelect.SelectExprs = append(sourceSelect.SelectExprs, selExpr) targetSelect.SelectExprs = append(targetSelect.SelectExprs, &sqlparser.AliasedExpr{Expr: targetCol}) + + // Check if it's an aggregate expression + if expr, ok := selExpr.Expr.(*sqlparser.FuncExpr); ok { + switch fname := expr.Name.Lowered(); fname { + case "count", "sum": + aggregates = append(aggregates, engine.AggregateParams{ + Opcode: engine.SupportedAggregates[fname], + Col: len(sourceSelect.SelectExprs) - 1, + }) + } + } default: return nil, fmt.Errorf("unexpected: %v", sqlparser.String(statement)) } @@ -305,6 +318,17 @@ func buildDifferPlan(table *tabletmanagerdatapb.TableDefinition, query string) ( td.sourceExpression = sqlparser.String(sourceSelect) td.targetExpression = sqlparser.String(targetSelect) + + td.sourcePrimitive = newMergeSorter(td.comparePKs) + td.targetPrimitive = newMergeSorter(td.comparePKs) + if len(aggregates) != 0 { + td.sourcePrimitive = &engine.OrderedAggregate{ + Aggregates: aggregates, + Keys: td.comparePKs, + Input: td.sourcePrimitive, + } + } + return td, nil } @@ -406,7 +430,7 @@ func (df *vdiff) stopTargets(ctx context.Context) error { return nil } -func (df *vdiff) startQueryStreams(ctx context.Context, keyspace string, participants map[string]*dfParams, query string, orderBy []engine.OrderbyParams, filteredReplicationWaitTime time.Duration) (*resultReader, error) { +func (df *vdiff) startQueryStreams(ctx context.Context, keyspace string, participants map[string]*dfParams, query string, filteredReplicationWaitTime time.Duration) (*resultReader, error) { waitCtx, cancel := context.WithTimeout(ctx, filteredReplicationWaitTime) defer cancel() err := df.forAll(participants, func(shard string, participant *dfParams) error { @@ -433,7 +457,7 @@ func (df *vdiff) startQueryStreams(ctx context.Context, keyspace string, partici if err != nil { return nil, err } - return newResultReader(ctx, participants, orderBy), nil + return newResultReader(ctx, participants), nil } // streamOne is called as a goroutine, and communicates its results through channels. @@ -544,70 +568,53 @@ func (df *vdiff) forAll(participants map[string]*dfParams, f func(string, *dfPar return allErrors.AggrError(vterrors.Aggregate) } -var _ engine.VCursor = (*resultReader)(nil) +//----------------------------------------------------------------- +// primitiveExecutor -// resultReader performs a merge-sorted read from the participants. -type resultReader struct { - ctx context.Context - participants map[string]*dfParams - rows [][]sqltypes.Value - result chan *sqltypes.Result - err error +type primitiveExecutor struct { + prim engine.Primitive + rows [][]sqltypes.Value + resultch chan *sqltypes.Result + err error } -func newResultReader(ctx context.Context, participants map[string]*dfParams, orderBy []engine.OrderbyParams) *resultReader { - rr := &resultReader{ - ctx: ctx, - participants: participants, - result: make(chan *sqltypes.Result, 1), - } - rss := make([]*srvtopo.ResolvedShard, 0, len(participants)) - bvs := make([]map[string]*querypb.BindVariable, 0, len(participants)) - for shard := range participants { - rss = append(rss, &srvtopo.ResolvedShard{ - Target: &querypb.Target{ - Shard: shard, - }, - }) - bvs = append(bvs, make(map[string]*querypb.BindVariable)) +func newPrimitiveExecutor(ctx context.Context, vcursor engine.VCursor, prim engine.Primitive) *primitiveExecutor { + pe := &primitiveExecutor{ + prim: prim, + resultch: make(chan *sqltypes.Result, 1), } go func() { - defer close(rr.result) - - rr.err = engine.MergeSort(rr, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { + defer close(pe.resultch) + pe.err = pe.prim.StreamExecute(vcursor, make(map[string]*querypb.BindVariable), false, func(qr *sqltypes.Result) error { select { - case rr.result <- qr: + case pe.resultch <- qr: case <-ctx.Done(): - return vterrors.Wrap(ctx.Err(), "MergeSort") + return vterrors.Wrap(ctx.Err(), "Outer Stream") } return nil }) }() - return rr + return pe } -func (rr *resultReader) next(ctx context.Context) ([]sqltypes.Value, error) { - for len(rr.rows) == 0 { - select { - case qr, ok := <-rr.result: - if !ok { - return nil, rr.err - } - rr.rows = qr.Rows - case <-ctx.Done(): - return nil, vterrors.Wrap(ctx.Err(), "next") +func (pe *primitiveExecutor) next() ([]sqltypes.Value, error) { + for len(pe.rows) == 0 { + qr, ok := <-pe.resultch + if !ok { + return nil, pe.err } + pe.rows = qr.Rows } - row := rr.rows[0] - rr.rows = rr.rows[1:] + row := pe.rows[0] + pe.rows = pe.rows[1:] return row, nil } -func (rr *resultReader) drain(ctx context.Context) (int, error) { +func (pe *primitiveExecutor) drain(ctx context.Context) (int, error) { count := 0 for { - row, err := rr.next(ctx) + row, err := pe.next() if err != nil { return 0, err } @@ -618,28 +625,64 @@ func (rr *resultReader) drain(ctx context.Context) (int, error) { } } -func (rr *resultReader) Context() context.Context { - return rr.ctx -} +//----------------------------------------------------------------- +// mergeSorter -func (rr *resultReader) MaxMemoryRows() int { return 0 } +var _ engine.Primitive = (*mergeSorter)(nil) -func (rr *resultReader) SetContextTimeout(timeout time.Duration) context.CancelFunc { return nil } +// mergeSorter performs a merge-sorted read from the participants. +type mergeSorter struct { + engine.Primitive + orderBy []engine.OrderbyParams +} -func (rr *resultReader) RecordWarning(warning *querypb.QueryWarning) {} +func newMergeSorter(comparePKs []int) *mergeSorter { + ob := make([]engine.OrderbyParams, 0, len(comparePKs)) + for _, col := range comparePKs { + ob = append(ob, engine.OrderbyParams{Col: col}) + } + return &mergeSorter{ + orderBy: ob, + } +} -func (rr *resultReader) Execute(method string, query string, bindvars map[string]*querypb.BindVariable, isDML bool, co vtgatepb.CommitOrder) (*sqltypes.Result, error) { - return nil, nil +func (ms *mergeSorter) StreamExecute(vcursor engine.VCursor, bindVars map[string]*querypb.BindVariable, wantields bool, callback func(*sqltypes.Result) error) error { + rr, ok := vcursor.(*resultReader) + if !ok { + return fmt.Errorf("internal error: vcursor is not a resultReader: %T", vcursor) + } + rss := make([]*srvtopo.ResolvedShard, 0, len(rr.participants)) + bvs := make([]map[string]*querypb.BindVariable, 0, len(rr.participants)) + for shard := range rr.participants { + rss = append(rss, &srvtopo.ResolvedShard{ + Target: &querypb.Target{ + Shard: shard, + }, + }) + bvs = append(bvs, bindVars) + } + return engine.MergeSort(vcursor, "", ms.orderBy, rss, bvs, callback) } -func (rr *resultReader) AutocommitApproval() bool { return false } +//----------------------------------------------------------------- +// resultReader -func (rr *resultReader) ExecuteMultiShard(rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, isDML, canAutocommit bool) (*sqltypes.Result, []error) { - return nil, nil +// resultReader acts as a VCursor for the wrapping primitives. +type resultReader struct { + engine.VCursor + ctx context.Context + participants map[string]*dfParams } -func (rr *resultReader) ExecuteStandalone(query string, bindvars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard) (*sqltypes.Result, error) { - return nil, nil +func newResultReader(ctx context.Context, participants map[string]*dfParams) *resultReader { + return &resultReader{ + ctx: ctx, + participants: participants, + } +} + +func (rr *resultReader) Context() context.Context { + return rr.ctx } func (rr *resultReader) StreamExecuteMulti(query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, callback func(reply *sqltypes.Result) error) error { @@ -651,15 +694,12 @@ func (rr *resultReader) StreamExecuteMulti(query string, rss []*srvtopo.Resolved return rr.participants[rss[0].Target.Shard].err } -func (rr *resultReader) ExecuteKeyspaceID(keyspace string, ksid []byte, query string, bindVars map[string]*querypb.BindVariable, isDML, autocommit bool) (*sqltypes.Result, error) { - return nil, nil -} - -func (rr *resultReader) ResolveDestinations(keyspace string, ids []*querypb.Value, destinations []key.Destination) ([]*srvtopo.ResolvedShard, [][]*querypb.Value, error) { - return nil, nil, nil -} +//----------------------------------------------------------------- +// tableDiffer func (td *tableDiffer) diff(ctx context.Context, wr *Wrangler, sourceReader, targetReader *resultReader) (*DiffReport, error) { + sourceExecutor := newPrimitiveExecutor(ctx, sourceReader, td.sourcePrimitive) + targetExecutor := newPrimitiveExecutor(ctx, targetReader, td.targetPrimitive) dr := &DiffReport{} var sourceRow, targetRow []sqltypes.Value var err error @@ -667,13 +707,13 @@ func (td *tableDiffer) diff(ctx context.Context, wr *Wrangler, sourceReader, tar advanceTarget := true for { if advanceSource { - sourceRow, err = sourceReader.next(ctx) + sourceRow, err = sourceExecutor.next() if err != nil { return nil, err } } if advanceTarget { - targetRow, err = targetReader.next(ctx) + targetRow, err = targetExecutor.next() if err != nil { return nil, err } @@ -689,7 +729,7 @@ func (td *tableDiffer) diff(ctx context.Context, wr *Wrangler, sourceReader, tar if sourceRow == nil { // drain target, update count wr.Logger().Errorf("Draining extra row(s) found on the target starting with: %v", targetRow) - count, err := targetReader.drain(ctx) + count, err := targetExecutor.drain(ctx) if err != nil { return nil, err } @@ -701,7 +741,7 @@ func (td *tableDiffer) diff(ctx context.Context, wr *Wrangler, sourceReader, tar // no more rows from the target // we know we have rows from source, drain, update count wr.Logger().Errorf("Draining extra row(s) found on the source starting with: %v", sourceRow) - count, err := sourceReader.drain(ctx) + count, err := sourceExecutor.drain(ctx) if err != nil { return nil, err } @@ -766,14 +806,6 @@ func (td *tableDiffer) compare(sourceRow, targetRow []sqltypes.Value, cols []int return 0, nil } -func (td *tableDiffer) orderbyParams() []engine.OrderbyParams { - ob := make([]engine.OrderbyParams, 0, len(td.comparePKs)) - for _, col := range td.comparePKs { - ob = append(ob, engine.OrderbyParams{Col: col}) - } - return ob -} - func removeKeyrange(where *sqlparser.Where) *sqlparser.Where { if where == nil { return nil diff --git a/go/vt/wrangler/vdiff_test.go b/go/vt/wrangler/vdiff_test.go index c120e6f966f..4934fa68eaf 100644 --- a/go/vt/wrangler/vdiff_test.go +++ b/go/vt/wrangler/vdiff_test.go @@ -26,6 +26,7 @@ import ( "vitess.io/vitess/go/sqltypes" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" + "vitess.io/vitess/go/vt/vtgate/engine" ) func TestVDiffPlanSuccess(t *testing.T) { @@ -50,6 +51,11 @@ func TestVDiffPlanSuccess(t *testing.T) { Columns: []string{"c1", "c2"}, PrimaryKeyColumns: []string{"c1", "c2"}, Fields: sqltypes.MakeTestFields("c1|c2", "int64|int64"), + }, { + Name: "aggr", + Columns: []string{"c1", "c2", "c3", "c4"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2|c3|c4", "int64|int64|int64|int64"), }}, } @@ -68,6 +74,8 @@ func TestVDiffPlanSuccess(t *testing.T) { targetExpression: "select c1, c2 from t1 order by c1 asc", compareCols: []int{-1, 1}, comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), }, }, { input: &binlogdatapb.Rule{ @@ -81,6 +89,8 @@ func TestVDiffPlanSuccess(t *testing.T) { targetExpression: "select c1, c2 from t1 order by c1 asc", compareCols: []int{-1, 1}, comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), }, }, { input: &binlogdatapb.Rule{ @@ -94,6 +104,8 @@ func TestVDiffPlanSuccess(t *testing.T) { targetExpression: "select c1, c2 from t1 order by c1 asc", compareCols: []int{-1, 1}, comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), }, }, { input: &binlogdatapb.Rule{ @@ -107,6 +119,8 @@ func TestVDiffPlanSuccess(t *testing.T) { targetExpression: "select c2, c1 from t1 order by c1 asc", compareCols: []int{0, -1}, comparePKs: []int{1}, + sourcePrimitive: newMergeSorter([]int{1}), + targetPrimitive: newMergeSorter([]int{1}), }, }, { input: &binlogdatapb.Rule{ @@ -120,6 +134,8 @@ func TestVDiffPlanSuccess(t *testing.T) { targetExpression: "select c1, c2 from t1 order by c1 asc", compareCols: []int{-1, 1}, comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), }, }, { // non-pk text column. @@ -134,6 +150,8 @@ func TestVDiffPlanSuccess(t *testing.T) { targetExpression: "select c1, textcol, weight_string(textcol) from nonpktext order by c1 asc", compareCols: []int{-1, 2}, comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), }, }, { // non-pk text column, different order. @@ -148,6 +166,8 @@ func TestVDiffPlanSuccess(t *testing.T) { targetExpression: "select textcol, c1, weight_string(textcol) from nonpktext order by c1 asc", compareCols: []int{2, -1}, comparePKs: []int{1}, + sourcePrimitive: newMergeSorter([]int{1}), + targetPrimitive: newMergeSorter([]int{1}), }, }, { // pk text column. @@ -162,6 +182,8 @@ func TestVDiffPlanSuccess(t *testing.T) { targetExpression: "select textcol, c2, weight_string(textcol) from pktext order by textcol asc", compareCols: []int{-1, 1}, comparePKs: []int{2}, + sourcePrimitive: newMergeSorter([]int{2}), + targetPrimitive: newMergeSorter([]int{2}), }, }, { // pk text column, different order. @@ -176,6 +198,8 @@ func TestVDiffPlanSuccess(t *testing.T) { targetExpression: "select c2, textcol, weight_string(textcol) from pktext order by textcol asc", compareCols: []int{0, -1}, comparePKs: []int{2}, + sourcePrimitive: newMergeSorter([]int{2}), + targetPrimitive: newMergeSorter([]int{2}), }, }, { // text column as expression. @@ -190,6 +214,8 @@ func TestVDiffPlanSuccess(t *testing.T) { targetExpression: "select c2, textcol, weight_string(textcol) from pktext order by textcol asc", compareCols: []int{0, -1}, comparePKs: []int{2}, + sourcePrimitive: newMergeSorter([]int{2}), + targetPrimitive: newMergeSorter([]int{2}), }, }, { input: &binlogdatapb.Rule{ @@ -202,6 +228,8 @@ func TestVDiffPlanSuccess(t *testing.T) { targetExpression: "select c1, c2 from multipk order by c1 asc, c2 asc", compareCols: []int{-1, -1}, comparePKs: []int{0, 1}, + sourcePrimitive: newMergeSorter([]int{0, 1}), + targetPrimitive: newMergeSorter([]int{0, 1}), }, }, { // in_keyrange @@ -216,6 +244,8 @@ func TestVDiffPlanSuccess(t *testing.T) { targetExpression: "select c1, c2 from t1 order by c1 asc", compareCols: []int{-1, 1}, comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), }, }, { // in_keyrange on RHS of AND. @@ -231,6 +261,8 @@ func TestVDiffPlanSuccess(t *testing.T) { targetExpression: "select c1, c2 from t1 order by c1 asc", compareCols: []int{-1, 1}, comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), }, }, { // in_keyrange on LHS of AND. @@ -246,6 +278,8 @@ func TestVDiffPlanSuccess(t *testing.T) { targetExpression: "select c1, c2 from t1 order by c1 asc", compareCols: []int{-1, 1}, comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), }, }, { // in_keyrange on cascaded AND expression @@ -261,6 +295,8 @@ func TestVDiffPlanSuccess(t *testing.T) { targetExpression: "select c1, c2 from t1 order by c1 asc", compareCols: []int{-1, 1}, comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), }, }, { // in_keyrange parenthesized @@ -276,6 +312,8 @@ func TestVDiffPlanSuccess(t *testing.T) { targetExpression: "select c1, c2 from t1 order by c1 asc", compareCols: []int{-1, 1}, comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), }, }, { // group by @@ -290,6 +328,34 @@ func TestVDiffPlanSuccess(t *testing.T) { targetExpression: "select c1, c2 from t1 order by c1 asc", compareCols: []int{-1, 1}, comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), + }, + }, { + // aggregations + input: &binlogdatapb.Rule{ + Match: "aggr", + Filter: "select c1, c2, count(*) as c3, sum(c4) as c4 from t1 group by c1", + }, + table: "aggr", + td: &tableDiffer{ + targetTable: "aggr", + sourceExpression: "select c1, c2, count(*) as c3, sum(c4) as c4 from t1 group by c1 order by c1 asc", + targetExpression: "select c1, c2, c3, c4 from aggr order by c1 asc", + compareCols: []int{-1, 1, 2, 3}, + comparePKs: []int{0}, + sourcePrimitive: &engine.OrderedAggregate{ + Aggregates: []engine.AggregateParams{{ + Opcode: engine.AggregateCount, + Col: 2, + }, { + Opcode: engine.AggregateSum, + Col: 3, + }}, + Keys: []int{0}, + Input: newMergeSorter([]int{0}), + }, + targetPrimitive: newMergeSorter([]int{0}), }, }} for _, tcase := range testcases { @@ -485,7 +551,7 @@ func TestVDiffUnsharded(t *testing.T) { for _, tcase := range testcases { env.tablets[101].setResults("select c1, c2 from t1 order by c1 asc", vdiffSourceGtid, tcase.source) - env.tablets[201].setResults("select c1, c2 from t1 order by c1 asc", vdiffSourceGtid, tcase.target) + env.tablets[201].setResults("select c1, c2 from t1 order by c1 asc", vdiffTargetMasterPosition, tcase.target) dr, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second) require.NoError(t, err) @@ -535,14 +601,14 @@ func TestVDiffSharded(t *testing.T) { ) env.tablets[201].setResults( query, - vdiffSourceGtid, + vdiffTargetMasterPosition, sqltypes.MakeTestStreamingResults(fields, "1|3", ), ) env.tablets[211].setResults( query, - vdiffSourceGtid, + vdiffTargetMasterPosition, sqltypes.MakeTestStreamingResults(fields, "2|4", "3|4", @@ -558,6 +624,72 @@ func TestVDiffSharded(t *testing.T) { assert.Equal(t, wantdr, dr["t1"]) } +func TestVDiffAggregates(t *testing.T) { + env := newTestVDiffEnv([]string{"-40", "40-"}, []string{"-80", "80-"}, "select c1, count(*) c2, sum(c3) c3 from t group by c1", nil) + defer env.close() + + schm := &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ + Name: "t1", + Columns: []string{"c1", "c2", "c3"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2|c3", "int64|int64|int64"), + }}, + } + env.tmc.schema = schm + + sourceQuery := "select c1, count(*) as c2, sum(c3) as c3 from t group by c1 order by c1 asc" + fields := sqltypes.MakeTestFields( + "c1|c2|c3", + "int64|int64|int64", + ) + + env.tablets[101].setResults( + sourceQuery, + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(fields, + "1|3|4", + "2|4|5", + "4|5|6", + ), + ) + env.tablets[111].setResults( + sourceQuery, + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(fields, + "1|1|1", + "3|2|2", + "5|3|3", + ), + ) + targetQuery := "select c1, c2, c3 from t1 order by c1 asc" + env.tablets[201].setResults( + targetQuery, + vdiffTargetMasterPosition, + sqltypes.MakeTestStreamingResults(fields, + "1|4|5", + "5|3|3", + ), + ) + env.tablets[211].setResults( + targetQuery, + vdiffTargetMasterPosition, + sqltypes.MakeTestStreamingResults(fields, + "2|4|5", + "3|2|2", + "4|5|6", + ), + ) + + dr, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second) + require.NoError(t, err) + wantdr := &DiffReport{ + ProcessedRows: 5, + MatchingRows: 5, + } + assert.Equal(t, wantdr, dr["t1"]) +} + func TestVDiffPKWeightString(t *testing.T) { // Also test that highest position ""MariaDB/5-456-892" will be used // if lower positions are found. @@ -598,14 +730,14 @@ func TestVDiffPKWeightString(t *testing.T) { ) env.tablets[201].setResults( query, - vdiffSourceGtid, + vdiffTargetMasterPosition, sqltypes.MakeTestStreamingResults(fields, "A|3|A", ), ) env.tablets[211].setResults( query, - vdiffSourceGtid, + vdiffTargetMasterPosition, sqltypes.MakeTestStreamingResults(fields, "b|4|B", "c|5|C", @@ -662,14 +794,14 @@ func TestVDiffNoPKWeightString(t *testing.T) { ) env.tablets[201].setResults( query, - vdiffSourceGtid, + vdiffTargetMasterPosition, sqltypes.MakeTestStreamingResults(fields, "3|A|A", ), ) env.tablets[211].setResults( query, - vdiffSourceGtid, + vdiffTargetMasterPosition, sqltypes.MakeTestStreamingResults(fields, "4|b|B", "5|c|C", @@ -713,7 +845,7 @@ func TestVDiffDefaults(t *testing.T) { ) target := source env.tablets[101].setResults("select c1, c2 from t1 order by c1 asc", vdiffSourceGtid, source) - env.tablets[201].setResults("select c1, c2 from t1 order by c1 asc", vdiffSourceGtid, target) + env.tablets[201].setResults("select c1, c2 from t1 order by c1 asc", vdiffTargetMasterPosition, target) _, err := env.wr.VDiff(context.Background(), "target", env.workflow, "", "", "replica", 30*time.Second) require.NoError(t, err) @@ -750,7 +882,7 @@ func TestVDiffReplicationWait(t *testing.T) { ) target := source env.tablets[101].setResults("select c1, c2 from t1 order by c1 asc", vdiffSourceGtid, source) - env.tablets[201].setResults("select c1, c2 from t1 order by c1 asc", vdiffSourceGtid, target) + env.tablets[201].setResults("select c1, c2 from t1 order by c1 asc", vdiffTargetMasterPosition, target) _, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 0*time.Second) require.EqualError(t, err, "startQueryStreams(sources): WaitForPosition for tablet cell-0000000101: context deadline exceeded") From 81afa303101eb9f0d86372cd0a0c9a3ca0a765f1 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Mon, 28 Oct 2019 11:34:00 -0700 Subject: [PATCH 26/28] vreplication: re-introduce healthcheck timeouts Some tests still depend on the healthcheck timeout options. So, tablet picker still needs to accept them as arguments. Signed-off-by: Sugu Sougoumarane --- go/vt/discovery/tablet_picker.go | 13 +++---------- go/vt/discovery/tablet_picker_test.go | 10 +++++----- go/vt/vtctl/vtctl.go | 3 ++- .../tabletmanager/vreplication/controller.go | 9 +++++++-- go/vt/wrangler/vdiff.go | 11 ++++++----- go/vt/wrangler/vdiff_test.go | 18 +++++++++--------- 6 files changed, 32 insertions(+), 32 deletions(-) diff --git a/go/vt/discovery/tablet_picker.go b/go/vt/discovery/tablet_picker.go index 32f71316bc3..1cd75ab60c2 100644 --- a/go/vt/discovery/tablet_picker.go +++ b/go/vt/discovery/tablet_picker.go @@ -28,13 +28,6 @@ import ( "vitess.io/vitess/go/vt/vterrors" ) -// These are vars because they need to be overridden for testing. -var ( - healthCheckTopologyRefresh = 30 * time.Second - healthcheckRetryDelay = 5 * time.Second - healthCheckTimeout = 1 * time.Minute -) - // TabletPicker gives a simplified API for picking tablets. type TabletPicker struct { ts *topo.Server @@ -49,16 +42,16 @@ type TabletPicker struct { } // NewTabletPicker returns a TabletPicker. -func NewTabletPicker(ctx context.Context, ts *topo.Server, cell, keyspace, shard, tabletTypesStr string) (*TabletPicker, error) { +func NewTabletPicker(ctx context.Context, ts *topo.Server, cell, keyspace, shard, tabletTypesStr string, healthcheckTopologyRefresh, healthcheckRetryDelay, healthcheckTimeout time.Duration) (*TabletPicker, error) { tabletTypes, err := topoproto.ParseTabletTypes(tabletTypesStr) if err != nil { return nil, fmt.Errorf("failed to parse list of tablet types: %v", tabletTypesStr) } // These have to be initialized in the following sequence (watcher must be last). - healthCheck := NewHealthCheck(healthcheckRetryDelay, healthCheckTimeout) + healthCheck := NewHealthCheck(healthcheckRetryDelay, healthcheckTimeout) statsCache := NewTabletStatsCache(healthCheck, ts, cell) - watcher := NewShardReplicationWatcher(ctx, ts, healthCheck, cell, keyspace, shard, healthCheckTopologyRefresh, DefaultTopoReadConcurrency) + watcher := NewShardReplicationWatcher(ctx, ts, healthCheck, cell, keyspace, shard, healthcheckTopologyRefresh, DefaultTopoReadConcurrency) return &TabletPicker{ ts: ts, diff --git a/go/vt/discovery/tablet_picker_test.go b/go/vt/discovery/tablet_picker_test.go index d73dd83af9f..dcbd84e649d 100644 --- a/go/vt/discovery/tablet_picker_test.go +++ b/go/vt/discovery/tablet_picker_test.go @@ -35,7 +35,7 @@ func TestPickSimple(t *testing.T) { want := addTablet(te, 100, topodatapb.TabletType_REPLICA, true, true) defer deleteTablet(te, want) - tp, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "replica") + tp, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "replica", 1*time.Second, 1*time.Second, 1*time.Minute) require.NoError(t, err) defer tp.Close() @@ -53,7 +53,7 @@ func TestPickFromTwoHealthy(t *testing.T) { want2 := addTablet(te, 101, topodatapb.TabletType_RDONLY, true, true) defer deleteTablet(te, want2) - tp, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "replica,rdonly") + tp, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "replica,rdonly", 1*time.Second, 1*time.Second, 1*time.Minute) require.NoError(t, err) defer tp.Close() @@ -79,7 +79,7 @@ func TestPickFromSomeUnhealthy(t *testing.T) { want := addTablet(te, 101, topodatapb.TabletType_RDONLY, false, true) defer deleteTablet(te, want) - tp, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "replica,rdonly") + tp, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "replica,rdonly", 1*time.Second, 1*time.Second, 1*time.Minute) require.NoError(t, err) defer tp.Close() @@ -94,10 +94,10 @@ func TestPickError(t *testing.T) { te := newPickerTestEnv(t) defer deleteTablet(te, addTablet(te, 100, topodatapb.TabletType_REPLICA, false, false)) - _, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "badtype") + _, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "badtype", 1*time.Second, 1*time.Second, 1*time.Minute) assert.EqualError(t, err, "failed to parse list of tablet types: badtype") - tp, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "replica,rdonly") + tp, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "replica,rdonly", 1*time.Second, 1*time.Second, 1*time.Minute) require.NoError(t, err) defer tp.Close() diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index a94e29aeea2..d8cd3d18e75 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -1824,7 +1824,8 @@ func commandVDiff(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.Fla } targetKeyspace := subFlags.Arg(0) - _, err := wr.VDiff(ctx, targetKeyspace, *workflow, *sourceCell, *targetCell, *tabletTypes, *filteredReplicationWaitTime) + _, err := wr.VDiff(ctx, targetKeyspace, *workflow, *sourceCell, *targetCell, *tabletTypes, *filteredReplicationWaitTime, + *HealthCheckTopologyRefresh, *HealthcheckRetryDelay, *HealthCheckTimeout) return err } diff --git a/go/vt/vttablet/tabletmanager/vreplication/controller.go b/go/vt/vttablet/tabletmanager/vreplication/controller.go index ecdad00f55c..85c957ecb3f 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/controller.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller.go @@ -38,7 +38,12 @@ import ( binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" ) -var retryDelay = flag.Duration("vreplication_retry_delay", 5*time.Second, "delay before retrying a failed binlog connection") +var ( + healthcheckTopologyRefresh = flag.Duration("vreplication_healthcheck_topology_refresh", 30*time.Second, "refresh interval for re-reading the topology") + healthcheckRetryDelay = flag.Duration("vreplication_healthcheck_retry_delay", 5*time.Second, "healthcheck retry delay") + healthcheckTimeout = flag.Duration("vreplication_healthcheck_timeout", 1*time.Minute, "healthcheck retry delay") + retryDelay = flag.Duration("vreplication_retry_delay", 5*time.Second, "delay before retrying a failed binlog connection") +) // controller is created by Engine. Members are initialized upfront. // There is no mutex within a controller becaust its members are @@ -100,7 +105,7 @@ func newController(ctx context.Context, params map[string]string, dbClientFactor if v, ok := params["tablet_types"]; ok { tabletTypesStr = v } - tp, err := discovery.NewTabletPicker(ctx, ts, cell, ct.source.Keyspace, ct.source.Shard, tabletTypesStr) + tp, err := discovery.NewTabletPicker(ctx, ts, cell, ct.source.Keyspace, ct.source.Shard, tabletTypesStr, *healthcheckTopologyRefresh, *healthcheckRetryDelay, *healthcheckTimeout) if err != nil { return nil, err } diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index 67eb4d6b004..7b85ed2c653 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -83,7 +83,8 @@ type dfParams struct { } // VDiff reports differences between the sources and targets of a vreplication workflow. -func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow, sourceCell, targetCell, tabletTypesStr string, filteredReplicationWaitTime time.Duration) (map[string]*DiffReport, error) { +func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow, sourceCell, targetCell, tabletTypesStr string, + filteredReplicationWaitTime, healthcheckTopologyRefresh, healthcheckRetryDelay, healthcheckTimeout time.Duration) (map[string]*DiffReport, error) { if sourceCell == "" && targetCell == "" { cells, err := wr.ts.GetCellInfoNames(ctx) if err != nil { @@ -144,7 +145,7 @@ func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow, sourceC if err != nil { return nil, vterrors.Wrap(err, "buildVDiffPlan") } - if err := df.selectTablets(ctx); err != nil { + if err := df.selectTablets(ctx, healthcheckTopologyRefresh, healthcheckRetryDelay, healthcheckTimeout); err != nil { return nil, vterrors.Wrap(err, "selectTablets") } defer func(ctx context.Context) { @@ -332,7 +333,7 @@ func buildDifferPlan(table *tabletmanagerdatapb.TableDefinition, query string) ( return td, nil } -func (df *vdiff) selectTablets(ctx context.Context) error { +func (df *vdiff) selectTablets(ctx context.Context, healthcheckTopologyRefresh, healthcheckRetryDelay, healthcheckTimeout time.Duration) error { var wg sync.WaitGroup var err1, err2 error @@ -341,7 +342,7 @@ func (df *vdiff) selectTablets(ctx context.Context) error { go func() { defer wg.Done() err1 = df.forAll(df.sources, func(shard string, source *dfParams) error { - tp, err := discovery.NewTabletPicker(ctx, df.mi.wr.ts, df.sourceCell, df.mi.sourceKeyspace, shard, df.tabletTypesStr) + tp, err := discovery.NewTabletPicker(ctx, df.mi.wr.ts, df.sourceCell, df.mi.sourceKeyspace, shard, df.tabletTypesStr, healthcheckTopologyRefresh, healthcheckRetryDelay, healthcheckTimeout) if err != nil { return err } @@ -360,7 +361,7 @@ func (df *vdiff) selectTablets(ctx context.Context) error { go func() { defer wg.Done() err2 = df.forAll(df.targets, func(shard string, target *dfParams) error { - tp, err := discovery.NewTabletPicker(ctx, df.mi.wr.ts, df.targetCell, df.mi.targetKeyspace, shard, df.tabletTypesStr) + tp, err := discovery.NewTabletPicker(ctx, df.mi.wr.ts, df.targetCell, df.mi.targetKeyspace, shard, df.tabletTypesStr, healthcheckTopologyRefresh, healthcheckRetryDelay, healthcheckTimeout) if err != nil { return err } diff --git a/go/vt/wrangler/vdiff_test.go b/go/vt/wrangler/vdiff_test.go index 4934fa68eaf..b2f92131c31 100644 --- a/go/vt/wrangler/vdiff_test.go +++ b/go/vt/wrangler/vdiff_test.go @@ -553,7 +553,7 @@ func TestVDiffUnsharded(t *testing.T) { env.tablets[101].setResults("select c1, c2 from t1 order by c1 asc", vdiffSourceGtid, tcase.source) env.tablets[201].setResults("select c1, c2 from t1 order by c1 asc", vdiffTargetMasterPosition, tcase.target) - dr, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second) + dr, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second, 1*time.Second, 1*time.Second, 1*time.Minute) require.NoError(t, err) assert.Equal(t, tcase.dr, dr["t1"], tcase.id) } @@ -615,7 +615,7 @@ func TestVDiffSharded(t *testing.T) { ), ) - dr, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second) + dr, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second, 1*time.Second, 1*time.Second, 1*time.Minute) require.NoError(t, err) wantdr := &DiffReport{ ProcessedRows: 3, @@ -681,7 +681,7 @@ func TestVDiffAggregates(t *testing.T) { ), ) - dr, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second) + dr, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second, 1*time.Second, 1*time.Second, 1*time.Minute) require.NoError(t, err) wantdr := &DiffReport{ ProcessedRows: 5, @@ -745,7 +745,7 @@ func TestVDiffPKWeightString(t *testing.T) { ), ) - dr, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second) + dr, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second, 1*time.Second, 1*time.Second, 1*time.Minute) require.NoError(t, err) wantdr := &DiffReport{ ProcessedRows: 4, @@ -809,7 +809,7 @@ func TestVDiffNoPKWeightString(t *testing.T) { ), ) - dr, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second) + dr, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second, 1*time.Second, 1*time.Second, 1*time.Minute) require.NoError(t, err) wantdr := &DiffReport{ ProcessedRows: 4, @@ -847,11 +847,11 @@ func TestVDiffDefaults(t *testing.T) { env.tablets[101].setResults("select c1, c2 from t1 order by c1 asc", vdiffSourceGtid, source) env.tablets[201].setResults("select c1, c2 from t1 order by c1 asc", vdiffTargetMasterPosition, target) - _, err := env.wr.VDiff(context.Background(), "target", env.workflow, "", "", "replica", 30*time.Second) + _, err := env.wr.VDiff(context.Background(), "target", env.workflow, "", "", "replica", 30*time.Second, 1*time.Second, 1*time.Second, 1*time.Minute) require.NoError(t, err) - _, err = env.wr.VDiff(context.Background(), "target", env.workflow, "", env.cell, "replica", 30*time.Second) + _, err = env.wr.VDiff(context.Background(), "target", env.workflow, "", env.cell, "replica", 30*time.Second, 1*time.Second, 1*time.Second, 1*time.Minute) require.NoError(t, err) - _, err = env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, "", "replica", 30*time.Second) + _, err = env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, "", "replica", 30*time.Second, 1*time.Second, 1*time.Second, 1*time.Minute) require.NoError(t, err) } @@ -884,6 +884,6 @@ func TestVDiffReplicationWait(t *testing.T) { env.tablets[101].setResults("select c1, c2 from t1 order by c1 asc", vdiffSourceGtid, source) env.tablets[201].setResults("select c1, c2 from t1 order by c1 asc", vdiffTargetMasterPosition, target) - _, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 0*time.Second) + _, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 0*time.Second, 1*time.Second, 1*time.Second, 1*time.Minute) require.EqualError(t, err, "startQueryStreams(sources): WaitForPosition for tablet cell-0000000101: context deadline exceeded") } From 7d8a08d6a6a4df9f23856ee383c5380fbd71dd7f Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 2 Nov 2019 18:06:39 -0700 Subject: [PATCH 27/28] vdiff: post-rebase fix change test to handle new mastership rules Signed-off-by: Sugu Sougoumarane --- go/vt/wrangler/vdiff_env_test.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/go/vt/wrangler/vdiff_env_test.go b/go/vt/wrangler/vdiff_env_test.go index afebe51d7c0..f41db6315e8 100644 --- a/go/vt/wrangler/vdiff_env_test.go +++ b/go/vt/wrangler/vdiff_env_test.go @@ -186,6 +186,15 @@ func (env *testVDiffEnv) addTablet(id int, keyspace, shard string, tabletType to if err := env.wr.InitTablet(context.Background(), tablet, false /* allowMasterOverride */, true /* createShardAndKeyspace */, false /* allowUpdate */); err != nil { panic(err) } + if tabletType == topodatapb.TabletType_MASTER { + _, err := env.wr.ts.UpdateShardFields(context.Background(), keyspace, shard, func(si *topo.ShardInfo) error { + si.MasterAlias = tablet.Alias + return nil + }) + if err != nil { + panic(err) + } + } return env.tablets[id] } From 1b8bece4fa96c3b73a7a8ddb783a1319b1bea1b2 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 2 Nov 2019 18:28:18 -0700 Subject: [PATCH 28/28] vdiff: fix broken tabletmanagerdata_pb2.py Signed-off-by: Sugu Sougoumarane --- py/vtproto/tabletmanagerdata_pb2.py | 114 ++++++---------------------- 1 file changed, 25 insertions(+), 89 deletions(-) diff --git a/py/vtproto/tabletmanagerdata_pb2.py b/py/vtproto/tabletmanagerdata_pb2.py index ac459f35a93..0b246f994d9 100644 --- a/py/vtproto/tabletmanagerdata_pb2.py +++ b/py/vtproto/tabletmanagerdata_pb2.py @@ -23,11 +23,7 @@ package='tabletmanagerdata', syntax='proto3', serialized_options=_b('Z.vitess.io/vitess/go/vt/proto/tabletmanagerdata'), -<<<<<<< HEAD - serialized_pb=_b('\n\x17tabletmanagerdata.proto\x12\x11tabletmanagerdata\x1a\x0bquery.proto\x1a\x0etopodata.proto\x1a\x15replicationdata.proto\x1a\rlogutil.proto\"\xb1\x01\n\x0fTableDefinition\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06schema\x18\x02 \x01(\t\x12\x0f\n\x07\x63olumns\x18\x03 \x03(\t\x12\x1b\n\x13primary_key_columns\x18\x04 \x03(\t\x12\x0c\n\x04type\x18\x05 \x01(\t\x12\x13\n\x0b\x64\x61ta_length\x18\x06 \x01(\x04\x12\x11\n\trow_count\x18\x07 \x01(\x04\x12\x1c\n\x06\x66ields\x18\x08 \x03(\x0b\x32\x0c.query.Field\"{\n\x10SchemaDefinition\x12\x17\n\x0f\x64\x61tabase_schema\x18\x01 \x01(\t\x12=\n\x11table_definitions\x18\x02 \x03(\x0b\x32\".tabletmanagerdata.TableDefinition\x12\x0f\n\x07version\x18\x03 \x01(\t\"\x8b\x01\n\x12SchemaChangeResult\x12:\n\rbefore_schema\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x02 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\xc1\x01\n\x0eUserPermission\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x0c\n\x04user\x18\x02 \x01(\t\x12\x19\n\x11password_checksum\x18\x03 \x01(\x04\x12\x45\n\nprivileges\x18\x04 \x03(\x0b\x32\x31.tabletmanagerdata.UserPermission.PrivilegesEntry\x1a\x31\n\x0fPrivilegesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xae\x01\n\x0c\x44\x62Permission\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\n\n\x02\x64\x62\x18\x02 \x01(\t\x12\x0c\n\x04user\x18\x03 \x01(\t\x12\x43\n\nprivileges\x18\x04 \x03(\x0b\x32/.tabletmanagerdata.DbPermission.PrivilegesEntry\x1a\x31\n\x0fPrivilegesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x83\x01\n\x0bPermissions\x12;\n\x10user_permissions\x18\x01 \x03(\x0b\x32!.tabletmanagerdata.UserPermission\x12\x37\n\x0e\x64\x62_permissions\x18\x02 \x03(\x0b\x32\x1f.tabletmanagerdata.DbPermission\"\x1e\n\x0bPingRequest\x12\x0f\n\x07payload\x18\x01 \x01(\t\"\x1f\n\x0cPingResponse\x12\x0f\n\x07payload\x18\x01 \x01(\t\" \n\x0cSleepRequest\x12\x10\n\x08\x64uration\x18\x01 \x01(\x03\"\x0f\n\rSleepResponse\"\xaf\x01\n\x12\x45xecuteHookRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\nparameters\x18\x02 \x03(\t\x12\x46\n\textra_env\x18\x03 \x03(\x0b\x32\x33.tabletmanagerdata.ExecuteHookRequest.ExtraEnvEntry\x1a/\n\rExtraEnvEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"J\n\x13\x45xecuteHookResponse\x12\x13\n\x0b\x65xit_status\x18\x01 \x01(\x03\x12\x0e\n\x06stdout\x18\x02 \x01(\t\x12\x0e\n\x06stderr\x18\x03 \x01(\t\"Q\n\x10GetSchemaRequest\x12\x0e\n\x06tables\x18\x01 \x03(\t\x12\x15\n\rinclude_views\x18\x02 \x01(\x08\x12\x16\n\x0e\x65xclude_tables\x18\x03 \x03(\t\"S\n\x11GetSchemaResponse\x12>\n\x11schema_definition\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x17\n\x15GetPermissionsRequest\"M\n\x16GetPermissionsResponse\x12\x33\n\x0bpermissions\x18\x01 \x01(\x0b\x32\x1e.tabletmanagerdata.Permissions\"\x14\n\x12SetReadOnlyRequest\"\x15\n\x13SetReadOnlyResponse\"\x15\n\x13SetReadWriteRequest\"\x16\n\x14SetReadWriteResponse\">\n\x11\x43hangeTypeRequest\x12)\n\x0btablet_type\x18\x01 \x01(\x0e\x32\x14.topodata.TabletType\"\x14\n\x12\x43hangeTypeResponse\"\x15\n\x13RefreshStateRequest\"\x16\n\x14RefreshStateResponse\"\x17\n\x15RunHealthCheckRequest\"\x18\n\x16RunHealthCheckResponse\"+\n\x18IgnoreHealthErrorRequest\x12\x0f\n\x07pattern\x18\x01 \x01(\t\"\x1b\n\x19IgnoreHealthErrorResponse\",\n\x13ReloadSchemaRequest\x12\x15\n\rwait_position\x18\x01 \x01(\t\"\x16\n\x14ReloadSchemaResponse\")\n\x16PreflightSchemaRequest\x12\x0f\n\x07\x63hanges\x18\x01 \x03(\t\"X\n\x17PreflightSchemaResponse\x12=\n\x0e\x63hange_results\x18\x01 \x03(\x0b\x32%.tabletmanagerdata.SchemaChangeResult\"\xc2\x01\n\x12\x41pplySchemaRequest\x12\x0b\n\x03sql\x18\x01 \x01(\t\x12\r\n\x05\x66orce\x18\x02 \x01(\x08\x12\x19\n\x11\x61llow_replication\x18\x03 \x01(\x08\x12:\n\rbefore_schema\x18\x04 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x05 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x8c\x01\n\x13\x41pplySchemaResponse\x12:\n\rbefore_schema\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x02 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x13\n\x11LockTablesRequest\"\x14\n\x12LockTablesResponse\"\x15\n\x13UnlockTablesRequest\"\x16\n\x14UnlockTablesResponse\"|\n\x18\x45xecuteFetchAsDbaRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x0f\n\x07\x64\x62_name\x18\x02 \x01(\t\x12\x10\n\x08max_rows\x18\x03 \x01(\x04\x12\x17\n\x0f\x64isable_binlogs\x18\x04 \x01(\x08\x12\x15\n\rreload_schema\x18\x05 \x01(\x08\"?\n\x19\x45xecuteFetchAsDbaResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"h\n\x1d\x45xecuteFetchAsAllPrivsRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x0f\n\x07\x64\x62_name\x18\x02 \x01(\t\x12\x10\n\x08max_rows\x18\x03 \x01(\x04\x12\x15\n\rreload_schema\x18\x04 \x01(\x08\"D\n\x1e\x45xecuteFetchAsAllPrivsResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\";\n\x18\x45xecuteFetchAsAppRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x10\n\x08max_rows\x18\x02 \x01(\x04\"?\n\x19\x45xecuteFetchAsAppResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"\x14\n\x12SlaveStatusRequest\">\n\x13SlaveStatusResponse\x12\'\n\x06status\x18\x01 \x01(\x0b\x32\x17.replicationdata.Status\"\x17\n\x15MasterPositionRequest\"*\n\x16MasterPositionResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x12\n\x10StopSlaveRequest\"\x13\n\x11StopSlaveResponse\"A\n\x17StopSlaveMinimumRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x14\n\x0cwait_timeout\x18\x02 \x01(\x03\",\n\x18StopSlaveMinimumResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x13\n\x11StartSlaveRequest\"\x14\n\x12StartSlaveResponse\"E\n\x1bStartSlaveUntilAfterRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x14\n\x0cwait_timeout\x18\x02 \x01(\x03\"\x1e\n\x1cStartSlaveUntilAfterResponse\"8\n!TabletExternallyReparentedRequest\x12\x13\n\x0b\x65xternal_id\x18\x01 \x01(\t\"$\n\"TabletExternallyReparentedResponse\" \n\x1eTabletExternallyElectedRequest\"!\n\x1fTabletExternallyElectedResponse\"\x12\n\x10GetSlavesRequest\"\"\n\x11GetSlavesResponse\x12\r\n\x05\x61\x64\x64rs\x18\x01 \x03(\t\"\x19\n\x17ResetReplicationRequest\"\x1a\n\x18ResetReplicationResponse\"(\n\x17VReplicationExecRequest\x12\r\n\x05query\x18\x01 \x01(\t\">\n\x18VReplicationExecResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"=\n\x1dVReplicationWaitForPosRequest\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08position\x18\x02 \x01(\t\" \n\x1eVReplicationWaitForPosResponse\"\x13\n\x11InitMasterRequest\"&\n\x12InitMasterResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x99\x01\n\x1ePopulateReparentJournalRequest\x12\x17\n\x0ftime_created_ns\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63tion_name\x18\x02 \x01(\t\x12+\n\x0cmaster_alias\x18\x03 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x1c\n\x14replication_position\x18\x04 \x01(\t\"!\n\x1fPopulateReparentJournalResponse\"p\n\x10InitSlaveRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x1c\n\x14replication_position\x18\x02 \x01(\t\x12\x17\n\x0ftime_created_ns\x18\x03 \x01(\x03\"\x13\n\x11InitSlaveResponse\"\x15\n\x13\x44\x65moteMasterRequest\"(\n\x14\x44\x65moteMasterResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17UndoDemoteMasterRequest\"\x1a\n\x18UndoDemoteMasterResponse\"3\n\x1fPromoteSlaveWhenCaughtUpRequest\x12\x10\n\x08position\x18\x01 \x01(\t\"4\n PromoteSlaveWhenCaughtUpResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17SlaveWasPromotedRequest\"\x1a\n\x18SlaveWasPromotedResponse\"\x84\x01\n\x10SetMasterRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x17\n\x0ftime_created_ns\x18\x02 \x01(\x03\x12\x15\n\rwait_position\x18\x04 \x01(\t\x12\x19\n\x11\x66orce_start_slave\x18\x03 \x01(\x08\"\x13\n\x11SetMasterResponse\"A\n\x18SlaveWasRestartedRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\"\x1b\n\x19SlaveWasRestartedResponse\"$\n\"StopReplicationAndGetStatusRequest\"N\n#StopReplicationAndGetStatusResponse\x12\'\n\x06status\x18\x01 \x01(\x0b\x32\x17.replicationdata.Status\"\x15\n\x13PromoteSlaveRequest\"(\n\x14PromoteSlaveResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"9\n\rBackupRequest\x12\x13\n\x0b\x63oncurrency\x18\x01 \x01(\x03\x12\x13\n\x0b\x61llowMaster\x18\x02 \x01(\x08\"/\n\x0e\x42\x61\x63kupResponse\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.logutil.Event\"\x1a\n\x18RestoreFromBackupRequest\":\n\x19RestoreFromBackupResponse\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.logutil.EventB0Z.vitess.io/vitess/go/vt/proto/tabletmanagerdatab\x06proto3') -======= - serialized_pb=_b('\n\x17tabletmanagerdata.proto\x12\x11tabletmanagerdata\x1a\x0bquery.proto\x1a\x0etopodata.proto\x1a\x15replicationdata.proto\x1a\rlogutil.proto\"\xb1\x01\n\x0fTableDefinition\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06schema\x18\x02 \x01(\t\x12\x0f\n\x07\x63olumns\x18\x03 \x03(\t\x12\x1b\n\x13primary_key_columns\x18\x04 \x03(\t\x12\x0c\n\x04type\x18\x05 \x01(\t\x12\x13\n\x0b\x64\x61ta_length\x18\x06 \x01(\x04\x12\x11\n\trow_count\x18\x07 \x01(\x04\x12\x1c\n\x06\x66ields\x18\x08 \x03(\x0b\x32\x0c.query.Field\"{\n\x10SchemaDefinition\x12\x17\n\x0f\x64\x61tabase_schema\x18\x01 \x01(\t\x12=\n\x11table_definitions\x18\x02 \x03(\x0b\x32\".tabletmanagerdata.TableDefinition\x12\x0f\n\x07version\x18\x03 \x01(\t\"\x8b\x01\n\x12SchemaChangeResult\x12:\n\rbefore_schema\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x02 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\xc1\x01\n\x0eUserPermission\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x0c\n\x04user\x18\x02 \x01(\t\x12\x19\n\x11password_checksum\x18\x03 \x01(\x04\x12\x45\n\nprivileges\x18\x04 \x03(\x0b\x32\x31.tabletmanagerdata.UserPermission.PrivilegesEntry\x1a\x31\n\x0fPrivilegesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xae\x01\n\x0c\x44\x62Permission\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\n\n\x02\x64\x62\x18\x02 \x01(\t\x12\x0c\n\x04user\x18\x03 \x01(\t\x12\x43\n\nprivileges\x18\x04 \x03(\x0b\x32/.tabletmanagerdata.DbPermission.PrivilegesEntry\x1a\x31\n\x0fPrivilegesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x83\x01\n\x0bPermissions\x12;\n\x10user_permissions\x18\x01 \x03(\x0b\x32!.tabletmanagerdata.UserPermission\x12\x37\n\x0e\x64\x62_permissions\x18\x02 \x03(\x0b\x32\x1f.tabletmanagerdata.DbPermission\"\x1e\n\x0bPingRequest\x12\x0f\n\x07payload\x18\x01 \x01(\t\"\x1f\n\x0cPingResponse\x12\x0f\n\x07payload\x18\x01 \x01(\t\" \n\x0cSleepRequest\x12\x10\n\x08\x64uration\x18\x01 \x01(\x03\"\x0f\n\rSleepResponse\"\xaf\x01\n\x12\x45xecuteHookRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\nparameters\x18\x02 \x03(\t\x12\x46\n\textra_env\x18\x03 \x03(\x0b\x32\x33.tabletmanagerdata.ExecuteHookRequest.ExtraEnvEntry\x1a/\n\rExtraEnvEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"J\n\x13\x45xecuteHookResponse\x12\x13\n\x0b\x65xit_status\x18\x01 \x01(\x03\x12\x0e\n\x06stdout\x18\x02 \x01(\t\x12\x0e\n\x06stderr\x18\x03 \x01(\t\"Q\n\x10GetSchemaRequest\x12\x0e\n\x06tables\x18\x01 \x03(\t\x12\x15\n\rinclude_views\x18\x02 \x01(\x08\x12\x16\n\x0e\x65xclude_tables\x18\x03 \x03(\t\"S\n\x11GetSchemaResponse\x12>\n\x11schema_definition\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x17\n\x15GetPermissionsRequest\"M\n\x16GetPermissionsResponse\x12\x33\n\x0bpermissions\x18\x01 \x01(\x0b\x32\x1e.tabletmanagerdata.Permissions\"\x14\n\x12SetReadOnlyRequest\"\x15\n\x13SetReadOnlyResponse\"\x15\n\x13SetReadWriteRequest\"\x16\n\x14SetReadWriteResponse\">\n\x11\x43hangeTypeRequest\x12)\n\x0btablet_type\x18\x01 \x01(\x0e\x32\x14.topodata.TabletType\"\x14\n\x12\x43hangeTypeResponse\"\x15\n\x13RefreshStateRequest\"\x16\n\x14RefreshStateResponse\"\x17\n\x15RunHealthCheckRequest\"\x18\n\x16RunHealthCheckResponse\"+\n\x18IgnoreHealthErrorRequest\x12\x0f\n\x07pattern\x18\x01 \x01(\t\"\x1b\n\x19IgnoreHealthErrorResponse\",\n\x13ReloadSchemaRequest\x12\x15\n\rwait_position\x18\x01 \x01(\t\"\x16\n\x14ReloadSchemaResponse\")\n\x16PreflightSchemaRequest\x12\x0f\n\x07\x63hanges\x18\x01 \x03(\t\"X\n\x17PreflightSchemaResponse\x12=\n\x0e\x63hange_results\x18\x01 \x03(\x0b\x32%.tabletmanagerdata.SchemaChangeResult\"\xc2\x01\n\x12\x41pplySchemaRequest\x12\x0b\n\x03sql\x18\x01 \x01(\t\x12\r\n\x05\x66orce\x18\x02 \x01(\x08\x12\x19\n\x11\x61llow_replication\x18\x03 \x01(\x08\x12:\n\rbefore_schema\x18\x04 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x05 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x8c\x01\n\x13\x41pplySchemaResponse\x12:\n\rbefore_schema\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x02 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x13\n\x11LockTablesRequest\"\x14\n\x12LockTablesResponse\"\x15\n\x13UnlockTablesRequest\"\x16\n\x14UnlockTablesResponse\"|\n\x18\x45xecuteFetchAsDbaRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x0f\n\x07\x64\x62_name\x18\x02 \x01(\t\x12\x10\n\x08max_rows\x18\x03 \x01(\x04\x12\x17\n\x0f\x64isable_binlogs\x18\x04 \x01(\x08\x12\x15\n\rreload_schema\x18\x05 \x01(\x08\"?\n\x19\x45xecuteFetchAsDbaResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"h\n\x1d\x45xecuteFetchAsAllPrivsRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x0f\n\x07\x64\x62_name\x18\x02 \x01(\t\x12\x10\n\x08max_rows\x18\x03 \x01(\x04\x12\x15\n\rreload_schema\x18\x04 \x01(\x08\"D\n\x1e\x45xecuteFetchAsAllPrivsResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\";\n\x18\x45xecuteFetchAsAppRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x10\n\x08max_rows\x18\x02 \x01(\x04\"?\n\x19\x45xecuteFetchAsAppResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"\x14\n\x12SlaveStatusRequest\">\n\x13SlaveStatusResponse\x12\'\n\x06status\x18\x01 \x01(\x0b\x32\x17.replicationdata.Status\"\x17\n\x15MasterPositionRequest\"*\n\x16MasterPositionResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"*\n\x16WaitForPositionRequest\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17WaitForPositionResponse\"\x12\n\x10StopSlaveRequest\"\x13\n\x11StopSlaveResponse\"A\n\x17StopSlaveMinimumRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x14\n\x0cwait_timeout\x18\x02 \x01(\x03\",\n\x18StopSlaveMinimumResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x13\n\x11StartSlaveRequest\"\x14\n\x12StartSlaveResponse\"E\n\x1bStartSlaveUntilAfterRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x14\n\x0cwait_timeout\x18\x02 \x01(\x03\"\x1e\n\x1cStartSlaveUntilAfterResponse\"8\n!TabletExternallyReparentedRequest\x12\x13\n\x0b\x65xternal_id\x18\x01 \x01(\t\"$\n\"TabletExternallyReparentedResponse\" \n\x1eTabletExternallyElectedRequest\"!\n\x1fTabletExternallyElectedResponse\"\x12\n\x10GetSlavesRequest\"\"\n\x11GetSlavesResponse\x12\r\n\x05\x61\x64\x64rs\x18\x01 \x03(\t\"\x19\n\x17ResetReplicationRequest\"\x1a\n\x18ResetReplicationResponse\"(\n\x17VReplicationExecRequest\x12\r\n\x05query\x18\x01 \x01(\t\">\n\x18VReplicationExecResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"=\n\x1dVReplicationWaitForPosRequest\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08position\x18\x02 \x01(\t\" \n\x1eVReplicationWaitForPosResponse\"\x13\n\x11InitMasterRequest\"&\n\x12InitMasterResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x99\x01\n\x1ePopulateReparentJournalRequest\x12\x17\n\x0ftime_created_ns\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63tion_name\x18\x02 \x01(\t\x12+\n\x0cmaster_alias\x18\x03 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x1c\n\x14replication_position\x18\x04 \x01(\t\"!\n\x1fPopulateReparentJournalResponse\"p\n\x10InitSlaveRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x1c\n\x14replication_position\x18\x02 \x01(\t\x12\x17\n\x0ftime_created_ns\x18\x03 \x01(\x03\"\x13\n\x11InitSlaveResponse\"\x15\n\x13\x44\x65moteMasterRequest\"(\n\x14\x44\x65moteMasterResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17UndoDemoteMasterRequest\"\x1a\n\x18UndoDemoteMasterResponse\"3\n\x1fPromoteSlaveWhenCaughtUpRequest\x12\x10\n\x08position\x18\x01 \x01(\t\"4\n PromoteSlaveWhenCaughtUpResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17SlaveWasPromotedRequest\"\x1a\n\x18SlaveWasPromotedResponse\"m\n\x10SetMasterRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x17\n\x0ftime_created_ns\x18\x02 \x01(\x03\x12\x19\n\x11\x66orce_start_slave\x18\x03 \x01(\x08\"\x13\n\x11SetMasterResponse\"A\n\x18SlaveWasRestartedRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\"\x1b\n\x19SlaveWasRestartedResponse\"$\n\"StopReplicationAndGetStatusRequest\"N\n#StopReplicationAndGetStatusResponse\x12\'\n\x06status\x18\x01 \x01(\x0b\x32\x17.replicationdata.Status\"\x15\n\x13PromoteSlaveRequest\"(\n\x14PromoteSlaveResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"9\n\rBackupRequest\x12\x13\n\x0b\x63oncurrency\x18\x01 \x01(\x03\x12\x13\n\x0b\x61llowMaster\x18\x02 \x01(\x08\"/\n\x0e\x42\x61\x63kupResponse\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.logutil.Event\"\x1a\n\x18RestoreFromBackupRequest\":\n\x19RestoreFromBackupResponse\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.logutil.EventB0Z.vitess.io/vitess/go/vt/proto/tabletmanagerdatab\x06proto3') ->>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition + serialized_pb=_b('\n\x17tabletmanagerdata.proto\x12\x11tabletmanagerdata\x1a\x0bquery.proto\x1a\x0etopodata.proto\x1a\x15replicationdata.proto\x1a\rlogutil.proto\"\xb1\x01\n\x0fTableDefinition\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06schema\x18\x02 \x01(\t\x12\x0f\n\x07\x63olumns\x18\x03 \x03(\t\x12\x1b\n\x13primary_key_columns\x18\x04 \x03(\t\x12\x0c\n\x04type\x18\x05 \x01(\t\x12\x13\n\x0b\x64\x61ta_length\x18\x06 \x01(\x04\x12\x11\n\trow_count\x18\x07 \x01(\x04\x12\x1c\n\x06\x66ields\x18\x08 \x03(\x0b\x32\x0c.query.Field\"{\n\x10SchemaDefinition\x12\x17\n\x0f\x64\x61tabase_schema\x18\x01 \x01(\t\x12=\n\x11table_definitions\x18\x02 \x03(\x0b\x32\".tabletmanagerdata.TableDefinition\x12\x0f\n\x07version\x18\x03 \x01(\t\"\x8b\x01\n\x12SchemaChangeResult\x12:\n\rbefore_schema\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x02 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\xc1\x01\n\x0eUserPermission\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x0c\n\x04user\x18\x02 \x01(\t\x12\x19\n\x11password_checksum\x18\x03 \x01(\x04\x12\x45\n\nprivileges\x18\x04 \x03(\x0b\x32\x31.tabletmanagerdata.UserPermission.PrivilegesEntry\x1a\x31\n\x0fPrivilegesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xae\x01\n\x0c\x44\x62Permission\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\n\n\x02\x64\x62\x18\x02 \x01(\t\x12\x0c\n\x04user\x18\x03 \x01(\t\x12\x43\n\nprivileges\x18\x04 \x03(\x0b\x32/.tabletmanagerdata.DbPermission.PrivilegesEntry\x1a\x31\n\x0fPrivilegesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x83\x01\n\x0bPermissions\x12;\n\x10user_permissions\x18\x01 \x03(\x0b\x32!.tabletmanagerdata.UserPermission\x12\x37\n\x0e\x64\x62_permissions\x18\x02 \x03(\x0b\x32\x1f.tabletmanagerdata.DbPermission\"\x1e\n\x0bPingRequest\x12\x0f\n\x07payload\x18\x01 \x01(\t\"\x1f\n\x0cPingResponse\x12\x0f\n\x07payload\x18\x01 \x01(\t\" \n\x0cSleepRequest\x12\x10\n\x08\x64uration\x18\x01 \x01(\x03\"\x0f\n\rSleepResponse\"\xaf\x01\n\x12\x45xecuteHookRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\nparameters\x18\x02 \x03(\t\x12\x46\n\textra_env\x18\x03 \x03(\x0b\x32\x33.tabletmanagerdata.ExecuteHookRequest.ExtraEnvEntry\x1a/\n\rExtraEnvEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"J\n\x13\x45xecuteHookResponse\x12\x13\n\x0b\x65xit_status\x18\x01 \x01(\x03\x12\x0e\n\x06stdout\x18\x02 \x01(\t\x12\x0e\n\x06stderr\x18\x03 \x01(\t\"Q\n\x10GetSchemaRequest\x12\x0e\n\x06tables\x18\x01 \x03(\t\x12\x15\n\rinclude_views\x18\x02 \x01(\x08\x12\x16\n\x0e\x65xclude_tables\x18\x03 \x03(\t\"S\n\x11GetSchemaResponse\x12>\n\x11schema_definition\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x17\n\x15GetPermissionsRequest\"M\n\x16GetPermissionsResponse\x12\x33\n\x0bpermissions\x18\x01 \x01(\x0b\x32\x1e.tabletmanagerdata.Permissions\"\x14\n\x12SetReadOnlyRequest\"\x15\n\x13SetReadOnlyResponse\"\x15\n\x13SetReadWriteRequest\"\x16\n\x14SetReadWriteResponse\">\n\x11\x43hangeTypeRequest\x12)\n\x0btablet_type\x18\x01 \x01(\x0e\x32\x14.topodata.TabletType\"\x14\n\x12\x43hangeTypeResponse\"\x15\n\x13RefreshStateRequest\"\x16\n\x14RefreshStateResponse\"\x17\n\x15RunHealthCheckRequest\"\x18\n\x16RunHealthCheckResponse\"+\n\x18IgnoreHealthErrorRequest\x12\x0f\n\x07pattern\x18\x01 \x01(\t\"\x1b\n\x19IgnoreHealthErrorResponse\",\n\x13ReloadSchemaRequest\x12\x15\n\rwait_position\x18\x01 \x01(\t\"\x16\n\x14ReloadSchemaResponse\")\n\x16PreflightSchemaRequest\x12\x0f\n\x07\x63hanges\x18\x01 \x03(\t\"X\n\x17PreflightSchemaResponse\x12=\n\x0e\x63hange_results\x18\x01 \x03(\x0b\x32%.tabletmanagerdata.SchemaChangeResult\"\xc2\x01\n\x12\x41pplySchemaRequest\x12\x0b\n\x03sql\x18\x01 \x01(\t\x12\r\n\x05\x66orce\x18\x02 \x01(\x08\x12\x19\n\x11\x61llow_replication\x18\x03 \x01(\x08\x12:\n\rbefore_schema\x18\x04 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x05 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x8c\x01\n\x13\x41pplySchemaResponse\x12:\n\rbefore_schema\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x02 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x13\n\x11LockTablesRequest\"\x14\n\x12LockTablesResponse\"\x15\n\x13UnlockTablesRequest\"\x16\n\x14UnlockTablesResponse\"|\n\x18\x45xecuteFetchAsDbaRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x0f\n\x07\x64\x62_name\x18\x02 \x01(\t\x12\x10\n\x08max_rows\x18\x03 \x01(\x04\x12\x17\n\x0f\x64isable_binlogs\x18\x04 \x01(\x08\x12\x15\n\rreload_schema\x18\x05 \x01(\x08\"?\n\x19\x45xecuteFetchAsDbaResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"h\n\x1d\x45xecuteFetchAsAllPrivsRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x0f\n\x07\x64\x62_name\x18\x02 \x01(\t\x12\x10\n\x08max_rows\x18\x03 \x01(\x04\x12\x15\n\rreload_schema\x18\x04 \x01(\x08\"D\n\x1e\x45xecuteFetchAsAllPrivsResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\";\n\x18\x45xecuteFetchAsAppRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x10\n\x08max_rows\x18\x02 \x01(\x04\"?\n\x19\x45xecuteFetchAsAppResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"\x14\n\x12SlaveStatusRequest\">\n\x13SlaveStatusResponse\x12\'\n\x06status\x18\x01 \x01(\x0b\x32\x17.replicationdata.Status\"\x17\n\x15MasterPositionRequest\"*\n\x16MasterPositionResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"*\n\x16WaitForPositionRequest\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17WaitForPositionResponse\"\x12\n\x10StopSlaveRequest\"\x13\n\x11StopSlaveResponse\"A\n\x17StopSlaveMinimumRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x14\n\x0cwait_timeout\x18\x02 \x01(\x03\",\n\x18StopSlaveMinimumResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x13\n\x11StartSlaveRequest\"\x14\n\x12StartSlaveResponse\"E\n\x1bStartSlaveUntilAfterRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x14\n\x0cwait_timeout\x18\x02 \x01(\x03\"\x1e\n\x1cStartSlaveUntilAfterResponse\"8\n!TabletExternallyReparentedRequest\x12\x13\n\x0b\x65xternal_id\x18\x01 \x01(\t\"$\n\"TabletExternallyReparentedResponse\" \n\x1eTabletExternallyElectedRequest\"!\n\x1fTabletExternallyElectedResponse\"\x12\n\x10GetSlavesRequest\"\"\n\x11GetSlavesResponse\x12\r\n\x05\x61\x64\x64rs\x18\x01 \x03(\t\"\x19\n\x17ResetReplicationRequest\"\x1a\n\x18ResetReplicationResponse\"(\n\x17VReplicationExecRequest\x12\r\n\x05query\x18\x01 \x01(\t\">\n\x18VReplicationExecResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"=\n\x1dVReplicationWaitForPosRequest\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08position\x18\x02 \x01(\t\" \n\x1eVReplicationWaitForPosResponse\"\x13\n\x11InitMasterRequest\"&\n\x12InitMasterResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x99\x01\n\x1ePopulateReparentJournalRequest\x12\x17\n\x0ftime_created_ns\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63tion_name\x18\x02 \x01(\t\x12+\n\x0cmaster_alias\x18\x03 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x1c\n\x14replication_position\x18\x04 \x01(\t\"!\n\x1fPopulateReparentJournalResponse\"p\n\x10InitSlaveRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x1c\n\x14replication_position\x18\x02 \x01(\t\x12\x17\n\x0ftime_created_ns\x18\x03 \x01(\x03\"\x13\n\x11InitSlaveResponse\"\x15\n\x13\x44\x65moteMasterRequest\"(\n\x14\x44\x65moteMasterResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17UndoDemoteMasterRequest\"\x1a\n\x18UndoDemoteMasterResponse\"3\n\x1fPromoteSlaveWhenCaughtUpRequest\x12\x10\n\x08position\x18\x01 \x01(\t\"4\n PromoteSlaveWhenCaughtUpResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17SlaveWasPromotedRequest\"\x1a\n\x18SlaveWasPromotedResponse\"\x84\x01\n\x10SetMasterRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x17\n\x0ftime_created_ns\x18\x02 \x01(\x03\x12\x15\n\rwait_position\x18\x04 \x01(\t\x12\x19\n\x11\x66orce_start_slave\x18\x03 \x01(\x08\"\x13\n\x11SetMasterResponse\"A\n\x18SlaveWasRestartedRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\"\x1b\n\x19SlaveWasRestartedResponse\"$\n\"StopReplicationAndGetStatusRequest\"N\n#StopReplicationAndGetStatusResponse\x12\'\n\x06status\x18\x01 \x01(\x0b\x32\x17.replicationdata.Status\"\x15\n\x13PromoteSlaveRequest\"(\n\x14PromoteSlaveResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"9\n\rBackupRequest\x12\x13\n\x0b\x63oncurrency\x18\x01 \x01(\x03\x12\x13\n\x0b\x61llowMaster\x18\x02 \x01(\x08\"/\n\x0e\x42\x61\x63kupResponse\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.logutil.Event\"\x1a\n\x18RestoreFromBackupRequest\":\n\x19RestoreFromBackupResponse\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.logutil.EventB0Z.vitess.io/vitess/go/vt/proto/tabletmanagerdatab\x06proto3') , dependencies=[query__pb2.DESCRIPTOR,topodata__pb2.DESCRIPTOR,replicationdata__pb2.DESCRIPTOR,logutil__pb2.DESCRIPTOR,]) @@ -2824,13 +2820,8 @@ extension_ranges=[], oneofs=[ ], -<<<<<<< HEAD - serialized_start=4789, - serialized_end=4921, -======= - serialized_start=4859, - serialized_end=4968, ->>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition + serialized_start=4860, + serialized_end=4992, ) @@ -2853,13 +2844,8 @@ extension_ranges=[], oneofs=[ ], -<<<<<<< HEAD - serialized_start=4923, - serialized_end=4942, -======= - serialized_start=4970, - serialized_end=4989, ->>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition + serialized_start=4994, + serialized_end=5013, ) @@ -2889,13 +2875,8 @@ extension_ranges=[], oneofs=[ ], -<<<<<<< HEAD - serialized_start=4944, - serialized_end=5009, -======= - serialized_start=4991, - serialized_end=5056, ->>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition + serialized_start=5015, + serialized_end=5080, ) @@ -2918,13 +2899,8 @@ extension_ranges=[], oneofs=[ ], -<<<<<<< HEAD - serialized_start=5011, - serialized_end=5038, -======= - serialized_start=5058, - serialized_end=5085, ->>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition + serialized_start=5082, + serialized_end=5109, ) @@ -2947,13 +2923,8 @@ extension_ranges=[], oneofs=[ ], -<<<<<<< HEAD - serialized_start=5040, - serialized_end=5076, -======= - serialized_start=5087, - serialized_end=5123, ->>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition + serialized_start=5111, + serialized_end=5147, ) @@ -2983,13 +2954,8 @@ extension_ranges=[], oneofs=[ ], -<<<<<<< HEAD - serialized_start=5078, - serialized_end=5156, -======= - serialized_start=5125, - serialized_end=5203, ->>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition + serialized_start=5149, + serialized_end=5227, ) @@ -3012,13 +2978,8 @@ extension_ranges=[], oneofs=[ ], -<<<<<<< HEAD - serialized_start=5158, - serialized_end=5179, -======= - serialized_start=5205, - serialized_end=5226, ->>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition + serialized_start=5229, + serialized_end=5250, ) @@ -3048,13 +3009,8 @@ extension_ranges=[], oneofs=[ ], -<<<<<<< HEAD - serialized_start=5181, - serialized_end=5221, -======= - serialized_start=5228, - serialized_end=5268, ->>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition + serialized_start=5252, + serialized_end=5292, ) @@ -3091,13 +3047,8 @@ extension_ranges=[], oneofs=[ ], -<<<<<<< HEAD - serialized_start=5223, - serialized_end=5280, -======= - serialized_start=5270, - serialized_end=5327, ->>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition + serialized_start=5294, + serialized_end=5351, ) @@ -3127,13 +3078,8 @@ extension_ranges=[], oneofs=[ ], -<<<<<<< HEAD - serialized_start=5282, - serialized_end=5329, -======= - serialized_start=5329, - serialized_end=5376, ->>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition + serialized_start=5353, + serialized_end=5400, ) @@ -3156,13 +3102,8 @@ extension_ranges=[], oneofs=[ ], -<<<<<<< HEAD - serialized_start=5331, - serialized_end=5357, -======= - serialized_start=5378, - serialized_end=5404, ->>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition + serialized_start=5402, + serialized_end=5428, ) @@ -3192,13 +3133,8 @@ extension_ranges=[], oneofs=[ ], -<<<<<<< HEAD - serialized_start=5359, - serialized_end=5417, -======= - serialized_start=5406, - serialized_end=5464, ->>>>>>> 1ba2c8b09... tabletmanager: WaitForPosition + serialized_start=5430, + serialized_end=5488, ) _TABLEDEFINITION.fields_by_name['fields'].message_type = query__pb2._FIELD