ฉันจะตรวจสอบว่า DB ของฉันต้องการ RAM เพิ่มขึ้นได้อย่างไร


11

คุณจะตรวจสอบว่าอินสแตนซ์ฐานข้อมูล postgresql ของคุณต้องการหน่วยความจำ RAM เพิ่มเติมเพื่อจัดการกับข้อมูลการทำงานปัจจุบันได้อย่างไร


8
ไม่จำเป็นต้องตรวจสอบคุณต้องการ RAM เพิ่มขึ้นเสมอ :)
อเล็กซ์ Howansky

1
ไม่ใช่คำถามการเขียนโปรแกรมฉันลงคะแนนเพื่อย้ายไปยัง ServerFault
GManNickG

1
ฉันไม่ใช่ DBA แต่ฉันเริ่มต้นด้วยการดูข้อความค้นหาทั่วไปใด ๆ ที่อยู่บนขอบของการเข้าร่วมแฮชแทนที่จะรวมเข้าด้วยกันแบบวนซ้ำ มีการปรับแต่งการตั้งค่า db บางอย่างที่คุณสามารถทำได้ซึ่งอาจส่งผลต่อจำนวนหน่วยความจำที่พร้อมใช้งานสำหรับการสืบค้นใด ๆ โดยเฉพาะ [ตรวจสอบเอกสารหรืออีเมลที่รายชื่อผู้รับจดหมายเป็นข้อเสนอแนะของฉัน] นอกจากนี้ยังมีประโยชน์ที่จะดูว่าคุณมี RAM เพียงพอที่จะใช้แคชกับตารางที่ใช้กันทั่วไปหรือไม่ แต่ท้ายที่สุดถ้าฐานข้อมูลทั้งหมดของคุณไม่เหมาะกับ RAM คุณสามารถใช้งานได้มากกว่า :)

คำตอบ:


14

หากทั้งหมดที่คุณใช้บน Linux RAM จริงทั้งหมดของคุณควรใหญ่กว่าขนาดฐานข้อมูลของคุณบนดิสก์เพื่อลด I / O ให้น้อยที่สุด ในที่สุดฐานข้อมูลทั้งหมดจะอยู่ในแคชการอ่านของระบบปฏิบัติการและ I / O จะถูก จำกัด ให้กระทำการเปลี่ยนแปลงดิสก์ ฉันต้องการค้นหาขนาดฐานข้อมูลโดยเรียกใช้ "du -shc $ PGDATA / base" - วิธีการนี้จะรวมฐานข้อมูลทั้งหมดเป็นตัวเลขเดียว ตราบใดที่คุณมีขนาดใหญ่กว่านั้นก็ควรจะดี

นอกจากนี้คุณสามารถดูอัตราการเข้าชมแคชของการดึงข้อมูลฮีปและการบล็อกดัชนี สิ่งเหล่านี้วัดอัตราความนิยมในบัฟเฟอร์ที่แชร์ของ PostgreSQL ตัวเลขอาจทำให้เข้าใจผิดเล็กน้อย - แม้ว่าอาจจะพลาดแคชที่ใช้ร่วมกันไปแล้ว แต่ก็อาจยังเป็นที่นิยมในการอ่านแคชของระบบปฏิบัติการ ยังคงความนิยมในบัฟเฟอร์ที่ใช้ร่วมกันยังคงมีราคาไม่แพงกว่าการอ่านแคชในระบบปฏิบัติการ (ซึ่งในทางกลับกันมีราคาที่ถูกกว่าโดยคำสั่งที่มีขนาดเล็กกว่าการกลับไปที่ดิสก์)

เพื่อที่จะดูอัตราการเข้าชมบัฟเฟอร์ที่แชร์ฉันใช้แบบสอบถามนี้:

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เป็น 1/4 ของ RAM แต่ไม่เกิน 8GB นี่ไม่ใช่กฎที่ยากและรวดเร็ว แต่เป็นจุดเริ่มต้นที่ดีสำหรับการปรับแต่งเซิร์ฟเวอร์ หากฐานข้อมูลของคุณมีเพียง 4GB และคุณมีเซิร์ฟเวอร์ 32GB แล้วบัฟเฟอร์ที่ใช้ร่วมกัน 8GB นั้นมากเกินไปและคุณควรตั้งค่านี้เป็น 5 หรือ 6 GB และยังมีพื้นที่สำหรับการเติบโตในอนาคต


9

ฉันทำ SQL นี้เพื่อแสดงตาราง vs อัตราส่วนการพบดิสก์:

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

ป้อนคำอธิบายรูปภาพที่นี่


1

มันใช้งานได้ดังที่ได้กล่าวไว้ใน Heroku doc:

SELECT
    'cache hit rate' AS name,
     sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) AS ratio
FROM pg_statio_user_tables;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.