การดำเนินการสูญญากาศ / autovacuum ใช้เวลาเท่าไหร่


18

ฉันจัดการฐานข้อมูลขนาดใหญ่ (หลายร้อยกิ๊ก) ที่มีตารางที่มีบทบาทหลายอย่างบางคนเก็บบันทึกนับล้าน บางตารางจะได้รับการแทรกและลบจำนวนมากเท่านั้นการเพิ่มจำนวนน้อยและการปรับปรุงจำนวนมาก

ฐานข้อมูลทำงานบน PostgreSQL 8.4 บนระบบ Debian 6.0 amd64 พร้อม RAM ขนาด 16 กิกะไบต์

บางครั้งคำถามนั้นเป็นกระบวนการอัตโนมัติในตารางใช้เวลานานมาก (วัน) ในการดำเนินการให้เสร็จสมบูรณ์ ฉันต้องการที่จะบอกอย่างคร่าวๆว่าต้องใช้เวลานานเท่าไรในการสั่งการสูญญากาศโดยเฉพาะเพื่อให้สามารถตัดสินใจได้ว่าจะยกเลิกหรือไม่ นอกจากนี้หากมีตัวบ่งชี้ความคืบหน้าสำหรับการดำเนินการสูญญากาศ postgres มันจะมีประโยชน์จริงๆ

แก้ไข:

ฉันไม่ได้มองหาวิธีแก้ปัญหากระสุน เพียงแค่คำแนะนำคร่าวๆเกี่ยวกับจำนวนของ tuples ที่ตายแล้วหรือไบต์ I / O ที่จำเป็นก็เพียงพอที่จะตัดสินใจได้ มันน่ารำคาญจริง ๆ ที่ไม่มีเงื่อนงำเมื่อVACUUMจะเสร็จสิ้นอะไรก็ตาม

ฉันเคยเห็นว่าpg_catalog.pg_stat_all_tablesมีคอลัมน์สำหรับจำนวน tuples ที่ตายแล้ว ดังนั้นจึงเป็นไปได้ที่จะมีการประมาณค่าแม้ว่ามันจะหมายถึงสิ่งที่มีANALYZEอยู่ในตารางก่อนหน้า บนมืออื่น ๆ , autovacuum_vacuum_thresholdและautovacuum_vacuum_scale_factorการตั้งค่าเพียงอย่างเดียวพิสูจน์ว่า postgres ตัวเองรู้ว่าบางสิ่งบางอย่างเกี่ยวกับจำนวนของการเปลี่ยนแปลงบนโต๊ะและอาจทำให้มันอยู่ในมือของ DBA เกินไป

ฉันไม่แน่ใจว่าแบบสอบถามใดที่จะเรียกใช้เพราะเมื่อฉันเรียกใช้VACUUM VERBOSEฉันเห็นว่าไม่เพียง แต่ตารางเท่านั้น แต่ดัชนีของพวกเขากำลังถูกประมวลผลด้วย

คำตอบ:


34

ใน PostgreSQL ของฉัน (8.3) ฉันใช้เคล็ดลับนี้:

  1. ฉันได้ขนาดดิสก์ของตารางโดยใช้pg_total_relation_size()- ซึ่งรวมถึงดัชนีและขนาด TOAST ซึ่งเป็นVACUUMกระบวนการอะไร นี้ทำให้ผมคิดว่ากี่ไบต์ที่VACUUMมีการอ่าน
  2. ฉันวิ่งVACUUMบนโต๊ะ
  3. ผมหาpidของVACUUMกระบวนการ (ในpg_catalog.pg_stat_activity)
  4. ใน Linux shell ฉันเรียกใช้while true; do cat /proc/123/io | grep read_bytes; sleep 60; done(ซึ่ง123เป็น pid) - มันแสดงให้ฉันไบต์อ่านโดยกระบวนการจากดิสก์จนถึง

นี้ทำให้ผมคิดที่หยาบกับวิธีการหลายไบต์มีการประมวลผล (อ่าน) VACUUMทุกนาทีโดย ฉันคิดว่าVACUUMต้องอ่านทั้งตาราง (รวมถึงดัชนีและ TOAST) ซึ่งมีขนาดดิสก์ที่ฉันรู้จากขั้นตอนที่ 1

ฉันคิดว่าตารางมีขนาดใหญ่พอที่จะให้หน้าส่วนใหญ่ของมันต้องอ่านจากดิสก์ (ไม่มีอยู่ในหน่วยความจำที่แชร์ของ Postgres) ดังนั้นread_bytesฟิลด์จึงดีพอที่จะใช้เป็นตัวนับความคืบหน้า

ทุกครั้งที่ฉันทำสิ่งนี้จำนวนไบต์ทั้งหมดที่อ่านโดยกระบวนการไม่เกิน 5% จากขนาดความสัมพันธ์ทั้งหมดดังนั้นฉันคิดว่าวิธีการนี้อาจดีพอสำหรับคุณ


น่ารังเกียจ :) สิ่งนี้ใช้ได้กับรุ่นที่ใหม่กว่าด้วยหรือไม่ และที่สำคัญกว่าสำหรับ autovacuum
dezso

ฉันไม่ได้ลองสำหรับรุ่นที่ใหม่กว่า ควรใช้งานได้VACUUM FULLตั้งแต่ 9.0+ ขึ้นไปเนื่องจากจะเขียนตารางใหม่ทั้งหมด มันควรจะทำงานเป็นปกติVACUUMด้วย แต่ฉันยังไม่ได้ทดสอบ เพราะautovacuumมันจะใช้ได้ถ้าคุณสามารถจับกระบวนการผู้ทำงานอัตโนมัติในตารางที่กำหนด แต่ฉันไม่รู้ว่าจะทำสิ่งนี้ได้อย่างไร
Roman Hocke

