Chương 13 — Anti-pattern & Khi nào PostgreSQL không phù hợp

Level 5. Chương kết. Phần một: các cách dùng sai lặp đi lặp lại — mỗi cái là một chương lý thuyết bị vi phạm. Phần hai: ranh giới kiến trúc thật sự của PostgreSQL — nơi vấn đề không phải “dùng sai” mà là “chọn sai công cụ”. Phần 1 — Anti-patterns Mỗi anti-pattern dưới đây đều có chung cấu trúc: tiện trước mắt → vi phạm một cơ chế nội tại → trả giá trễ và trả bằng lãi kép. ...

July 11, 2026 · 8 min

Chương 12 — Production Failure Cases: 21 hồ sơ sự cố

Level 5. Mỗi case theo khuôn: Triệu chứng → Root cause → Bên trong PostgreSQL → Điều tra (metric/log/lệnh) → Khắc phục → Phòng tránh. Các case tham chiếu ngược về chương lý thuyết tương ứng — chương này đồng thời là bài tổng ôn. Dashboard nền khuyến nghị (dùng chung cho mọi case): wait events theo thời gian (pg_stat_activity), TPS + p99 latency, connections theo state, dead tuples + last_(auto)vacuum các bảng top, WAL bytes/s + checkpoint timeline, replication lag byte, disk %util + fsync latency, cache hit ratio, max(age(datfrozenxid)). ...

July 11, 2026 · 13 min

Chương 11 — Checkpoint, Recovery, Replication

Level 3–5. Chương 5 hứa: “crash không mất gì, WAL dựng lại được”. Chương này trả nghĩa vụ chứng minh — và mở rộng cùng cơ chế đó thành PITR và replication: ba tính năng, một nền tảng duy nhất là WAL replay. 1. Problem Statement Crash recovery: sau mất điện, dựng lại trạng thái đã commit — tự động, không thao tác tay, thời gian đoán được. Backup/PITR: “khôi phục về 14:59, ngay trước câu DELETE nhầm lúc 15:00” — backup định kỳ thuần túy không làm nổi. Replication: bản sao nóng, trễ mili giây, đọc được — và failover khi primary chết. Cả ba là cùng một bài toán: tái tạo trạng thái từ (một ảnh chụp cũ) + (dòng WAL). Ai kiểm soát điểm dừng replay, người đó có tính năng tương ứng: dừng ở cuối WAL = crash recovery; dừng ở timestamp = PITR; không bao giờ dừng = replica. ...

July 11, 2026 · 9 min

Chương 10 — VACUUM, HOT, Freeze, Wraparound

Level 3–5. MVCC vay nợ: mỗi UPDATE/DELETE để lại rác, mỗi transaction đốt một XID hữu hạn. VACUUM là bộ máy trả nợ. Vận hành PostgreSQL nghiêm túc = vận hành VACUUM nghiêm túc. Chương này là chương “đáng tiền” nhất với người trực production. 1. Problem Statement — ba món nợ của MVCC Dead tuple: version cũ không còn snapshot nào cần (Chương 6). Không dọn → bảng/index phình, cache loãng, scan chậm. Không gian XID hữu hạn: XID 32 bit so sánh vòng tròn. Tuple mang xmin quá già (cách hiện tại >2³¹) sẽ bị phép so sánh hiểu ngược thành “tương lai” → dữ liệu committed biến mất. Phải “đóng băng” (freeze) tuple già trước khi điều đó xảy ra. Thống kê & Visibility Map lạc hậu: planner cần ANALYZE; index-only scan cần VM được cập nhật. VACUUM giải cả ba. Nếu bỏ VACUUM? — không phải “chậm dần” mà là dừng hẳn: đầy disk vì bloat, rồi trước cả đó, cluster tự khóa ghi để chống wraparound. Không có lựa chọn “không vacuum”, chỉ có “vacuum có kiểm soát” hoặc “vacuum lúc 3h sáng theo lệnh của PostgreSQL”. ...

July 11, 2026 · 10 min

Chương 9 — Index Internals: B-tree, Hash, GIN, GiST, BRIN

