vitess.io/vitess@v0.16.2/go/vt/vttablet/tabletmanager/vreplication/journal_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 vreplication
    18  
    19  import (
    20  	"fmt"
    21  	"testing"
    22  
    23  	"context"
    24  
    25  	binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata"
    26  	qh "vitess.io/vitess/go/vt/vttablet/tabletmanager/vreplication/queryhistory"
    27  )
    28  
    29  func TestJournalOneToOne(t *testing.T) {
    30  	defer deleteTablet(addTablet(100))
    31  	defer deleteTablet(addOtherTablet(101, "other_keyspace", "0"))
    32  
    33  	execStatements(t, []string{
    34  		"create table t(id int, val varbinary(128), primary key(id))",
    35  		fmt.Sprintf("create table %s.t(id int, val varbinary(128), primary key(id))", vrepldb),
    36  	})
    37  	defer execStatements(t, []string{
    38  		"drop table t",
    39  		fmt.Sprintf("drop table %s.t", vrepldb),
    40  	})
    41  	env.SchemaEngine.Reload(context.Background())
    42  
    43  	filter := &binlogdatapb.Filter{
    44  		Rules: []*binlogdatapb.Rule{{
    45  			Match: "t",
    46  		}},
    47  	}
    48  	bls := &binlogdatapb.BinlogSource{
    49  		Keyspace: env.KeyspaceName,
    50  		Shard:    env.ShardName,
    51  		Filter:   filter,
    52  		OnDdl:    binlogdatapb.OnDDLAction_IGNORE,
    53  	}
    54  
    55  	_, firstID := startVReplication(t, bls, "")
    56  
    57  	journal := &binlogdatapb.Journal{
    58  		Id:            1,
    59  		MigrationType: binlogdatapb.MigrationType_SHARDS,
    60  		Participants: []*binlogdatapb.KeyspaceShard{{
    61  			Keyspace: "vttest",
    62  			Shard:    "0",
    63  		}},
    64  		ShardGtids: []*binlogdatapb.ShardGtid{{
    65  			Keyspace: "other_keyspace",
    66  			Shard:    "0",
    67  			Gtid:     "MySQL56/7b04699f-f5e9-11e9-bf88-9cb6d089e1c3:1-10",
    68  		}},
    69  	}
    70  	query := fmt.Sprintf("insert into _vt.resharding_journal(id, db_name, val) values (1, 'vttest', %v)", encodeString(journal.String()))
    71  	execStatements(t, []string{query})
    72  	defer execStatements(t, []string{"delete from _vt.resharding_journal"})
    73  
    74  	expectDBClientQueries(t, qh.Expect(
    75  		"begin",
    76  		`/insert into _vt.vreplication.*workflow, source, pos.*values.*'test', 'keyspace:\\"other_keyspace\\" shard:\\"0\\.*'MySQL56/7b04699f-f5e9-11e9-bf88-9cb6d089e1c3:1-10'`,
    77  		fmt.Sprintf("delete from _vt.vreplication where id=%d", firstID),
    78  		"commit",
    79  		"/update _vt.vreplication set message='Picked source tablet.*",
    80  		"/update _vt.vreplication set state='Running', message='' where id.*",
    81  	))
    82  
    83  	// Delete all vreplication streams. There should be only one, but we don't know its id.
    84  	if _, err := playerEngine.Exec("delete from _vt.vreplication"); err != nil {
    85  		t.Fatal(err)
    86  	}
    87  	expectDeleteQueries(t)
    88  }
    89  
    90  func TestJournalOneToMany(t *testing.T) {
    91  	defer deleteTablet(addTablet(100))
    92  	defer deleteTablet(addOtherTablet(101, "other_keyspace", "-80"))
    93  	defer deleteTablet(addOtherTablet(102, "other_keyspace", "80-"))
    94  
    95  	execStatements(t, []string{
    96  		"create table t(id int, val varbinary(128), primary key(id))",
    97  		fmt.Sprintf("create table %s.t(id int, val varbinary(128), primary key(id))", vrepldb),
    98  	})
    99  	defer execStatements(t, []string{
   100  		"drop table t",
   101  		fmt.Sprintf("drop table %s.t", vrepldb),
   102  	})
   103  	env.SchemaEngine.Reload(context.Background())
   104  
   105  	filter := &binlogdatapb.Filter{
   106  		Rules: []*binlogdatapb.Rule{{
   107  			Match: "t",
   108  		}},
   109  	}
   110  	bls := &binlogdatapb.BinlogSource{
   111  		Keyspace: env.KeyspaceName,
   112  		Shard:    env.ShardName,
   113  		Filter:   filter,
   114  		OnDdl:    binlogdatapb.OnDDLAction_IGNORE,
   115  	}
   116  
   117  	_, firstID := startVReplication(t, bls, "")
   118  
   119  	journal := &binlogdatapb.Journal{
   120  		Id:            1,
   121  		MigrationType: binlogdatapb.MigrationType_SHARDS,
   122  		Participants: []*binlogdatapb.KeyspaceShard{{
   123  			Keyspace: "vttest",
   124  			Shard:    "0",
   125  		}},
   126  		ShardGtids: []*binlogdatapb.ShardGtid{{
   127  			Keyspace: "other_keyspace",
   128  			Shard:    "-80",
   129  			Gtid:     "MySQL56/7b04699f-f5e9-11e9-bf88-9cb6d089e1c3:1-5",
   130  		}, {
   131  			Keyspace: "other_keyspace",
   132  			Shard:    "80-",
   133  			Gtid:     "MySQL56/7b04699f-f5e9-11e9-bf88-9cb6d089e1c3:5-10",
   134  		}},
   135  	}
   136  	query := fmt.Sprintf("insert into _vt.resharding_journal(id, db_name, val) values (1, 'vttest', %v)", encodeString(journal.String()))
   137  	execStatements(t, []string{query})
   138  	defer execStatements(t, []string{"delete from _vt.resharding_journal"})
   139  
   140  	expectDBClientQueries(t, qh.Expect(
   141  		"begin",
   142  		`/insert into _vt.vreplication.*workflow, source, pos.*values.*'test', 'keyspace:\\"other_keyspace\\" shard:\\"-80\\.*'MySQL56/7b04699f-f5e9-11e9-bf88-9cb6d089e1c3:1-5'`,
   143  		`/insert into _vt.vreplication.*workflow, source, pos.*values.*'test', 'keyspace:\\"other_keyspace\\" shard:\\"80-\\.*'MySQL56/7b04699f-f5e9-11e9-bf88-9cb6d089e1c3:5-10'`,
   144  		fmt.Sprintf("delete from _vt.vreplication where id=%d", firstID),
   145  		"commit",
   146  		"/update _vt.vreplication set message='Picked source tablet.*",
   147  		"/update _vt.vreplication set message='Picked source tablet.*",
   148  		"/update _vt.vreplication set state='Running', message='' where id.*",
   149  		"/update _vt.vreplication set state='Running', message='' where id.*",
   150  	))
   151  
   152  	// Delete all vreplication streams. There should be only one, but we don't know its id.
   153  	if _, err := playerEngine.Exec("delete from _vt.vreplication"); err != nil {
   154  		t.Fatal(err)
   155  	}
   156  	expectDeleteQueries(t)
   157  }
   158  
   159  func TestJournalTablePresent(t *testing.T) {
   160  	defer deleteTablet(addTablet(100))
   161  	defer deleteTablet(addOtherTablet(101, "other_keyspace", "0"))
   162  
   163  	execStatements(t, []string{
   164  		"create table t(id int, val varbinary(128), primary key(id))",
   165  		fmt.Sprintf("create table %s.t(id int, val varbinary(128), primary key(id))", vrepldb),
   166  	})
   167  	defer execStatements(t, []string{
   168  		"drop table t",
   169  		fmt.Sprintf("drop table %s.t", vrepldb),
   170  	})
   171  	env.SchemaEngine.Reload(context.Background())
   172  
   173  	filter := &binlogdatapb.Filter{
   174  		Rules: []*binlogdatapb.Rule{{
   175  			Match: "t",
   176  		}},
   177  	}
   178  	bls := &binlogdatapb.BinlogSource{
   179  		Keyspace: env.KeyspaceName,
   180  		Shard:    env.ShardName,
   181  		Filter:   filter,
   182  		OnDdl:    binlogdatapb.OnDDLAction_IGNORE,
   183  	}
   184  	_, firstID := startVReplication(t, bls, "")
   185  
   186  	journal := &binlogdatapb.Journal{
   187  		Id:            1,
   188  		MigrationType: binlogdatapb.MigrationType_TABLES,
   189  		Participants: []*binlogdatapb.KeyspaceShard{{
   190  			Keyspace: "vttest",
   191  			Shard:    "0",
   192  		}},
   193  		Tables: []string{"t"},
   194  		ShardGtids: []*binlogdatapb.ShardGtid{{
   195  			Keyspace: "other_keyspace",
   196  			Shard:    "0",
   197  			Gtid:     "MySQL56/7b04699f-f5e9-11e9-bf88-9cb6d089e1c3:1-10",
   198  		}},
   199  	}
   200  	query := fmt.Sprintf("insert into _vt.resharding_journal(id, db_name, val) values (1, 'vttest', %v)", encodeString(journal.String()))
   201  	execStatements(t, []string{query})
   202  	defer execStatements(t, []string{"delete from _vt.resharding_journal"})
   203  
   204  	expectDBClientQueries(t, qh.Expect(
   205  		"begin",
   206  		`/insert into _vt.vreplication.*workflow, source, pos.*values.*'test', 'keyspace:\\"other_keyspace\\" shard:\\"0\\.*'MySQL56/7b04699f-f5e9-11e9-bf88-9cb6d089e1c3:1-10'`,
   207  		fmt.Sprintf("delete from _vt.vreplication where id=%d", firstID),
   208  		"commit",
   209  		"/update _vt.vreplication set message='Picked source tablet.*",
   210  		"/update _vt.vreplication set state='Running', message='' where id.*",
   211  	))
   212  
   213  	// Delete all vreplication streams. There should be only one, but we don't know its id.
   214  	if _, err := playerEngine.Exec("delete from _vt.vreplication"); err != nil {
   215  		t.Fatal(err)
   216  	}
   217  	expectDeleteQueries(t)
   218  }
   219  
   220  func TestJournalTableNotPresent(t *testing.T) {
   221  	defer deleteTablet(addTablet(100))
   222  	defer deleteTablet(addOtherTablet(101, "other_keyspace", "0"))
   223  
   224  	execStatements(t, []string{
   225  		"create table t(id int, val varbinary(128), primary key(id))",
   226  		fmt.Sprintf("create table %s.t(id int, val varbinary(128), primary key(id))", vrepldb),
   227  	})
   228  	defer execStatements(t, []string{
   229  		"drop table t",
   230  		fmt.Sprintf("drop table %s.t", vrepldb),
   231  	})
   232  	env.SchemaEngine.Reload(context.Background())
   233  
   234  	filter := &binlogdatapb.Filter{
   235  		Rules: []*binlogdatapb.Rule{{
   236  			Match: "t",
   237  		}},
   238  	}
   239  	bls := &binlogdatapb.BinlogSource{
   240  		Keyspace: env.KeyspaceName,
   241  		Shard:    env.ShardName,
   242  		Filter:   filter,
   243  		OnDdl:    binlogdatapb.OnDDLAction_IGNORE,
   244  	}
   245  
   246  	_, _ = startVReplication(t, bls, "")
   247  
   248  	journal := &binlogdatapb.Journal{
   249  		Id:            1,
   250  		MigrationType: binlogdatapb.MigrationType_TABLES,
   251  		Participants: []*binlogdatapb.KeyspaceShard{{
   252  			Keyspace: "vttest",
   253  			Shard:    "0",
   254  		}},
   255  		Tables: []string{"t1"},
   256  		ShardGtids: []*binlogdatapb.ShardGtid{{
   257  			Keyspace: "other_keyspace",
   258  			Shard:    "0",
   259  			Gtid:     "MySQL56/7b04699f-f5e9-11e9-bf88-9cb6d089e1c3:1-10",
   260  		}},
   261  	}
   262  	query := fmt.Sprintf("insert into _vt.resharding_journal(id, db_name, val) values (1, 'vttest', %v)", encodeString(journal.String()))
   263  	execStatements(t, []string{query})
   264  	defer execStatements(t, []string{"delete from _vt.resharding_journal"})
   265  
   266  	// Delete all vreplication streams. There should be only one, but we don't know its id.
   267  	if _, err := playerEngine.Exec("delete from _vt.vreplication"); err != nil {
   268  		t.Fatal(err)
   269  	}
   270  	expectDeleteQueries(t)
   271  }
   272  
   273  func TestJournalTableMixed(t *testing.T) {
   274  	defer deleteTablet(addTablet(100))
   275  	defer deleteTablet(addOtherTablet(101, "other_keyspace", "0"))
   276  
   277  	execStatements(t, []string{
   278  		"create table t(id int, val varbinary(128), primary key(id))",
   279  		"create table t1(id int, val varbinary(128), primary key(id))",
   280  		fmt.Sprintf("create table %s.t(id int, val varbinary(128), primary key(id))", vrepldb),
   281  		fmt.Sprintf("create table %s.t1(id int, val varbinary(128), primary key(id))", vrepldb),
   282  	})
   283  	defer execStatements(t, []string{
   284  		"drop table t",
   285  		"drop table t1",
   286  		fmt.Sprintf("drop table %s.t", vrepldb),
   287  		fmt.Sprintf("drop table %s.t1", vrepldb),
   288  	})
   289  	env.SchemaEngine.Reload(context.Background())
   290  
   291  	filter := &binlogdatapb.Filter{
   292  		Rules: []*binlogdatapb.Rule{{
   293  			Match: "t",
   294  		}, {
   295  			Match: "t1",
   296  		}},
   297  	}
   298  	bls := &binlogdatapb.BinlogSource{
   299  		Keyspace: env.KeyspaceName,
   300  		Shard:    env.ShardName,
   301  		Filter:   filter,
   302  		OnDdl:    binlogdatapb.OnDDLAction_IGNORE,
   303  	}
   304  	_, _ = startVReplication(t, bls, "")
   305  
   306  	journal := &binlogdatapb.Journal{
   307  		Id:            1,
   308  		MigrationType: binlogdatapb.MigrationType_TABLES,
   309  		Participants: []*binlogdatapb.KeyspaceShard{{
   310  			Keyspace: "vttest",
   311  			Shard:    "0",
   312  		}},
   313  		Tables: []string{"t"},
   314  		ShardGtids: []*binlogdatapb.ShardGtid{{
   315  			Keyspace: "other_keyspace",
   316  			Shard:    "0",
   317  			Gtid:     "MySQL56/7b04699f-f5e9-11e9-bf88-9cb6d089e1c3:1-10",
   318  		}},
   319  	}
   320  	query := fmt.Sprintf("insert into _vt.resharding_journal(id, db_name, val) values (1, 'vttest', %v)", encodeString(journal.String()))
   321  	execStatements(t, []string{query})
   322  	defer execStatements(t, []string{"delete from _vt.resharding_journal"})
   323  
   324  	expectDBClientQueries(t, qh.Expect(
   325  		"/update _vt.vreplication set state='Stopped', message='unable to handle journal event: tables were partially matched' where id",
   326  	))
   327  
   328  	// Delete all vreplication streams. There should be only one, but we don't know its id.
   329  	if _, err := playerEngine.Exec("delete from _vt.vreplication"); err != nil {
   330  		t.Fatal(err)
   331  	}
   332  	expectDeleteQueries(t)
   333  }