diff --git a/go/vt/tabletmanager/agentrpctest/test_agent_rpc.go b/go/vt/tabletmanager/agentrpctest/test_agent_rpc.go index de3e6384ea..8d7b9af8d8 100644 --- a/go/vt/tabletmanager/agentrpctest/test_agent_rpc.go +++ b/go/vt/tabletmanager/agentrpctest/test_agent_rpc.go @@ -611,7 +611,7 @@ func (fra *fakeRPCAgent) ExecuteFetch(ctx context.Context, query string, maxrows func agentRPCTestExecuteFetch(ctx context.Context, t *testing.T, client tmclient.TabletManagerClient, ti *topo.TabletInfo) { testExecuteFetchDbConfigName = dbconfigs.DbaConfigName - qr, err := client.ExecuteFetchAsDba(ctx, ti, testExecuteFetchQuery, testExecuteFetchMaxRows, true, true) + qr, err := client.ExecuteFetchAsDba(ctx, ti, testExecuteFetchQuery, testExecuteFetchMaxRows, true, true, false) compareError(t, "ExecuteFetch", err, qr, testExecuteFetchResult) testExecuteFetchDbConfigName = dbconfigs.AppConfigName qr, err = client.ExecuteFetchAsApp(ctx, ti, testExecuteFetchQuery, testExecuteFetchMaxRows, true) @@ -619,7 +619,7 @@ func agentRPCTestExecuteFetch(ctx context.Context, t *testing.T, client tmclient } func agentRPCTestExecuteFetchPanic(ctx context.Context, t *testing.T, client tmclient.TabletManagerClient, ti *topo.TabletInfo) { - _, err := client.ExecuteFetchAsDba(ctx, ti, testExecuteFetchQuery, testExecuteFetchMaxRows, true, true) + _, err := client.ExecuteFetchAsDba(ctx, ti, testExecuteFetchQuery, testExecuteFetchMaxRows, true, true, false) expectRPCWrapPanic(t, err) _, err = client.ExecuteFetchAsApp(ctx, ti, testExecuteFetchQuery, testExecuteFetchMaxRows, true) diff --git a/go/vt/tabletmanager/faketmclient/fake_client.go b/go/vt/tabletmanager/faketmclient/fake_client.go index b917618f6f..448910b09a 100644 --- a/go/vt/tabletmanager/faketmclient/fake_client.go +++ b/go/vt/tabletmanager/faketmclient/fake_client.go @@ -142,7 +142,7 @@ func (client *FakeTabletManagerClient) ApplySchema(ctx context.Context, tablet * } // ExecuteFetchAsDba is part of the tmclient.TabletManagerClient interface -func (client *FakeTabletManagerClient) ExecuteFetchAsDba(ctx context.Context, tablet *topo.TabletInfo, query string, maxRows int, wantFields, disableBinlogs bool) (*mproto.QueryResult, error) { +func (client *FakeTabletManagerClient) ExecuteFetchAsDba(ctx context.Context, tablet *topo.TabletInfo, query string, maxRows int, wantFields, disableBinlogs, reloadSchema bool) (*mproto.QueryResult, error) { var qr mproto.QueryResult return &qr, nil } diff --git a/go/vt/tabletmanager/gorpcproto/structs.go b/go/vt/tabletmanager/gorpcproto/structs.go index 00b04ff138..ecd3498975 100644 --- a/go/vt/tabletmanager/gorpcproto/structs.go +++ b/go/vt/tabletmanager/gorpcproto/structs.go @@ -90,6 +90,7 @@ type ExecuteFetchArgs struct { MaxRows int WantFields bool DisableBinlogs bool + ReloadSchema bool DBConfigName dbconfigs.DbConfigName } diff --git a/go/vt/tabletmanager/gorpctmclient/gorpc_client.go b/go/vt/tabletmanager/gorpctmclient/gorpc_client.go index 8eca86352c..033c319986 100644 --- a/go/vt/tabletmanager/gorpctmclient/gorpc_client.go +++ b/go/vt/tabletmanager/gorpctmclient/gorpc_client.go @@ -223,13 +223,14 @@ func (client *GoRPCTabletManagerClient) ApplySchema(ctx context.Context, tablet } // ExecuteFetchAsDba is part of the tmclient.TabletManagerClient interface -func (client *GoRPCTabletManagerClient) ExecuteFetchAsDba(ctx context.Context, tablet *topo.TabletInfo, query string, maxRows int, wantFields, disableBinlogs bool) (*mproto.QueryResult, error) { +func (client *GoRPCTabletManagerClient) ExecuteFetchAsDba(ctx context.Context, tablet *topo.TabletInfo, query string, maxRows int, wantFields, disableBinlogs, reloadSchema bool) (*mproto.QueryResult, error) { var qr mproto.QueryResult if err := client.rpcCallTablet(ctx, tablet, actionnode.TabletActionExecuteFetch, &gorpcproto.ExecuteFetchArgs{ Query: query, MaxRows: maxRows, WantFields: wantFields, DisableBinlogs: disableBinlogs, + ReloadSchema: reloadSchema, DBConfigName: dbconfigs.DbaConfigName, }, &qr); err != nil { return nil, err diff --git a/go/vt/tabletmanager/gorpctmserver/gorpc_server.go b/go/vt/tabletmanager/gorpctmserver/gorpc_server.go index 2922c10ff3..ffb4f84598 100644 --- a/go/vt/tabletmanager/gorpctmserver/gorpc_server.go +++ b/go/vt/tabletmanager/gorpctmserver/gorpc_server.go @@ -207,6 +207,9 @@ func (tm *TabletManager) ExecuteFetch(ctx context.Context, args *gorpcproto.Exec qr, err := tm.agent.ExecuteFetch(ctx, args.Query, args.MaxRows, args.WantFields, args.DisableBinlogs, args.DBConfigName) if err == nil { *reply = *qr + if args.ReloadSchema { + tm.agent.ReloadSchema(ctx) + } } return err }) diff --git a/go/vt/tabletmanager/tmclient/rpc_client_api.go b/go/vt/tabletmanager/tmclient/rpc_client_api.go index 9b37fdbc53..65ffabb287 100644 --- a/go/vt/tabletmanager/tmclient/rpc_client_api.go +++ b/go/vt/tabletmanager/tmclient/rpc_client_api.go @@ -84,7 +84,7 @@ type TabletManagerClient interface { ApplySchema(ctx context.Context, tablet *topo.TabletInfo, change *myproto.SchemaChange) (*myproto.SchemaChangeResult, error) // ExecuteFetchAsDba executes a query remotely using the DBA pool - ExecuteFetchAsDba(ctx context.Context, tablet *topo.TabletInfo, query string, maxRows int, wantFields, disableBinlogs bool) (*mproto.QueryResult, error) + ExecuteFetchAsDba(ctx context.Context, tablet *topo.TabletInfo, query string, maxRows int, wantFields, disableBinlogs, reloadSchema bool) (*mproto.QueryResult, error) // ExecuteFetchAsApp executes a query remotely using the App pool ExecuteFetchAsApp(ctx context.Context, tablet *topo.TabletInfo, query string, maxRows int, wantFields bool) (*mproto.QueryResult, error) diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index 1458f60fbf..8191a611e9 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -973,6 +973,8 @@ func commandExecuteFetchAsDba(ctx context.Context, wr *wrangler.Wrangler, subFla maxRows := subFlags.Int("max_rows", 10000, "maximum number of rows to allow in reset") wantFields := subFlags.Bool("want_fields", false, "also get the field names") disableBinlogs := subFlags.Bool("disable_binlogs", false, "disable writing to binlogs during the query") + reloadSchema := subFlags.Bool("reload_schema", false, "if this flag is true, tablet schema will be reloaded after executing given query") + if err := subFlags.Parse(args); err != nil { return err } @@ -985,7 +987,7 @@ func commandExecuteFetchAsDba(ctx context.Context, wr *wrangler.Wrangler, subFla return err } query := subFlags.Arg(1) - qr, err := wr.ExecuteFetchAsDba(ctx, alias, query, *maxRows, *wantFields, *disableBinlogs) + qr, err := wr.ExecuteFetchAsDba(ctx, alias, query, *maxRows, *wantFields, *disableBinlogs, *reloadSchema) if err == nil { wr.Logger().Printf("%v\n", jscfg.ToJSON(qr)) } diff --git a/go/vt/wrangler/schema.go b/go/vt/wrangler/schema.go index 84555324da..3d0d555876 100644 --- a/go/vt/wrangler/schema.go +++ b/go/vt/wrangler/schema.go @@ -540,8 +540,8 @@ func (wr *Wrangler) CopySchemaShard(ctx context.Context, srcTabletAlias topo.Tab } createSql := sd.ToSQLStrings() - for _, sqlLine := range createSql { - err = wr.applySqlShard(ctx, tabletInfo, sqlLine) + for i, sqlLine := range createSql { + err = wr.applySqlShard(ctx, tabletInfo, sqlLine, i == len(createSql)-1) if err != nil { return err } @@ -556,7 +556,7 @@ func (wr *Wrangler) CopySchemaShard(ctx context.Context, srcTabletAlias topo.Tab // Thus it should be used only for changes that can be applies on a live instance without causing issues; // it shouldn't be used for anything that will require a pivot. // The SQL statement string is expected to have {{.DatabaseName}} in place of the actual db name. -func (wr *Wrangler) applySqlShard(ctx context.Context, tabletInfo *topo.TabletInfo, change string) error { +func (wr *Wrangler) applySqlShard(ctx context.Context, tabletInfo *topo.TabletInfo, change string, reloadSchema bool) error { filledChange, err := fillStringTemplate(change, map[string]string{"DatabaseName": tabletInfo.DbName()}) if err != nil { return fmt.Errorf("fillStringTemplate failed: %v", err) @@ -564,7 +564,7 @@ func (wr *Wrangler) applySqlShard(ctx context.Context, tabletInfo *topo.TabletIn ctx, cancel := context.WithTimeout(ctx, 30*time.Second) defer cancel() // Need to make sure that we enable binlog, since we're only applying the statement on masters. - _, err = wr.tmc.ExecuteFetchAsDba(ctx, tabletInfo, filledChange, 0, false, false) + _, err = wr.tmc.ExecuteFetchAsDba(ctx, tabletInfo, filledChange, 0, false, false, reloadSchema) return err } diff --git a/go/vt/wrangler/tablet.go b/go/vt/wrangler/tablet.go index 73fc86d071..931137c583 100644 --- a/go/vt/wrangler/tablet.go +++ b/go/vt/wrangler/tablet.go @@ -269,10 +269,10 @@ func (wr *Wrangler) DeleteTablet(tabletAlias topo.TabletAlias) error { } // ExecuteFetchAsDba executes a query remotely using the DBA pool -func (wr *Wrangler) ExecuteFetchAsDba(ctx context.Context, tabletAlias topo.TabletAlias, query string, maxRows int, wantFields, disableBinlogs bool) (*mproto.QueryResult, error) { +func (wr *Wrangler) ExecuteFetchAsDba(ctx context.Context, tabletAlias topo.TabletAlias, query string, maxRows int, wantFields, disableBinlogs bool, reloadSchema bool) (*mproto.QueryResult, error) { ti, err := wr.ts.GetTablet(tabletAlias) if err != nil { return nil, err } - return wr.tmc.ExecuteFetchAsDba(ctx, ti, query, maxRows, wantFields, disableBinlogs) + return wr.tmc.ExecuteFetchAsDba(ctx, ti, query, maxRows, wantFields, disableBinlogs, reloadSchema) }