Level 4. Index là cấu trúc dữ liệu trên disk — nghĩa là mọi thiết kế của nó bị chi phối bởi page 8KB, WAL, MVCC và concurrency. Chương này mở nắp từng loại. 1. Problem Statement Heap không có thứ tự (Chương 3): tìm WHERE email='x@y.vn' = đọc toàn bộ bảng, O(N) page. Bảng 100GB → ~13 giây chỉ riêng I/O tuần tự, mỗi query. Cần cấu trúc phụ ánh xạ giá trị → ctid với chi phí tra cứu ~O(log N) tính bằng số page (không phải số phần tử — mỗi page là một lần I/O tiềm năng). ...

July 11, 2026 · 9 min

Chương 8 — Query Processing: từ SQL text đến thao tác trên Page

Level 4. SQL là ngôn ngữ khai báo: bạn nói cần gì, không nói làm thế nào. Toàn bộ chương này là câu chuyện PostgreSQL biến “cần gì” thành “làm thế nào” — và tại sao đôi khi nó chọn sai. 1. Problem Statement SELECT c.name, sum(o.amount) FROM customers c JOIN orders o ON o.customer_id = c.id WHERE c.region = 'APAC' AND o.created_at > now() - interval '30 days' GROUP BY c.name; Câu này có thể thực thi theo hàng nghìn cách: quét bảng nào trước, dùng index nào, join bằng thuật toán nào, group bằng hash hay sort. Chênh lệch giữa plan tốt nhất và tệ nhất trên dữ liệu lớn: 10⁴–10⁶ lần. Không tầng nào khác của database tạo ra chênh lệch hiệu năng lớn như planner. ...

July 11, 2026 · 10 min

Chương 7 — Lock Manager

Level 3. MVCC loại bỏ xung đột reader–writer. Phần còn lại — writer–writer, DDL, và bảo vệ cấu trúc trong bộ nhớ — thuộc về ba tầng lock của PostgreSQL. Đa số sự cố “database treo” trong production là sự cố lock, không phải sự cố I/O. 1. Problem Statement Ba lớp bài toán tranh chấp khác nhau về bản chất và thang thời gian: Micro (nanô giây): hai CPU cùng sửa một biến trong shared memory (refcount của buffer). Cần loại trừ trong vài chục chu kỳ CPU. Meso (micro giây): một backend sửa nội dung page trong khi backend khác đọc. Cần read/write lock ngắn. Macro (mili giây → giờ): hai transaction cùng UPDATE một row; ALTER TABLE trong khi query đang chạy. Cần lock theo ngữ nghĩa transaction: có hàng đợi, có phát hiện deadlock, tự nhả khi commit. Một cơ chế duy nhất không phục vụ nổi cả ba (lock có hàng đợi + deadlock detection quá đắt cho việc tăng một biến đếm). PostgreSQL xây ba tầng: ...

July 11, 2026 · 10 min

Chương 6 — Transaction Engine: MVCC, Snapshot, Visibility

Level 3. MVCC là quyết định thiết kế trung tâm của PostgreSQL. Hiểu nó là hiểu được: tại sao reader không block writer, tại sao có dead tuple, tại sao có VACUUM, tại sao “idle in transaction” là kẻ giết hệ thống thầm lặng. 1. Problem Statement 1.000 transaction đồng thời trên cùng bảng. Yêu cầu Isolation: mỗi transaction thấy database như một ảnh chụp nhất quán, không thấy thay đổi dở dang của người khác. ...

July 11, 2026 · 10 min

Chương 5 — WAL: Write-Ahead Log

Level 3. WAL là phát minh quan trọng nhất của ngành database (ARIES, 1992). Nó là lý do PostgreSQL dám giữ dirty page trong RAM, là nền của recovery, replication, PITR — và là nguồn của một nửa số sự cố production về disk. 1. Problem Statement Chương 1 xác lập hai sự thật vật lý mâu thuẫn nhau: Durability đòi hỏi fsync trước khi báo commit — mà fsync đắt (~0.1–1ms NVMe, ~10ms HDD). Thay đổi của một transaction rải rác trên nhiều page (heap, nhiều index, toast) — fsync tất cả các page đó mỗi commit = nhiều random write + nhiều fsync → vài chục ms mỗi commit → throughput chết. Thêm bài toán thứ ba: page 8KB > sector atomic 4KB → crash giữa lúc ghi page tạo torn page — nửa mới nửa cũ, checksum sai, không dùng được. ...

July 11, 2026 · 10 min

