013: Thực hành Vacuum với PostgreSQL

Bài viết nằm trong series Performance optimization với PostgreSQL. Phần trước đã tìm hiểu về một mớ lý thuyết của Vacuum, phần này sẽ xem qua về reindex và tập trung vào practice với vacuum để kiểm nghiệm thực tế thế nào. Let’s begin. 1) Reindex REINDEX, nghe phát hiểu luôn ý nghĩa, đó là

Bài viết nằm trong series Performance optimization với PostgreSQL.

Phần trước đã tìm hiểu về một mớ lý thuyết của Vacuum, phần này sẽ xem qua về reindex và tập trung vào practice với vacuum để kiểm nghiệm thực tế thế nào. Let’s begin.

1) Reindex

REINDEX, nghe phát hiểu luôn ý nghĩa, đó là thực hiện build lại index cho index/table/database…

REINDEX INDEX index_name;

REINDEX TABLE table_name;

REINDEX SCHEMA schema_name;

REINDEX DATABASE database_name;

Về cơ bản, reindex build lại index table từ đầu, giống kết quả của việc dropcreate index. Tuy nhiên cơ chế locking giữa hai cách thực thi có đôi chút khác biệt.

Trước khi tìm hiểu kĩ hơn, cùng trả lời câu hỏi vì sao cần reindex. Có 3 lý do chính ta cần thực hiện reindex:

  • Thứ nhất, không có gì là hoàn hảo. Index table hoàn toàn có khả năng bị lỗi do hardware failure hoặc… PostgreSQL bugs 😂. Reindex như một cách recovery hệ thống trong trường hợp này.
  • Thứ hai, index cũng là table, cũng sẽ có dead tuple. Nếu quá nhiều dead tuple thì quá trình scan cũng ảnh hưởng đến performance và tốn disk space.
  • Cuối cùng, khi thực hiện alter index, ví dụ từ một column thành hai column.

Vậy sự khác biệt giữa reindexdrop & create index là gì?

Với reindex:

  • Hệ thống sẽ tạo lại index table sử dụng shared lock. Có thể concurrent read nhưng không thể concurrent write.

Với drop & create:

  • DROP thực hiện exclusive lock trên table, đảm bảo không thể concurrent read/write tránh inconsistence data.
  • Sau đó CREATE thực hiện shared lock trên table, đảm bảo không có concurrent write để thực hiện build index table.

Như vậy, reindex đâu đó sẽ cho performance tốt hơn so với việc xóa đi và tạo lại, tuy nhiên cost cho nó khá lớn. Do vậy chỉ khi không nghĩ ra cách nào khác thì thực hiện reindex.

2) Practice

Sử dụng data từ bài trước.

Trước tiên cần install extension pgstattuple để theo dõi các thông số liên quan đến dead tuple:

CREATE EXTENSION pgstattuple;

Kiểm tra thông tin tuple của table ENGINEER:

SELECT*FROM pgstattuple('engineer');
table_len tuple_count dead_tuple_count free_space free_percent
9150464 100000 0 44572 0.49

Còn một vài column khác tuy nhiên chỉ cần quan tâm đến những column sau:

  • table_len: dung lượng table.
  • tuple_count: tổng số lượng record hiện có trong table, bằng số lượng record insert vào table.
  • dead_tuple_count: số lượng dead tuple. Do chưa thực hiện DELTE/UPDATE nên giá trị = 0.
  • free_space: dung lượng còn trống trong các page của table.
  • free_percent: tỉ lệ free_space/table_len.

Tiến hành delete 100 record trong table ENGINEER:

DELETEFROM engineer WHERE id IN(SELECT id FROM engineer ORDERBY id LIMIT100);

Query lại statistic của table ENGINEER:

SELECT*FROM pgstattuple('engineer');
table_len tuple_count dead_tuple_count free_space free_percent
9150464 99900 100 44572 0.49

