← 中文资源

简体中文版本

零停机迁移 Postgres 列

新增列并分批回填,在代码中切换读写,再在后续部署中删除旧列,全程不锁表。

阅读英文原文

扩展、回填、收缩

安全的列重命名分三步:加新列、回填、删旧列。每步独立部署,任何一步都不会持长锁。

ALTER TABLE users ADD COLUMN username text;
CREATE TRIGGER users_sync_username BEFORE INSERT OR UPDATE ON users
  FOR EACH ROW EXECUTE FUNCTION sync_username();

分批回填

每次更新有界范围的行并设锁超时。若批次拿不到锁就跳过重试,写入始终畅通。用 where username is null 的计数跟踪进度,确认回填完成。

SET lock_timeout = '2s';
UPDATE users SET username = usr_name
WHERE id BETWEEN $start AND $end AND username IS NULL;

预期结果

应用全程在线,任何步骤都不持长表锁,最终部署以短暂 access exclusive lock 删除旧列。触发器仅用于过渡,在删除列的同一次部署中一并移除。迁移需两次部署,新旧列在一个发布周期内共存。