Chương 4 — Buffer Manager

Level 2. Disk chậm hơn RAM ~1000 lần. Buffer Manager là tầng quyết định PostgreSQL chạy ở tốc độ RAM hay tốc độ disk — tức là quyết định 90% cảm nhận hiệu năng. 1. Problem Statement Mỗi thao tác đọc/ghi tuple đều cần page 8KB tương ứng. Nếu mỗi lần đều read()/write() xuống disk: một query đọc 1 triệu tuple rải trên 100k page × ~100µs/lần đọc NVMe = 10 giây thuần I/O — trong khi từ RAM mất ~50ms. ...

July 11, 2026 · 10 min

Chương 3 — Physical Storage: Page, Tuple, TOAST, FSM, Visibility Map

Level 2. Đây là chương nền tảng nhất của bộ tài liệu. Hiểu từng byte của heap page là hiểu được một nửa PostgreSQL: MVCC, VACUUM, HOT, bloat, index — tất cả đều quy về đây. 1. Problem Statement Bảng orders 200GB phải nằm trên disk sao cho: Tìm một order theo con trỏ mất đúng 1 lần đọc disk. Thêm order mới không phải dịch chuyển dữ liệu cũ. Nhiều version của một row (MVCC) cùng tồn tại được. Crash giữa chừng không phá cấu trúc. Cột note dài 1MB không làm hỏng hiệu quả của các cột 8 byte bên cạnh. Nếu tổ chức sai tầng này: mọi thao tác đọc thành O(n), UPDATE phải rewrite file, crash để lại file rác. Toàn bộ chương này là câu trả lời của PostgreSQL cho bài toán đó. ...

July 11, 2026 · 13 min

Chương 2 — Kiến trúc tổng thể: Process & Shared Memory

Level 1–2. PostgreSQL là một “hệ điều hành thu nhỏ”: có process quản lý, có bộ nhớ chia sẻ, có scheduler nền, có cơ chế phục hồi. Chương này vẽ bản đồ toàn bộ hệ thống đó. 1. Problem Statement Một database server phải đồng thời: phục vụ hàng trăm connection, ghi dữ liệu nền, dọn rác, đồng bộ replica, thu thập thống kê — mà một thành phần chết không được kéo sập dữ liệu. Bài toán: tổ chức các đơn vị thực thi (process/thread) và bộ nhớ chung như thế nào để vừa cô lập lỗi, vừa chia sẻ trạng thái hiệu quả? ...

July 11, 2026 · 12 min

Chương 1 — Database Fundamentals: từ First Principles

Level 1. Trước khi nói về PostgreSQL, phải trả lời câu hỏi gốc: tại sao phần mềm quản lý dữ liệu lại khó đến mức cần một engine hàng triệu dòng code? 1. Problem Statement Mọi hệ thống phần mềm đều quy về một bài toán: nhận dữ liệu, lưu dữ liệu, trả lại dữ liệu đúng. Một hệ thống thanh toán nhận lệnh chuyển 500.000đ từ tài khoản A sang B. Yêu cầu nghe đơn giản: ...

July 11, 2026 · 12 min

PostgreSQL Internals — Bên dưới lớp SQL

Bộ tài liệu chuyên sâu về cách PostgreSQL hoạt động bên dưới lớp SQL và Storage, viết cho Backend Engineer, Database Engineer và Software Architect. Tài liệu này KHÔNG phải là gì Đây không phải tài liệu dạy SQL. Không có CREATE TABLE ở chương mở đầu. Không giải thích cú pháp. Đây là tài liệu giúp bạn hiểu PostgreSQL như một hệ điều hành thu nhỏ dành cho dữ liệu: cách nó tổ chức bộ nhớ, quản lý page, lưu tuple, điều phối transaction, ghi WAL, phục hồi sau sự cố, tối ưu truy vấn, và phối hợp với OS để đạt hiệu năng và độ tin cậy. ...

July 11, 2026 · 4 min

Bài 4 — MongoDB, Redis & ClickHouse