Như vậy đã có 100 dead tuple, vẫn nằm trong table. Free space không có gì thay đổi.

Thực hiện vacuum và kiểm tra lại xem thế nào:

VACUUM engineer;SELECT*FROM pgstattuple('engineer');
table_len tuple_count dead_tuple_count free_space free_percent
9150464 99900 0 53168 0.58

Ta biết rằng vacuum không thực sự giải phóng disk space, mà chỉ clear dead tuple, dự trữ space cho future tuple. Như vậy, table len không đổi, dead tuple clear về 0 và free space đã tăng.

Nếu lý thuyết đúng như trên, khi thực hiện insert thêm record thì expect table len không đổi, tuple count tăng và free space giảm:

INSERTINTO engineer(first_name, last_name, gender, country_id, created)VALUES('Vacuum','Test',1,1,CURRENT_TIMESTAMP);SELECT*FROM pgstattuple('engineer');
table_len tuple_count dead_tuple_count free_space free_percent
9150464 99901 0 53104 0.58

Cuối cùng, tiến hành vacuum full để giải phóng disk space. Expect table len giảm do đã xóa 100 records, free space cũng giảm xuống xung quanh giá trị khi insert ban đầu là 44572:

VACUUM FULL engineer;SELECT*FROM pgstattuple('engineer');
table_len tuple_count dead_tuple_count free_space free_percent
9142272 99901 0 45344 0.5

3) Khi nào nên sử dụng vacuum full?

Câu trả lời sẽ dựa trên mục đích của câu lệnh và mục đích mà bạn cần.

Cả 2 đều giải phóng unused disk space, giảm thiểu phân mảnh, giúp quá trình scan table/index table mượt mà hơn, đem lại performance tốt hơn. Tuy nhiên cost để xử lý là khá cao.

Do vậy, có một vài lưu ý khi quyết định sử dụng hay không:

  • Vacuum full với table có số lượng record nhỏ không đem lại nhiều hiệu quả.
  • Do vậy, chỉ thực sự cần thiết khi table có tần suất UPDATE/DELETE cực nhiều và số lượng record cực lớn. Mặc định PostgreSQL đã enable autovacuum nên với những table bình thường không cần quá lo lắng.
  • Đồng nghĩ với việc đó, quá trình vacuum full có thể diễn ra trong một khoảng thời gian dài, ảnh hưởng đến business. Do vậy nếu có thực hiện thì nên lựa lúc nửa đêm hoặc giờ thấp điểm.
  • Đừng sử dụng quá thường xuyên, nó không đem lại hiệu quả nhiều. Kinh nghiệm thực tế once per month là đủ. Lưu ý rằng đó là những table có tần suất modify data cực lớn mới cần sử dụng.
  • Cố gắng tránh vacuum full. Thay vì thế hãy tunning các thông số autovacuum và thực hiện vacuum là đủ.
  • Chỉ nên dùng khi.. hết cách. Hoặc bạn muốn nghịch hệ thống.. cũng không có vấn đề gì với mình 😂.

Reference

Reference in series https://viblo.asia/s/performance-optimization-voi-postgresql-OVlYq8oal8W

© Dat Bui

Nguồn: viblo.asia

Bài viết liên quan

WebP là gì? Hướng dẫn cách để chuyển hình ảnh jpg, png qua webp

WebP là gì? WebP là một định dạng ảnh hiện đại, được phát triển bởi Google

Điểm khác biệt giữa IPv4 và IPv6 là gì?

IPv4 và IPv6 là hai phiên bản của hệ thống địa chỉ Giao thức Internet (IP). IP l

Check nameservers của tên miền xem website trỏ đúng chưa

Tìm hiểu cách check nameservers của tên miền để xác định tên miền đó đang dùn

Mình đang dùng Google Domains để check tên miền hàng ngày

Từ khi thông báo dịch vụ Google Domains bỏ mác Beta, mình mới để ý và bắt đầ