📚 Phân biệt chi tiết các lệnh bảo trì trong PostgreSQL
Dưới đây là sự phân biệt chi tiết về cơ chế, mục đích, tác động và cách sử dụng của 6 lệnh bảo trì quan trọng trong PostgreSQL.
1️⃣ VACUUM (Standard VACUUM)
Bản chất:
Làm sạch dead tuples (các dòng dữ liệu đã bị xóa hoặc cập nhật)
Đánh dấu không gian trống để tái sử dụng
Cập nhật visibility map
Cơ chế hoạt động:
VACUUM table_name;| Đặc điểm | Chi tiết |
|---|---|
| Lock bảng | ❌ Không (chỉ lock rất ngắn, microsecond) |
| Trả space cho OS | ❌ Không (giữ lại cho bảng) |
| Cho phép concurrent access | ✅ Có (đọc/ghi vẫn hoạt động) |
| Thời gian chạy | Nhanh (chỉ quét, không copy) |
| Giảm bloat | Một phần (chỉ ngăn không cho tăng thêm) |
Khi nào dùng:
Thường xuyên (hàng giờ/hàng ngày) cho bảng có nhiều UPDATE/DELETE
Khi muốn ngăn bloat mà không gây downtime
Trên bảng OLTP có concurrent access cao
Ví dụ:
-- Bảng orders có 1 triệu rows, bạn DELETE 200,000 rows VACUUM orders; -- Kết quả: 200,000 vị trí được đánh dấu trống -- File vẫn giữ kích thước 1 triệu rows -- Rows mới sẽ được chèn vào các vị trí trống này
2️⃣ VACUUM FULL
Bản chất:
Nén bảng vật lý, loại bỏ hoàn toàn dead tuples
Trả lại không gian trống cho OS
Rewrite toàn bộ bảng (tạo bảng mới, copy dữ liệu, xóa bảng cũ)
Cơ chế hoạt động:
VACUUM FULL table_name;
| Đặc điểm | Chi tiết |
|---|---|
| Lock bảng | ✅ Có (Access Exclusive Lock) - toàn bộ bảng bị khóa |
| Trả space cho OS | ✅ Có (giảm kích thước file) |
| Cho phép concurrent access | ❌ Không (downtime hoàn toàn) |
| Thời gian chạy | Rất chậm (phải copy toàn bộ dữ liệu) |
| Giảm bloat | Hoàn toàn (bảng như mới) |
Quy trình thực hiện:
1. Lock bảng (Access Exclusive Lock) 2. Tạo bảng mới tạm thời 3. Copy dữ liệu còn sống (live tuples) sang bảng mới 4. Xóa bảng cũ 5. Đổi tên bảng mới thành bảng cũ 6. Rebuild index 7. Release lock
Khi nào dùng:
Hiếm khi (chỉ khi bảng bị bloat nghiêm trọng)
Trong maintenance window (cho phép downtime)
Sau khi xóa lượng lớn dữ liệu (>50% bảng)
Ví dụ:
-- Bảng orders có 1 triệu rows, bạn DELETE 800,000 rows VACUUM FULL orders; -- Kết quả: -- - File giảm từ 1GB xuống 200MB -- - Bảng bị lock trong suốt quá trình (có thể 5-10 phút) -- - 200,000 rows được giữ lại
3️⃣ VACUUM ANALYZE
Bản chất:
Kết hợp VACUUM (dọn dẹp dead tuples) + ANALYZE (cập nhật thống kê)
Thực hiện tuần tự: VACUUM trước, ANALYZE sau
Cơ chế hoạt động:
VACUUM ANALYZE table_name;
| Đặc điểm | Chi tiết |
|---|---|
| Lock bảng | ❌ Không (giống VACUUM thường) |
| Trả space cho OS | ❌ Không |
| Cập nhật thống kê | ✅ Có |
| Thời gian chạy | Nhanh hơn chạy riêng lẻ (chỉ quét 1 lần) |
Lợi ích của kết hợp:
Hiệu quả hơn: Quét bảng 1 lần thay vì 2 lần
Thống kê chính xác: Sau khi dọn dẹp dead tuples
Tiết kiệm I/O: Giảm tải cho hệ thống
Khi nào dùng:
Định kỳ (hàng ngày) cho bảng transaction
Sau khi xóa/cập nhật nhiều dữ liệu
Khi cần cả dọn dẹp và cập nhật thống kê
4️⃣ VACUUM FULL ANALYZE
Bản chất:
Kết hợp VACUUM FULL + ANALYZE
Thực hiện tuần tự: VACUUM FULL trước (nén bảng), ANALYZE sau (cập nhật thống kê)
Cơ chế hoạt động:
VACUUM FULL ANALYZE table_name;
| Đặc điểm | Chi tiết |
|---|---|
| Lock bảng | ✅ Có (Access Exclusive Lock) |
| Trả space cho OS | ✅ Có |
| Cập nhật thống kê | ✅ Có |
| Thời gian chạy | Chậm nhất (VACUUM FULL + ANALYZE) |
Khi nào dùng:
Rất hiếm (chỉ khi thực sự cần)
Trong maintenance window dài
Sau khi xóa >70% dữ liệu và cần thống kê mới
Ví dụ:
-- Bảng logs có 10GB, bạn xóa 9GB dữ liệu cũ VACUUM FULL ANALYZE logs; -- Kết quả: -- - File giảm từ 10GB xuống 1GB -- - Bảng bị lock 15-30 phút -- - Thống kê được cập nhật cho query planner
5️⃣ ANALYZE (chỉ ANALYZE)
Bản chất:
Chỉ thu thập thống kê về phân bố dữ liệu
Không làm sạch dead tuples
Cập nhật pg_statistic cho query planner
Cơ chế hoạt động:
ANALYZE table_name;
| Đặc điểm | Chi tiết |
|---|---|
| Lock bảng | ❌ Không (chỉ đọc, không ghi) |
| Làm sạch dead tuples | ❌ Không |
| Cập nhật thống kê | ✅ Có |
| Thời gian chạy | Nhanh nhất (chỉ lấy mẫu, không quét toàn bộ) |
Cơ chế lấy mẫu:
1. Lấy mẫu ngẫu nhiên (default: 100 * default_statistics_target ≈ 30,000 rows) 2. Tính toán: - Most common values (các giá trị phổ biến) - Histogram bounds (phân bố giá trị) - Null fraction (tỷ lệ NULL) - Distinct values count (số giá trị unique) 3. Lưu vào pg_statistic
Khi nào dùng:
Thường xuyên nhất (hàng giờ) cho bảng có nhiều INSERT
Sau khi INSERT lượng lớn dữ liệu mới
Khi query chậm do execution plan tồi
Trên bảng append-only (chỉ INSERT, không UPDATE/DELETE)
Ví dụ:
-- Bảng logs chỉ INSERT, không DELETE ANALYZE logs; -- Kết quả: Query planner biết logs có 10 triệu rows mới -- Execution plan: Chuyển từ sequential scan sang index scan -- Query chạy nhanh hơn từ 30s xuống 0.5s
6️⃣ REINDEX
Bản chất:
Xây dựng lại index từ đầu
Loại bỏ bloat trong index
Sửa lỗi index bị corrupt (nếu có)
Cơ chế hoạt động:
REINDEX INDEX index_name; REINDEX TABLE table_name; REINDEX DATABASE database_name;
| Đặc điểm | REINDEX INDEX | REINDEX TABLE | REINDEX DATABASE |
|---|---|---|---|
| Lock bảng | ✅ Lock chia sẻ (Share Lock) | ✅ Có (Access Exclusive) | ✅ Có (toàn bộ DB) |
| Trả space cho OS | ✅ Có (index mới nhỏ hơn) | ✅ Có | ✅ Có |
| Cho phép concurrent access | ⚠️ Đọc được, ghi bị ảnh hưởng | ❌ Không | ❌ Không |
| Thời gian chạy | Trung bình | Chậm | Rất chậm |
Quy trình thực hiện REINDEX:
1. Lock index/bảng 2. Tạo index mới tạm thời 3. Copy dữ liệu từ index cũ sang index mới 4. Xóa index cũ 5. Đổi tên index mới 6. Release lock
REINDEX CONCURRENTLY (PostgreSQL 12+):
-- Không lock bảng, nhưng chậm hơn và tốn CPU/RAM hơn REINDEX INDEX CONCURRENTLY index_name; REINDEX TABLE CONCURRENTLY table_name;
Khi nào dùng:
Index bị bloat (phình to do nhiều UPDATE/DELETE)
Sau VACUUM FULL (nên REINDEX để tối ưu)
Khi phát hiện index corrupt
Định kỳ (hàng tháng/quý) cho index thường xuyên thay đổi
Ví dụ:
-- Index trên cột status bị bloat (cập nhật status liên tục) REINDEX INDEX idx_orders_status; -- Kết quả: Index từ 500MB giảm xuống 200MB -- Query sử dụng index nhanh hơn 40%
📊 SO SÁNH TỔNG HỢP
Bảng so sánh chi tiết:
| Lệnh | Lock bảng | Trả space OS | Giảm bloat | Cập nhật thống kê | Downtime | Tần suất dùng |
|---|---|---|---|---|---|---|
| VACUUM | ❌ Không | ❌ Không | ⚠️ Một phần | ❌ Không | Không | Hàng giờ/ngày |
| VACUUM FULL | ✅ Có | ✅ Có | ✅ Hoàn toàn | ❌ Không | Cao | Hàng tháng/năm |
| VACUUM ANALYZE | ❌ Không | ❌ Không | ⚠️ Một phần | ✅ Có | Không | Hàng ngày |
| VACUUM FULL ANALYZE | ✅ Có | ✅ Có | ✅ Hoàn toàn | ✅ Có | Rất cao | Hiếm (năm) |
| ANALYZE | ❌ Không | ❌ Không | ❌ Không | ✅ Có | Không | Hàng giờ/ngày |
| REINDEX | ⚠️ Tùy loại | ✅ Có | ✅ Cho index | ❌ Không | Trung bình | Hàng tuần/tháng |
🎯 HƯỚNG DẪN LỰA CHỌN
1. Cho bảng OLTP (nhiều UPDATE/DELETE):
-- Mỗi 1-2 giờ VACUUM ANALYZE app_data.request_his_NEW; -- Hàng tuần (maintenance window) REINDEX TABLE CONCURRENTLY app_data.request_his_NEW; -- Hàng tháng (nếu bị bloat nặng) VACUUM FULL ANALYZE app_data.request_his_NEW;
2. Cho bảng Log/Append-only (chỉ INSERT):
-- Mỗi 6-12 giờ (chỉ cập nhật thống kê) ANALYZE app_data.request_his_log_NEW; -- Không cần VACUUM (ít dead tuples) -- Không cần REINDEX (index ít thay đổi)
3. Cho bảng Master (ít thay đổi, chủ yếu SELECT):
-- Hàng ngày ANALYZE app_data.master_table; -- Hàng tháng (phòng ngừa) VACUUM ANALYZE app_data.master_table;
🔍 CÁCH KIỂM TRA KHI NÀO CẦN DÙNG
Kiểm tra bloat (cần VACUUM FULL hoặc REINDEX):
-- Kiểm tra bloat của bảng SELECT schemaname, tablename, pg_size_pretty(pg_relation_size(schemaname||'.'||tablename)) AS table_size, pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename) - pg_relation_size(schemaname||'.'||tablename)) AS index_size FROM pg_tables WHERE tablename LIKE 'request_his%'; -- Kiểm tra dead tuples (cần VACUUM) SELECT relname, n_dead_tup, n_live_tup, round(100 * n_dead_tup / nullif(n_live_tup, 0), 2) AS dead_ratio FROM pg_stat_user_tables WHERE relname LIKE 'request_his%'; -- Nếu dead_ratio > 10% → VACUUM -- Nếu dead_ratio > 30% → VACUUM FULL
⚠️ LƯU Ý QUAN TRỌNG
VACUUM FULL và REINDEX (không CONCURRENTLY) gây downtime
VACUUM thường và ANALYZE có thể chạy online (không ảnh hưởng ứng dụng)
REINDEX CONCURRENTLY tốn CPU và RAM gấp đôi nhưng không lock bảng
VACUUM FULL ANALYZE = VACUUM FULL + ANALYZE (chạy tuần tự)
Không nên VACUUM FULL quá thường xuyên (tốn I/O, lock bảng)
📋 SCRIPT KIỂM TRA VÀ ĐỀ XUẤT
-- Tự động đề xuất lệnh cần chạy SELECT relname, n_dead_tup, round(100 * n_dead_tup / nullif(n_live_tup, 0), 2) AS dead_ratio, CASE WHEN n_dead_tup = 0 THEN '✅ Không cần xử lý' WHEN dead_ratio < 5 THEN '📊 ANALYZE' WHEN dead_ratio < 20 THEN '🧹 VACUUM ANALYZE' WHEN dead_ratio < 50 THEN '⚠️ VACUUM FULL (cần maintenance window)' ELSE '🚨 VACUUM FULL ANALYZE (khẩn cấp)' END AS recommended_action FROM pg_stat_user_tables WHERE relname LIKE 'request_his%' ORDER BY dead_ratio DESC;
TƯ VẤN: Click Here hoặc Hotline/Zalo 090.29.12.888
=============================
Website không chứa bất kỳ quảng cáo nào, mọi đóng góp để duy trì phát triển cho website (donation) xin vui lòng gửi về STK 90.2142.8888 - Ngân hàng Vietcombank Thăng Long - TRAN VAN BINH
=============================
Nếu bạn không muốn bị AI thay thế và tiết kiệm 3-5 NĂM trên con đường trở thành DBA chuyên nghiệp hay làm chủ Database thì hãy đăng ký ngay KHOÁ HỌC ORACLE DATABASE A-Z ENTERPRISE, được Coaching trực tiếp từ tôi với toàn bộ bí kíp thực chiến, thủ tục, quy trình của gần 20 năm kinh nghiệm (mà bạn sẽ KHÔNG THỂ tìm kiếm trên Internet/Google) từ đó giúp bạn dễ dàng quản trị mọi hệ thống Core tại Việt Nam và trên thế giới, đỗ OCP.
- CÁCH ĐĂNG KÝ: Gõ (.) hoặc để lại số điện thoại hoặc inbox https://m.me/tranvanbinh.vn hoặc Hotline/Zalo 090.29.12.888
- Chi tiết tham khảo:
https://bit.ly/oaz_w
=============================
2 khóa học online qua video giúp bạn nhanh chóng có những kiến thức nền tảng về Linux, Oracle, học mọi nơi, chỉ cần có Internet/4G:
- Oracle cơ bản: https://bit.ly/admin_1200
- Linux: https://bit.ly/linux_1200
=============================
KẾT NỐI VỚI CHUYÊN GIA TRẦN VĂN BÌNH:
📧 Mail: binhoracle@gmail.com
☎️ Mobile/Zalo: 0902912888
👨 Facebook: https://www.facebook.com/BinhOracleMaster
👨 Inbox Messenger: https://m.me/101036604657441 (profile)
👨 Fanpage: https://www.facebook.com/tranvanbinh.vn
👨 Inbox Fanpage: https://m.me/tranvanbinh.vn
👨👩 Group FB: https://www.facebook.com/groups/DBAVietNam
👨 Website: https://www.tranvanbinh.vn
👨 Blogger: https://tranvanbinhmaster.blogspot.com
🎬 Youtube: https://www.youtube.com/@binhguru
👨 Tiktok: https://www.tiktok.com/@binhguru
👨 Linkin: https://www.linkedin.com/in/binhoracle
👨 Twitter: https://twitter.com/binhguru
👨 Podcast: https://www.podbean.com/pu/pbblog-eskre-5f82d6
👨 Địa chỉ: Tòa nhà Sun Square - 21 Lê Đức Thọ - Phường Mỹ Đình 1 - Quận Nam Từ Liêm - TP.Hà Nội
=============================
cơ sở dữ liệu, cơ sở dữ liệu quốc gia, database, AI, trí tuệ nhân tạo, artificial intelligence, machine learning, deep learning, LLM, ChatGPT, DeepSeek, Grok, oracle tutorial, học oracle database, Tự học Oracle, Tài liệu Oracle 12c tiếng Việt, Hướng dẫn sử dụng Oracle Database, Oracle SQL cơ bản, Oracle SQL là gì, Khóa học Oracle Hà Nội, Học chứng chỉ Oracle ở đầu, Khóa học Oracle online,sql tutorial, khóa học pl/sql tutorial, học dba, học dba ở việt nam, khóa học dba, khóa học dba sql, tài liệu học dba oracle, Khóa học Oracle online, học oracle sql, học oracle ở đâu tphcm, học oracle bắt đầu từ đâu, học oracle ở hà nội, oracle database tutorial, oracle database 12c, oracle database là gì, oracle database 11g, oracle download, oracle database 19c/21c/23c/23ai, oracle dba tutorial, oracle tunning, sql tunning , oracle 12c, oracle multitenant, Container Databases (CDB), Pluggable Databases (PDB), oracle cloud, oracle security, oracle fga, audit_trail,oracle RAC, ASM, oracle dataguard, oracle goldengate, mview, oracle exadata, oracle oca, oracle ocp, oracle ocm , oracle weblogic, postgresql tutorial, mysql tutorial, mariadb tutorial, ms sql server tutorial, nosql, mongodb tutorial, oci, cloud, middleware tutorial, docker, k8s, micro service, hoc solaris tutorial, hoc linux tutorial, hoc aix tutorial, unix tutorial, securecrt, xshell, mobaxterm, putty