คุณมีข้อเสนอแนะเกี่ยวกับวิธีการทำสิ่งนี้ด้วย RDS หรือไม่? โดยธรรมชาติแล้วเราไม่สามารถเข้าถึงเชลล์ลินุกซ์เมื่อใช้ RDS แต่เราก็อยากที่จะประเมินสิ่งนี้เช่นกัน
jwg2s

@ jwg2s คุณหมายถึงอะไรโดย "RDS" โปรด? บริการฐานข้อมูลของ Amazon ถ้าเป็นเช่นนั้นฉันโชคไม่ดีที่ไม่คุ้นเคย :-( บางทีการสนับสนุนของพวกเขาอาจช่วยได้
Roman Hocke

1
ดูเหมือนว่าจะทำงานได้ดีกับ PG 10 ที่มีสูญญากาศเต็มเช่นกัน
DylanYoung

9

มันยากที่จะตัดสิน คุณสามารถปรับแต่งระบบตอบโต้อัตโนมัติเพื่อให้มีความก้าวร้าวมากกว่าหรือเบากว่า แต่เมื่อตั้งค่าเป็นอ่อนและมันล้าหลังและโหลดฐาน I / O สูงเกินไปก็สามารถเกิดขึ้นได้ว่ามันไม่เคยถึงสภาวะสูญญากาศที่เหมาะสม - จากนั้นคุณจะเห็นกระบวนการทำงานและทำงานและทำงาน นอกจากนี้ภายหลังรุ่น PostreSQL มีการปรับปรุงความสามารถในการทำ autovacuum ให้ดีขึ้นมากเพียงอย่างเดียวนี้อาจเพียงพอที่จะย้ายไปยังหนึ่งในนั้น (ควรเป็น 9.2 เป็นรุ่นล่าสุด)

แถบความคืบหน้าเป็นความคิดที่ดี แต่ฉันคิดว่ามันไม่ง่ายเลยที่จะใช้งานอย่างมีความหมาย เมื่อคุณมีการโหลดอย่างต่อเนื่องในตารางของคุณมันเป็นไปได้ค่อนข้างที่ความคืบหน้าจะย้อนกลับ (ฉันหมายความว่าจำนวนแถว / จำนวนแถวที่ตายแล้วเพิ่มขึ้นแทนที่จะลดลง) - แล้วคุณจะสรุปอะไร?


2
ฉันชอบที่จะเห็นตัวบ่งชี้ความคืบหน้าบางอย่างแม้ว่ามันจะย้อนกลับแทนที่จะเป็นอะไรก็ตาม
zaadeh

3
VACUUM ANALYZE VERBOSEอย่างน้อยพิมพ์กิจกรรมบางอย่างไปยังคอนโซลเช่นเดียวกับที่ทำ มันจะเป็นการดีกว่าถ้าคุณจ้องมองที่พรอมต์คงที่โดยสงสัยว่ามีบางอย่างติดขัดอยู่หลายชั่วโมง
ชื่อปลอม

คำถามถามเกี่ยวกับ "สูญญากาศ / autovacuum" ด้านบนมีประโยชน์สำหรับVACUUMไม่ได้เป็นระบบอัตโนมัติ แต่ก็ยังมีบางสิ่ง
ชื่อปลอม

@FakeName เอ๊ะฉันอ่านคำถามผิดพลาด - พลาดส่วนสุญญากาศแบบแมนนวล ขออภัยฉันลบความคิดเห็นของฉัน
dezso

3

ในการผลิตของเราหนึ่งในตารางที่ใหญ่ที่สุดมีบันทึกนี้:

pages: 0 removed, 1801722 remain
tuples: 238912 removed, 42582083 remain, 1396 are dead but not yet removable
buffer usage: 9477565 hits, 3834218 misses, 2220101 dirtied
avg read rate: 2.976 MB/s, avg write rate: 1.723 MB/s
system usage: CPU 68.47s/177.49u sec elapsed 10065.08 sec

นี่คือการใช้ทรัพยากรที่เลวร้ายที่สุดตารางอื่น ๆ ทั้งหมดใช้เวลาน้อยกว่า 2 วินาที

หากต้องการดูบันทึกประเภทนี้คุณควรดำเนินการสิ่งนี้:

alter system set log_autovacuum_min_duration TO 5; 

(เป็นเวลา 5 มิลลิวินาที) ให้โหลดไฟล์กำหนดค่าอีกครั้ง


3

ฉันพบว่าโพสต์นี้และโพสต์นี้มีประโยชน์ แต่ก็เหมือนกับคนอื่น ๆ ที่กล่าวถึงมันอาจเป็นเรื่องยากที่จะคำนวณความคืบหน้าโดยรวมของสุญญากาศเนื่องจากกระบวนการเกี่ยวข้องกับการดำเนินการแยกกันสองสามครั้ง

ฉันใช้แบบสอบถามนี้เพื่อตรวจสอบความคืบหน้าของการสแกนตารางของสุญญากาศซึ่งดูเหมือนว่าจะเป็นงานชิ้นใหญ่:

SELECT heap_blks_scanned/cast(heap_blks_total as numeric)*100 as heap_blks_percent, progress.*, activity.query
FROM pg_stat_progress_vacuum AS progress
INNER JOIN pg_stat_activity AS activity ON activity.pid = progress.pid;

อย่างไรก็ตามสิ่งนี้จะไม่รวมการสแกนดัชนีซึ่งจะเกิดขึ้นหลังจากนั้นและอาจใช้เวลานานหากไม่นานหากคุณมีดัชนีจำนวนมาก น่าเสียดายที่ฉันไม่สามารถตรวจสอบการสแกนดัชนี / ดูดฝุ่นได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.