Thứ Ba, 7 tháng 4, 2026

Phân biệt kỹ vacuum, vacuum full, vacuum analyze, vacuum full analyze, analyze , reindex trong postgresql

📚 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:

sql
VACUUM table_name;
Đặc điểmChi 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ạyNhanh (chỉ quét, không copy)
Giảm bloatMộ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ụ:

sql
-- 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:

sql
VACUUM FULL table_name;
Đặc điểmChi tiết
Lock bảng✅ Có (Access Exclusive Lock) - toàn bộ bảng bị khóa
Trả space cho OS✅  (giảm kích thước file)
Cho phép concurrent access❌ Không (downtime hoàn toàn)
Thời gian chạyRất chậm (phải copy toàn bộ dữ liệu)
Giảm bloatHoàn toàn (bảng như mới)

Quy trình thực hiện:

text
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ụ:

sql
-- 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:

sql
VACUUM ANALYZE table_name;
Đặc điểmChi 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ê✅ 
Thời gian chạyNhanh 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:

sql
VACUUM FULL ANALYZE table_name;
Đặc điểmChi tiết
Lock bảng✅ Có (Access Exclusive Lock)
Trả space cho OS✅ 
Cập nhật thống kê✅ 
Thời gian chạyChậ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ụ:

sql
-- 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:

sql
ANALYZE table_name;
Đặc điểmChi 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ê✅ 
Thời gian chạyNhanh nhất (chỉ lấy mẫu, không quét toàn bộ)

Cơ chế lấy mẫu:

text
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ụ:

sql
-- 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:

sql
REINDEX INDEX index_name;
REINDEX TABLE table_name;
REINDEX DATABASE database_name;
Đặc điểmREINDEX INDEXREINDEX TABLEREINDEX DATABASE
Lock bảng✅ Lock chia sẻ (Share Lock)✅  (Access Exclusive)✅  (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ạyTrung bìnhChậmRất chậm

Quy trình thực hiện REINDEX:

text
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+):

sql
-- 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ụ:

sql
-- 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ệnhLock bảngTrả space OSGiảm bloatCập nhật thống kêDowntimeTần suất dùng
VACUUM❌ Không❌ Không⚠️ Một phần❌ KhôngKhôngHàng giờ/ngày
VACUUM FULL✅ Có✅ Có✅ Hoàn toàn❌ KhôngCaoHàng tháng/năm
VACUUM ANALYZE❌ Không❌ Không⚠️ Một phần✅ CóKhôngHàng ngày
VACUUM FULL ANALYZE✅ Có✅ Có✅ Hoàn toàn✅ CóRất caoHiếm (năm)
ANALYZE❌ Không❌ Không❌ Không✅ CóKhôngHàng giờ/ngày
REINDEX⚠️ Tùy loại✅ Có✅ Cho index❌ KhôngTrung bìnhHàng tuần/tháng

🎯 HƯỚNG DẪN LỰA CHỌN

1. Cho bảng OLTP (nhiều UPDATE/DELETE):

sql
-- 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):

sql
-- 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):

sql
-- 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):

sql
-- 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

  1. VACUUM FULL và REINDEX (không CONCURRENTLY) gây downtime

  2. VACUUM thường và ANALYZE có thể chạy online (không ảnh hưởng ứng dụng)

  3. REINDEX CONCURRENTLY tốn CPU và RAM gấp đôi nhưng không lock bảng

  4. VACUUM FULL ANALYZE = VACUUM FULL + ANALYZE (chạy tuần tự)

  5. 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

sql
-- 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

ĐỌC NHIỀU

Trần Văn Bình - Oracle Database Master