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 }