vitess.io/vitess@v0.16.2/go/vt/vtcombo/tablet_map.go (about) 1 /* 2 Copyright 2019 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package vtcombo 18 19 import ( 20 "context" 21 "fmt" 22 "os" 23 "path" 24 "time" 25 26 "vitess.io/vitess/go/sqltypes" 27 "vitess.io/vitess/go/vt/dbconfigs" 28 "vitess.io/vitess/go/vt/grpcclient" 29 "vitess.io/vitess/go/vt/hook" 30 "vitess.io/vitess/go/vt/log" 31 "vitess.io/vitess/go/vt/logutil" 32 "vitess.io/vitess/go/vt/mysqlctl" 33 "vitess.io/vitess/go/vt/mysqlctl/tmutils" 34 "vitess.io/vitess/go/vt/topo" 35 "vitess.io/vitess/go/vt/topo/topoproto" 36 "vitess.io/vitess/go/vt/topotools" 37 "vitess.io/vitess/go/vt/vterrors" 38 "vitess.io/vitess/go/vt/vtgate/vindexes" 39 "vitess.io/vitess/go/vt/vttablet/queryservice" 40 "vitess.io/vitess/go/vt/vttablet/tabletconn" 41 "vitess.io/vitess/go/vt/vttablet/tabletmanager" 42 "vitess.io/vitess/go/vt/vttablet/tabletserver" 43 "vitess.io/vitess/go/vt/vttablet/tmclient" 44 "vitess.io/vitess/go/vt/wrangler" 45 46 binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" 47 querypb "vitess.io/vitess/go/vt/proto/query" 48 replicationdatapb "vitess.io/vitess/go/vt/proto/replicationdata" 49 tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" 50 topodatapb "vitess.io/vitess/go/vt/proto/topodata" 51 vschemapb "vitess.io/vitess/go/vt/proto/vschema" 52 vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" 53 vttestpb "vitess.io/vitess/go/vt/proto/vttest" 54 ) 55 56 // tablet contains all the data for an individual tablet. 57 type comboTablet struct { 58 // configuration parameters 59 alias *topodatapb.TabletAlias 60 keyspace string 61 shard string 62 tabletType topodatapb.TabletType 63 dbname string 64 uid uint32 65 66 // objects built at construction time 67 qsc tabletserver.Controller 68 tm *tabletmanager.TabletManager 69 } 70 71 // tabletMap maps the tablet uid to the tablet record 72 var tabletMap map[uint32]*comboTablet 73 74 // CreateTablet creates an individual tablet, with its tm, and adds 75 // it to the map. If it's a primary tablet, it also issues a TER. 76 func CreateTablet( 77 ctx context.Context, 78 ts *topo.Server, 79 cell string, 80 uid uint32, 81 keyspace, shard, dbname string, 82 tabletType topodatapb.TabletType, 83 mysqld mysqlctl.MysqlDaemon, 84 dbcfgs *dbconfigs.DBConfigs, 85 ) error { 86 alias := &topodatapb.TabletAlias{ 87 Cell: cell, 88 Uid: uid, 89 } 90 log.Infof("Creating %v tablet %v for %v/%v", tabletType, topoproto.TabletAliasString(alias), keyspace, shard) 91 92 controller := tabletserver.NewServer(topoproto.TabletAliasString(alias), ts, alias) 93 initTabletType := tabletType 94 if tabletType == topodatapb.TabletType_PRIMARY { 95 initTabletType = topodatapb.TabletType_REPLICA 96 } 97 _, kr, err := topo.ValidateShardName(shard) 98 if err != nil { 99 return err 100 } 101 tm := &tabletmanager.TabletManager{ 102 BatchCtx: context.Background(), 103 TopoServer: ts, 104 MysqlDaemon: mysqld, 105 DBConfigs: dbcfgs, 106 QueryServiceControl: controller, 107 } 108 tablet := &topodatapb.Tablet{ 109 Alias: alias, 110 PortMap: map[string]int32{ 111 "vt": int32(8000 + uid), 112 "grpc": int32(9000 + uid), 113 }, 114 Keyspace: keyspace, 115 Shard: shard, 116 KeyRange: kr, 117 Type: initTabletType, 118 DbNameOverride: dbname, 119 } 120 if err := tm.Start(tablet, 0); err != nil { 121 return err 122 } 123 124 if tabletType == topodatapb.TabletType_PRIMARY { 125 // Semi-sync has to be set to false, since we have 1 single backing MySQL 126 if err := tm.ChangeType(ctx, topodatapb.TabletType_PRIMARY /* semi-sync */, false); err != nil { 127 return fmt.Errorf("TabletExternallyReparented failed on primary %v: %v", topoproto.TabletAliasString(alias), err) 128 } 129 } 130 controller.AddStatusHeader() 131 controller.AddStatusPart() 132 tabletMap[uid] = &comboTablet{ 133 alias: alias, 134 keyspace: keyspace, 135 shard: shard, 136 tabletType: tabletType, 137 dbname: dbname, 138 uid: uid, 139 140 qsc: controller, 141 tm: tm, 142 } 143 return nil 144 } 145 146 // InitRoutingRules saves the routing rules into ts and reloads the vschema. 147 func InitRoutingRules( 148 ctx context.Context, 149 ts *topo.Server, 150 rr *vschemapb.RoutingRules, 151 ) error { 152 if rr == nil { 153 return nil 154 } 155 156 if err := ts.SaveRoutingRules(ctx, rr); err != nil { 157 return err 158 } 159 160 return ts.RebuildSrvVSchema(ctx, nil) 161 } 162 163 // InitTabletMap creates the action tms and associated data structures 164 // for all tablets, based on the vttest proto parameter. 165 func InitTabletMap( 166 ts *topo.Server, 167 tpb *vttestpb.VTTestTopology, 168 mysqld mysqlctl.MysqlDaemon, 169 dbcfgs *dbconfigs.DBConfigs, 170 schemaDir string, 171 ensureDatabase bool, 172 ) (uint32, error) { 173 tabletMap = make(map[uint32]*comboTablet) 174 175 ctx := context.Background() 176 177 // Register the tablet manager client factory for tablet manager 178 // Do this before any tablets are created so that they respect the protocol, 179 // otherwise it defaults to grpc. 180 // 181 // main() forces the --tablet_manager_protocol flag to this value. 182 tmclient.RegisterTabletManagerClientFactory("internal", func() tmclient.TabletManagerClient { 183 return &internalTabletManagerClient{} 184 }) 185 186 // iterate through the keyspaces 187 wr := wrangler.New(logutil.NewConsoleLogger(), ts, nil) 188 var uid uint32 = 1 189 for _, kpb := range tpb.Keyspaces { 190 var err error 191 uid, err = CreateKs(ctx, ts, tpb, mysqld, dbcfgs, schemaDir, kpb, ensureDatabase, uid, wr) 192 if err != nil { 193 return 0, err 194 } 195 } 196 197 // Rebuild the SrvVSchema object 198 if err := ts.RebuildSrvVSchema(ctx, tpb.Cells); err != nil { 199 return 0, fmt.Errorf("RebuildVSchemaGraph failed: %v", err) 200 } 201 202 // Register the tablet dialer for tablet server. main() forces the --tablet_protocol 203 // flag to this value. 204 tabletconn.RegisterDialer("internal", dialer) 205 206 // run healthcheck on all vttablets 207 tmc := tmclient.NewTabletManagerClient() 208 for _, tablet := range tabletMap { 209 tabletInfo, err := ts.GetTablet(ctx, tablet.alias) 210 if err != nil { 211 return 0, fmt.Errorf("cannot find tablet: %+v", tablet.alias) 212 } 213 tmc.RunHealthCheck(ctx, tabletInfo.Tablet) 214 } 215 216 return uid, nil 217 } 218 219 // DeleteKs deletes keyspace, shards and tablets with mysql databases 220 func DeleteKs( 221 ctx context.Context, 222 ts *topo.Server, 223 ksName string, 224 mysqld mysqlctl.MysqlDaemon, 225 tpb *vttestpb.VTTestTopology, 226 ) error { 227 for key, tablet := range tabletMap { 228 if tablet.keyspace == ksName { 229 delete(tabletMap, key) 230 tablet.tm.Stop() 231 tablet.tm.Close() 232 tablet.qsc.SchemaEngine().Close() 233 err := ts.DeleteTablet(ctx, tablet.alias) 234 if err != nil { 235 return err 236 } 237 } 238 } 239 240 var ks *vttestpb.Keyspace 241 index := 0 242 for _, keyspace := range tpb.Keyspaces { 243 if keyspace.Name == ksName { 244 ks = keyspace 245 break 246 } 247 index++ 248 } 249 if ks == nil { 250 return fmt.Errorf("database not found") 251 } 252 253 conn, err := mysqld.GetDbaConnection(ctx) 254 if err != nil { 255 return err 256 } 257 defer conn.Close() 258 for _, shard := range ks.Shards { 259 q := fmt.Sprintf("DROP DATABASE IF EXISTS `vt_%s_%s`", ksName, shard.GetName()) 260 if _, err = conn.ExecuteFetch(q, 1, false); err != nil { 261 return err 262 } 263 if err := ts.DeleteShard(ctx, ksName, shard.GetName()); err != nil { 264 return err 265 } 266 } 267 268 if err = ts.DeleteKeyspace(ctx, ksName); err != nil { 269 return err 270 } 271 272 kss := tpb.Keyspaces // to save on chars 273 copy(kss[index:], kss[index+1:]) // shift keyspaces to the left, overwriting the value to remove 274 tpb.Keyspaces = kss[:len(kss)-1] // shrink the slice by one 275 276 return nil 277 } 278 279 // CreateKs creates keyspace, shards and tablets with mysql database 280 func CreateKs( 281 ctx context.Context, 282 ts *topo.Server, 283 tpb *vttestpb.VTTestTopology, 284 mysqld mysqlctl.MysqlDaemon, 285 dbcfgs *dbconfigs.DBConfigs, 286 schemaDir string, 287 kpb *vttestpb.Keyspace, 288 ensureDatabase bool, 289 uid uint32, 290 wr *wrangler.Wrangler, 291 ) (uint32, error) { 292 keyspace := kpb.Name 293 294 if kpb.ServedFrom != "" { 295 // if we have a redirect, create a completely redirected 296 // keyspace and no tablet 297 if err := ts.CreateKeyspace(ctx, keyspace, &topodatapb.Keyspace{ 298 ServedFroms: []*topodatapb.Keyspace_ServedFrom{ 299 { 300 TabletType: topodatapb.TabletType_PRIMARY, 301 Keyspace: kpb.ServedFrom, 302 }, 303 { 304 TabletType: topodatapb.TabletType_REPLICA, 305 Keyspace: kpb.ServedFrom, 306 }, 307 { 308 TabletType: topodatapb.TabletType_RDONLY, 309 Keyspace: kpb.ServedFrom, 310 }, 311 }, 312 }); err != nil { 313 return 0, fmt.Errorf("CreateKeyspace(%v) failed: %v", keyspace, err) 314 } 315 } else { 316 // create a regular keyspace 317 if err := ts.CreateKeyspace(ctx, keyspace, &topodatapb.Keyspace{}); err != nil { 318 return 0, fmt.Errorf("CreateKeyspace(%v) failed: %v", keyspace, err) 319 } 320 321 // iterate through the shards 322 for _, spb := range kpb.Shards { 323 shard := spb.Name 324 if err := ts.CreateShard(ctx, keyspace, shard); err != nil { 325 return 0, fmt.Errorf("CreateShard(%v:%v) failed: %v", keyspace, shard, err) 326 } 327 328 for _, cell := range tpb.Cells { 329 dbname := spb.DbNameOverride 330 if dbname == "" { 331 dbname = fmt.Sprintf("vt_%v_%v", keyspace, shard) 332 } 333 334 replicas := int(kpb.ReplicaCount) 335 if replicas == 0 { 336 // 2 replicas in order to ensure the primary cell has a primary and a replica 337 replicas = 2 338 } 339 rdonlys := int(kpb.RdonlyCount) 340 if rdonlys == 0 { 341 rdonlys = 1 342 } 343 344 if ensureDatabase { 345 // Create Database if not exist 346 conn, err := mysqld.GetDbaConnection(context.TODO()) 347 if err != nil { 348 return 0, fmt.Errorf("GetConnection failed: %v", err) 349 } 350 defer conn.Close() 351 352 _, err = conn.ExecuteFetch("CREATE DATABASE IF NOT EXISTS `"+dbname+"`", 1, false) 353 if err != nil { 354 return 0, fmt.Errorf("error ensuring database exists: %v", err) 355 } 356 357 } 358 if cell == tpb.Cells[0] { 359 replicas-- 360 361 // create the primary 362 if err := CreateTablet(ctx, ts, cell, uid, keyspace, shard, dbname, topodatapb.TabletType_PRIMARY, mysqld, dbcfgs.Clone()); err != nil { 363 return 0, err 364 } 365 uid++ 366 } 367 368 for i := 0; i < replicas; i++ { 369 // create a replica tablet 370 if err := CreateTablet(ctx, ts, cell, uid, keyspace, shard, dbname, topodatapb.TabletType_REPLICA, mysqld, dbcfgs.Clone()); err != nil { 371 return 0, err 372 } 373 uid++ 374 } 375 376 for i := 0; i < rdonlys; i++ { 377 // create a rdonly tablet 378 if err := CreateTablet(ctx, ts, cell, uid, keyspace, shard, dbname, topodatapb.TabletType_RDONLY, mysqld, dbcfgs.Clone()); err != nil { 379 return 0, err 380 } 381 uid++ 382 } 383 } 384 } 385 } 386 387 // vschema for the keyspace 388 if schemaDir != "" { 389 f := path.Join(schemaDir, keyspace, "vschema.json") 390 if _, err := os.Stat(f); err == nil { 391 // load the vschema 392 formal, err := vindexes.LoadFormalKeyspace(f) 393 if err != nil { 394 return 0, fmt.Errorf("cannot load vschema file %v for keyspace %v: %v", f, keyspace, err) 395 } 396 397 if err := ts.SaveVSchema(ctx, keyspace, formal); err != nil { 398 return 0, fmt.Errorf("SaveVSchema(%v) failed: %v", keyspace, err) 399 } 400 } else { 401 log.Infof("File %v doesn't exist, skipping vschema for keyspace %v", f, keyspace) 402 } 403 } 404 405 // Rebuild the SrvKeyspace object, so we can support 406 // range-based sharding queries, and export the redirects. 407 if err := topotools.RebuildKeyspace(ctx, wr.Logger(), wr.TopoServer(), keyspace, nil, false); err != nil { 408 return 0, fmt.Errorf("cannot rebuild %v: %v", keyspace, err) 409 } 410 return uid, nil 411 } 412 413 // 414 // TabletConn implementation 415 // 416 417 // dialer is our tabletconn.Dialer 418 func dialer(tablet *topodatapb.Tablet, failFast grpcclient.FailFast) (queryservice.QueryService, error) { 419 t, ok := tabletMap[tablet.Alias.Uid] 420 if !ok { 421 return nil, vterrors.New(vtrpcpb.Code_UNAVAILABLE, "connection refused") 422 } 423 424 return &internalTabletConn{ 425 tablet: t, 426 topoTablet: tablet, 427 }, nil 428 } 429 430 // internalTabletConn implements queryservice.QueryService by forwarding everything 431 // to the tablet 432 type internalTabletConn struct { 433 tablet *comboTablet 434 topoTablet *topodatapb.Tablet 435 } 436 437 var _ queryservice.QueryService = (*internalTabletConn)(nil) 438 439 // Execute is part of queryservice.QueryService 440 // We need to copy the bind variables as tablet server will change them. 441 func (itc *internalTabletConn) Execute( 442 ctx context.Context, 443 target *querypb.Target, 444 query string, 445 bindVars map[string]*querypb.BindVariable, 446 transactionID, reservedID int64, 447 options *querypb.ExecuteOptions, 448 ) (*sqltypes.Result, error) { 449 bindVars = sqltypes.CopyBindVariables(bindVars) 450 reply, err := itc.tablet.qsc.QueryService().Execute(ctx, target, query, bindVars, transactionID, reservedID, options) 451 if err != nil { 452 return nil, tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 453 } 454 return reply, nil 455 } 456 457 // StreamExecute is part of queryservice.QueryService 458 // We need to copy the bind variables as tablet server will change them. 459 func (itc *internalTabletConn) StreamExecute( 460 ctx context.Context, 461 target *querypb.Target, 462 query string, 463 bindVars map[string]*querypb.BindVariable, 464 transactionID int64, 465 reservedID int64, 466 options *querypb.ExecuteOptions, 467 callback func(*sqltypes.Result) error, 468 ) error { 469 bindVars = sqltypes.CopyBindVariables(bindVars) 470 err := itc.tablet.qsc.QueryService().StreamExecute(ctx, target, query, bindVars, transactionID, reservedID, options, callback) 471 return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 472 } 473 474 // Begin is part of queryservice.QueryService 475 func (itc *internalTabletConn) Begin( 476 ctx context.Context, 477 target *querypb.Target, 478 options *querypb.ExecuteOptions, 479 ) (queryservice.TransactionState, error) { 480 state, err := itc.tablet.qsc.QueryService().Begin(ctx, target, options) 481 return state, tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 482 } 483 484 // Commit is part of queryservice.QueryService 485 func (itc *internalTabletConn) Commit(ctx context.Context, target *querypb.Target, transactionID int64) (int64, error) { 486 rID, err := itc.tablet.qsc.QueryService().Commit(ctx, target, transactionID) 487 return rID, tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 488 } 489 490 // Rollback is part of queryservice.QueryService 491 func (itc *internalTabletConn) Rollback(ctx context.Context, target *querypb.Target, transactionID int64) (int64, error) { 492 rID, err := itc.tablet.qsc.QueryService().Rollback(ctx, target, transactionID) 493 return rID, tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 494 } 495 496 // Prepare is part of queryservice.QueryService 497 func (itc *internalTabletConn) Prepare(ctx context.Context, target *querypb.Target, transactionID int64, dtid string) error { 498 err := itc.tablet.qsc.QueryService().Prepare(ctx, target, transactionID, dtid) 499 return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 500 } 501 502 // CommitPrepared is part of queryservice.QueryService 503 func (itc *internalTabletConn) CommitPrepared(ctx context.Context, target *querypb.Target, dtid string) error { 504 err := itc.tablet.qsc.QueryService().CommitPrepared(ctx, target, dtid) 505 return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 506 } 507 508 // RollbackPrepared is part of queryservice.QueryService 509 func (itc *internalTabletConn) RollbackPrepared(ctx context.Context, target *querypb.Target, dtid string, originalID int64) error { 510 err := itc.tablet.qsc.QueryService().RollbackPrepared(ctx, target, dtid, originalID) 511 return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 512 } 513 514 // CreateTransaction is part of queryservice.QueryService 515 func (itc *internalTabletConn) CreateTransaction( 516 ctx context.Context, 517 target *querypb.Target, 518 dtid string, 519 participants []*querypb.Target, 520 ) error { 521 err := itc.tablet.qsc.QueryService().CreateTransaction(ctx, target, dtid, participants) 522 return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 523 } 524 525 // StartCommit is part of queryservice.QueryService 526 func (itc *internalTabletConn) StartCommit(ctx context.Context, target *querypb.Target, transactionID int64, dtid string) error { 527 err := itc.tablet.qsc.QueryService().StartCommit(ctx, target, transactionID, dtid) 528 return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 529 } 530 531 // SetRollback is part of queryservice.QueryService 532 func (itc *internalTabletConn) SetRollback(ctx context.Context, target *querypb.Target, dtid string, transactionID int64) error { 533 err := itc.tablet.qsc.QueryService().SetRollback(ctx, target, dtid, transactionID) 534 return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 535 } 536 537 // ConcludeTransaction is part of queryservice.QueryService 538 func (itc *internalTabletConn) ConcludeTransaction(ctx context.Context, target *querypb.Target, dtid string) error { 539 err := itc.tablet.qsc.QueryService().ConcludeTransaction(ctx, target, dtid) 540 return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 541 } 542 543 // ReadTransaction is part of queryservice.QueryService 544 func (itc *internalTabletConn) ReadTransaction(ctx context.Context, target *querypb.Target, dtid string) (metadata *querypb.TransactionMetadata, err error) { 545 metadata, err = itc.tablet.qsc.QueryService().ReadTransaction(ctx, target, dtid) 546 return metadata, tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 547 } 548 549 // BeginExecute is part of queryservice.QueryService 550 func (itc *internalTabletConn) BeginExecute( 551 ctx context.Context, 552 target *querypb.Target, 553 preQueries []string, 554 query string, 555 bindVars map[string]*querypb.BindVariable, 556 reserveID int64, 557 options *querypb.ExecuteOptions, 558 ) (queryservice.TransactionState, *sqltypes.Result, error) { 559 bindVars = sqltypes.CopyBindVariables(bindVars) 560 state, result, err := itc.tablet.qsc.QueryService().BeginExecute(ctx, target, preQueries, query, bindVars, reserveID, options) 561 return state, result, tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 562 } 563 564 // BeginStreamExecute is part of queryservice.QueryService 565 func (itc *internalTabletConn) BeginStreamExecute( 566 ctx context.Context, 567 target *querypb.Target, 568 preQueries []string, 569 query string, 570 bindVars map[string]*querypb.BindVariable, 571 reservedID int64, 572 options *querypb.ExecuteOptions, 573 callback func(*sqltypes.Result) error, 574 ) (queryservice.TransactionState, error) { 575 bindVars = sqltypes.CopyBindVariables(bindVars) 576 state, err := itc.tablet.qsc.QueryService().BeginStreamExecute(ctx, target, preQueries, query, bindVars, reservedID, options, callback) 577 return state, tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 578 } 579 580 // MessageStream is part of queryservice.QueryService 581 func (itc *internalTabletConn) MessageStream(ctx context.Context, target *querypb.Target, name string, callback func(*sqltypes.Result) error) error { 582 err := itc.tablet.qsc.QueryService().MessageStream(ctx, target, name, callback) 583 return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 584 } 585 586 // MessageAck is part of queryservice.QueryService 587 func (itc *internalTabletConn) MessageAck(ctx context.Context, target *querypb.Target, name string, ids []*querypb.Value) (int64, error) { 588 count, err := itc.tablet.qsc.QueryService().MessageAck(ctx, target, name, ids) 589 return count, tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 590 } 591 592 // HandlePanic is part of the QueryService interface. 593 func (itc *internalTabletConn) HandlePanic(err *error) { 594 } 595 596 // ReserveBeginExecute is part of the QueryService interface. 597 func (itc *internalTabletConn) ReserveBeginExecute( 598 ctx context.Context, 599 target *querypb.Target, 600 preQueries []string, 601 postBeginQueries []string, 602 sql string, 603 bindVariables map[string]*querypb.BindVariable, 604 options *querypb.ExecuteOptions, 605 ) (queryservice.ReservedTransactionState, *sqltypes.Result, error) { 606 bindVariables = sqltypes.CopyBindVariables(bindVariables) 607 state, result, err := itc.tablet.qsc.QueryService().ReserveBeginExecute(ctx, target, preQueries, postBeginQueries, sql, bindVariables, options) 608 return state, result, tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 609 } 610 611 // ReserveBeginStreamExecute is part of the QueryService interface. 612 func (itc *internalTabletConn) ReserveBeginStreamExecute( 613 ctx context.Context, 614 target *querypb.Target, 615 preQueries []string, 616 postBeginQueries []string, 617 sql string, 618 bindVariables map[string]*querypb.BindVariable, 619 options *querypb.ExecuteOptions, 620 callback func(*sqltypes.Result) error, 621 ) (queryservice.ReservedTransactionState, error) { 622 bindVariables = sqltypes.CopyBindVariables(bindVariables) 623 state, err := itc.tablet.qsc.QueryService().ReserveBeginStreamExecute(ctx, target, preQueries, postBeginQueries, sql, bindVariables, options, callback) 624 return state, tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 625 } 626 627 // ReserveExecute is part of the QueryService interface. 628 func (itc *internalTabletConn) ReserveExecute( 629 ctx context.Context, 630 target *querypb.Target, 631 preQueries []string, 632 sql string, 633 bindVariables map[string]*querypb.BindVariable, 634 transactionID int64, 635 options *querypb.ExecuteOptions, 636 ) (queryservice.ReservedState, *sqltypes.Result, error) { 637 bindVariables = sqltypes.CopyBindVariables(bindVariables) 638 state, result, err := itc.tablet.qsc.QueryService().ReserveExecute(ctx, target, preQueries, sql, bindVariables, transactionID, options) 639 return state, result, tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 640 } 641 642 // ReserveStreamExecute is part of the QueryService interface. 643 func (itc *internalTabletConn) ReserveStreamExecute( 644 ctx context.Context, 645 target *querypb.Target, 646 preQueries []string, 647 sql string, 648 bindVariables map[string]*querypb.BindVariable, 649 transactionID int64, 650 options *querypb.ExecuteOptions, 651 callback func(*sqltypes.Result) error, 652 ) (queryservice.ReservedState, error) { 653 bindVariables = sqltypes.CopyBindVariables(bindVariables) 654 state, err := itc.tablet.qsc.QueryService().ReserveStreamExecute(ctx, target, preQueries, sql, bindVariables, transactionID, options, callback) 655 return state, tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 656 } 657 658 // Release is part of the QueryService interface. 659 func (itc *internalTabletConn) Release(ctx context.Context, target *querypb.Target, transactionID, reservedID int64) error { 660 err := itc.tablet.qsc.QueryService().Release(ctx, target, transactionID, reservedID) 661 return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 662 } 663 664 // GetSchema is part of the QueryService interface. 665 func (itc *internalTabletConn) GetSchema(ctx context.Context, target *querypb.Target, tableType querypb.SchemaTableType, tableNames []string, callback func(schemaRes *querypb.GetSchemaResponse) error) error { 666 err := itc.tablet.qsc.QueryService().GetSchema(ctx, target, tableType, tableNames, callback) 667 return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 668 } 669 670 // Close is part of queryservice.QueryService 671 func (itc *internalTabletConn) Close(ctx context.Context) error { 672 return nil 673 } 674 675 // Tablet is part of queryservice.QueryService 676 func (itc *internalTabletConn) Tablet() *topodatapb.Tablet { 677 return itc.topoTablet 678 } 679 680 // StreamHealth is part of queryservice.QueryService 681 func (itc *internalTabletConn) StreamHealth(ctx context.Context, callback func(*querypb.StreamHealthResponse) error) error { 682 err := itc.tablet.qsc.QueryService().StreamHealth(ctx, callback) 683 return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 684 } 685 686 // VStream is part of queryservice.QueryService. 687 func (itc *internalTabletConn) VStream( 688 ctx context.Context, 689 request *binlogdatapb.VStreamRequest, 690 send func([]*binlogdatapb.VEvent) error, 691 ) error { 692 err := itc.tablet.qsc.QueryService().VStream(ctx, request, send) 693 return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 694 } 695 696 // VStreamRows is part of the QueryService interface. 697 func (itc *internalTabletConn) VStreamRows( 698 ctx context.Context, 699 request *binlogdatapb.VStreamRowsRequest, 700 send func(*binlogdatapb.VStreamRowsResponse) error, 701 ) error { 702 err := itc.tablet.qsc.QueryService().VStreamRows(ctx, request, send) 703 return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 704 } 705 706 // VStreamResults is part of the QueryService interface. 707 func (itc *internalTabletConn) VStreamResults( 708 ctx context.Context, 709 target *querypb.Target, 710 query string, 711 send func(*binlogdatapb.VStreamResultsResponse) error, 712 ) error { 713 err := itc.tablet.qsc.QueryService().VStreamResults(ctx, target, query, send) 714 return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) 715 } 716 717 // 718 // TabletManagerClient implementation 719 // 720 721 // internalTabletManagerClient implements tmclient.TabletManagerClient 722 type internalTabletManagerClient struct{} 723 724 func (itmc *internalTabletManagerClient) VDiff(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.VDiffRequest) (*tabletmanagerdatapb.VDiffResponse, error) { 725 return nil, fmt.Errorf("VDiff not implemented in vtcombo") 726 } 727 728 func (itmc *internalTabletManagerClient) LockTables(ctx context.Context, tablet *topodatapb.Tablet) error { 729 return fmt.Errorf("not implemented in vtcombo") 730 } 731 732 func (itmc *internalTabletManagerClient) UnlockTables(ctx context.Context, tablet *topodatapb.Tablet) error { 733 return fmt.Errorf("not implemented in vtcombo") 734 } 735 736 func (itmc *internalTabletManagerClient) Ping(ctx context.Context, tablet *topodatapb.Tablet) error { 737 t, ok := tabletMap[tablet.Alias.Uid] 738 if !ok { 739 return fmt.Errorf("tmclient: cannot find tablet %v", tablet.Alias.Uid) 740 } 741 t.tm.Ping(ctx, "payload") 742 return nil 743 } 744 745 func (itmc *internalTabletManagerClient) GetSchema( 746 ctx context.Context, 747 tablet *topodatapb.Tablet, 748 request *tabletmanagerdatapb.GetSchemaRequest, 749 ) (*tabletmanagerdatapb.SchemaDefinition, error) { 750 t, ok := tabletMap[tablet.Alias.Uid] 751 if !ok { 752 return nil, fmt.Errorf("tmclient: cannot find tablet %v", tablet.Alias.Uid) 753 } 754 return t.tm.GetSchema(ctx, request) 755 } 756 757 func (itmc *internalTabletManagerClient) GetPermissions(ctx context.Context, tablet *topodatapb.Tablet) (*tabletmanagerdatapb.Permissions, error) { 758 t, ok := tabletMap[tablet.Alias.Uid] 759 if !ok { 760 return nil, fmt.Errorf("tmclient: cannot find tablet %v", tablet.Alias.Uid) 761 } 762 return t.tm.GetPermissions(ctx) 763 } 764 765 func (itmc *internalTabletManagerClient) SetReadOnly(ctx context.Context, tablet *topodatapb.Tablet) error { 766 return fmt.Errorf("not implemented in vtcombo") 767 } 768 769 func (itmc *internalTabletManagerClient) SetReadWrite(ctx context.Context, tablet *topodatapb.Tablet) error { 770 return fmt.Errorf("not implemented in vtcombo") 771 } 772 773 func (itmc *internalTabletManagerClient) ChangeType(ctx context.Context, tablet *topodatapb.Tablet, dbType topodatapb.TabletType, semiSync bool) error { 774 t, ok := tabletMap[tablet.Alias.Uid] 775 if !ok { 776 return fmt.Errorf("tmclient: cannot find tablet %v", tablet.Alias.Uid) 777 } 778 t.tm.ChangeType(ctx, dbType, semiSync) 779 return nil 780 } 781 782 func (itmc *internalTabletManagerClient) Sleep(ctx context.Context, tablet *topodatapb.Tablet, duration time.Duration) error { 783 t, ok := tabletMap[tablet.Alias.Uid] 784 if !ok { 785 return fmt.Errorf("tmclient: cannot find tablet %v", tablet.Alias.Uid) 786 } 787 t.tm.Sleep(ctx, duration) 788 return nil 789 } 790 791 func (itmc *internalTabletManagerClient) ExecuteHook(ctx context.Context, tablet *topodatapb.Tablet, hk *hook.Hook) (*hook.HookResult, error) { 792 return nil, fmt.Errorf("not implemented in vtcombo") 793 } 794 795 func (itmc *internalTabletManagerClient) RefreshState(ctx context.Context, tablet *topodatapb.Tablet) error { 796 t, ok := tabletMap[tablet.Alias.Uid] 797 if !ok { 798 return fmt.Errorf("tmclient: cannot find tablet %v", tablet.Alias.Uid) 799 } 800 return t.tm.RefreshState(ctx) 801 } 802 803 func (itmc *internalTabletManagerClient) RunHealthCheck(ctx context.Context, tablet *topodatapb.Tablet) error { 804 t, ok := tabletMap[tablet.Alias.Uid] 805 if !ok { 806 return fmt.Errorf("tmclient: cannot find tablet %v", tablet.Alias.Uid) 807 } 808 t.tm.RunHealthCheck(ctx) 809 return nil 810 } 811 812 func (itmc *internalTabletManagerClient) ReloadSchema(ctx context.Context, tablet *topodatapb.Tablet, waitPosition string) error { 813 t, ok := tabletMap[tablet.Alias.Uid] 814 if !ok { 815 return fmt.Errorf("tmclient: cannot find tablet %v", tablet.Alias.Uid) 816 } 817 return t.tm.ReloadSchema(ctx, waitPosition) 818 } 819 820 func (itmc *internalTabletManagerClient) PreflightSchema(ctx context.Context, tablet *topodatapb.Tablet, changes []string) ([]*tabletmanagerdatapb.SchemaChangeResult, error) { 821 t, ok := tabletMap[tablet.Alias.Uid] 822 if !ok { 823 return nil, fmt.Errorf("tmclient: cannot find tablet %v", tablet.Alias.Uid) 824 } 825 return t.tm.PreflightSchema(ctx, changes) 826 } 827 828 func (itmc *internalTabletManagerClient) ApplySchema(ctx context.Context, tablet *topodatapb.Tablet, change *tmutils.SchemaChange) (*tabletmanagerdatapb.SchemaChangeResult, error) { 829 t, ok := tabletMap[tablet.Alias.Uid] 830 if !ok { 831 return nil, fmt.Errorf("tmclient: cannot find tablet %v", tablet.Alias.Uid) 832 } 833 return t.tm.ApplySchema(ctx, change) 834 } 835 836 func (itmc *internalTabletManagerClient) ExecuteQuery(context.Context, *topodatapb.Tablet, *tabletmanagerdatapb.ExecuteQueryRequest) (*querypb.QueryResult, error) { 837 return nil, fmt.Errorf("not implemented in vtcombo") 838 } 839 840 func (itmc *internalTabletManagerClient) ExecuteFetchAsDba(context.Context, *topodatapb.Tablet, bool, *tabletmanagerdatapb.ExecuteFetchAsDbaRequest) (*querypb.QueryResult, error) { 841 return nil, fmt.Errorf("not implemented in vtcombo") 842 } 843 844 func (itmc *internalTabletManagerClient) ExecuteFetchAsAllPrivs(context.Context, *topodatapb.Tablet, *tabletmanagerdatapb.ExecuteFetchAsAllPrivsRequest) (*querypb.QueryResult, error) { 845 return nil, fmt.Errorf("not implemented in vtcombo") 846 } 847 848 func (itmc *internalTabletManagerClient) ExecuteFetchAsApp(context.Context, *topodatapb.Tablet, bool, *tabletmanagerdatapb.ExecuteFetchAsAppRequest) (*querypb.QueryResult, error) { 849 return nil, fmt.Errorf("not implemented in vtcombo") 850 } 851 852 func (itmc *internalTabletManagerClient) PrimaryStatus(context.Context, *topodatapb.Tablet) (*replicationdatapb.PrimaryStatus, error) { 853 return nil, fmt.Errorf("not implemented in vtcombo") 854 } 855 856 func (itmc *internalTabletManagerClient) PrimaryPosition(context.Context, *topodatapb.Tablet) (string, error) { 857 return "", fmt.Errorf("not implemented in vtcombo") 858 } 859 860 func (itmc *internalTabletManagerClient) WaitForPosition(context.Context, *topodatapb.Tablet, string) error { 861 return fmt.Errorf("not implemented in vtcombo") 862 } 863 864 func (itmc *internalTabletManagerClient) VExec(context.Context, *topodatapb.Tablet, string, string, string) (*querypb.QueryResult, error) { 865 return nil, fmt.Errorf("not implemented in vtcombo") 866 } 867 868 func (itmc *internalTabletManagerClient) VReplicationExec(context.Context, *topodatapb.Tablet, string) (*querypb.QueryResult, error) { 869 return nil, fmt.Errorf("not implemented in vtcombo") 870 } 871 872 func (itmc *internalTabletManagerClient) VReplicationWaitForPos(context.Context, *topodatapb.Tablet, int, string) error { 873 return fmt.Errorf("not implemented in vtcombo") 874 } 875 876 func (itmc *internalTabletManagerClient) ResetReplication(context.Context, *topodatapb.Tablet) error { 877 return fmt.Errorf("not implemented in vtcombo") 878 } 879 880 func (itmc *internalTabletManagerClient) InitPrimary(context.Context, *topodatapb.Tablet, bool) (string, error) { 881 return "", fmt.Errorf("not implemented in vtcombo") 882 } 883 884 func (itmc *internalTabletManagerClient) PopulateReparentJournal(context.Context, *topodatapb.Tablet, int64, string, *topodatapb.TabletAlias, string) error { 885 return fmt.Errorf("not implemented in vtcombo") 886 } 887 888 func (itmc *internalTabletManagerClient) DemotePrimary(context.Context, *topodatapb.Tablet) (*replicationdatapb.PrimaryStatus, error) { 889 return nil, fmt.Errorf("not implemented in vtcombo") 890 } 891 892 func (itmc *internalTabletManagerClient) UndoDemotePrimary(context.Context, *topodatapb.Tablet, bool) error { 893 return fmt.Errorf("not implemented in vtcombo") 894 } 895 896 func (itmc *internalTabletManagerClient) SetReplicationSource(context.Context, *topodatapb.Tablet, *topodatapb.TabletAlias, int64, string, bool, bool) error { 897 return fmt.Errorf("not implemented in vtcombo") 898 } 899 900 func (itmc *internalTabletManagerClient) StopReplicationAndGetStatus(context.Context, *topodatapb.Tablet, replicationdatapb.StopReplicationMode) (*replicationdatapb.StopReplicationStatus, error) { 901 return nil, fmt.Errorf("not implemented in vtcombo") 902 } 903 904 func (itmc *internalTabletManagerClient) PromoteReplica(context.Context, *topodatapb.Tablet, bool) (string, error) { 905 return "", fmt.Errorf("not implemented in vtcombo") 906 } 907 908 func (itmc *internalTabletManagerClient) Backup(context.Context, *topodatapb.Tablet, *tabletmanagerdatapb.BackupRequest) (logutil.EventStream, error) { 909 return nil, fmt.Errorf("not implemented in vtcombo") 910 } 911 912 func (itmc *internalTabletManagerClient) RestoreFromBackup(context.Context, *topodatapb.Tablet, *tabletmanagerdatapb.RestoreFromBackupRequest) (logutil.EventStream, error) { 913 return nil, fmt.Errorf("not implemented in vtcombo") 914 } 915 916 func (itmc *internalTabletManagerClient) Close() { 917 } 918 919 func (itmc *internalTabletManagerClient) ReplicationStatus(context.Context, *topodatapb.Tablet) (*replicationdatapb.Status, error) { 920 return nil, fmt.Errorf("not implemented in vtcombo") 921 } 922 923 func (itmc *internalTabletManagerClient) FullStatus(context.Context, *topodatapb.Tablet) (*replicationdatapb.FullStatus, error) { 924 return nil, fmt.Errorf("not implemented in vtcombo") 925 } 926 927 func (itmc *internalTabletManagerClient) StopReplication(context.Context, *topodatapb.Tablet) error { 928 return fmt.Errorf("not implemented in vtcombo") 929 } 930 931 func (itmc *internalTabletManagerClient) StopReplicationMinimum(context.Context, *topodatapb.Tablet, string, time.Duration) (string, error) { 932 return "", fmt.Errorf("not implemented in vtcombo") 933 } 934 935 func (itmc *internalTabletManagerClient) StartReplication(context.Context, *topodatapb.Tablet, bool) error { 936 return fmt.Errorf("not implemented in vtcombo") 937 } 938 939 func (itmc *internalTabletManagerClient) StartReplicationUntilAfter(context.Context, *topodatapb.Tablet, string, time.Duration) error { 940 return fmt.Errorf("not implemented in vtcombo") 941 } 942 943 func (itmc *internalTabletManagerClient) GetReplicas(context.Context, *topodatapb.Tablet) ([]string, error) { 944 return nil, fmt.Errorf("not implemented in vtcombo") 945 } 946 947 func (itmc *internalTabletManagerClient) InitReplica(context.Context, *topodatapb.Tablet, *topodatapb.TabletAlias, string, int64, bool) error { 948 return fmt.Errorf("not implemented in vtcombo") 949 } 950 951 func (itmc *internalTabletManagerClient) ReplicaWasPromoted(context.Context, *topodatapb.Tablet) error { 952 return fmt.Errorf("not implemented in vtcombo") 953 } 954 955 func (itmc *internalTabletManagerClient) ResetReplicationParameters(context.Context, *topodatapb.Tablet) error { 956 return fmt.Errorf("not implemented in vtcombo") 957 } 958 959 func (itmc *internalTabletManagerClient) ReplicaWasRestarted(context.Context, *topodatapb.Tablet, *topodatapb.TabletAlias) error { 960 return fmt.Errorf("not implemented in vtcombo") 961 }