CMD Guide
HomeDatabasesSQL Fundamentals

ALTER

ALTER

ALTER TABLE edits a table's definition in the data dictionary (the catalog that describes every column, type, and constraint), and depending on what you change, the engine either flips a few bytes of metadata in microseconds or copies every existing row into a brand-new physical table while holding a lock — the entire art of safe schema change is knowing which of those two paths a given statement takes.

The whole surface (not just ADD)

One verb, many sub-commands. Syntax differs slightly between engines — MySQL/MariaDB use MODIFY/CHANGE, PostgreSQL uses ALTER COLUMN ... TYPE. The operations:

IntentMySQL / MariaDBPostgreSQL
Add a columnALTER TABLE t ADD COLUMN c INT;ALTER TABLE t ADD COLUMN c INT;
Change a column's type (keep name)ALTER TABLE t MODIFY c BIGINT;ALTER TABLE t ALTER COLUMN c TYPE BIGINT;
Rename and retype a columnALTER TABLE t CHANGE old new BIGINT;(two statements: RENAME, then TYPE)
Rename a column onlyALTER TABLE t RENAME COLUMN old TO new;ALTER TABLE t RENAME COLUMN old TO new;
Drop a columnALTER TABLE t DROP COLUMN c;ALTER TABLE t DROP COLUMN c;
Add a constraintALTER TABLE t ADD CONSTRAINT fk FOREIGN KEY (uid) REFERENCES u(id);same
Set / drop a defaultALTER TABLE t ALTER c SET DEFAULT 0;ALTER TABLE t ALTER COLUMN c SET DEFAULT 0;
Rename the tableALTER TABLE t RENAME TO t2;ALTER TABLE t RENAME TO t2;

The grader's note was right that the old page promised MODIFY/DROP/RENAME and showed none — they are all above. The interesting part is not the syntax, though. It is what each one costs.

The mechanism: metadata-only vs. table rewrite

Every ALTER lands on one of three execution strategies. In MySQL 8 you can name the strategy with ALGORITHM= and force it to refuse anything slower with LOCK=; in Postgres the planner picks automatically but the same three buckets exist.

Which bucket you get is decided by the operation, not by you. MODIFY c INT → BIGINT changes the on-disk byte width of every row, so it cannot be INSTANT — it falls to COPY. That single fact is why an innocent-looking ALTER can take a 50M-row table offline for 20 minutes.

diagram
diagram

Worked example: one ADD that is free, one MODIFY that is not

Start with a real Employees table (the same one the old page used) and trace what the engine physically does, step by step. Assume MySQL 8, InnoDB, 50 million rows.

CREATE TABLE Employees (
  id        INT PRIMARY KEY,
  firstName VARCHAR(50),
  lastName  VARCHAR(50)
);

Step 1 — Add a column (INSTANT path).

ALTER TABLE Employees
  ADD COLUMN salary INT,
  ALGORITHM=INSTANT;        -- explicitly demand the fast path

Trace of what InnoDB does:

  1. Bump the table's row version in the data dictionary from v0 to v1, recording "as of v1 there is a 4th column salary, default NULL."
  2. Touch zero of the 50M rows on disk. The statement returns in milliseconds.
  3. A later SELECT salary FROM Employees reads an old (v0) row, sees it predates v1, and synthesises salary = NULL on the fly. New inserts store the column physically.

Step 2 — Widen id from INT to BIGINT (COPY path, the trap). Your sequence is about to overflow 2.1 billion, so:

ALTER TABLE Employees
  MODIFY id BIGINT,
  ALGORITHM=INSTANT;        -- you ASK for instant...

Trace:

  1. The engine evaluates the request: changing INT(4 bytes) to BIGINT(8 bytes) rewrites the byte layout of every row. INSTANT is impossible.
  2. Because you pinned ALGORITHM=INSTANT, MySQL aborts with ER_ALTER_OPERATION_NOT_SUPPORTED rather than silently doing something slow — exactly the safety net you want.
  3. Drop the hint and the engine falls back to ALGORITHM=COPY: it builds a 50M-row shadow table, copies row by row (minutes), holds a write lock the whole time, then atomically swaps. Every INSERT/UPDATE from your app blocks until it finishes.

