PostgreSQL — Kiến trúc nội bộ
Port từ tài liệu HTML gốc — tương tác (tab INSERT/UPDATE/DELETE, layer, tooltip, mobile menu) được nối lại bằng React hooks.
Port từ tài liệu HTML gốc — tương tác (tab INSERT/UPDATE/DELETE, layer, tooltip, mobile menu) được nối lại bằng React hooks.
Hướng dẫn chuyên sâu cho DevOps Engineers — Hiểu rõ luồng dữ liệu bên trong PostgreSQL, từ kết nối đến ổ đĩa, thông qua SQL Pipeline, MVCC, và các background processes.
PostgreSQL sử dụng kiến trúc process-based (mỗi kết nối = 1 process riêng). Dưới đây là 5 lớp từ client đến ổ đĩa. Các thành phần đánh dấu MỚI là những gì bạn có thể chưa biết.
heap_insert(), heap_update(), heap_delete().pg_stat_activity, pg_stat_database, v.v.postgresql.conf (cấu hình), pg_hba.conf (auth), pg_ident.conf (user mapping).Khi 1 câu SQL được gửi đến PostgreSQL, nó đi qua 4 giai đoạn bên trong Backend Process. Đây là điều NHIỀU DevOps bỏ qua nhưng cực kỳ quan trọng để hiểu performance.
SELECT name, age FROM users WHERE age > 25;
| Stage | Input | Output | Kiểm tra gì? | Xem bằng |
|---|---|---|---|---|
| Parser | SQL text | Parse Tree | Cú pháp (grammar only) | — |
| Analyzer | Parse Tree | Query Tree | Bảng, cột, quyền, type | — |
| Planner | Query Tree | Plan Tree | Cost estimation | EXPLAIN |
| Executor | Plan Tree | Result Set | Thực thi & I/O | EXPLAIN ANALYZE |
PostgreSQL sử dụng MVCC để cho phép nhiều transaction đọc/ghi đồng thời KHÔNG block nhau. Đây là concept quan trọng NHẤT để hiểu INSERT, UPDATE, DELETE hoạt động như thế nào.
Mỗi row trong PostgreSQL có 1 header 23 bytes chứa metadata về MVCC:
| Trường | Ý nghĩa |
|---|---|
| t_xmin | Transaction ID tạo ra tuple này. PostgreSQL biết tuple nào do txn nào tạo. |
| t_xmax | Transaction ID xóa/cập nhật tuple. 0 = tuple còn sống (alive). Khác 0 = đã bị delete/update. |
| t_cid | Command ID trong transaction (thứ tự lệnh: 0, 1, 2...). Dùng cho visibility trong cùng 1 transaction. |
| t_ctid | Current Tuple ID = (block_number, offset). Sau UPDATE, old tuple t_ctid → new tuple. Đóng vai trò con trỏ. |
| infomask | Hint bits cache commit status trực tiếp trên tuple: HEAP_XMIN_COMMITTED, HEAP_XMAX_INVALID, v.v. Giảm CLOG lookup. |
| User Data | Dữ liệu thực tế (giá trị các cột). NULL bitmap nếu có null columns. |
Khi 1 transaction SELECT, PostgreSQL kiểm tra mỗi tuple:
HEAP_XMIN_COMMITTED — xmin đã commitHEAP_XMIN_INVALID — xmin aborted/rollbackHEAP_XMAX_COMMITTED — xmax đã commit (đã bị delete)HEAP_XMAX_INVALID — xmax aborted (tuple vẫn alive)
Mỗi UPDATE tạo ra 1 phiên bản MỚI của tuple (old version vẫn giữ lại). t_ctid tạo thành chuỗi liên kết:
Click vào tab tương ứng để xem luồng chi tiết của từng thao tác. Mỗi bước được gắn với Layer cụ thể và mô tả chi tiết những gì diễn ra bên trong.
INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com'); qua kết nối TCP/IP đến PostgreSQL.
users có tồn tại không.
users tồn tại? Columns name, email hợp lệ? Type match? User có quyền INSERT? Output: Query Tree.
heap_insert()heap_insert() của storage engine.
t_xmin của tuple mới.
users cần insert entry mới cho tuple. Mỗi index insert cũng tạo WAL record riêng.
pg_wal/ (đảm bảo durability).pg_wal/ — WAL records được flush (đảm bảo crash recovery).pg_data/base/.../table_file — dirty pages được flush bởi Checkpointer.
UPDATE users SET name = 'Alice B. Chen' WHERE id = 42;
id để tìm tuple cũ. Executor gọi heap_update().
id để nhanh chóng tìm tuple có id=42 trong heap.
pg_wal/, Data pages → pg_data/base/ (do Checkpointer flush).pg_stat_user_tables.dead_tup_count và n_dead_tup để biết khi nào cần VACUUM.
DELETE FROM users WHERE id = 42;
id. Executor gọi heap_delete().
id để tìm tuple id=42 trong heap. (Nếu DELETE không có WHERE → full table scan)
LP_DEAD trên index entry. Cleanup thực sự xảy ra khi:
pg_wal/, Dirty pages → pg_data/base/ (checkpointer). Tuple data vẫn còn trên disk!t_xmax trên header. Tuple data vẫn nằm nguyên trên disk.
SELECT relname, n_live_tup, n_dead_tup, last_vacuum, last_autovacuum
FROM pg_stat_user_tables WHERE n_dead_tup > 1000;
| Hoạt động | t_xmin | t_xmax | Physical space | Index update | WAL records | Vacuum needed? |
|---|---|---|---|---|---|---|
| INSERT | Set xid | 0 | Tăng | Có | 1+ per index | Không |
| UPDATE | Old: giữ, New: set xid | Old: set xid, New: 0 | Tăng (new tuple) | Có* (trừ HOT) | 2+ (old + new) | CÓ! |
| DELETE | Giữ nguyên | Set xid | Không đổi! | LP_DEAD hint | 1 (heap only) | CÓ! |
Dưới đây là tóm tắt các thành phần đã được thêm vào kiến trúc của bạn. Các mục này được đánh dấu MỚI trong toàn bộ trang.
pg_stat_user_tables.n_dead_tup — nếu quá cao → autovacuum không kịp → cần tune autovacuum parameters.