Streaming replication (physical) sao chép cả cụm ở mức byte của WAL — mạnh cho dự phòng và đọc, nhưng cứng nhắc: toàn bộ hoặc không gì, subscriber chỉ đọc, và phải cùng phiên bản PostgreSQL. Khi bạn cần linh hoạt hơn — chỉ nhân bản vài bảng, cho đích ghi được, hay nhân bản qua hai phiên bản khác nhau — câu trả lời là logical replication. Bài này dựng thật một cặp publisher/subscriber, publish chọn lọc, và đo từng khả năng.
Cơ chế: publisher và subscriber
Logical replication không sao chép byte WAL thô. Nó giải mã WAL thành các thay đổi ở mức hàng (chèn hàng này, sửa hàng kia), rồi gửi sang đích để áp lại. Kiến trúc là publisher/subscriber:
- Publisher khai một
PUBLICATION— tập các bảng muốn công bố. - Subscriber khai một
SUBSCRIPTIONtrỏ tới publication đó; nó tự copy dữ liệu ban đầu rồi nhận các thay đổi tiếp theo.
Điều kiện tiên quyết: wal_level = logical (cao hơn replica của physical), cần restart để áp.
-- PUBLISHER: chỉ công bố MỘT SỐ bảng
CREATE PUBLICATION pub_kinhdoanh FOR TABLE khach_hang, don_hang; -- KHÔNG log_debug

Hình 1: Logical replication cần wal_level=logical. Publisher khai PUBLICATION chọn lọc bảng; subscriber tự dựng schema rồi CREATE SUBSCRIPTION. Khác physical: chọn bảng, subscriber ghi được, chạy khác phiên bản.
Đo thật: publish chọn lọc, copy, và stream
Tôi dựng ba bảng trên publisher (khach_hang 1.000 dòng, don_hang 5.000 dòng, log_debug 101 dòng) nhưng chỉ publish hai bảng đầu. Subscriber là một database riêng (sub_db) trong cùng cluster — tôi tạo trước schema hai bảng đó (logical replication không tự copy cấu trúc bảng, chỉ copy dữ liệu), rồi CREATE SUBSCRIPTION.

Hình 2: Publish 2 trong 3 bảng. Sau CREATE SUBSCRIPTION, subscriber tự copy đủ 1.000 + 5.000 dòng (srsubstate=r). INSERT/UPDATE/DELETE trên publisher nhân bản tiếp. Bảng log_debug không publish thì không tồn tại ở subscriber. Slot active, walsender streaming.
Kết quả thật, từng khả năng:
1. Copy ban đầu tự động. Ngay sau CREATE SUBSCRIPTION, subscriber tự đồng bộ đủ 1.000 dòng khach_hang và 5.000 dòng don_hang (srsubstate = r — ready). Không cần tự dump/restore.
2. Thay đổi tiếp theo được stream. Tôi INSERT một đơn (id 99999, tiền 777), UPDATE tên khách id=1 thành 'ĐÃ ĐỔI', và DELETE đơn id=1 trên publisher. Sau vài giây, subscriber phản ánh đúng cả ba: đơn mới có tiền 777, tên đã đổi, đơn id=1 biến mất. Cả INSERT, UPDATE, DELETE đều nhân bản.
3. Chọn lọc thật sự. Bảng log_debug không nằm trong publication: nó có 101 dòng trên publisher nhưng không tồn tại trên subscriber (does not exist). Đây là điểm mấu chốt khác physical — bạn chọn chính xác bảng nào đi, bảng nào ở lại.
Khác physical replication ở đâu
| Physical (streaming) | Logical | |
|---|---|---|
| Phạm vi | Cả cụm (mọi DB) | Chọn từng bảng |
| Cơ chế | Byte WAL | Giải mã ra hàng |
| Subscriber | Chỉ đọc | Ghi được |
| Phiên bản | Phải giống | Khác được |
Chính vì subscriber ghi được và chạy khác phiên bản, logical replication mở ra những việc physical không làm nổi: nâng cấp phiên bản gần như không downtime (dựng cụm mới phiên bản cao, logical replicate sang, rồi chuyển tải), gộp nhiều database vào một, tách một phần dữ liệu ra hệ thống phân tích riêng.
Đánh đổi cần cân nhắc
Không copy schema, không copy DDL. Logical replication chỉ nhân bản dữ liệu, không nhân bản cấu trúc bảng hay thay đổi cấu trúc (ALTER TABLE ADD COLUMN). Bạn phải tự tạo schema ở subscriber trước, và khi đổi cấu trúc phải làm ở cả hai phía, đúng thứ tự, nếu không nhân bản sẽ lỗi. Đây là gánh vận hành thật.
Cần khoá định danh hàng (REPLICA IDENTITY). Để nhân bản UPDATE/DELETE, subscriber cần biết hàng nào bị sửa — mặc định dùng khoá chính. Bảng không có khoá chính phải khai REPLICA IDENTITY FULL (dùng cả hàng làm định danh, chậm hơn) hoặc một unique index, nếu không UPDATE/DELETE sẽ lỗi.
Tốn CPU giải mã và có thể lag. Giải mã WAL thành hàng tốn CPU hơn physical (chỉ copy byte). Trên tải ghi rất cao, logical replication có thể lag nhiều hơn — và như mọi replication, slot giữ WAL khiến publisher phình pg_wal nếu subscriber chết. Giám sát pg_replication_slots và pg_stat_replication như với physical.
Ba ý mang về
- Logical replication nhân bản chọn lọc theo bảng qua publisher/subscriber: dựng thật, publish 2 trong 3 bảng thì subscriber tự copy đủ 1.000 + 5.000 dòng còn bảng
log_debugkhông publish thì không tồn tại ở đích — khác hẳn physical vốn sao cả cụm. - Subscriber ghi được và chạy khác phiên bản, mở ra nâng cấp không downtime, gộp/tách database, đẩy một phần dữ liệu sang hệ thống khác — những việc physical replication (chỉ đọc, cùng phiên bản) không làm được;
INSERT/UPDATE/DELETEđều nhân bản (đo thật cả ba). - Cái giá là gánh vận hành: không copy schema/DDL (phải tự đồng bộ cấu trúc hai phía), cần
REPLICA IDENTITYđể nhân bảnUPDATE/DELETE, và tốn CPU giải mã hơn physical — chọn logical khi cần sự linh hoạt, dùng physical khi chỉ cần bản sao nóng cả cụm.
Phần sau ta chuyển sang chủ đề chẩn đoán vận hành hằng ngày: Phần sau mổ xẻ pg_stat_activity — cách nhìn database đang chạy truy vấn gì, phiên nào đang chờ, và tìm ra thủ phạm khi hệ thống chậm.