Same verb, same table, two outcomes separated by 6+ orders of magnitude. The lesson: never run an ALTER in production without first knowing which path it takes — and let ALGORITHM=INSTANT / LOCK=NONE fail loudly instead of finding out at 3 a.m.

Doing it online on a large table

When the operation genuinely requires a rewrite (type change, adding a column in the middle, certain constraints), the production answer is not "run ALTER and pray." It is an external online-schema-change tool that turns one blocking ALTER into a slow, throttle-able, abortable background copy:

Pitfalls

Takeaways


Sources: MySQL 8.4 Reference Manual, “ALTER TABLE Statement” and “Online DDL Operations” (ALGORITHM/LOCK, INSTANT supported operations, 64-version limit); Oracle MySQL Server Blog, “MySQL 8.0 INSTANT ADD and DROP Column(s)”; PostgreSQL 18 Documentation, “ALTER TABLE” and “Modifying Tables” (constant vs. volatile defaults, attmissingval fast path); Percona pt-online-schema-change and GitHub gh-ost documentation. Re-authored and deepened for this guide: the original covered only ADD COLUMN despite promising MODIFY/DROP/RENAME, and omitted the locking / table-rewrite mechanism that makes ALTER systems-relevant.

🎯 STRICT STANDOUT: Why / worked / when-not / failure / drills — ALTER TABLE

Why this concept exists (judgment chain)

ALTER is catalog mutation with three cost classes: INSTANT (metadata), INPLACE (online rebuild), COPY (full rewrite, write-blocking). Production safety is knowing the path and failing closed with ALGORITHM=INSTANT/LOCK=NONE, or using gh-ost/pt-osc for true rewrites. MDL queues turn a "fast" alter into a global stall.

Worked example with numbers or traced steps

50M-row Employees: ADD COLUMN salary INT ALGORITHM=INSTANT → row version bump, 0 row rewrites, ms.
MODIFY id INT→BIGINT with ALGORITHM=INSTANT → ER_ALTER_OPERATION_NOT_SUPPORTED (good fail).
Without pin: COPY shadow table, minutes of write lock.
Postgres: ADD col DEFAULT constant (v11+) catalog-only; DEFAULT clock_timestamp() rewrites.
pt-osc/gh-ost: shadow table + backfill + cutover; gh-ost uses binlog not triggers.
MySQL INSTANT version ceiling 64 before rebuild required.

When NOT to use / named alternative

Run raw COPY ALTER only on small/dev tables. Prefer expand-contract (add nullable col, backfill, switch reads, drop old) over in-place type shrink. Do not ADD NOT NULL without default on populated tables in one step — multi-phase instead.

Failure / ops fingerprint

Outage: ALTER waits on long transaction MDL; new queries queue behind ALTER. Disk fill during COPY. Failed mid-ALTER on MySQL (non-transactional DDL). Ops: lock_wait_timeout low; monitor Threads_running; rehearsal on prod-sized staging; ALGORITHM=INSTANT in migration PR checklist.

Hostile-panel Q&As (model answers)

Q1. Why pin ALGORITHM=INSTANT?
Model answer: Forces loud failure if the engine would rewrite; prevents silent multi-minute locks.

Q2. INSTANT vs gh-ost?
Model answer: INSTANT only for metadata-safe ops; type changes and many constraints need online tools that copy without long exclusive locks.

Q3. MDL pile-up mechanism?
Model answer: ALTER needs exclusive metadata lock; idle-in-transaction holders block it; subsequent DML queues behind the waiting ALTER.

🤖 Don't fully get this? Learn it with Claude

Stuck on ALTER? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **ALTER** (Databases) and want to truly understand it. Explain ALTER from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **ALTER** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **ALTER** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **ALTER** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes