postgresql DB 인스턴스에 현재 작업 데이터를 처리하기 위해 더 많은 RAM 메모리가 필요한지 어떻게 확인 하시겠습니까?
postgresql DB 인스턴스에 현재 작업 데이터를 처리하기 위해 더 많은 RAM 메모리가 필요한지 어떻게 확인 하시겠습니까?
답변:
Linux에있는 모든 경우 I / O를 최소화하려면 총 실제 RAM이 디스크의 데이터베이스 크기보다 커야합니다. 결국 전체 데이터베이스는 OS 읽기 캐시에 있으며 I / O는 디스크 변경 사항을 커밋하는 것으로 제한됩니다. "du -shc $ PGDATA / base"를 실행하여 DB 크기를 찾는 것이 좋습니다.이 방법은 모든 데이터베이스를 단일 숫자로 집계합니다. 그것보다 크면 괜찮을 것입니다.
또한 힙 및 인덱스 블록 페치의 캐시 적중률을 확인할 수 있습니다. PostgreSQL의 공유 버퍼에 대한 적중률을 측정합니다. 공유 버퍼 캐시에서 누락되었을 수 있지만 OS 읽기 캐시에서 여전히 적중 할 수 있지만 숫자는 약간 오해의 소지가 있습니다. 그럼에도 불구하고 공유 버퍼의 적중은 OS 읽기 캐시의 적중보다 여전히 저렴합니다 (다시 디스크로 돌아가는 것보다 몇 배 정도 저렴합니다).
공유 버퍼 적중률을 확인하기 위해이 쿼리를 사용합니다.
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;
따라서 "디스크"에서 하나 이상의 블록을 가져와야하는 모든 테이블에 대해 버퍼 캐시를 놓친 상위 25 개의 최악의 위반자 (다시 말하면 OS 읽기 캐시 또는 실제 디스크 I / O 일 수 있음)가 발생합니다. WHERE 절의 값을 늘리거나 heap_blks_hit에 다른 조건을 추가하여 거의 사용하지 않는 테이블을 필터링 할 수 있습니다.
동일한 기본 쿼리를 사용하여 문자열 "heap"을 "idx"로 전역 적으로 대체하여 테이블 당 총 인덱스 적중률을 확인할 수 있습니다. 인덱스 별 분석을 보려면 pg_statio_user_indexes를 살펴보십시오.
공유 버퍼에 대한 간단한 참고 사항 : Linux에서이를위한 좋은 방법은 구성 매개 변수 shared_buffers 를 RAM의 1/4 로 설정 하지만 8GB를 넘지 않는 것입니다. 이것은 어렵고 빠른 규칙이 아니라 서버 튜닝을위한 좋은 출발점입니다. 데이터베이스가 4GB에 불과하고 32GB 서버가있는 경우 실제로 8GB의 공유 버퍼는 과도하게 사용되며이를 5 또는 6GB로 설정할 수 있으며 향후 성장의 여지가 남아 있습니다.
테이블 대 디스크 적중률을 보여주기 위해이 SQL을 만들었습니다.
-- 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