PHẦN A — MONGODB Câu 1 — [Intermediate → Senior] Replica Set hoạt động thế nào? Điều gì xảy ra khi failover? 1. Câu hỏi “Trình bày cơ chế replica set của MongoDB: bầu chọn, oplog, và các mức write/read concern. Khi primary chết, dữ liệu có thể mất không?” 2. Interviewer muốn kiểm tra điều gì? Hiểu consensus/election thực tế (Raft-like) chứ không chỉ “có 3 node tự failover”. Nắm write concern / read concern — nơi ẩn chứa các quyết định mất-hay-không-mất dữ liệu. Kinh nghiệm với rollback sau failover — thứ ít người biết cho tới khi gặp. 3. Câu trả lời ngắn gọn (30 giây) “Replica set gồm 1 primary nhận ghi và các secondary kéo oplog (log thao tác idempotent) để replay. Election dựa trên giao thức giống Raft: cần đa số phiếu, node có oplog mới nhất được ưu tiên; vì cần majority nên phải có số node lẻ hoặc arbiter. Có mất dữ liệu không phụ thuộc write concern: w:1 (ack từ primary) — ghi chưa kịp replicate sẽ bị rollback khi failover; w:majority — an toàn qua failover, đổi lấy latency. Read concern và read preference quyết định bạn đọc thấy gì và từ đâu.” ...

July 3, 2026 · 39 min

Bài 3 — PostgreSQL

Câu 1 — [Fundamental → Senior] Tại sao PostgreSQL cần MVCC? Nó hoạt động thế nào và cái giá phải trả là gì? 1. Câu hỏi “Tại sao PostgreSQL cần MVCC? Trình bày cơ chế và hệ quả của nó.” 2. Interviewer muốn kiểm tra điều gì? Hiểu bài toán gốc: concurrency control — reader và writer tranh chấp thế nào. Hiểu cơ chế bên trong (tuple version, xmin/xmax, snapshot) chứ không chỉ khẩu hiệu “reader không chặn writer”. Kinh nghiệm production với hệ quả: bloat, vacuum, wraparound. 3. Câu trả lời ngắn gọn (30 giây) “Không có MVCC, để đọc dữ liệu nhất quán, reader phải lock chặn writer và ngược lại — throughput sụp đổ khi mixed workload. MVCC giải quyết bằng cách: UPDATE/DELETE không ghi đè mà tạo phiên bản tuple mới; mỗi tuple mang xmin/xmax (transaction tạo/xóa nó); mỗi transaction cầm một snapshot và chỉ ’nhìn thấy’ các version phù hợp snapshot của mình. Kết quả: reader không bao giờ chặn writer. Cái giá: các version chết tích tụ thành bloat, cần VACUUM dọn dẹp, và transaction ID 32-bit cần chống wraparound — đây là nguồn của phần lớn sự cố vận hành Postgres.” ...

July 3, 2026 · 29 min

Bài 6 — Kiến Trúc Thực Tế

Cách đọc: mỗi mục trả lời năm câu hỏi — chọn gì, vì sao, vì sao KHÔNG chọn phương án khác, scale/chi phí dự kiến, và rủi ro chính. Các con số là mức định cỡ (order of magnitude) để lập luận, không phải cam kết hiệu năng. 6.1. E-commerce Phân rã workload: đơn hàng/thanh toán/tồn kho (transactional, bất biến chặt) · catalog sản phẩm (schema đa dạng, đọc nhiều) · hành vi người dùng + funnel (event, tỷ row) · giỏ hàng/session (nóng, TTL). ...

July 2, 2026 · 13 min

Bài 5 — So Sánh PostgreSQL, MongoDB & ClickHouse

