vitess.io/vitess@v0.16.2/go/vt/wrangler/stream_migrater_test.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 wrangler
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"strings"
    23  	"testing"
    24  	"time"
    25  
    26  	"vitess.io/vitess/go/sqltypes"
    27  	"vitess.io/vitess/go/vt/vtctl/workflow"
    28  
    29  	binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata"
    30  	topodatapb "vitess.io/vitess/go/vt/proto/topodata"
    31  )
    32  
    33  var (
    34  	rdOnly  = []topodatapb.TabletType{topodatapb.TabletType_RDONLY}
    35  	replica = []topodatapb.TabletType{topodatapb.TabletType_REPLICA}
    36  )
    37  
    38  func TestStreamMigrateMainflow(t *testing.T) {
    39  	ctx := context.Background()
    40  	tme := newTestShardMigrater(ctx, t, []string{"-40", "40-"}, []string{"-80", "80-"})
    41  	defer tme.stopTablets(t)
    42  
    43  	tme.expectNoPreviousJournals()
    44  
    45  	// Migrate reads
    46  	_, err := tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", rdOnly, nil, workflow.DirectionForward, false)
    47  	if err != nil {
    48  		t.Fatal(err)
    49  	}
    50  
    51  	tme.expectCheckJournals()
    52  	_, err = tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", replica, nil, workflow.DirectionForward, false)
    53  	if err != nil {
    54  		t.Fatal(err)
    55  	}
    56  
    57  	tme.expectCheckJournals()
    58  	stopStreams := func() {
    59  		// sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped')
    60  		tme.dbSourceClients[0].addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped' and message != 'FROZEN'", &sqltypes.Result{}, nil)
    61  		tme.dbSourceClients[1].addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped' and message != 'FROZEN'", &sqltypes.Result{}, nil)
    62  
    63  		// pre-compute sourceRows because they're re-read multiple times.
    64  		var sourceRows [][]string
    65  		for _, sourceTargetShard := range tme.sourceShards {
    66  			var rows []string
    67  			for j, sourceShard := range tme.sourceShards {
    68  				bls := &binlogdatapb.BinlogSource{
    69  					Keyspace: "ks1",
    70  					Shard:    sourceShard,
    71  					Filter: &binlogdatapb.Filter{
    72  						Rules: []*binlogdatapb.Rule{{
    73  							Match:  "t1",
    74  							Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard),
    75  						}, {
    76  							Match:  "t2",
    77  							Filter: fmt.Sprintf("select * from t2 where in_keyrange('%s')", sourceTargetShard),
    78  						}},
    79  					},
    80  				}
    81  				rows = append(rows, fmt.Sprintf("%d|t1t2|%v|MariaDB/5-456-888|0|0|0", j+1, bls))
    82  			}
    83  			sourceRows = append(sourceRows, rows)
    84  		}
    85  
    86  		for i, dbclient := range tme.dbSourceClients {
    87  			// sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state)
    88  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
    89  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
    90  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
    91  				sourceRows[i]...),
    92  				nil)
    93  			dbclient.addQuery("select distinct vrepl_id from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil)
    94  
    95  			// sm.stopStreams->sm.stopSourceStreams->VReplicationExec('Stopped')
    96  			dbclient.addQuery("select id from _vt.vreplication where id in (1, 2)", resultid12, nil)
    97  			dbclient.addQuery("update _vt.vreplication set state = 'Stopped', message = 'for cutover' where id in (1, 2)", &sqltypes.Result{}, nil)
    98  			dbclient.addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil)
    99  			dbclient.addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil)
   100  
   101  			// sm.stopStreams->sm.stopSourceStreams->sm.readTabletStreams('id in...')
   102  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1, 2)", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
   103  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
   104  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
   105  				sourceRows[i]...),
   106  				nil)
   107  
   108  			// sm.stopStreams->sm.verifyStreamPositions->sm.readTabletStreams('id in...')
   109  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1, 2)", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
   110  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
   111  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
   112  				sourceRows[i]...),
   113  				nil)
   114  		}
   115  
   116  	}
   117  	stopStreams()
   118  
   119  	tme.expectWaitForCatchup()
   120  
   121  	migrateStreams := func() {
   122  		// sm.migrateStreams->->sm.deleteTargetStreams (no previously migrated streams)
   123  		tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2')", &sqltypes.Result{}, nil)
   124  		tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2')", &sqltypes.Result{}, nil)
   125  
   126  		// sm.migrateStreams->sm.createTargetStreams
   127  		for i, targetShard := range tme.targetShards {
   128  			buf := &strings.Builder{}
   129  			buf.WriteString("insert into.*vreplication")
   130  			for _, sourceShard := range tme.sourceShards {
   131  				fmt.Fprintf(buf, ".*t1t2.*ks.*%s.*t1.*in_keyrange.*%s.*t2.*in_keyrange.*%s.*MariaDB/5-456-888.*Stopped", sourceShard, targetShard, targetShard)
   132  			}
   133  			// Insert id is 3 so it doesn't overlap with the existing streams.
   134  			tme.dbTargetClients[i].addQueryRE(buf.String(), &sqltypes.Result{InsertID: 3}, nil)
   135  			tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil)
   136  			tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil)
   137  		}
   138  	}
   139  	migrateStreams()
   140  
   141  	// mi.createJournals (verify workflows are in the insert)
   142  	journal := "insert into _vt.resharding_journal.*source_workflows.*t1t2"
   143  	tme.dbSourceClients[0].addQueryRE(journal, &sqltypes.Result{}, nil)
   144  	tme.dbSourceClients[1].addQueryRE(journal, &sqltypes.Result{}, nil)
   145  
   146  	finalize := func() {
   147  		// sm.finalize->Source
   148  		tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2')", resultid12, nil)
   149  		tme.dbSourceClients[0].addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil)
   150  		tme.dbSourceClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil)
   151  		tme.dbSourceClients[0].addQuery("delete from _vt.post_copy_action where vrepl_id in (1, 2)", &sqltypes.Result{}, nil)
   152  		tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2')", resultid12, nil)
   153  		tme.dbSourceClients[1].addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil)
   154  		tme.dbSourceClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil)
   155  		tme.dbSourceClients[1].addQuery("delete from _vt.post_copy_action where vrepl_id in (1, 2)", &sqltypes.Result{}, nil)
   156  
   157  		// sm.finalize->Target
   158  		tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2')", resultid34, nil)
   159  		tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2')", resultid34, nil)
   160  		tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Running' where id in (3, 4)", &sqltypes.Result{}, nil)
   161  		tme.dbTargetClients[1].addQuery("update _vt.vreplication set state = 'Running' where id in (3, 4)", &sqltypes.Result{}, nil)
   162  		tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil)
   163  		tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil)
   164  		tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil)
   165  		tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil)
   166  	}
   167  	finalize()
   168  
   169  	tme.expectCreateReverseVReplication()
   170  	tme.expectStartReverseVReplication()
   171  	tme.expectFrozenTargetVReplication()
   172  	if _, _, err := tme.wr.SwitchWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, false, true, false); err != nil {
   173  		t.Fatal(err)
   174  	}
   175  
   176  	checkServedTypes(t, tme.ts, "ks:-40", 0)
   177  	checkServedTypes(t, tme.ts, "ks:40-", 0)
   178  	checkServedTypes(t, tme.ts, "ks:-80", 3)
   179  	checkServedTypes(t, tme.ts, "ks:80-", 3)
   180  
   181  	checkIfPrimaryServing(t, tme.ts, "ks:-40", false)
   182  	checkIfPrimaryServing(t, tme.ts, "ks:40-", false)
   183  	checkIfPrimaryServing(t, tme.ts, "ks:-80", true)
   184  	checkIfPrimaryServing(t, tme.ts, "ks:80-", true)
   185  
   186  	tme.expectDeleteReverseVReplication()
   187  	tme.expectDeleteTargetVReplication()
   188  	if _, err := tme.wr.DropSources(ctx, tme.targetKeyspace, "test", workflow.DropTable, false, false, false, false); err != nil {
   189  		t.Fatal(err)
   190  	}
   191  	verifyQueries(t, tme.allDBClients)
   192  }
   193  
   194  func TestStreamMigrateTwoStreams(t *testing.T) {
   195  	ctx := context.Background()
   196  	tme := newTestShardMigrater(ctx, t, []string{"-40", "40-"}, []string{"-80", "80-"})
   197  	defer tme.stopTablets(t)
   198  
   199  	tme.expectNoPreviousJournals()
   200  	// Migrate reads
   201  	_, err := tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", rdOnly, nil, workflow.DirectionForward, false)
   202  	if err != nil {
   203  		t.Fatal(err)
   204  	}
   205  	tme.expectNoPreviousJournals()
   206  	_, err = tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", replica, nil, workflow.DirectionForward, false)
   207  	if err != nil {
   208  		t.Fatal(err)
   209  	}
   210  
   211  	tme.expectCheckJournals()
   212  
   213  	stopStreams := func() {
   214  		// sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped')
   215  		tme.dbSourceClients[0].addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped' and message != 'FROZEN'", &sqltypes.Result{}, nil)
   216  		tme.dbSourceClients[1].addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped' and message != 'FROZEN'", &sqltypes.Result{}, nil)
   217  
   218  		// pre-compute sourceRows because they're re-read multiple times.
   219  		var sourceRows [][]string
   220  		for _, sourceTargetShard := range tme.sourceShards {
   221  			var rows []string
   222  			for j, sourceShard := range tme.sourceShards {
   223  				bls := &binlogdatapb.BinlogSource{
   224  					Keyspace: "ks1",
   225  					Shard:    sourceShard,
   226  					Filter: &binlogdatapb.Filter{
   227  						Rules: []*binlogdatapb.Rule{{
   228  							Match:  "t1",
   229  							Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard),
   230  						}, {
   231  							Match:  "t2",
   232  							Filter: fmt.Sprintf("select * from t2 where in_keyrange('%s')", sourceTargetShard),
   233  						}},
   234  					},
   235  				}
   236  				rows = append(rows, fmt.Sprintf("%d|t1t2|%v|MariaDB/5-456-888|0|0|0", j+1, bls))
   237  			}
   238  			for j, sourceShard := range tme.sourceShards {
   239  				bls := &binlogdatapb.BinlogSource{
   240  					Keyspace: "ks1",
   241  					Shard:    sourceShard,
   242  					Filter: &binlogdatapb.Filter{
   243  						Rules: []*binlogdatapb.Rule{{
   244  							Match:  "t3",
   245  							Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard),
   246  						}},
   247  					},
   248  				}
   249  				rows = append(rows, fmt.Sprintf("%d|t3|%v|MariaDB/5-456-888|0|0|0", j+3, bls))
   250  			}
   251  			sourceRows = append(sourceRows, rows)
   252  		}
   253  
   254  		for i, dbclient := range tme.dbSourceClients {
   255  			// sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state)
   256  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
   257  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
   258  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
   259  				sourceRows[i]...),
   260  				nil)
   261  			dbclient.addQuery("select distinct vrepl_id from _vt.copy_state where vrepl_id in (1, 2, 3, 4)", &sqltypes.Result{}, nil)
   262  
   263  			// sm.stopStreams->sm.stopSourceStreams->VReplicationExec('Stopped')
   264  			dbclient.addQuery("select id from _vt.vreplication where id in (1, 2, 3, 4)", resultid1234, nil)
   265  			dbclient.addQuery("update _vt.vreplication set state = 'Stopped', message = 'for cutover' where id in (1, 2, 3, 4)", &sqltypes.Result{}, nil)
   266  			dbclient.addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil)
   267  			dbclient.addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil)
   268  			dbclient.addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil)
   269  			dbclient.addQuery("select * from _vt.vreplication where id = 4", stoppedResult(3), nil)
   270  
   271  			// sm.stopStreams->sm.stopSourceStreams->sm.readTabletStreams('id in...')
   272  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1, 2, 3, 4)", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
   273  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
   274  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
   275  				sourceRows[i]...),
   276  				nil)
   277  
   278  			// sm.stopStreams->sm.verifyStreamPositions->sm.readTabletStreams('id in...')
   279  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1, 2, 3, 4)", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
   280  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
   281  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
   282  				sourceRows[i]...),
   283  				nil)
   284  		}
   285  	}
   286  	stopStreams()
   287  
   288  	tme.expectWaitForCatchup()
   289  
   290  	migrateStreams := func() {
   291  		// sm.migrateStreams->->sm.deleteTargetStreams (no previously migrated streams)
   292  		tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2', 't3')", &sqltypes.Result{}, nil)
   293  		tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2', 't3')", &sqltypes.Result{}, nil)
   294  
   295  		// sm.migrateStreams->sm.createTargetStreams
   296  		for i, targetShard := range tme.targetShards {
   297  			buf := &strings.Builder{}
   298  			buf.WriteString("insert into.*vreplication")
   299  			for _, sourceShard := range tme.sourceShards {
   300  				fmt.Fprintf(buf, ".*t1t2.*ks.*%s.*t1.*in_keyrange.*%s.*t2.*in_keyrange.*%s.*MariaDB/5-456-888.*Stopped", sourceShard, targetShard, targetShard)
   301  			}
   302  			for _, sourceShard := range tme.sourceShards {
   303  				fmt.Fprintf(buf, ".*t3.*ks.*%s.*t3.*in_keyrange.*%s.*MariaDB/5-456-888.*Stopped", sourceShard, targetShard)
   304  			}
   305  			// Insert id is 3 so it doesn't overlap with the existing streams.
   306  			tme.dbTargetClients[i].addQueryRE(buf.String(), &sqltypes.Result{InsertID: 3}, nil)
   307  			tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil)
   308  			tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil)
   309  			tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 5", stoppedResult(5), nil)
   310  			tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 6", stoppedResult(6), nil)
   311  		}
   312  	}
   313  	migrateStreams()
   314  
   315  	tme.expectCreateJournals()
   316  
   317  	finalize := func() {
   318  		// sm.finalize->Source
   319  		tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2', 't3')", resultid1234, nil)
   320  		tme.dbSourceClients[0].addQuery("delete from _vt.vreplication where id in (1, 2, 3, 4)", &sqltypes.Result{}, nil)
   321  		tme.dbSourceClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2, 3, 4)", &sqltypes.Result{}, nil)
   322  		tme.dbSourceClients[0].addQuery("delete from _vt.post_copy_action where vrepl_id in (1, 2, 3, 4)", &sqltypes.Result{}, nil)
   323  		tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2', 't3')", resultid1234, nil)
   324  		tme.dbSourceClients[1].addQuery("delete from _vt.vreplication where id in (1, 2, 3, 4)", &sqltypes.Result{}, nil)
   325  		tme.dbSourceClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2, 3, 4)", &sqltypes.Result{}, nil)
   326  		tme.dbSourceClients[1].addQuery("delete from _vt.post_copy_action where vrepl_id in (1, 2, 3, 4)", &sqltypes.Result{}, nil)
   327  
   328  		// sm.finalize->Target
   329  		tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2', 't3')", resultid3456, nil)
   330  		tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2', 't3')", resultid3456, nil)
   331  		tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Running' where id in (3, 4, 5, 6)", &sqltypes.Result{}, nil)
   332  		tme.dbTargetClients[1].addQuery("update _vt.vreplication set state = 'Running' where id in (3, 4, 5, 6)", &sqltypes.Result{}, nil)
   333  		tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil)
   334  		tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil)
   335  		tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil)
   336  		tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil)
   337  		tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 5", stoppedResult(5), nil)
   338  		tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 5", stoppedResult(5), nil)
   339  		tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 6", stoppedResult(6), nil)
   340  		tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 6", stoppedResult(6), nil)
   341  	}
   342  	finalize()
   343  
   344  	tme.expectCreateReverseVReplication()
   345  	tme.expectStartReverseVReplication()
   346  	tme.expectFrozenTargetVReplication()
   347  
   348  	if _, _, err := tme.wr.SwitchWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, false, true, false); err != nil {
   349  		t.Fatal(err)
   350  	}
   351  
   352  	checkServedTypes(t, tme.ts, "ks:-40", 0)
   353  	checkServedTypes(t, tme.ts, "ks:40-", 0)
   354  	checkServedTypes(t, tme.ts, "ks:-80", 3)
   355  	checkServedTypes(t, tme.ts, "ks:80-", 3)
   356  
   357  	checkIfPrimaryServing(t, tme.ts, "ks:-40", false)
   358  	checkIfPrimaryServing(t, tme.ts, "ks:40-", false)
   359  	checkIfPrimaryServing(t, tme.ts, "ks:-80", true)
   360  	checkIfPrimaryServing(t, tme.ts, "ks:80-", true)
   361  
   362  	verifyQueries(t, tme.allDBClients)
   363  }
   364  
   365  func TestStreamMigrateOneToMany(t *testing.T) {
   366  	ctx := context.Background()
   367  	tme := newTestShardMigrater(ctx, t, []string{"0"}, []string{"-80", "80-"})
   368  	defer tme.stopTablets(t)
   369  
   370  	tme.expectNoPreviousJournals()
   371  	// Migrate reads
   372  	_, err := tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", rdOnly, nil, workflow.DirectionForward, false)
   373  	if err != nil {
   374  		t.Fatal(err)
   375  	}
   376  	tme.expectNoPreviousJournals()
   377  	_, err = tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", replica, nil, workflow.DirectionForward, false)
   378  	if err != nil {
   379  		t.Fatal(err)
   380  	}
   381  
   382  	tme.expectCheckJournals()
   383  
   384  	stopStreams := func() {
   385  		// sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped')
   386  		tme.dbSourceClients[0].addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped' and message != 'FROZEN'", &sqltypes.Result{}, nil)
   387  
   388  		// pre-compute sourceRows because they're re-read multiple times.
   389  		var sourceRows [][]string
   390  		for _, sourceTargetShard := range tme.sourceShards {
   391  			var rows []string
   392  			for j, sourceShard := range tme.sourceShards {
   393  				bls := &binlogdatapb.BinlogSource{
   394  					Keyspace: "ks1",
   395  					Shard:    sourceShard,
   396  					Filter: &binlogdatapb.Filter{
   397  						Rules: []*binlogdatapb.Rule{{
   398  							Match:  "t1",
   399  							Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard),
   400  						}},
   401  					},
   402  				}
   403  				rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888|0|0|0", j+1, bls))
   404  			}
   405  			sourceRows = append(sourceRows, rows)
   406  		}
   407  
   408  		for i, dbclient := range tme.dbSourceClients {
   409  			// sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state)
   410  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
   411  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
   412  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
   413  				sourceRows[i]...),
   414  				nil)
   415  			dbclient.addQuery("select distinct vrepl_id from _vt.copy_state where vrepl_id in (1)", &sqltypes.Result{}, nil)
   416  
   417  			// sm.stopStreams->sm.stopSourceStreams->VReplicationExec('Stopped')
   418  			dbclient.addQuery("select id from _vt.vreplication where id in (1)", resultid1, nil)
   419  			dbclient.addQuery("update _vt.vreplication set state = 'Stopped', message = 'for cutover' where id in (1)", &sqltypes.Result{}, nil)
   420  			dbclient.addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil)
   421  
   422  			// sm.stopStreams->sm.stopSourceStreams->sm.readTabletStreams('id in...')
   423  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1)", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
   424  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
   425  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
   426  				sourceRows[i]...),
   427  				nil)
   428  
   429  			// sm.stopStreams->sm.verifyStreamPositions->sm.readTabletStreams('id in...')
   430  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1)", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
   431  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
   432  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
   433  				sourceRows[i]...),
   434  				nil)
   435  		}
   436  	}
   437  	stopStreams()
   438  
   439  	tme.expectWaitForCatchup()
   440  
   441  	migrateStreams := func() {
   442  		// sm.migrateStreams->->sm.deleteTargetStreams (no previously migrated streams)
   443  		tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", &sqltypes.Result{}, nil)
   444  		tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", &sqltypes.Result{}, nil)
   445  
   446  		// sm.migrateStreams->sm.createTargetStreams
   447  		for i, targetShard := range tme.targetShards {
   448  			buf := &strings.Builder{}
   449  			buf.WriteString("insert into.*vreplication")
   450  			for _, sourceShard := range tme.sourceShards {
   451  				fmt.Fprintf(buf, ".*t1.*ks.*%s.*t1.*in_keyrange.*%s.*MariaDB/5-456-888.*Stopped", sourceShard, targetShard)
   452  			}
   453  			// Insert id is 3 so it doesn't overlap with the existing streams.
   454  			tme.dbTargetClients[i].addQueryRE(buf.String(), &sqltypes.Result{InsertID: 3}, nil)
   455  			tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil)
   456  		}
   457  	}
   458  	migrateStreams()
   459  
   460  	tme.expectCreateJournals()
   461  
   462  	finalize := func() {
   463  		// sm.finalize->Source
   464  		tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid1, nil)
   465  		tme.dbSourceClients[0].addQuery("delete from _vt.vreplication where id in (1)", &sqltypes.Result{}, nil)
   466  		tme.dbSourceClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (1)", &sqltypes.Result{}, nil)
   467  		tme.dbSourceClients[0].addQuery("delete from _vt.post_copy_action where vrepl_id in (1)", &sqltypes.Result{}, nil)
   468  
   469  		// sm.finalize->Target
   470  		tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid3, nil)
   471  		tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid3, nil)
   472  		tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Running' where id in (3)", &sqltypes.Result{}, nil)
   473  		tme.dbTargetClients[1].addQuery("update _vt.vreplication set state = 'Running' where id in (3)", &sqltypes.Result{}, nil)
   474  		tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil)
   475  		tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil)
   476  	}
   477  	finalize()
   478  
   479  	tme.expectCreateReverseVReplication()
   480  	tme.expectStartReverseVReplication()
   481  	tme.expectFrozenTargetVReplication()
   482  
   483  	if _, _, err := tme.wr.SwitchWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, false, true, false); err != nil {
   484  		t.Fatal(err)
   485  	}
   486  
   487  	checkServedTypes(t, tme.ts, "ks:0", 0)
   488  	checkServedTypes(t, tme.ts, "ks:-80", 3)
   489  	checkServedTypes(t, tme.ts, "ks:80-", 3)
   490  
   491  	checkIfPrimaryServing(t, tme.ts, "ks:0", false)
   492  	checkIfPrimaryServing(t, tme.ts, "ks:-80", true)
   493  	checkIfPrimaryServing(t, tme.ts, "ks:80-", true)
   494  
   495  	verifyQueries(t, tme.allDBClients)
   496  }
   497  
   498  func TestStreamMigrateManyToOne(t *testing.T) {
   499  	ctx := context.Background()
   500  	// Interesting tidbit: you cannot create a shard "0" for an already sharded keyspace.
   501  	tme := newTestShardMigrater(ctx, t, []string{"-80", "80-"}, []string{"-"})
   502  	defer tme.stopTablets(t)
   503  
   504  	tme.expectNoPreviousJournals()
   505  	// Migrate reads
   506  	_, err := tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", rdOnly, nil, workflow.DirectionForward, false)
   507  	if err != nil {
   508  		t.Fatal(err)
   509  	}
   510  	tme.expectNoPreviousJournals()
   511  	_, err = tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", replica, nil, workflow.DirectionForward, false)
   512  	if err != nil {
   513  		t.Fatal(err)
   514  	}
   515  
   516  	tme.expectCheckJournals()
   517  
   518  	stopStreams := func() {
   519  		// sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped')
   520  		tme.dbSourceClients[0].addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped' and message != 'FROZEN'", &sqltypes.Result{}, nil)
   521  		tme.dbSourceClients[1].addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped' and message != 'FROZEN'", &sqltypes.Result{}, nil)
   522  
   523  		// pre-compute sourceRows because they're re-read multiple times.
   524  		var sourceRows [][]string
   525  		for _, sourceTargetShard := range tme.sourceShards {
   526  			var rows []string
   527  			for j, sourceShard := range tme.sourceShards {
   528  				bls := &binlogdatapb.BinlogSource{
   529  					Keyspace: "ks1",
   530  					Shard:    sourceShard,
   531  					Filter: &binlogdatapb.Filter{
   532  						Rules: []*binlogdatapb.Rule{{
   533  							Match:  "t1",
   534  							Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard),
   535  						}},
   536  					},
   537  				}
   538  				rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888|0|0|0", j+1, bls))
   539  			}
   540  			sourceRows = append(sourceRows, rows)
   541  		}
   542  
   543  		for i, dbclient := range tme.dbSourceClients {
   544  			// sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state)
   545  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
   546  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
   547  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
   548  				sourceRows[i]...),
   549  				nil)
   550  			dbclient.addQuery("select distinct vrepl_id from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil)
   551  
   552  			// sm.stopStreams->sm.stopSourceStreams->VReplicationExec('Stopped')
   553  			dbclient.addQuery("select id from _vt.vreplication where id in (1, 2)", resultid12, nil)
   554  			dbclient.addQuery("update _vt.vreplication set state = 'Stopped', message = 'for cutover' where id in (1, 2)", &sqltypes.Result{}, nil)
   555  			dbclient.addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil)
   556  			dbclient.addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil)
   557  
   558  			// sm.stopStreams->sm.stopSourceStreams->sm.readTabletStreams('id in...')
   559  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1, 2)", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
   560  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
   561  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
   562  				sourceRows[i]...),
   563  				nil)
   564  
   565  			// sm.stopStreams->sm.verifyStreamPositions->sm.readTabletStreams('id in...')
   566  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1, 2)", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
   567  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
   568  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
   569  				sourceRows[i]...),
   570  				nil)
   571  		}
   572  	}
   573  	stopStreams()
   574  
   575  	tme.expectWaitForCatchup()
   576  
   577  	migrateStreams := func() {
   578  		// sm.migrateStreams->->sm.deleteTargetStreams (no previously migrated streams)
   579  		tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", &sqltypes.Result{}, nil)
   580  
   581  		// sm.migrateStreams->sm.createTargetStreams
   582  		for i, targetShard := range tme.targetShards {
   583  			buf := &strings.Builder{}
   584  			buf.WriteString("insert into.*vreplication")
   585  			for _, sourceShard := range tme.sourceShards {
   586  				fmt.Fprintf(buf, ".*t1.*ks.*%s.*t1.*in_keyrange.*%s.*MariaDB/5-456-888.*Stopped", sourceShard, targetShard)
   587  			}
   588  			// Insert id is 3 so it doesn't overlap with the existing streams.
   589  			tme.dbTargetClients[i].addQueryRE(buf.String(), &sqltypes.Result{InsertID: 3}, nil)
   590  			tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil)
   591  			tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil)
   592  		}
   593  	}
   594  	migrateStreams()
   595  	tme.expectCreateReverseVReplication()
   596  
   597  	tme.expectCreateJournals()
   598  
   599  	finalize := func() {
   600  		// sm.finalize->Source
   601  		tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid12, nil)
   602  		tme.dbSourceClients[0].addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil)
   603  		tme.dbSourceClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil)
   604  		tme.dbSourceClients[0].addQuery("delete from _vt.post_copy_action where vrepl_id in (1, 2)", &sqltypes.Result{}, nil)
   605  		tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid12, nil)
   606  		tme.dbSourceClients[1].addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil)
   607  		tme.dbSourceClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil)
   608  		tme.dbSourceClients[1].addQuery("delete from _vt.post_copy_action where vrepl_id in (1, 2)", &sqltypes.Result{}, nil)
   609  
   610  		// sm.finalize->Target
   611  		tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid34, nil)
   612  		tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Running' where id in (3, 4)", &sqltypes.Result{}, nil)
   613  		tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil)
   614  		tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil)
   615  	}
   616  	finalize()
   617  
   618  	tme.expectStartReverseVReplication()
   619  	tme.expectFrozenTargetVReplication()
   620  
   621  	if _, _, err := tme.wr.SwitchWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, false, true, false); err != nil {
   622  		t.Fatal(err)
   623  	}
   624  
   625  	checkServedTypes(t, tme.ts, "ks:-80", 0)
   626  	checkServedTypes(t, tme.ts, "ks:80-", 0)
   627  	checkServedTypes(t, tme.ts, "ks:-", 3)
   628  
   629  	checkIfPrimaryServing(t, tme.ts, "ks:-80", false)
   630  	checkIfPrimaryServing(t, tme.ts, "ks:80-", false)
   631  	checkIfPrimaryServing(t, tme.ts, "ks:-", true)
   632  
   633  	verifyQueries(t, tme.allDBClients)
   634  }
   635  
   636  func TestStreamMigrateSyncSuccess(t *testing.T) {
   637  	ctx := context.Background()
   638  	tme := newTestShardMigrater(ctx, t, []string{"-40", "40-"}, []string{"-80", "80-"})
   639  	defer tme.stopTablets(t)
   640  
   641  	tme.expectNoPreviousJournals()
   642  	// Migrate reads
   643  	_, err := tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", rdOnly, nil, workflow.DirectionForward, false)
   644  	if err != nil {
   645  		t.Fatal(err)
   646  	}
   647  	tme.expectNoPreviousJournals()
   648  	_, err = tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", replica, nil, workflow.DirectionForward, false)
   649  	if err != nil {
   650  		t.Fatal(err)
   651  	}
   652  
   653  	tme.expectCheckJournals()
   654  
   655  	stopStreams := func() {
   656  		// sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped')
   657  		tme.dbSourceClients[0].addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped' and message != 'FROZEN'", &sqltypes.Result{}, nil)
   658  		tme.dbSourceClients[1].addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped' and message != 'FROZEN'", &sqltypes.Result{}, nil)
   659  
   660  		var sourceRows [][]string
   661  		for i, sourceTargetShard := range tme.sourceShards {
   662  			var rows []string
   663  			for j, sourceShard := range tme.sourceShards {
   664  				bls := &binlogdatapb.BinlogSource{
   665  					Keyspace: "ks1",
   666  					Shard:    sourceShard,
   667  					Filter: &binlogdatapb.Filter{
   668  						Rules: []*binlogdatapb.Rule{{
   669  							Match:  "t1",
   670  							Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard),
   671  						}},
   672  					},
   673  				}
   674  				switch i {
   675  				case 0:
   676  					switch j {
   677  					case 0:
   678  						rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-887|0|0|0", j+1, bls))
   679  					case 1:
   680  						rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888|0|0|0", j+1, bls))
   681  					}
   682  				case 1:
   683  					switch j {
   684  					case 0:
   685  						rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888|0|0|0", j+1, bls))
   686  					case 1:
   687  						rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-887|0|0|0", j+1, bls))
   688  					}
   689  				}
   690  			}
   691  			sourceRows = append(sourceRows, rows)
   692  		}
   693  		var finalSources [][]string
   694  		for _, sourceTargetShard := range tme.sourceShards {
   695  			var rows []string
   696  			for j, sourceShard := range tme.sourceShards {
   697  				bls := &binlogdatapb.BinlogSource{
   698  					Keyspace: "ks1",
   699  					Shard:    sourceShard,
   700  					Filter: &binlogdatapb.Filter{
   701  						Rules: []*binlogdatapb.Rule{{
   702  							Match:  "t1",
   703  							Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard),
   704  						}},
   705  					},
   706  				}
   707  				rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888|0|0|0", j+1, bls))
   708  			}
   709  			finalSources = append(finalSources, rows)
   710  		}
   711  
   712  		for i, dbclient := range tme.dbSourceClients {
   713  			// sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state)
   714  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
   715  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
   716  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
   717  				sourceRows[i]...),
   718  				nil)
   719  			dbclient.addQuery("select distinct vrepl_id from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil)
   720  
   721  			// sm.stopStreams->sm.stopSourceStreams->VReplicationExec('Stopped')
   722  			dbclient.addQuery("select id from _vt.vreplication where id in (1, 2)", resultid12, nil)
   723  			dbclient.addQuery("update _vt.vreplication set state = 'Stopped', message = 'for cutover' where id in (1, 2)", &sqltypes.Result{}, nil)
   724  			dbclient.addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil)
   725  			dbclient.addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil)
   726  
   727  			// sm.stopStreams->sm.stopSourceStreams->sm.readTabletStreams('id in...')
   728  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1, 2)", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
   729  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
   730  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
   731  				sourceRows[i]...),
   732  				nil)
   733  
   734  			// sm.stopStreams->sm.verifyStreamPositions->sm.readTabletStreams('id in...')
   735  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1, 2)", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
   736  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
   737  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
   738  				finalSources[i]...),
   739  				nil)
   740  		}
   741  	}
   742  	stopStreams()
   743  
   744  	// sm.stopStreams->sm.syncSourceStreams: Note that this happens inside stopStreams before verifyStreamPositions.
   745  	syncSourceStreams := func() {
   746  		reached := sqltypes.MakeTestResult(sqltypes.MakeTestFields(
   747  			"pos|state|message",
   748  			"varbinary|varbinary|varbinary"),
   749  			"MariaDB/5-456-888|Running|",
   750  		)
   751  		tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where id = 1", resultid1, nil)
   752  		tme.dbSourceClients[0].addQuery("update _vt.vreplication set state = 'Running', stop_pos = 'MariaDB/5-456-888', message = 'synchronizing for cutover' where id in (1)", &sqltypes.Result{}, nil)
   753  		tme.dbSourceClients[0].addQuery("select pos, state, message from _vt.vreplication where id=1", reached, nil)
   754  		tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil)
   755  		tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where id = 2", resultid2, nil)
   756  		tme.dbSourceClients[1].addQuery("update _vt.vreplication set state = 'Running', stop_pos = 'MariaDB/5-456-888', message = 'synchronizing for cutover' where id in (2)", &sqltypes.Result{}, nil)
   757  		tme.dbSourceClients[1].addQuery("select pos, state, message from _vt.vreplication where id=2", reached, nil)
   758  		tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil)
   759  	}
   760  	syncSourceStreams()
   761  
   762  	tme.expectWaitForCatchup()
   763  
   764  	migrateStreams := func() {
   765  		// sm.migrateStreams->->sm.deleteTargetStreams (no previously migrated streams)
   766  		tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", &sqltypes.Result{}, nil)
   767  		tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", &sqltypes.Result{}, nil)
   768  
   769  		// sm.migrateStreams->sm.createTargetStreams
   770  		for i, targetShard := range tme.targetShards {
   771  			buf := &strings.Builder{}
   772  			buf.WriteString("insert into.*vreplication")
   773  			for _, sourceShard := range tme.sourceShards {
   774  				fmt.Fprintf(buf, ".*t1.*ks.*%s.*t1.*in_keyrange.*%s.*MariaDB/5-456-888.*Stopped", sourceShard, targetShard)
   775  			}
   776  			// Insert id is 3 so it doesn't overlap with the existing streams.
   777  			tme.dbTargetClients[i].addQueryRE(buf.String(), &sqltypes.Result{InsertID: 3}, nil)
   778  			tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil)
   779  			tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil)
   780  		}
   781  	}
   782  	migrateStreams()
   783  
   784  	tme.expectCreateJournals()
   785  
   786  	finalize := func() {
   787  		// sm.finalize->Source
   788  		tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid12, nil)
   789  		tme.dbSourceClients[0].addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil)
   790  		tme.dbSourceClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil)
   791  		tme.dbSourceClients[0].addQuery("delete from _vt.post_copy_action where vrepl_id in (1, 2)", &sqltypes.Result{}, nil)
   792  		tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid12, nil)
   793  		tme.dbSourceClients[1].addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil)
   794  		tme.dbSourceClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil)
   795  		tme.dbSourceClients[1].addQuery("delete from _vt.post_copy_action where vrepl_id in (1, 2)", &sqltypes.Result{}, nil)
   796  
   797  		// sm.finalize->Target
   798  		tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid34, nil)
   799  		tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid34, nil)
   800  		tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Running' where id in (3, 4)", &sqltypes.Result{}, nil)
   801  		tme.dbTargetClients[1].addQuery("update _vt.vreplication set state = 'Running' where id in (3, 4)", &sqltypes.Result{}, nil)
   802  		tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil)
   803  		tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil)
   804  		tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil)
   805  		tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil)
   806  	}
   807  	finalize()
   808  
   809  	tme.expectCreateReverseVReplication()
   810  	tme.expectStartReverseVReplication()
   811  	tme.expectFrozenTargetVReplication()
   812  
   813  	if _, _, err := tme.wr.SwitchWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, false, true, false); err != nil {
   814  		t.Fatal(err)
   815  	}
   816  
   817  	checkServedTypes(t, tme.ts, "ks:-40", 0)
   818  	checkServedTypes(t, tme.ts, "ks:40-", 0)
   819  	checkServedTypes(t, tme.ts, "ks:-80", 3)
   820  	checkServedTypes(t, tme.ts, "ks:80-", 3)
   821  
   822  	checkIfPrimaryServing(t, tme.ts, "ks:-40", false)
   823  	checkIfPrimaryServing(t, tme.ts, "ks:40-", false)
   824  	checkIfPrimaryServing(t, tme.ts, "ks:-80", true)
   825  	checkIfPrimaryServing(t, tme.ts, "ks:80-", true)
   826  
   827  	verifyQueries(t, tme.allDBClients)
   828  }
   829  
   830  func TestStreamMigrateSyncFail(t *testing.T) {
   831  	ctx := context.Background()
   832  	tme := newTestShardMigrater(ctx, t, []string{"-40", "40-"}, []string{"-80", "80-"})
   833  	defer tme.stopTablets(t)
   834  
   835  	tme.expectNoPreviousJournals()
   836  	// Migrate reads
   837  	_, err := tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", rdOnly, nil, workflow.DirectionForward, false)
   838  	if err != nil {
   839  		t.Fatal(err)
   840  	}
   841  	tme.expectNoPreviousJournals()
   842  	_, err = tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", replica, nil, workflow.DirectionForward, false)
   843  	if err != nil {
   844  		t.Fatal(err)
   845  	}
   846  
   847  	tme.expectCheckJournals()
   848  
   849  	stopStreams := func() {
   850  		// sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped')
   851  		tme.dbSourceClients[0].addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped' and message != 'FROZEN'", &sqltypes.Result{}, nil)
   852  		tme.dbSourceClients[1].addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped' and message != 'FROZEN'", &sqltypes.Result{}, nil)
   853  
   854  		var sourceRows [][]string
   855  		for i, sourceTargetShard := range tme.sourceShards {
   856  			var rows []string
   857  			for j, sourceShard := range tme.sourceShards {
   858  				bls := &binlogdatapb.BinlogSource{
   859  					Keyspace: "ks1",
   860  					Shard:    sourceShard,
   861  					Filter: &binlogdatapb.Filter{
   862  						Rules: []*binlogdatapb.Rule{{
   863  							Match:  "t1",
   864  							Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard),
   865  						}},
   866  					},
   867  				}
   868  				switch i {
   869  				case 0:
   870  					switch j {
   871  					case 0:
   872  						rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-887|0|0|0", j+1, bls))
   873  					case 1:
   874  						rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888|0|0|0", j+1, bls))
   875  					}
   876  				case 1:
   877  					switch j {
   878  					case 0:
   879  						rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888|0|0|0", j+1, bls))
   880  					case 1:
   881  						rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-887|0|0|0", j+1, bls))
   882  					}
   883  				}
   884  			}
   885  			sourceRows = append(sourceRows, rows)
   886  		}
   887  
   888  		for i, dbclient := range tme.dbSourceClients {
   889  			// sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state)
   890  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
   891  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
   892  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
   893  				sourceRows[i]...),
   894  				nil)
   895  			dbclient.addQuery("select distinct vrepl_id from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil)
   896  
   897  			// sm.stopStreams->sm.stopSourceStreams->VReplicationExec('Stopped')
   898  			dbclient.addQuery("select id from _vt.vreplication where id in (1, 2)", resultid12, nil)
   899  			dbclient.addQuery("update _vt.vreplication set state = 'Stopped', message = 'for cutover' where id in (1, 2)", &sqltypes.Result{}, nil)
   900  			dbclient.addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil)
   901  			dbclient.addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil)
   902  
   903  			// sm.stopStreams->sm.stopSourceStreams->sm.readTabletStreams('id in...')
   904  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1, 2)", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
   905  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
   906  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
   907  				sourceRows[i]...),
   908  				nil)
   909  
   910  			// sm.stopStreams->sm.verifyStreamPositions->sm.readTabletStreams('id in...')
   911  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1, 2)", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
   912  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
   913  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
   914  				sourceRows[i]...),
   915  				nil)
   916  		}
   917  	}
   918  	stopStreams()
   919  
   920  	// sm.stopStreams->sm.syncSourceStreams: Note that this happens inside stopStreams before verifyStreamPositions.
   921  	syncSourceStreams := func() {
   922  		reached := sqltypes.MakeTestResult(sqltypes.MakeTestFields(
   923  			"pos|state|message",
   924  			"varbinary|varbinary|varbinary"),
   925  			"MariaDB/5-456-888|Running|",
   926  		)
   927  		tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where id = 1", resultid1, nil)
   928  		tme.dbSourceClients[0].addQuery("update _vt.vreplication set state = 'Running', stop_pos = 'MariaDB/5-456-888', message = 'synchronizing for cutover' where id in (1)", &sqltypes.Result{}, nil)
   929  		tme.dbSourceClients[0].addQuery("select pos, state, message from _vt.vreplication where id=1", reached, nil)
   930  		tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil)
   931  		tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where id = 2", resultid2, nil)
   932  		tme.dbSourceClients[1].addQuery("update _vt.vreplication set state = 'Running', stop_pos = 'MariaDB/5-456-888', message = 'synchronizing for cutover' where id in (2)", &sqltypes.Result{}, nil)
   933  		tme.dbSourceClients[1].addQuery("select pos, state, message from _vt.vreplication where id=2", reached, nil)
   934  		tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil)
   935  	}
   936  	syncSourceStreams()
   937  
   938  	// sm.deleteTargetStreams (simplified to delete nothing)
   939  	tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", &sqltypes.Result{}, nil)
   940  	tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", &sqltypes.Result{}, nil)
   941  
   942  	tme.expectCancelMigration()
   943  
   944  	_, _, err = tme.wr.SwitchWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, false, true, false)
   945  	want := "does not match"
   946  	if err == nil || !strings.Contains(err.Error(), want) {
   947  		t.Errorf("SwitchWrites err: %v, want %s", err, want)
   948  	}
   949  	verifyQueries(t, tme.allDBClients)
   950  }
   951  
   952  func TestStreamMigrateCancel(t *testing.T) {
   953  	ctx := context.Background()
   954  	tme := newTestShardMigrater(ctx, t, []string{"-40", "40-"}, []string{"-80", "80-"})
   955  	defer tme.stopTablets(t)
   956  
   957  	tme.expectNoPreviousJournals()
   958  	// Migrate reads
   959  	_, err := tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", rdOnly, nil, workflow.DirectionForward, false)
   960  	if err != nil {
   961  		t.Fatal(err)
   962  	}
   963  	tme.expectNoPreviousJournals()
   964  	_, err = tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", replica, nil, workflow.DirectionForward, false)
   965  	if err != nil {
   966  		t.Fatal(err)
   967  	}
   968  
   969  	tme.expectCheckJournals()
   970  
   971  	stopStreamsFail := func() {
   972  		// sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped')
   973  		tme.dbSourceClients[0].addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped' and message != 'FROZEN'", &sqltypes.Result{}, nil)
   974  		tme.dbSourceClients[1].addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped' and message != 'FROZEN'", &sqltypes.Result{}, nil)
   975  
   976  		// pre-compute sourceRows because they're re-read multiple times.
   977  		var sourceRows [][]string
   978  		for _, sourceTargetShard := range tme.sourceShards {
   979  			var rows []string
   980  			for j, sourceShard := range tme.sourceShards {
   981  				bls := &binlogdatapb.BinlogSource{
   982  					Keyspace: "ks1",
   983  					Shard:    sourceShard,
   984  					Filter: &binlogdatapb.Filter{
   985  						Rules: []*binlogdatapb.Rule{{
   986  							Match:  "t1",
   987  							Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard),
   988  						}},
   989  					},
   990  				}
   991  				rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888|0|0|0", j+1, bls))
   992  			}
   993  			sourceRows = append(sourceRows, rows)
   994  		}
   995  
   996  		for i, dbclient := range tme.dbSourceClients {
   997  			// sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state)
   998  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
   999  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
  1000  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
  1001  				sourceRows[i]...),
  1002  				nil)
  1003  			dbclient.addQuery("select distinct vrepl_id from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil)
  1004  
  1005  			// sm.stopStreams->sm.stopSourceStreams->VReplicationExec('Stopped'): fail this
  1006  			dbclient.addQuery("select id from _vt.vreplication where id in (1, 2)", nil, fmt.Errorf("intentionally failed"))
  1007  		}
  1008  	}
  1009  	stopStreamsFail()
  1010  
  1011  	cancelMigration := func() {
  1012  		// sm.migrateStreams->sm.deleteTargetStreams
  1013  		tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid34, nil)
  1014  		tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid34, nil)
  1015  		tme.dbTargetClients[0].addQuery("delete from _vt.vreplication where id in (3, 4)", &sqltypes.Result{}, nil)
  1016  		tme.dbTargetClients[1].addQuery("delete from _vt.vreplication where id in (3, 4)", &sqltypes.Result{}, nil)
  1017  		tme.dbTargetClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (3, 4)", &sqltypes.Result{}, nil)
  1018  		tme.dbTargetClients[0].addQuery("delete from _vt.post_copy_action where vrepl_id in (3, 4)", &sqltypes.Result{}, nil)
  1019  		tme.dbTargetClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (3, 4)", &sqltypes.Result{}, nil)
  1020  		tme.dbTargetClients[1].addQuery("delete from _vt.post_copy_action where vrepl_id in (3, 4)", &sqltypes.Result{}, nil)
  1021  
  1022  		// sm.migrateStreams->->restart source streams
  1023  		tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow != 'test_reverse'", resultid12, nil)
  1024  		tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow != 'test_reverse'", resultid12, nil)
  1025  		tme.dbSourceClients[0].addQuery("update _vt.vreplication set state = 'Running', stop_pos = null, message = '' where id in (1, 2)", &sqltypes.Result{}, nil)
  1026  		tme.dbSourceClients[1].addQuery("update _vt.vreplication set state = 'Running', stop_pos = null, message = '' where id in (1, 2)", &sqltypes.Result{}, nil)
  1027  		tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 1", runningResult(1), nil)
  1028  		tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 1", runningResult(1), nil)
  1029  		tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 2", runningResult(2), nil)
  1030  		tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 2", runningResult(2), nil)
  1031  
  1032  		// mi.cancelMigration->restart target streams
  1033  		tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow = 'test'", &sqltypes.Result{}, nil)
  1034  		tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow = 'test'", &sqltypes.Result{}, nil)
  1035  
  1036  		tme.expectDeleteReverseVReplication()
  1037  	}
  1038  	cancelMigration()
  1039  
  1040  	_, _, err = tme.wr.SwitchWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, false, true, false)
  1041  	want := "intentionally failed"
  1042  	if err == nil || !strings.Contains(err.Error(), want) {
  1043  		t.Errorf("SwitchWrites err: %v, want %s", err, want)
  1044  	}
  1045  
  1046  	checkServedTypes(t, tme.ts, "ks:-40", 1)
  1047  	checkServedTypes(t, tme.ts, "ks:40-", 1)
  1048  	checkServedTypes(t, tme.ts, "ks:-80", 2)
  1049  	checkServedTypes(t, tme.ts, "ks:80-", 2)
  1050  
  1051  	checkIfPrimaryServing(t, tme.ts, "ks:-40", true)
  1052  	checkIfPrimaryServing(t, tme.ts, "ks:40-", true)
  1053  	checkIfPrimaryServing(t, tme.ts, "ks:-80", false)
  1054  	checkIfPrimaryServing(t, tme.ts, "ks:80-", false)
  1055  
  1056  	verifyQueries(t, tme.allDBClients)
  1057  }
  1058  
  1059  func TestStreamMigrateStoppedStreams(t *testing.T) {
  1060  	ctx := context.Background()
  1061  	tme := newTestShardMigrater(ctx, t, []string{"0"}, []string{"-80", "80-"})
  1062  	defer tme.stopTablets(t)
  1063  
  1064  	tme.expectNoPreviousJournals()
  1065  	// Migrate reads
  1066  	_, err := tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", rdOnly, nil, workflow.DirectionForward, false)
  1067  	if err != nil {
  1068  		t.Fatal(err)
  1069  	}
  1070  	tme.expectNoPreviousJournals()
  1071  	_, err = tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", replica, nil, workflow.DirectionForward, false)
  1072  	if err != nil {
  1073  		t.Fatal(err)
  1074  	}
  1075  
  1076  	tme.expectCheckJournals()
  1077  
  1078  	stopStreams := func() {
  1079  		// sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped'): returns non-empty
  1080  		var sourceRows [][]string
  1081  		for _, sourceTargetShard := range tme.sourceShards {
  1082  			var rows []string
  1083  			for j, sourceShard := range tme.sourceShards {
  1084  				bls := &binlogdatapb.BinlogSource{
  1085  					Keyspace: "ks1",
  1086  					Shard:    sourceShard,
  1087  					Filter: &binlogdatapb.Filter{
  1088  						Rules: []*binlogdatapb.Rule{{
  1089  							Match:  "t1",
  1090  							Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard),
  1091  						}},
  1092  					},
  1093  				}
  1094  				rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888|0|0|0", j+1, bls))
  1095  			}
  1096  			sourceRows = append(sourceRows, rows)
  1097  		}
  1098  
  1099  		for i, dbclient := range tme.dbSourceClients {
  1100  			// sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state)
  1101  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped' and message != 'FROZEN'", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
  1102  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
  1103  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
  1104  				sourceRows[i]...),
  1105  				nil)
  1106  		}
  1107  	}
  1108  	stopStreams()
  1109  
  1110  	_, _, err = tme.wr.SwitchWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, false, true, false)
  1111  	want := "cannot migrate until all streams are running: 0: 10"
  1112  	if err == nil || err.Error() != want {
  1113  		t.Errorf("SwitchWrites err: %v, want %v", err, want)
  1114  	}
  1115  	verifyQueries(t, tme.allDBClients)
  1116  }
  1117  
  1118  func TestStreamMigrateCancelWithStoppedStreams(t *testing.T) {
  1119  	ctx := context.Background()
  1120  	tme := newTestShardMigrater(ctx, t, []string{"-40", "40-"}, []string{"-80", "80-"})
  1121  	defer tme.stopTablets(t)
  1122  
  1123  	tme.expectNoPreviousJournals()
  1124  	// Migrate reads
  1125  	_, err := tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", rdOnly, nil, workflow.DirectionForward, false)
  1126  	if err != nil {
  1127  		t.Fatal(err)
  1128  	}
  1129  	tme.expectNoPreviousJournals()
  1130  	_, err = tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", replica, nil, workflow.DirectionForward, false)
  1131  	if err != nil {
  1132  		t.Fatal(err)
  1133  	}
  1134  
  1135  	tme.expectCheckJournals()
  1136  
  1137  	stopStreams := func() {
  1138  		var sourceRows [][]string
  1139  		for _, sourceTargetShard := range tme.sourceShards {
  1140  			var rows []string
  1141  			for j, sourceShard := range tme.sourceShards {
  1142  				bls := &binlogdatapb.BinlogSource{
  1143  					Keyspace: "ks1",
  1144  					Shard:    sourceShard,
  1145  					Filter: &binlogdatapb.Filter{
  1146  						Rules: []*binlogdatapb.Rule{{
  1147  							Match:  "t1",
  1148  							Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard),
  1149  						}, {
  1150  							Match:  "t2",
  1151  							Filter: fmt.Sprintf("select * from t2 where in_keyrange('%s')", sourceTargetShard),
  1152  						}},
  1153  					},
  1154  				}
  1155  				rows = append(rows, fmt.Sprintf("%d|t1t2|%v|MariaDB/5-456-888|0|0|0", j+1, bls))
  1156  			}
  1157  			sourceRows = append(sourceRows, rows)
  1158  		}
  1159  
  1160  		for i, dbclient := range tme.dbSourceClients {
  1161  			// sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state)
  1162  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
  1163  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
  1164  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
  1165  				sourceRows[i]...),
  1166  				nil)
  1167  			dbclient.addQuery("select distinct vrepl_id from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil)
  1168  		}
  1169  	}
  1170  	stopStreams()
  1171  
  1172  	// sm.migrateStreams->->sm.deleteTargetStreams (no previously migrated streams)
  1173  	tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2')", &sqltypes.Result{}, nil)
  1174  	tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2')", &sqltypes.Result{}, nil)
  1175  
  1176  	tme.expectCancelMigration()
  1177  
  1178  	_, _, err = tme.wr.SwitchWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, true, false, false, false)
  1179  	if err != nil {
  1180  		t.Fatal(err)
  1181  	}
  1182  	verifyQueries(t, tme.allDBClients)
  1183  }
  1184  
  1185  func TestStreamMigrateStillCopying(t *testing.T) {
  1186  	ctx := context.Background()
  1187  	tme := newTestShardMigrater(ctx, t, []string{"0"}, []string{"-80", "80-"})
  1188  	defer tme.stopTablets(t)
  1189  
  1190  	tme.expectNoPreviousJournals()
  1191  	// Migrate reads
  1192  	_, err := tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", rdOnly, nil, workflow.DirectionForward, false)
  1193  	if err != nil {
  1194  		t.Fatal(err)
  1195  	}
  1196  	tme.expectNoPreviousJournals()
  1197  	_, err = tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", replica, nil, workflow.DirectionForward, false)
  1198  	if err != nil {
  1199  		t.Fatal(err)
  1200  	}
  1201  
  1202  	tme.expectCheckJournals()
  1203  
  1204  	stopStreams := func() {
  1205  		// sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped')
  1206  		tme.dbSourceClients[0].addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped' and message != 'FROZEN'", &sqltypes.Result{}, nil)
  1207  
  1208  		// pre-compute sourceRows because they're re-read multiple times.
  1209  		var sourceRows [][]string
  1210  		for _, sourceTargetShard := range tme.sourceShards {
  1211  			var rows []string
  1212  			for j, sourceShard := range tme.sourceShards {
  1213  				bls := &binlogdatapb.BinlogSource{
  1214  					Keyspace: "ks1",
  1215  					Shard:    sourceShard,
  1216  					Filter: &binlogdatapb.Filter{
  1217  						Rules: []*binlogdatapb.Rule{{
  1218  							Match:  "t1",
  1219  							Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard),
  1220  						}},
  1221  					},
  1222  				}
  1223  				rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888|0|0|0", j+1, bls))
  1224  			}
  1225  			sourceRows = append(sourceRows, rows)
  1226  		}
  1227  
  1228  		for i, dbclient := range tme.dbSourceClients {
  1229  			// sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state)
  1230  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
  1231  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
  1232  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
  1233  				sourceRows[i]...),
  1234  				nil)
  1235  			dbclient.addQuery("select distinct vrepl_id from _vt.copy_state where vrepl_id in (1)", resultid1, nil)
  1236  		}
  1237  	}
  1238  	stopStreams()
  1239  
  1240  	_, _, err = tme.wr.SwitchWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, false, true, false)
  1241  	want := "cannot migrate while vreplication streams in source shards are still copying: 0"
  1242  	if err == nil || err.Error() != want {
  1243  		t.Errorf("SwitchWrites err: %v, want %v", err, want)
  1244  	}
  1245  	verifyQueries(t, tme.allDBClients)
  1246  }
  1247  
  1248  func TestStreamMigrateEmptyWorkflow(t *testing.T) {
  1249  	ctx := context.Background()
  1250  	tme := newTestShardMigrater(ctx, t, []string{"0"}, []string{"-80", "80-"})
  1251  	defer tme.stopTablets(t)
  1252  
  1253  	tme.expectNoPreviousJournals()
  1254  	// Migrate reads
  1255  	_, err := tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", rdOnly, nil, workflow.DirectionForward, false)
  1256  	if err != nil {
  1257  		t.Fatal(err)
  1258  	}
  1259  	tme.expectNoPreviousJournals()
  1260  	_, err = tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", replica, nil, workflow.DirectionForward, false)
  1261  	if err != nil {
  1262  		t.Fatal(err)
  1263  	}
  1264  
  1265  	tme.expectCheckJournals()
  1266  
  1267  	stopStreams := func() {
  1268  		// sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped')
  1269  		tme.dbSourceClients[0].addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped' and message != 'FROZEN'", &sqltypes.Result{}, nil)
  1270  
  1271  		// pre-compute sourceRows because they're re-read multiple times.
  1272  		var sourceRows [][]string
  1273  		for _, sourceTargetShard := range tme.sourceShards {
  1274  			var rows []string
  1275  			for j, sourceShard := range tme.sourceShards {
  1276  				bls := &binlogdatapb.BinlogSource{
  1277  					Keyspace: "ks1",
  1278  					Shard:    sourceShard,
  1279  					Filter: &binlogdatapb.Filter{
  1280  						Rules: []*binlogdatapb.Rule{{
  1281  							Match:  "t1",
  1282  							Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard),
  1283  						}},
  1284  					},
  1285  				}
  1286  				rows = append(rows, fmt.Sprintf("%d||%v|MariaDB/5-456-888|0|0|0", j+1, bls))
  1287  			}
  1288  			sourceRows = append(sourceRows, rows)
  1289  		}
  1290  
  1291  		for i, dbclient := range tme.dbSourceClients {
  1292  			// sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state)
  1293  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
  1294  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
  1295  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
  1296  				sourceRows[i]...),
  1297  				nil)
  1298  		}
  1299  	}
  1300  	stopStreams()
  1301  
  1302  	_, _, err = tme.wr.SwitchWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, false, true, false)
  1303  	want := "VReplication streams must have named workflows for migration: shard: ks:0, stream: 1"
  1304  	if err == nil || err.Error() != want {
  1305  		t.Errorf("SwitchWrites err: %v, want %v", err, want)
  1306  	}
  1307  	verifyQueries(t, tme.allDBClients)
  1308  }
  1309  
  1310  func TestStreamMigrateDupWorkflow(t *testing.T) {
  1311  	ctx := context.Background()
  1312  	tme := newTestShardMigrater(ctx, t, []string{"0"}, []string{"-80", "80-"})
  1313  	defer tme.stopTablets(t)
  1314  
  1315  	tme.expectNoPreviousJournals()
  1316  	// Migrate reads
  1317  	_, err := tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", rdOnly, nil, workflow.DirectionForward, false)
  1318  	if err != nil {
  1319  		t.Fatal(err)
  1320  	}
  1321  	tme.expectNoPreviousJournals()
  1322  	_, err = tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", replica, nil, workflow.DirectionForward, false)
  1323  	if err != nil {
  1324  		t.Fatal(err)
  1325  	}
  1326  
  1327  	tme.expectCheckJournals()
  1328  
  1329  	stopStreams := func() {
  1330  		// sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped')
  1331  		tme.dbSourceClients[0].addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped' and message != 'FROZEN'", &sqltypes.Result{}, nil)
  1332  
  1333  		// pre-compute sourceRows because they're re-read multiple times.
  1334  		var sourceRows [][]string
  1335  		for _, sourceTargetShard := range tme.sourceShards {
  1336  			var rows []string
  1337  			for j, sourceShard := range tme.sourceShards {
  1338  				bls := &binlogdatapb.BinlogSource{
  1339  					Keyspace: "ks1",
  1340  					Shard:    sourceShard,
  1341  					Filter: &binlogdatapb.Filter{
  1342  						Rules: []*binlogdatapb.Rule{{
  1343  							Match:  "t1",
  1344  							Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard),
  1345  						}},
  1346  					},
  1347  				}
  1348  				rows = append(rows, fmt.Sprintf("%d|test|%v|MariaDB/5-456-888|0|0|0", j+1, bls))
  1349  			}
  1350  			sourceRows = append(sourceRows, rows)
  1351  		}
  1352  
  1353  		for i, dbclient := range tme.dbSourceClients {
  1354  			// sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state)
  1355  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
  1356  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
  1357  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
  1358  				sourceRows[i]...),
  1359  				nil)
  1360  		}
  1361  	}
  1362  	stopStreams()
  1363  
  1364  	_, _, err = tme.wr.SwitchWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, false, true, false)
  1365  	want := "VReplication stream has the same workflow name as the resharding workflow: shard: ks:0, stream: 1"
  1366  	if err == nil || err.Error() != want {
  1367  		t.Errorf("SwitchWrites err: %v, want %v", err, want)
  1368  	}
  1369  	verifyQueries(t, tme.allDBClients)
  1370  }
  1371  
  1372  func TestStreamMigrateStreamsMismatch(t *testing.T) {
  1373  	ctx := context.Background()
  1374  	// Interesting tidbit: you cannot create a shard "0" for an already sharded keyspace.
  1375  	tme := newTestShardMigrater(ctx, t, []string{"-80", "80-"}, []string{"-"})
  1376  	defer tme.stopTablets(t)
  1377  
  1378  	tme.expectNoPreviousJournals()
  1379  	// Migrate reads
  1380  	_, err := tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", rdOnly, nil, workflow.DirectionForward, false)
  1381  	if err != nil {
  1382  		t.Fatal(err)
  1383  	}
  1384  	tme.expectNoPreviousJournals()
  1385  	_, err = tme.wr.SwitchReads(ctx, tme.targetKeyspace, "test", replica, nil, workflow.DirectionForward, false)
  1386  	if err != nil {
  1387  		t.Fatal(err)
  1388  	}
  1389  
  1390  	tme.expectCheckJournals()
  1391  
  1392  	stopStreams := func() {
  1393  		// sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped')
  1394  		tme.dbSourceClients[0].addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped' and message != 'FROZEN'", &sqltypes.Result{}, nil)
  1395  		tme.dbSourceClients[1].addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped' and message != 'FROZEN'", &sqltypes.Result{}, nil)
  1396  
  1397  		// pre-compute sourceRows because they're re-read multiple times.
  1398  		var sourceRows [][]string
  1399  		for i, sourceTargetShard := range tme.sourceShards {
  1400  			var rows []string
  1401  			for j, sourceShard := range tme.sourceShards {
  1402  				// Skip one stream in one shard.
  1403  				if i == 0 && j == 0 {
  1404  					continue
  1405  				}
  1406  				bls := &binlogdatapb.BinlogSource{
  1407  					Keyspace: "ks1",
  1408  					Shard:    sourceShard,
  1409  					Filter: &binlogdatapb.Filter{
  1410  						Rules: []*binlogdatapb.Rule{{
  1411  							Match:  "t1",
  1412  							Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard),
  1413  						}},
  1414  					},
  1415  				}
  1416  				rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888|0|0|0", j+1, bls))
  1417  			}
  1418  			sourceRows = append(sourceRows, rows)
  1419  		}
  1420  
  1421  		for i, dbclient := range tme.dbSourceClients {
  1422  			// sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state)
  1423  			dbclient.addQuery("select id, workflow, source, pos, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields(
  1424  				"id|workflow|source|pos|workflow_type|workflow_sub_type|defer_secondary_keys",
  1425  				"int64|varbinary|varchar|varbinary|int64|int64|int64"),
  1426  				sourceRows[i]...),
  1427  				nil)
  1428  			if i == 0 {
  1429  				dbclient.addQuery("select distinct vrepl_id from _vt.copy_state where vrepl_id in (2)", &sqltypes.Result{}, nil)
  1430  			} else {
  1431  				dbclient.addQuery("select distinct vrepl_id from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil)
  1432  			}
  1433  		}
  1434  	}
  1435  	stopStreams()
  1436  
  1437  	_, _, err = tme.wr.SwitchWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, false, true, false)
  1438  	want := "streams are mismatched across source shards"
  1439  	if err == nil || !strings.Contains(err.Error(), want) {
  1440  		t.Errorf("SwitchWrites err: %v, must contain %v", err, want)
  1441  	}
  1442  	verifyQueries(t, tme.allDBClients)
  1443  }