Lập trình 22/09/2026 7 phút

Đọc trên replica đo thật: truy vấn dài bị huỷ sau 2,2 giây hoặc 30,9 giây tuỳ max_standby_streaming_delay, chờ mãi thì lag phình 454 MB trong 12 giây, feedback hết huỷ nhưng để lại 400.000 dead tuple trên primary, đọc ngay sau ghi trượt 299/300

Trên replica PostgreSQL 16 ở chế độ hot standby, một truy vấn 40 giây giữ snapshot gặp VACUUM từ primary: với max_standby_streaming_delay 2 giây bị huỷ sau 2,2 giây, với 30 giây mặc định bị huỷ sau 30,9 giây, với -1 chạy xong nhưng lag replica lên 454 MB và 12 giây dưới tải. Bật hot_standby_feedback thì truy vấn chạy xong, xmin của replica xuất hiện trong slot và VACUUM VERBOSE trên primary báo 400.000 dead tuple chưa dọn được. Đọc ngay sau ghi bằng Go pgx: 299 trong 300 lượt chưa thấy dòng vừa commit, thấy sau 1,4 ms trung vị và tối đa 120 ms dưới tải, dù lag báo 0 byte.

Lập trình 22/09/2026 9 phút

Failover PostgreSQL đo thật: kill primary dưới tải, promote replica trong 179 ms, bất đồng bộ mất 22 giao dịch đã COMMIT trong 144.531, synchronous_commit=on mất 0 nhưng thừa 1 commit client không được báo, pg_rewind đưa primary cũ về trong 2,5 giây

Dựng thật trên PostgreSQL 16 với writer Go đếm từng COMMIT được xác nhận: SIGKILL primary ở giây thứ 10 dưới pgbench 8 client, pg_promote replica xong sau 179 ms. Bất đồng bộ: 144.531 commit được xác nhận, 144.509 có trên primary mới, mất 22 với lag chỉ 10 KB. Đồng bộ với synchronous_commit on: 13.480 xác nhận, 13.481 có mặt, mất 0 và thừa 1 commit client chưa được báo. Giá của từng nấc: INSERT 0,05 ms ở off, 0,23 ms ở on, TPS từ 19.534 xuống 3.736 ở remote_apply; replica tắt thì INSERT treo 9 phút và statement_timeout không cắt được. pg_rewind chép 1,4 GB trong 2,5 giây.

Lập trình 22/09/2026 8 phút

Logical replication đo thật: chép một triệu dòng sang cụm khác sẵn sàng sau 1,2 giây, lag 0 byte dưới tải nhẹ nhưng một giao dịch 300.000 dòng mất 1,2 giây để áp, và ba thứ nó không chép làm subscription đứng: DDL, sequence, xung đột khoá chính

Publication trên PostgreSQL 16, subscription trên cụm riêng: 1.000.000 dòng 158 MB sẵn sàng sau 1.185 ms. Dưới 200 giao dịch UPDATE 500 dòng, lag logic và vật lý đều 0 byte. Một UPDATE 300.000 dòng một giao dịch: publisher 639 ms, subscriber áp xong sau 1.836 ms. ADD COLUMN ở publisher làm worker chết với lỗi missing replicated column, thêm cột ở subscriber thì nối lại sau 1,3 giây. Sequence không sang: subscriber ở 1 khi publisher ở 1.000, insert đầu tiên duplicate key. Xung đột khoá chính kẹt mọi giao dịch phía sau, worker thử lại mỗi 5 giây, SKIP lsn gỡ trong 1,9 giây. TRUNCATE có sang.

Lập trình 22/09/2026 9 phút

VACUUM, bloat và wraparound đo thật: mười lần UPDATE toàn bảng biến 27 MB thành 296 MB, VACUUM giải phóng 90% chỗ nhưng không trả đĩa, autovacuum mặc định không chạy lần nào trong 60 giây tải, và một giao dịch mở giữ 600.000 dead tuple không dọn được

Đo trên PostgreSQL 16 với pgstattuple: bảng 200.000 dòng sau 10 UPDATE toàn bảng phình từ 27 MB lên 296 MB, VACUUM 599 ms đưa dead về 0,13% và free lên 90% nhưng kích thước giữ nguyên, VACUUM FULL 278 ms trả về 27 MB. Dưới pgbench 60 giây trên 3 triệu dòng, autovacuum mặc định chạy 0 lần và dead tuple lên 96.000; chỉnh scale 0.01, naptime 5 giây, cost_delay 0 thì chạy 4 lần. Một giao dịch mở 40 giây làm VACUUM báo 600.000 dead but not yet removable và bảng phình 108 lên 189 MB dù vacuum đều. Hạ freeze_max_age xuống 100.000 rồi đốt 160.000 XID: 773 lần aggressive vacuum giữ age dưới ngưỡng.

Lập trình 22/09/2026 10 phút

Đổi schema không downtime đo thật: ADD COLUMN mất 1 ms nhưng một giao dịch quên COMMIT làm mọi SELECT về 0 trong 5 giây, lock_timeout cắt còn 2 giây, DEFAULT random() viết lại bảng 739 ms, CREATE INDEX chặn ghi còn CONCURRENTLY thì không

PostgreSQL 16, timing phía máy chủ: ADD COLUMN 7,6 ms, NOT NULL DEFAULT hằng 1,1 ms, DEFAULT now() 1,0 ms vì now() là stable, DEFAULT random() 739 ms viết lại 1 triệu dòng, SET NOT NULL trực tiếp 241 ms. Một giao dịch mở 8 giây cộng một ALTER vô hại làm tps đọc từ 80.000 về 0 trong 5 giây; lock_timeout 2 giây cắt tổn thất còn 2 giây. CREATE INDEX giữ ShareLock và chặn UPDATE 113 ms, CONCURRENTLY để UPDATE qua trong 1,6 ms. ADD CHECK trực tiếp dưới tải ghi mất 5 giây với ghi về 0, NOT VALID rồi VALIDATE không chặn giây nào. SET NOT NULL sau CHECK VALID còn 26 ms.

Lập trình 22/09/2026 10 phút

PgBouncer đo thật: 1.000 client chạy trên đúng 20 backend PostgreSQL trong khi 300 client trực tiếp bị từ chối, proxy một luồng chạm trần 70.000 TPS so với 235.000 trực tiếp, và một SET work_mem của một client làm bẩn pool cho 50 client sau

PgBouncer 1.26 ở transaction mode với pool 20 trước PostgreSQL 16 max_connections 100. Connect mỗi giao dịch: 1.224 TPS trực tiếp, 2.322 qua pool. 300 client trực tiếp nhận FATAL too many clients; 1.000 client qua pool chạy trên 20 backend với 951 client xếp hàng, 64.088 TPS. Nhưng PgBouncer một luồng chạm trần 70.000 TPS truy vấn đơn giản so với 235.000 trực tiếp. Một client SET work_mem rồi ngắt: 50 trong 50 client mới nhận 64MB vì transaction mode không reset phiên. Prepared statement lỗi với max_prepared_statements 0, chạy 89.480 TPS khi bật 100. Pool cạn: SELECT 1 chờ 2,9 giây.