Nguyên tắc đọc chương này: ba hệ không cùng hạng cân trên cùng một trục. So sánh đúng nghĩa là ánh xạ workload → điểm mạnh cấu trúc, không phải tìm “database tốt nhất”. Mỗi ô dưới đây là hệ quả của kiến trúc đã phân tích ở Chương 2–4; khi nghi ngờ, quay lại chương tương ứng để xem “vì sao”. 5.1. Bảng so sánh tổng hợp Tiêu chí PostgreSQL MongoDB ClickHouse Data Model Quan hệ (bảng, JOIN, constraint) + JSONB làm van linh hoạt Document (BSON), embed/reference, schema-on-read Bảng phẳng columnar, denormalize có chủ đích, không quan hệ Transaction ACID đầy đủ, Serializable thật, transactional DDL — chuẩn vàng ACID trong 1 document (luôn); đa document từ 4.0 — dùng như ngoại lệ, không hàng ngày Gần như không (atomic theo block insert; không đa statement) — theo thiết kế Query Capability Giàu nhất: SQL đầy đủ, CTE, window, lateral, geo, full-text, vector Giàu theo trục document: CRUD + aggregation pipeline; JOIN yếu SQL analytics rất mạnh (aggregate, window, hàm xấp xỉ); JOIN lớn hạn chế; không tối ưu cho OLTP query Read Performance Point lookup/OLTP xuất sắc (B+Tree + buffer pool); analytics lớn kém Point/one-trục xuất sắc khi có index + đủ RAM; analytics lớn kém Point lookup kém (cấu trúc); scan/aggregate hàng tỷ row: nhanh hơn 2 hệ kia 10–1000× Write Performance Tốt (chục nghìn TPS đơn giản/máy tốt); trần = 1 máy; update-heavy chịu thuế vacuum Tốt + scale-out ghi qua sharding; per-document atomic rẻ Ingest batch cực cao (triệu row/s/node); ghi lẻ tẻ = sự cố; update/delete đắt Analytics Đủ cho báo cáo vừa (parallel query, partition); đuối từ trăm triệu row Aggregation operational tốt; analytical toàn dataset yếu Sinh ra để làm việc này Horizontal Scaling Read replica dễ; sharding không tích hợp (Citus/app-level) Tích hợp, trưởng thành (mongos, balancer, reshard 5.0+) Tích hợp (Distributed table) nhưng thủ công hơn Mongo; Cloud tách compute/storage Compression Khiêm tốn (TOAST cho giá trị lớn; không nén page mặc định) Tốt (block compression WiredTiger, prefix index) Xuất sắc (5–20×, codec chuyên dụng theo cột) Storage Efficiency Trung bình; bloat nếu vacuum không theo kịp Khá; thuế tên field lặp, bù bằng nén Tốt nhất cho analytics; part immutable + TTL/tiered Consistency Mạnh mặc định; single-leader rõ ràng Tunable per-operation (w/readConcern) — mạnh khi cấu hình đúng Eventual giữa replica; đủ cho analytics, không cho nghiệp vụ Availability Cao nhưng failover cần tầng ngoài (Patroni/managed) Cao, failover tự động tích hợp (~10–30s) Cao cho đọc (multi-replica); ghi cần thiết kế ingest chịu lỗi Operational Complexity Thấp–vừa (1 node/RS); vacuum + pooler là hai môn bắt buộc Vừa (replica set dễ); sharded cluster = bậc phức tạp mới Vừa–cao tự quản (Keeper, merge, ingest pipeline); thấp nếu Cloud Cost Rẻ nhất ở quy mô nhỏ–vừa; đắt khi ép làm analytics lớn (máy khủng) Hạ tầng RAM-heavy; Atlas tiện nhưng đắt ở scale Chi phí/TB analytics thấp nhất (nén + máy thường); tốn đầu tư ingest Learning Curve SQL phổ cập; nội tạng (vacuum, planner) cần thời gian Bắt đầu dễ nhất; modeling ĐÚNG khó hơn vẻ ngoài nhiều SQL quen; tư duy OLAP (batch, ORDER BY key, denormalize) phải học lại Best Use Cases Hệ giao dịch, tiền, tồn kho, SaaS core, dữ liệu quan hệ bất kỳ Catalog/profile/content đa dạng schema, IoT theo thiết bị, scale-out một-trục Event/log/metric/clickstream, dashboard real-time, time-series lớn Worst Use Cases Analytics tỷ row; write scale-out; queue tần suất cực cao Quan hệ chặt + bất biến phức tạp; BI toàn dataset OLTP bất kỳ; dữ liệu nhỏ; update thường xuyên 5.2. Ba trục phân tích sâu Trục 1 — Mô hình dữ liệu quyết định 80% quyết định Ba câu hỏi theo thứ tự: ...

July 2, 2026 · 7 min

Bài 4 — ClickHouse

Tiền đề: Chương 1 (columnar vs row, LSM, vectorized execution) và các chương PostgreSQL/MongoDB để đối chiếu. Chủ đề trung tâm của chương: ClickHouse nhanh không phải vì “code giỏi hơn”, mà vì nó từ bỏ một cách có chủ đích những thứ OLAP không cần. 1. Problem Statement Bài toán: trả lời câu hỏi phân tích (aggregation, group by, filter) trên hàng tỷ đến hàng nghìn tỷ row trong dưới một giây, với dữ liệu mới đến liên tục. ...

