Back to changelog
New
3 minute read

Lint: New MySQL Blocking-Change Checks

Six new analyzers, MY137 to MY142, detect MySQL and MariaDB schema changes that copy or rebuild the table, block concurrent writes, or silently forfeit instant DDL, and report them in atlas migrate lint.

MySQL runs some schema changes online and others with a full table copy that blocks concurrent writes, and the SQL alone rarely tells you which. Six new checks in the blocking-changes analyzer classify the copy and rebuild cases according to the MySQL online-DDL operations matrix, so they surface in atlas migrate lint before the migration reaches a busy table. The analyzer is part of Atlas Pro, enabled with atlas login.

The New Checks

CheckDescription
MY137Modifying the primary key rebuilds the table and its secondary indexes
MY138Changing the storage engine requires a table copy and blocks DML
MY139Partitioning or removing partitioning from a table requires a table copy and blocks DML
MY140Adding a STORED generated column requires a table copy and blocks DML
MY141Adding an AUTO_INCREMENT column rebuilds the table and blocks DML
MY142Adding a column before existing columns prevents an instant operation on older versions

Rebuilds and Copies

Redefining a primary key in a single statement rewrites the clustered index and, with it, every secondary index, since their row pointers are the primary-key values:

20260829120000.sql
ALTER TABLE users DROP PRIMARY KEY, ADD PRIMARY KEY (tenant_id, id);
atlas migrate lint
-- analyzing version 20260829120000    -- blocking table changes detected:      -- L1: Modifying the primary key of table "users" rebuilds the table and its secondary         indexes https://atlasgo.io/lint/analyzers#MY137  -- ok (4.213ms)  -------------------------  -- 1 version with warnings  -- 1 schema change  -- 1 diagnostic

MY138 and MY139 catch the two operations that only run with ALGORITHM=COPY: storage-engine conversion, often an accidental change to an engine attribute in the desired schema, and partitioning or un-partitioning an existing table.

Suggested Fixes

Where a cheaper form of the change exists, the diagnostic says so. Adding a STORED generated column requires the server to evaluate the expression for every existing row, while a VIRTUAL column is added instantly and remains indexable:

ALTER TABLE orders ADD COLUMN total INT AS (price * qty) STORED NOT NULL;
atlas migrate lint
-- blocking table changes detected:      -- L1: Adding stored generated column "total" on table "orders" requires a table copy and         blocks concurrent DML https://atlasgo.io/lint/analyzers#MY140    -- suggested fix:      -> Define the column as VIRTUAL to add it instantly, unless its value must be stored

MY141 reports AUTO_INCREMENT column additions, which rebuild the table and block writes, unlike a plain column add that has been instant since MySQL 8.0.12. The suggested fix: add the column without AUTO_INCREMENT when values can be assigned by the application.

Version-Aware Analysis

On MySQL 8.0.12 to 8.0.28 and MariaDB 10.3, instant DDL supports adding a column only at the last position. Adding one mid-table silently falls back to a full in-place rebuild. MY142 consults the dev database version, so it reports nothing on servers where instant addition works at any position:

atlas migrate lint
-- blocking table changes detected:      -- L1: Adding column "c" on table "t" before existing columns prevents an instant operation         and rebuilds the table https://atlasgo.io/lint/analyzers#MY142    -- suggested fixes:      -> Add the column at the last position to keep the operation instant      -> Upgrade to MySQL 8.0.29 or MariaDB 10.4, where instant addition works at any position

See the analyzers reference for the full check documentation.

featuremigrate lintanalyzersmysqlmariadb