Làm thế nào bạn sẽ kiểm tra xem cá thể DB postgresql của bạn cần thêm bộ nhớ RAM để xử lý dữ liệu làm việc hiện tại của họ không?
Làm thế nào bạn sẽ kiểm tra xem cá thể DB postgresql của bạn cần thêm bộ nhớ RAM để xử lý dữ liệu làm việc hiện tại của họ không?
Câu trả lời:
Nếu tất cả những gì bạn có trên Linux, tổng RAM vật lý của bạn phải lớn hơn kích thước cơ sở dữ liệu của bạn trên đĩa để giảm thiểu I / O. Cuối cùng, toàn bộ cơ sở dữ liệu sẽ nằm trong bộ đệm đọc hệ điều hành và I / O sẽ bị giới hạn trong việc cam kết thay đổi đối với đĩa. Tôi thích tìm kích thước DB bằng cách chạy "du -shc $ PGDATA / cơ sở" - phương pháp đó tổng hợp tất cả các cơ sở dữ liệu thành một số duy nhất. Miễn là bạn lớn hơn thế, nó sẽ ổn thôi.
Ngoài ra, bạn có thể xem tỷ lệ truy cập bộ đệm của heap và tìm nạp khối chỉ mục. Chúng đo tỷ lệ số lần truy cập vào bộ đệm được chia sẻ của PostgreQuery. Các con số có thể gây hiểu nhầm đôi chút - mặc dù có thể là một lỗi trong bộ đệm bộ đệm được chia sẻ, nó vẫn có thể là một điểm nhấn trong bộ đệm đọc hệ điều hành. Tuy nhiên, các lần truy cập trong bộ đệm được chia sẻ vẫn ít tốn kém hơn so với các lần truy cập trong bộ đệm đọc hệ điều hành (lần lượt, ít tốn kém hơn bởi một vài đơn đặt hàng lớn hơn so với việc phải quay lại đĩa).
Để xem tỷ lệ trúng bộ đệm được chia sẻ, tôi sử dụng truy vấn này:
SELECT relname, heap_blks_read, heap_blks_hit,
round(heap_blks_hit::numeric/(heap_blks_hit + heap_blks_read),3)
FROM pg_statio_user_tables
WHERE heap_blks_read > 0
ORDER BY 4
LIMIT 25;
Điều này cung cấp cho bạn 25 tội phạm tồi tệ nhất trong đó bộ đệm bộ đệm bị bỏ qua cho tất cả các bảng trong đó ít nhất một khối phải được tìm nạp từ "đĩa" (một lần nữa, có thể là bộ đệm đọc hệ điều hành hoặc I / O trên đĩa thực tế). Bạn có thể tăng giá trị trong mệnh đề WHERE hoặc thêm một điều kiện khác cho heap_blks_hit để lọc ra các bảng ít được sử dụng.
Truy vấn cơ bản tương tự có thể được sử dụng để kiểm tra tỷ lệ trúng tổng chỉ mục trên mỗi bảng bằng cách thay thế toàn bộ chuỗi "heap" bằng "idx". Hãy xem pg_statio_user_indexes để phân tích theo chỉ số.
Lưu ý nhanh về bộ đệm được chia sẻ: một nguyên tắc tốt cho việc này trong Linux là đặt tham số cấu hình shared_buffers thành 1/4 RAM, nhưng không quá 8GB. Đây không phải là một quy tắc khó và nhanh, mà là một điểm khởi đầu tốt để điều chỉnh máy chủ. Nếu cơ sở dữ liệu của bạn chỉ có 4GB và bạn có máy chủ 32 GB, bộ đệm chia sẻ 8GB thực sự quá mức cần thiết và bạn có thể đặt cài đặt này thành 5 hoặc 6 GB và vẫn có thể phát triển trong tương lai.
Tôi đã tạo SQL này để hiển thị tỷ lệ bảng so với đĩa:
-- perform a "select pg_stat_reset();" when you want to reset counter statistics
with
all_tables as
(
SELECT *
FROM (
SELECT 'all'::text as table_name,
sum( (coalesce(heap_blks_read,0) + coalesce(idx_blks_read,0) + coalesce(toast_blks_read,0) + coalesce(tidx_blks_read,0)) ) as from_disk,
sum( (coalesce(heap_blks_hit,0) + coalesce(idx_blks_hit,0) + coalesce(toast_blks_hit,0) + coalesce(tidx_blks_hit,0)) ) as from_cache
FROM pg_statio_all_tables --> change to pg_statio_USER_tables if you want to check only user tables (excluding postgres's own tables)
) a
WHERE (from_disk + from_cache) > 0 -- discard tables without hits
),
tables as
(
SELECT *
FROM (
SELECT relname as table_name,
( (coalesce(heap_blks_read,0) + coalesce(idx_blks_read,0) + coalesce(toast_blks_read,0) + coalesce(tidx_blks_read,0)) ) as from_disk,
( (coalesce(heap_blks_hit,0) + coalesce(idx_blks_hit,0) + coalesce(toast_blks_hit,0) + coalesce(tidx_blks_hit,0)) ) as from_cache
FROM pg_statio_all_tables --> change to pg_statio_USER_tables if you want to check only user tables (excluding postgres's own tables)
) a
WHERE (from_disk + from_cache) > 0 -- discard tables without hits
)
SELECT table_name as "table name",
from_disk as "disk hits",
round((from_disk::numeric / (from_disk + from_cache)::numeric)*100.0,2) as "% disk hits",
round((from_cache::numeric / (from_disk + from_cache)::numeric)*100.0,2) as "% cache hits",
(from_disk + from_cache) as "total hits"
FROM (SELECT * FROM all_tables UNION ALL SELECT * FROM tables) a
ORDER BY (case when table_name = 'all' then 0 else 1 end), from_disk desc