This page describes how to add and drop indexes on Cloud SQL read replicas. While a replica is normally read-only, there might be times you want to create secondary indexes on tables for reporting purposes. Cloud SQL offers a set of stored procedures for managing these indexes.
Terminology
- Clustered index. The main index on a MySQL table that physically orders the rows on disk. When you define a primary key on a table, MySQL uses it as the clustered index. There can only be one clustered index on a table.
- Secondary index. An additional index on a MySQL table that optimizes query performance.
Stored procedures for indexes
Cloud SQL includes two stored procedures in the mysql
schema that you
can use to add and drop secondary indexes on a MySQL read replica. Note that
while these procedures can run on a primary source instance, they are designed
for read replicas.
- mysql.addSecondaryIdxOnReplica
- Adds a secondary index on the database. This stored procedure is a
wrapper for the
CREATE INDEX
DDL statement.
Parameters:
idxType
- Type of index to create. For example, pass UNIQUE to create a unique index.idxName
- Name of the index.tableName
- Name of the table in the format of schema.name.idxDefinition
- Definition of the index. Do not include outer parentheses.idxOption
- Any additional options to pass on index creation. For example, in MySQL 8.0, an option could pass INVISIBLE for an invisible index.
Syntax:
mysql.addSecondaryIdxOnReplica(idxType, idxName, tableName, idxDefinition, idxOption)
- mysql.dropSecondaryIdxOnReplica
- Drops a secondary index on the database. This stored procedure is a
wrapper for the
DROP INDEX
DDL statement.
Parameters:
idxName
- Name of the index.tableName
- Name of the table in the format of schema.name.idxOption
- Any additional options to pass when dropping an index. For example, an algorithm option like INPLACE.
Syntax:
mysql.dropSecondaryIdxOnReplica(idxName, tableName, idxOption)
For the idxType
and idxOption
parameters, consult the documentation for the
major version of MySQL running on the Cloud SQL instance.
Examples
Correct Usage
Here are some example invocations of the procedures. Suppose we have a table with the following definition.
CREATE TABLE sampletest.t1(
id int(10) unsigned NOT NULL AUTO_INCREMENT,
first_name varchar(64) NOT NULL,
last_name varchar(64) NOT NULL,
license_id int NOT NULL,
PRIMARY KEY (id),
KEY idx_fname (first_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
If you wanted to create a regular index named t1_fname_lname
on the
first_name
and last_name
columns, you would execute the following:
call mysql.addSecondaryIdxOnReplica('', 't1_fname_lname', 'sampletest.t1', 'first_name, last_name', '')
If you also wanted to create a unique index named t1_license_id
on the
license_id
column with the comment "unique license id," you would execute the
following:
call mysql.addSecondaryIdxOnReplica('unique', 't1_license_id', 'sampletest.t1', 'license_id', 'comment \"unique license id\"')
If you then wanted to drop the t1_fname_lname index, you would execute the following:
call mysql.dropSecondaryIdxOnReplica('t1_fname_lname', 'sampletest.t1', '')
Incorrect Usage
The following attempt to create an index on the first_name
and last_name
columns fails due to the outer parentheses in the idxDefinition parameter.
call mysql.addSecondaryIdxOnReplica('', 't1_extra_parenthesis', 'sampletest.t1', '(first_name, last_name)', '')
You can only add indexes on customer created tables. The following attempt to create an index on the host column of the mysql.servers table fails.
call mysql.addSecondaryIdxOnReplica('', 'idx_invalid', 'mysql.servers', 'host', '')
You can only use the dropSecondaryIdxOnReplica
procedure to drop indexes
previously created using the addSecondaryIdxOnReplica
procedure. For example,
the following call to drop the existing idx_fname
index fails.
call mysql.dropSecondaryIdxOnReplica('idx_fname', 'sampletest.t1', '')
SQL injection in these procedure calls will fail. For example, the following SQL injection with a comment sequence will fail.
call mysql.addSecondaryIdxOnReplica(\"user 'a'@'%' --\", 'idx_fname', 'sampletest.t1', 'first_name', '')
Similarly, this SQL injection attempt with a delimiter fails.
call mysql.addSecondaryIdxOnReplica('', 'idx_fname', 'sampletest.t1', 'first_name', ';flush status')
Recreation of read replicas
Occasionally, when there's an issue, Cloud SQL recreates a read replica from the primary source in order to quickly recover the instance. Indexes created on the read replica prior to a recreate operation are not persisted. It is the responsibility of the customer to recreate these indexes using the stored procedures on the read replica.