首页/数据/SQL 速查/ALTER TABLE 的锁与执行方式
变更与事务52 条

ALTER TABLE 的锁与执行方式

结构变更的锁代价差异很大:MySQL 支持 INSTANT/INPLACE 减少锁表,PostgreSQL 多数操作会持有 ACCESS EXCLUSIVE。

SQL 速查数据更新于 2026-10-13

ALTER TABLE 是什么

结构变更操作。同一句话的代价可能天差地别:MySQL 支持 INSTANT 与 INPLACE 算法来减少锁表时间,PostgreSQL 大多数 DDL 会短暂持有 ACCESS EXCLUSIVE 锁——能立刻拿到就很快,拿不到就会排在已有查询后面,把后续请求一起堵住。

基本信息

MySQL 算法ALGORITHM=INSTANT / INPLACE / COPY,可显式指定
MySQL 锁选项LOCK=NONE 表示不阻塞读写,不支持时直接报错
PostgreSQL 锁多数 ALTER 需要 ACCESS EXCLUSIVE 锁
PG 加列加可空列是元数据操作;PG 11+ 加常量默认值同样是元数据操作
PG 改类型常需要重写整表并重建索引
通用护栏设置 lock_timeout,拿不到锁就退出而不是排队

MySQL 指定算法

MySQL 指定算法
ALTER TABLE orders
  ADD COLUMN memo VARCHAR(255) NULL,   -- 加可空列
  ALGORITHM=INPLACE,
  LOCK=NONE;                           -- 不支持时直接报错,便于测试阶段暴露风险

-- 不指定 ALGORITHM 时由优化器自行选择,可能退化成 COPY 拷贝整表
-- 上线前先在预发环境用同样的语句验证一次

PostgreSQL 注意锁等待

PostgreSQL 注意锁等待
-- 先设锁等待上限,避免把后续请求一起堵住
SET lock_timeout = '3s';

ALTER TABLE orders ADD COLUMN memo text;                   -- 元数据操作,很快
ALTER TABLE orders ADD COLUMN cnt int NOT NULL DEFAULT 0;  -- PG 11+ 同样只改元数据
ALTER TABLE orders ALTER COLUMN amount TYPE numeric(14,2); -- 通常需要重写整表

变更类型与代价

变更类型MySQL 8PostgreSQL
加可空列INSTANT,很快元数据操作,很快
加带默认值的列视版本与默认值而定11+ 常量默认值也是元数据操作
改列类型多数需要重建表通常重写整表并重建索引
加索引INPLACE,一般不阻塞写入默认阻塞写;可用 CONCURRENTLY 不阻塞
加 NOT NULL 约束需要校验全表可先加 NOT VALID 再单独校验

典型使用场景

  • 业务迭代加字段:新增备注与扩展字段
  • 加索引提升查询性能:安排到低峰执行
  • 调整字段类型或长度:应对业务量增长
  • 拆分大表:配合在线工具或影子表方案
  • 加约束保证数据质量:注意校验开销
  • 归档后清理列:删除不再使用的冗余字段
PostgreSQL 可以用 CREATE INDEX CONCURRENTLY 建索引而不阻塞写入,代价是耗时更长、失败会留下无效索引需要清理;MySQL 建索引通常走 INPLACE,但仍会消耗大量 IO 与 CPU,建议低峰执行。
DDL 排在长事务后面会连锁阻塞:一条长查询持锁不释放时,ALTER 会一直等,后续所有请求又排到 ALTER 之后。执行前先设置 lock_timeout,并确认没有长事务与长查询在跑。

易错点

  • 业务高峰直接执行 ALTER:可能长时间阻塞读写,先挑低峰并设置锁等待上限
  • MySQL 不指定 ALGORITHM:优化器可能选择 COPY 拷贝整表,显式指定能在预发环境提前暴露风险
  • PG 改列类型前不做评估:可能重写整表并重建索引,大表要评估停机窗口或改用影子表
  • 回滚方案缺失:DDL 失败可能留下中间状态(例如无效索引),上线前准备好回退与清理脚本

数据来源与参考

  • MySQL 8.0 Reference Manual · ALTER TABLE
  • PostgreSQL Documentation · ALTER TABLE
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