Chiến lược Zero-Downtime Migration trên PostgreSQL với CREATE INDEX CONCURRENTLY
Nỗi sợ mỗi khi chạy lệnh Database Migration trên Production Đã bao nhiêu lần team bạn phải thức dậy lúc 2h sáng chỉ để chạy một lệnh thêm cột hoặc tạo index mới? Nếu chạy CREATE INDEX trên bảng có hà…
☰ Mục lục bài viết (5 phần) Mở / Đóng mục lục
Nỗi sợ mỗi khi chạy lệnh Database Migration trên Production#
Đã bao nhiêu lần team bạn phải thức dậy lúc 2h sáng chỉ để chạy một lệnh thêm cột hoặc tạo index mới? Nếu chạy CREATE INDEX trên bảng có hàng chục triệu dòng theo cách thông thường, PostgreSQL sẽ đặt một khóa độc quyền (SHARE LOCK):
- Mọi lệnh
INSERT,UPDATE,DELETEtừ người dùng đều bị chặn lại và xếp hàng chờ. - Connection pool bị dồn ứ, dẫn tới sập ứng dụng (Downtime).
Dưới đây là các kỹ thuật thực chiến để migration database mượt mà 0 giây gián đoạn.
1. Tạo Index không chặn ghi với CONCURRENTLY#
-- ĐÚNG: Chạy song song không khóa bảng
CREATE INDEX CONCURRENTLY idx_users_email_active ON users (email) WHERE is_active = true;
- Lưu ý quan trọng: Lệnh
CONCURRENTLYkhông thể chạy bên trong một Transaction block (BEGIN ... COMMIT). Nếu công cụ migration của bạn (Prisma, TypeORM, Knex) tự động bọc câu lệnh trong transaction, bạn phải tắt cờ transaction cho file migration đó. - Nếu quá trình tạo bị lỗi (ví dụ rớt mạng), index sẽ rơi vào trạng thái
INVALID. Bạn cần drop index và chạy lại.
2. Thêm cột mới có giá trị mặc định (DEFAULT) an toàn#
- Từ PostgreSQL 11 trở lên: Lệnh
ALTER TABLE ... ADD COLUMN ... DEFAULT 'abc'chỉ cập nhật metadata trong catalog của Postgres, diễn ra trong vài mili-giây và không phải viết lại toàn bộ bảng. - Thêm cột NOT NULL: Nên thêm cột NULL trước, cập nhật dữ liệu theo lô nhỏ (batching), sau đó mới thêm ràng buộc
CHECK (...) NOT VALIDrồi mớiVALIDATE CONSTRAINT.
3. Đặt Timeout an toàn cho lệnh Lock#
Để tránh việc migration đứng chờ một transaction khác quá lâu làm tắc nghẽn cả hệ thống:
SET lock_timeout = '3s';
ALTER TABLE orders ADD COLUMN notes TEXT;
Nếu sau 3 giây không lấy được lock, lệnh sẽ tự hủy an toàn thay vì làm nghẽn hàng ngợi của client.
Góc thảo luận#
Team bạn đang dùng công cụ migration nào (Flyway, Liquibase, Prisma, golang-migrate)? Quy trình deploy migration lên production của anh em diễn ra thế nào?
Xem thêm nội dung liên quan:
Thảo luận
1 phản hồi
Tham gia thảo luận
Bài liên quan trong #Backend & Microservices
-
Áp dụng Model Context Protocol (MCP) của Anthropic để kết nối AI với Postgres và Docker
Hoàng Nam (Tech Lead) · 💬 1 -
So sánh mô hình Embedding đa ngữ: OpenAI text-embedding-3 vs BGE-M3 vs Cohere
Minh Trí (AI Engineer) · 💬 1 -
Xây dựng Voice AI Agent thời gian thực với WebRTC và Whisper Live: Độ trễ dưới 500ms
Lan Anh (Senior Frontend) · 💬 1 -
Cấu hình Rate Limiting ở tầng Nginx và API Gateway: Chống DDOS Layer 7 hiệu quả
Đức Huy (DevOps Specialist) · 💬 1 -
Tokenization tiếng Việt của các LLM: Tại sao chi phí tiếng Việt đắt gấp 3 lần tiếng Anh?
Minh Trí (AI Engineer) · 💬 1