July 2, 2026 · 13 min

Bài 3 — MongoDB

Tiền đề: Chương 1 (LSM/B+Tree, replication, sharding, CAP/PACELC). Góc nhìn: từ người thiết kế engine — WiredTiger, oplog, Replica Set, sharding — không phải từ tutorial CRUD. 1. Problem Statement MongoDB giải bài toán gì? Hai bài toán mà RDBMS đầu những năm 2000 giải kém: Impedance mismatch: đối tượng trong ứng dụng (nested, mảng, đa hình) phải “băm” ra hàng chục bảng chuẩn hóa rồi JOIN lại. Mỗi thay đổi cấu trúc là một cuộc migration. Tốc độ phát triển sản phẩm bị schema ghì lại. Scale-out: RDBMS thời đó scale ghi bằng cách mua máy to hơn; sharding phải tự chế ở tầng ứng dụng (như Facebook/YouTube từng làm với MySQL — tốn cả đội ngũ chỉ để vận hành sharding). Nếu không có nó thì sao? Hoặc chịu ma sát schema + tự shard bằng tay, hoặc dùng key-value store thuần (mất khả năng query phong phú). MongoDB đặt cược vào điểm giữa: document model giàu query + sharding tích hợp. ...

July 2, 2026 · 14 min

Bài 2 — PostgreSQL

Tiền đề: đã đọc Chương 1 (WAL, MVCC, B+Tree, buffer pool, replication). Góc nhìn: từ vị trí người thiết kế engine, không phải người dùng API. 1. Problem Statement PostgreSQL giải bài toán gì? Lưu trữ dữ liệu quan hệ với tính đúng đắn tuyệt đối dưới concurrency cao: transaction ACID đầy đủ, constraint được thực thi nghiêm ngặt, SQL chuẩn và giàu tính năng, mở rộng được (extension), trong khi vẫn đủ nhanh cho đại đa số workload OLTP. ...

July 2, 2026 · 14 min

Bài 1 — Database Fundamentals

Đối tượng: Software Engineer → Software Architect Mục tiêu: Hiểu bản chất vật lý và logic của mọi database engine, làm nền tảng để hiểu sâu PostgreSQL, MongoDB và ClickHouse ở các chương sau. 1.1. Problem Statement: Vì sao database là bài toán khó? Về mặt bề ngoài, một database chỉ làm hai việc: ghi dữ liệu xuống và đọc dữ liệu lên. Vậy tại sao nhân loại cần hàng chục năm và hàng trăm engine khác nhau để giải bài toán này? ...

July 2, 2026 · 20 min

Bài 0 — Giới Thiệu Series

Database Engineering — từ First Principles đến quyết định kiến trúc production Dành cho Software Engineer, Backend Engineer, Senior Engineer, Tech Lead, Solution Architect và Software Architect. Viết theo tinh thần Principal Engineer hướng dẫn Senior Engineer: mọi kết luận đều trả lời tại sao, đánh đổi điều gì, và điều gì xảy ra nếu làm ngược lại. Mục lục Chương 1 — Database Fundamentals Nền tảng bắt buộc trước khi đọc các chương sau: Disk vs Memory, Page, Buffer Pool, WAL, Transaction & ACID, Isolation Levels, MVCC, B+Tree vs LSM Tree, Query Execution & Optimizer, Replication, Partitioning vs Sharding, CAP & PACELC, Distributed Systems Fundamentals. Kết chương bằng bản đồ tư duy đối chiếu ba database. ...

July 2, 2026 · 3 min

4 Nguyên Tắc Vàng Khi Dùng Index Mà Mình Ước Gì Biết Sớm Hơn

Chào mọi người, trong quá trình làm việc với database, mình thấy rất nhiều trường hợp không hiểu rõ bản chất của index dẫn đến không sử dụng index một cách hiệu quả. Hôm nay, tranh thủ dịp lễ 1/5 không được đi chơi, ở nhà thôi thì ngồi viết một bài blog về vấn đề này vậy. (Lưu ý: Bài viết mình có tham khảo AI sau khi viết để chỉnh chu lại văn phong và ngữ pháp cũng như là verify lại kiến thức của mình nhé, nào gét gô) ...

