Databases 13 min read

How to Safely Add a Column to a Tens‑Million‑Row MySQL Table? 6 Proven Methods

Adding a column to a MySQL table with tens of millions of rows can lock the table for minutes or even hours, disrupting services, so this article evaluates six practical approaches—including native online DDL, offline maintenance, PT‑OSC, logical migration with dual‑write, gh‑ost, and partition sliding‑window—detailing their mechanisms, trade‑offs, and suitable scenarios.

Su San Talks Tech
Su San Talks Tech
Su San Talks Tech
How to Safely Add a Column to a Tens‑Million‑Row MySQL Table? 6 Proven Methods

Problem

Adding a column to a MySQL table that contains tens of millions of rows can lock the table and block all reads and writes, causing severe service disruption.

Why large‑table column addition is risky

Core issue: MySQL DDL locks tables. Before MySQL 5.6 the lock is exclusive for the whole operation; from MySQL 5.6+ only a subset of operations support online DDL.

Experiment:

-- Session 1: execute DDL
ALTER TABLE user ADD COLUMN age INT;

-- Session 2: query (blocked)
SELECT * FROM user WHERE id=1; -- waits for DDL to finish

Lock‑time ≈ table size / disk‑IO speed. For a 10 M‑row table (≈1 KB per row) on a 100 MB/s HDD the table is unavailable for about 100 seconds , which is intolerable in high‑concurrency systems.

1. Native Online DDL (MySQL 5.6+)

Syntax example:

ALTER TABLE user ADD COLUMN age INT,
    ALGORITHM=INPLACE,
    LOCK=NONE;

How it works: The operation is performed in place without copying the whole table.

Drawbacks:

May still acquire a table lock for certain actions (e.g., adding a full‑text index).

Requires double the disk space during the operation (e.g., a 500 GB table needs ~1 TB free).

Replication lag risk because the slave replays changes single‑threaded.

2. Offline Maintenance

Suitable when a maintenance window is acceptable (e.g., early morning) and the data size is < 100 GB. The steps are:

Dump the table (e.g., mysqldump).

Modify the schema (add the column).

Reload the data.

Ensure a full rollback plan.

3. Percona Toolkit – pt-online-schema-change

Workflow: create a shadow table, copy data in chunks, then atomically swap tables.

Typical command:

# Install the tool
sudo yum install percona-toolkit

# Run migration to add column "age"
pt-online-schema-change \
  --alter "ADD COLUMN age INT" \
  D=test,t=user \
  --execute

4. Logical Migration + Dual‑Write

Used in financial‑grade systems where zero data loss is required.

Steps:

Create a new table with the additional column.

Modify application code to write to both old and new tables.

Batch migrate existing rows from the old table to the new one.

Perform an atomic RENAME TABLE to switch the tables.

Java example for dual‑write:

public class UserService {
    @Transactional
    public void addUser(User user) {
        // write to old table
        userOldDAO.insert(user);
        // write to new table (with age column)
        userNewDAO.insert(convertToNew(user));
    }
    private UserNew convertToNew(User old) {
        UserNew userNew = new UserNew();
        userNew.setId(old.getId());
        userNew.setName(old.getName());
        userNew.setAge(getAgeFromCache(old.getId()));
        return userNew;
    }
}

Batch migration script (simplified):

SET @start_id = 0;
WHILE EXISTS(SELECT 1 FROM user WHERE id > @start_id) DO
  INSERT INTO user_new (id, name, age)
    SELECT id, name, COALESCE(age_cache,0)
    FROM user WHERE id > @start_id ORDER BY id LIMIT 10000;
  SET @start_id = (SELECT MAX(id) FROM user_new);
  COMMIT;
END WHILE;

5. gh‑ost (GitHub Online Schema Transmogrifier)

gh‑ost performs schema changes without triggers by parsing binlog events asynchronously, reducing load on the primary.

Typical command:

gh-ost \
  --alter="ADD COLUMN age INT NOT NULL DEFAULT 0 COMMENT 'User age'" \
  --host=PRIMARY_IP --port=3306 --user=gh_user --password=xxx \
  --database=test --table=user \
  --chunk-size=2000 \
  --max-load=Threads_running=80 \
  --critical-load=Threads_running=200 \
  --cut-over-lock-timeout-seconds=5 \
  --execute \
  --allow-on-master

Monitoring and safety tips:

Track progress with echo status | nc -U /tmp/gh-ost.sock.

Control lag via --max-lag-millis=1500 (auto‑pause if exceeded).

Use --postpone-cut-over-flag-file to manually trigger the final cut‑over.

6. Partition Sliding‑Window

Applicable to time‑partitioned log tables. Only the newest partition’s definition is altered, leaving historic partitions untouched.

Steps:

-- Original partitioned table definition
CREATE TABLE logs (
  id BIGINT PRIMARY KEY,
  log_time DATETIME,
  content TEXT
) PARTITION BY RANGE (TO_DAYS(log_time)) (
  PARTITION p202301 VALUES LESS THAN (TO_DAYS('2023-02-01')),
  PARTITION p202302 VALUES LESS THAN (TO_DAYS('2023-03-01'))
);

-- Add new column (affects only new partitions)
ALTER TABLE logs ADD COLUMN log_level VARCHAR(10) DEFAULT 'INFO';

-- Reorganize partitions to apply the new schema to future data
ALTER TABLE logs REORGANIZE PARTITION p202302 INTO (
  PARTITION p202302 VALUES LESS THAN (TO_DAYS('2023-03-01')),
  PARTITION p202303 VALUES LESS THAN (TO_DAYS('2023-04-01'))
);

Comparison of the Six Solutions

Native Online DDL

Lock time: seconds‑to‑minutes

Business impact: medium (concurrent DML limited)

Data consistency: strong

Applicable scenario: < 100 M rows, small tables

Complexity: low

Offline Maintenance

Lock time: hours

Business impact: high (service outage)

Data consistency: strong

Applicable scenario: allowed downtime, data < 100 GB

Complexity: medium

PT‑OSC

Lock time: milliseconds (cut‑over only)

Business impact: medium (trigger overhead)

Data consistency: eventual

Applicable scenario: tables without foreign keys/triggers

Complexity: medium

Logical Migration + Dual‑Write

Lock time: 0 (instant cut‑over)

Business impact: low (code change required)

Data consistency: strong

Applicable scenario: financial core tables > 1 B rows

Complexity: high

gh‑ost

Lock time: milliseconds (cut‑over only)

Business impact: low (no triggers)

Data consistency: eventual

Applicable scenario: high‑concurrency large tables (TB scale)

Complexity: medium‑high

Partition Sliding‑Window

Lock time: only new partitions affected

Business impact: low

Data consistency: partition‑level strong

Applicable scenario: time‑partitioned log tables

Complexity: medium

Conclusion

Regular tables (<100 M rows): Prefer native online DDL (MySQL 8.0 ALGORITHM=INSTANT gives second‑level column addition). PT‑OSC is a viable fallback for older MySQL versions.

High‑concurrency large tables (>100 M rows): gh‑ost is mandatory because it avoids triggers and limits write impact to <5 %.

Financial core tables: Dual‑write is the only safe choice, though it requires 2‑4 weeks of development.

Log‑type tables: Partition sliding‑window is optimal as it only touches the newest partition.

Emergency failures on ultra‑large tables: Consider offline maintenance with a full rollback plan.

Practical tips: Before adding a column, consider a JSON “metadata” column as a flexible extension ( ALTER TABLE user ADD COLUMN metadata JSON ). For trillion‑row tables, use sharding instead of direct DDL. Always take a full backup ( mysqldump + binlog ) before any schema change. Monitor traffic with Prometheus + Grafana to watch QPS during migration.
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

MySQLlarge tablesOnline DDLdatabase operationsgh-ostschema migrationpt-online-schema-change
Su San Talks Tech
Written by

Su San Talks Tech

Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.