From 85847a7514b936461032f6af887d2bd99d93da5f Mon Sep 17 00:00:00 2001 From: Adam Saponara Date: Thu, 29 Nov 2018 11:14:58 -0500 Subject: [PATCH] Add `-init_populate_metadata` to vttablet (#4115) Signed-off-by: Adam Saponara --- go/vt/mysqlctl/backup.go | 6 ++--- go/vt/mysqlctl/metadata_tables.go | 4 +-- go/vt/vttablet/tabletmanager/init_tablet.go | 27 +++++++++++++------ .../tabletmanager/init_tablet_test.go | 18 ++++++++++++- 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/go/vt/mysqlctl/backup.go b/go/vt/mysqlctl/backup.go index 7120e9f6c7a..6af46b12e6d 100644 --- a/go/vt/mysqlctl/backup.go +++ b/go/vt/mysqlctl/backup.go @@ -797,7 +797,7 @@ func Restore( } if !ok { logger.Infof("Auto-restore is enabled, but mysqld already contains data. Assuming vttablet was just restarted.") - if err = populateMetadataTables(mysqld, localMetadata); err == nil { + if err = PopulateMetadataTables(mysqld, localMetadata); err == nil { err = ErrExistingDB } return mysql.Position{}, err @@ -820,7 +820,7 @@ func Restore( if len(bhs) == 0 { // There are no backups (not even broken/incomplete ones). logger.Errorf("No backup to restore on BackupStorage for directory %v. Starting up empty.", dir) - if err = populateMetadataTables(mysqld, localMetadata); err == nil { + if err = PopulateMetadataTables(mysqld, localMetadata); err == nil { err = ErrNoBackup } return mysql.Position{}, err @@ -901,7 +901,7 @@ func Restore( // Populate local_metadata before starting without --skip-networking, // so it's there before we start announcing ourselves. logger.Infof("Restore: populating local_metadata") - err = populateMetadataTables(mysqld, localMetadata) + err = PopulateMetadataTables(mysqld, localMetadata) if err != nil { return mysql.Position{}, err } diff --git a/go/vt/mysqlctl/metadata_tables.go b/go/vt/mysqlctl/metadata_tables.go index ac911ccfdbc..5fd4aee1134 100644 --- a/go/vt/mysqlctl/metadata_tables.go +++ b/go/vt/mysqlctl/metadata_tables.go @@ -36,7 +36,7 @@ const sqlCreateShardMetadataTable = `CREATE TABLE IF NOT EXISTS _vt.shard_metada PRIMARY KEY (name) ) ENGINE=InnoDB` -// populateMetadataTables creates and fills the _vt.local_metadata table and +// PopulateMetadataTables creates and fills the _vt.local_metadata table and // creates _vt.shard_metadata table. _vt.local_metadata table is // a per-tablet table that is never replicated. This allows queries // against local_metadata to return different values on different tablets, @@ -46,7 +46,7 @@ const sqlCreateShardMetadataTable = `CREATE TABLE IF NOT EXISTS _vt.shard_metada // created here to make it easier to create it on databases that were running // old version of Vitess, or databases that are getting converted to run under // Vitess. -func populateMetadataTables(mysqld MysqlDaemon, localMetadata map[string]string) error { +func PopulateMetadataTables(mysqld MysqlDaemon, localMetadata map[string]string) error { log.Infof("Populating _vt.local_metadata table...") // Get a non-pooled DBA connection. diff --git a/go/vt/vttablet/tabletmanager/init_tablet.go b/go/vt/vttablet/tabletmanager/init_tablet.go index 9a28e0fac38..804590d2d82 100644 --- a/go/vt/vttablet/tabletmanager/init_tablet.go +++ b/go/vt/vttablet/tabletmanager/init_tablet.go @@ -30,19 +30,20 @@ import ( "vitess.io/vitess/go/flagutil" "vitess.io/vitess/go/netutil" "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/mysqlctl" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" - - topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) var ( - initDbNameOverride = flag.String("init_db_name_override", "", "(init parameter) override the name of the db used by vttablet") - initKeyspace = flag.String("init_keyspace", "", "(init parameter) keyspace to use for this tablet") - initShard = flag.String("init_shard", "", "(init parameter) shard to use for this tablet") - initTags flagutil.StringMapValue - initTabletType = flag.String("init_tablet_type", "", "(init parameter) the tablet type to use for this tablet.") - initTimeout = flag.Duration("init_timeout", 1*time.Minute, "(init parameter) timeout to use for the init phase.") + initDbNameOverride = flag.String("init_db_name_override", "", "(init parameter) override the name of the db used by vttablet") + initKeyspace = flag.String("init_keyspace", "", "(init parameter) keyspace to use for this tablet") + initShard = flag.String("init_shard", "", "(init parameter) shard to use for this tablet") + initTags flagutil.StringMapValue + initTabletType = flag.String("init_tablet_type", "", "(init parameter) the tablet type to use for this tablet.") + initTimeout = flag.Duration("init_timeout", 1*time.Minute, "(init parameter) timeout to use for the init phase.") + initPopulateMetadata = flag.Bool("init_populate_metadata", false, "(init parameter) populate metadata tables") ) func init() { @@ -206,5 +207,15 @@ func (agent *ActionAgent) InitTablet(port, gRPCPort int32) error { return vterrors.Wrap(err, "CreateTablet failed") } + // optionally populate metadata records + if *initPopulateMetadata { + agent.setTablet(tablet) + localMetadata := agent.getLocalMetadataValues(tablet.Type) + err := mysqlctl.PopulateMetadataTables(agent.MysqlDaemon, localMetadata) + if err != nil { + return vterrors.Wrap(err, "failed to -init_populate_metadata") + } + } + return nil } diff --git a/go/vt/vttablet/tabletmanager/init_tablet_test.go b/go/vt/vttablet/tabletmanager/init_tablet_test.go index d9083ab86ef..1171474637e 100644 --- a/go/vt/vttablet/tabletmanager/init_tablet_test.go +++ b/go/vt/vttablet/tabletmanager/init_tablet_test.go @@ -25,6 +25,8 @@ import ( "github.com/golang/protobuf/proto" "vitess.io/vitess/go/history" + "vitess.io/vitess/go/mysql/fakesqldb" + "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/dbconfigs" "vitess.io/vitess/go/vt/mysqlctl/fakemysqldaemon" "vitess.io/vitess/go/vt/topo" @@ -169,11 +171,24 @@ func TestInitTablet(t *testing.T) { Cell: "cell1", Uid: 1, } + db := fakesqldb.New(t) + defer db.Close() + db.AddQueryPattern(`(SET|CREATE|BEGIN|INSERT|COMMIT)\b.*`, &sqltypes.Result{}) + /* + db.AddQuery("SET @@session.sql_log_bin = 0", &sqltypes.Result{}) + db.AddQuery("CREATE DATABASE IF NOT EXISTS _vt", &sqltypes.Result{}) + db.AddQueryPattern(`CREATE TABLE IF NOT EXISTS _vt\.local_metadata.*`, &sqltypes.Result{}) + db.AddQueryPattern(`CREATE TABLE IF NOT EXISTS _vt\.shard_metadata.*`, &sqltypes.Result{}) + db.AddQuery("BEGIN", &sqltypes.Result{}) + db.AddQueryPattern(`INSERT INTO _vt.local_metadata.*`, &sqltypes.Result{}) + db.AddQueryPattern(`INSERT INTO _vt.shard_metadata.*`, &sqltypes.Result{}) + db.AddQuery("COMMIT", &sqltypes.Result{}) + */ // start with a tablet record that doesn't exist port := int32(1234) gRPCPort := int32(3456) - mysqlDaemon := fakemysqldaemon.NewFakeMysqlDaemon(nil) + mysqlDaemon := fakemysqldaemon.NewFakeMysqlDaemon(db) agent := &ActionAgent{ TopoServer: ts, TabletAlias: tabletAlias, @@ -194,6 +209,7 @@ func TestInitTablet(t *testing.T) { *initKeyspace = "test_keyspace" *initShard = "-C0" *initTabletType = "replica" + *initPopulateMetadata = true tabletAlias = &topodatapb.TabletAlias{ Cell: "cell1", Uid: 2,