- Changes to your table schema happen while the database is running.
- Your application’s queries can run normally, with no effect on read/write latency. The schema is cached for performance.
- Your data is kept in a safe, consistent state throughout the entire schema change process.
- The schema change runs as a background job without holding locks on the underlying table data.
-
As soon as the statement is accepted, CockroachDB returns a SQL
NOTICE(as shown below) that includes the ID of the background job. To track the job’s progress, use or view the .
-
As soon as the statement is accepted, CockroachDB returns a SQL
Schema changes consume additional resources, and if they are run when the cluster is near peak capacity, latency spikes can occur. This is especially true for any schema change that adds columns, drops columns, or adds an index. We do not recommend doing more than one schema change at a time while in production.
CockroachDB does not support schema changes within explicit transactions with full atomicity guarantees. CockroachDB only supports DDL changes within implicit transactions (individual statements). If a schema management tool uses transactions on your behalf, it should only execute one schema change operation per transaction.Some tools and applications may be able to workaround CockroachDB’s lack of transactional schema changes by enabling a setting that automatically commits before running schema changes inside transactions.
How online schema changes work
At a high level, online schema changes are accomplished by using a bridging strategy involving concurrent uses of multiple versions of the schema. The process is as follows:-
You initiate a schema change by executing
ALTER TABLE,CREATE INDEX,TRUNCATE, etc. - The schema change engine converts the original schema to the new schema in discrete steps while ensuring that the underlying table data is always in a consistent state. These changes are executed as a background job, and can be , , and .
- Changes that trigger an index backfill (adding data to an index).
- The following statements:
- when the statement also features
INDEXorUNIQUE. - under one of the following conditions:
- The locality changes from to something that is not
REGIONAL BY ROW. - The locality changes from something that is not
REGIONAL BY ROWtoREGIONAL BY ROW.
- The locality changes from to something that is not
- when the statement also features
If a schema change job is paused, any jobs waiting on that schema change will stop waiting and return an error.
If a schema change fails, the schema change job will be cleaned up automatically. However, there are limitations with rolling back schema changes within a transaction; for more information, see Schema change DDL statements inside a multi-statement transaction can fail while other statements succeed.
Best practices for online schema changes
Improve changefeed performance with schema_locked
Set the to true to indicate that a schema change is not currently ongoing on a table. By default, CockroachDB attempts to automatically unset this parameter before performing many schema changes and reapplies it when done. To require manual unlocks for all DDL on schema-locked tables, set to false. Some schema changes, such as ALTER TABLE ... SET LOCALITY, still require a manual unlock even when automatic unlocking is enabled. Enabling schema_locked can help running on the table, which can reduce commit-to-emit latency.
Use the to set this storage parameter to true on every table created in the session. In v26.1 and later, it is enabled by default.
Estimate your storage capacity before performing online schema changes
Some schema change operations, like adding or dropping columns or altering primary keys, will temporarily increase a cluster’s storage consumption. Specifically, these operations may temporarily require up to three times more storage space for the range size while the schema change is being applied, and this may cause the cluster to run out of storage space or fail to apply the schema change. To estimate the size of the indexes in your table, use the statement.range_size_mb column that shows the size of the range in megabytes for each index.
In many cases this range size is trivial, but when the range size is many gigabytes or terabytes, you will need at least three times that amount of free storage space to successfully apply an online schema change.
Example of finding the range size of an index
-
Start a 3 node cluster with the MovR dataset.
-
Turn off the deprecated behavior of
SHOW RANGES: -
Find the range size of the indexes in the
movr.vehiclestable:
Run schema changes with large backfills during off-peak hours
Online schema changes that result in large backfill operations (for example, statements) are computationally expensive, and can result in degraded performance. The will help keep high-priority operations running, but it’s recommended to run backfill-heavy schema changes during times when the cluster is under relatively low loads.Schema changes in multi-region clusters
To reduce latency while making online schema changes, we recommend specifying alease_preference on the system database to a single region and running all subsequent schema changes from a node within that region. For example, if the majority of online schema changes come from machines that are geographically close to us-east1, run the following:
Access to tables and built-in functions in the
system database is controlled by the . The above ALTER DATABASE system statement executes regardless of the variable’s setting because it does not access tables or invoke built-in functions.Examples
Run schema changes inside a transaction with CREATE TABLE
As noted in Known limitations, you cannot run schema changes inside transactions in general.
However, you can run schema changes inside the same transaction as a CREATE TABLE statement. For example:
Run multiple schema changes in a single ALTER TABLE statement
Some schema changes can be used in combination in a single ALTER TABLE statement. For a list of commands that can be combined, refer to . For examples, refer to and .
Show all schema change jobs
You can check on the status of the schema change jobs on your system at any time using theSHOW JOBS statement:
Enable automatic commit before running schema changes inside transactions
When the is set toon, any schema change statement that is sent during an will cause the transaction to before executing the schema change.
This setting can be used to:
- Improve compatibility with some third-party tools that do not work well due to our limitations on schema changes in explicit transactions.
- Use schema changes more easily under the . The error message returned when running schema changes under
READ COMMITTEDisolation includes a hint to use this setting.
autocommit_before_ddl enabled, , , and other statements that normally return errors when used outside of an explicit transaction will instead return warnings. This behavior change is necessary because this setting can cause a transaction to end earlier than a client application may expect.
To enable this setting for the current :
Demo videos
Updating primary key columns
To see a demo of an online schema change against a primary key column, watch the following video: HINT: Some of the non-DDL statements may have committed successfully, but some of the DDL statement(s) failed. Manual inspection may be required to determine the actual state of the database.t and seeing that the additional non-unique value 3 was successfully inserted.
No online schema changes if primary key change in progress
You cannot start an online schema change on a table if a is currently in progress on the same table.No online schema changes between executions of prepared statements
When the schema of a table targeted by a prepared statement changes after the prepared statement is created, future executions of the prepared statement could result in an error. For example, adding a column to a table referenced in a prepared statement with aSELECT * clause will result in an error:
SELECT * in prepared statements, when possible.
Column-dropping schema changes may not roll back properly
Some that cannot be properly. In some cases, the rollback will succeed, but the column data might be partially or totally missing, or stale due to the asynchronous nature of the schema change. In other cases, the rollback will fail in such a way that will never be cleaned up properly, leaving the table descriptor in a state where no other schema changes can be run successfully. To reduce the chance that a column drop will roll back incorrectly:- Perform column drops in transactions separate from other schema changes. This ensures that other schema change failures will not cause the column drop to be rolled back.
- Drop all (including ) on the column in a separate transaction, before dropping the column.
- Drop any or on a column before attempting to drop the column. This prevents conflicts between constraints and default/computed values during a column drop rollback.
cannot be reverted, manual cleanup may be required might require manual intervention.
See also
- How online schema changes are possible in CockroachDB: Blog post with more technical details about how our schema change engine works.
ALTER TABLECREATE INDEXDROP INDEXTRUNCATE