May 1, 2026 · 13 min

Chương 13: Best Practices, Anti-patterns và Khi nào KHÔNG nên dùng CDC

Chương cuối này là phần “chưng cất” của toàn bộ tài liệu. Sau mười hai chương về cơ chế, pattern, sự cố và kiến trúc, câu hỏi còn lại rất thực dụng: làm gì, tránh gì, và — quan trọng không kém — khi nào đừng làm cả. Tôi cố tình viết chương này theo kiểu có thể in ra dán cạnh bàn on-call: mỗi practice kèm lý do, mỗi anti-pattern kèm hậu quả thật, vì quy tắc không có lý do sẽ bị bỏ qua ngay lần deadline đầu tiên. ...

February 20, 2026 · 16 min

Chương 12: Kiến trúc CDC thực tế theo domain

Hai chương trước cho bạn pattern (chương 10) và bản đồ rủi ro (chương 11). Chương này ghép chúng lại thành thiết kế hoàn chỉnh theo từng loại hệ thống. Cùng một công nghệ — Debezium, Kafka — nhưng bài toán e-commerce, FinTech hay SaaS multi-tenant dẫn đến những quyết định rất khác nhau, và điều làm nên một Solution Architect giỏi không phải là biết công cụ, mà là biết bối cảnh nào bẻ cong thiết kế theo hướng nào. ...

February 20, 2026 · 17 min

Chương 11: Production Failure Cases

Đây là chương quan trọng nhất của toàn bộ tài liệu. Lý do rất đơn giản: CDC không khó ở lúc setup — CDC khó ở tháng thứ ba vận hành. Demo Debezium chạy trong một buổi chiều; nhưng pipeline CDC production là một chuỗi hệ thống stateful nối tiếp nhau (database → connector → Kafka → consumer → sink), và mỗi mắt xích có những chế độ hỏng riêng, đôi khi âm thầm, đôi khi phá hủy cả database nguồn. ...

February 20, 2026 · 38 min

Chương 10: CDC trong bức tranh kiến trúc — Outbox, Event Sourcing, CQRS

Đến chương này, chúng ta đã hiểu CDC hoạt động thế nào ở tầng cơ chế: transaction log, replication slot, connector, offset. Câu hỏi tiếp theo — và là câu hỏi mà một Tech Lead hay Solution Architect thực sự phải trả lời — là: CDC đứng ở đâu trong kiến trúc tổng thể? Nó thay thế cái gì, kết hợp với pattern nào, và quan trọng hơn: nó không phải là cái gì. ...

February 20, 2026 · 19 min

Chương 9: Xây dựng Event Pipeline hoàn chỉnh — Kafka đến ClickHouse, Elasticsearch, Data Warehouse

Hai chương trước cho bạn nguồn (Debezium) và nền tảng (Kafka Connect). Chương này lắp mọi thứ thành pipeline hoàn chỉnh — và quan trọng hơn, chỉ ra các quyết định thiết kế ở giữa hai đầu: topic và partition, schema contract, cách từng loại đích tiêu hóa change event, và latency/backpressure của toàn tuyến. Kinh nghiệm của tôi: pipeline CDC thất bại ở production hiếm khi vì Debezium hay Kafka lỗi — nó thất bại vì các quyết định thiết kế trung gian bị bỏ qua: topic 200 partition cho bảng 50 nghìn row, JSON không schema, insert từng row vào ClickHouse. Cuối chương có đúng ví dụ đó, kèm bản chữa. ...

February 20, 2026 · 17 min

Chương 8: Kafka Connect — Nền tảng vận hành Connector

Chương 7 kết thúc với một nhận định: phần khó nhất của CDC không phải đọc log mà là quản lý trạng thái và fault tolerance — và Debezium đẩy toàn bộ phần đó cho Kafka Connect. Chương này mở hộp đen Kafka Connect từ góc nhìn người vận hành platform. Nếu Debezium là động cơ, Connect là khung gầm: khi pipeline CDC gặp sự cố lúc 3 giờ sáng, thứ bạn thao tác gần như luôn là Connect — REST API, task state, rebalance, internal topic — chứ không phải code Debezium. ...

February 20, 2026 · 16 min