Unmanaged Schema Changes

Vitess offers multiple approaches to running unmanaged schema changes. Below, we review each of these approaches.

We assume we have a keyspace (schema) called commerce, with a table called demo, that has the following definition:

  1. CREATE TABLE `demo` (
  2. `id` int NOT NULL,
  3. `status` varchar(32) DEFAULT NULL,
  4. PRIMARY KEY (`id`)
  5. ) ENGINE=InnoDB

ApplySchema

ApplySchema is a vtctldclient command that can be used to apply a schema change to a keyspace. The main advantage of using this tool is that it performs some sanity checks about the schema before applying it. However, a downside is that it can be a little too strict and may not work for all use cases.

Consider the following examples:

  1. $ vtctldclient ApplySchema --sql "ALTER TABLE demo modify id bigint unsigned" commerce
  1. SHOW CREATE TABLE demo;
  2. CREATE TABLE `demo` (
  3. `id` bigint unsigned NOT NULL,
  4. `status` varchar(32) DEFAULT NULL,
  5. PRIMARY KEY (`id`)
  6. ) ENGINE=InnoDB

In the above, we run a direct, synchronous, blocking ALTER TABLE statement. Knowing the table is in commerce keyspace, Vitess autodetects the relevant shards, and then autodetects which is the primary server in each shard. It then directly invokes the ALTER TABLE statement on all shards (concurrently), and the vtctldclient command only returns when all are complete.

When applying a new schema, where all statements are CREATE TABLE or CREATE VIEW, you may supply the flag --batch-size=<n>. For example:

  1. $ vtctldclient ApplySchema --sql-file /tmp/create.sql --batch-size=100 commerce

This flag only applies for unmanaged schema changes, and optimizes total run time by sending batches of CREATE statements to the underlying databases.

VTGate

You may run DDL directly from VTGate just like you would send to a MySQL instance. For example:

  1. $ mysql -h 127.0.0.1 -P 15306 commerce
  2. Welcome to the MySQL monitor. Commands end with ; or \g.
  3. mysql> ALTER TABLE demo ADD COLUMN sample INT;
  4. Query OK, 0 rows affected (0.04 sec)

Just like in the previous example, Vitess will find out what the affected shards are, what the identity is of each shard’s primary, then invoke the statement on all shards.

You may apply the change to specific shards by connecting directly to those shards:

  1. $ mysql -h 127.0.0.1 -P 15306 commerce/-80
  2. Welcome to the MySQL monitor. Commands end with ; or \g.
  3. mysql> ALTER TABLE demo ADD COLUMN sample INT;
  4. Query OK, 0 rows affected (0.04 sec)

In the above we connect to VTGate via the mysql command line client, but of course you may connect with any standard MySQL client or from your application.

Please do note that if VTGate does not recognize a DDL syntax, the statement will get rejected and that this approach is not recommended for changing large tables.

Directly to MySQL

You can apply schema changes directly to the underlying MySQL shard primary instances.

VTTablet will eventually notice the change and update itself. This is controlled by the --queryserver-config-schema-reload-time parameter which defaults to 1800 seconds.

You can also explicitly issue the vtctldclient ReloadSchema command to make it reload immediately. Specify a tablet to reload the schema from, as in:

  1. $ vtctldclient ReloadSchema zone1-0000000100

Users will likely want to deploy schema changes via gh-ost or pt-online-schema-change, which do not block the table. Vitess offers managed, online schema changes where it automates the invocation and execution of these tools. Using these schema deployment tools can be a better approach for large tables, because they should incur no downtime.