9 คะแนน โดย GN⁺ 2025-07-28 | 2 ความคิดเห็น | แชร์ทาง WhatsApp
  • แนะนำแนวทางการทดลองเกี่ยวกับ ชุดพารามิเตอร์ที่สามารถทำให้ประสิทธิภาพของ Postgres ลดลงอย่างรุนแรง
  • โดยทั่วไปคือการจูนย้อนทางของ แคช, อินเด็กซ์, WAL, I/O และองค์ประกอบอื่น ๆ
  • ปรับ shared_buffers, autovacuum และออปชันที่เกี่ยวข้องกับ WAL แบบสุดขั้ว จนทำให้ TPS ลดลง 42,000 เท่า
  • นำฟีเจอร์ใหม่อย่าง io_method และ io_workers ใน Postgres 18/19 มาใช้เพื่อทดลองบังคับข้อจำกัด I/O แบบเธรดเดียว
  • ผลการทดลองพิสูจน์ว่า เพียงแค่ไฟล์ตั้งค่า Postgres ก็สามารถทำให้ประสิทธิภาพลดลงอย่างสุดขั้วได้

ภาพรวม

บทความนี้เป็นการทดลองที่ทำตรงข้ามกับการจูน Postgres เพื่อให้เร็วขึ้น โดยตั้งเป้าเพียงอย่างเดียวคือ ทำให้ช้าลง ผ่านการเปลี่ยนค่า config ของ PostgreSQL เท่านั้น เพื่อกดประสิทธิภาพลงให้สุดขีด
การทดสอบอิงกับ TPC-C workload ของ BenchBase (128 คลังสินค้า, 100 คอนเนกชัน, แต่ละคอนเนกชันพยายามทำธุรกรรมได้สูงสุด 10,000 ครั้งต่อวินาที, ใช้ Postgres 19devel รุ่นล่าสุด, Ryzen 7950x, RAM 32GB, SSD 2TB, รัน 120 วินาที)
ที่ค่าเริ่มต้น ประสิทธิภาพอยู่ที่ 7082 TPS และมีการสังเกตทีละขั้นว่าการปรับพารามิเตอร์แต่ละตัวทำให้ช้าลงได้มากแค่ไหน

ลดการแคชอย่างหนัก

  • Postgres ใช้ แคชที่ทรงพลัง (shared_buffers) เพื่อช่วยลด disk I/O
  • เมื่อลด shared_buffers จากค่าเริ่มต้น (10GB) เหลือ 8MB ค่า TPS ลดลงเหลือประมาณ 1/7 (1052 TPS)
  • พบว่า อัตรา cache hit ลดจาก 99.90% เหลือ 70.52% และจำนวน read syscall เพิ่มขึ้นมากกว่า 300 เท่า
  • มีความพยายามลดลงถึง 128kB แต่ Postgres อนุญาตขั้นต่ำเพียงราว 2MB ทำให้ TPS ลดลงต่อเหลือ 485 TPS

เพิ่มงานเบื้องหลัง (จูน autovacuum)

  • ปรับ ค่าเกณฑ์ทั้งหมดที่เกี่ยวข้องกับ autovacuum ให้ต่ำสุด จน vacuum ทำงานแทบทุกครั้งที่มีงาน
    • ชุดค่าเช่น autovacuum_vacuum_insert_threshold=1, autovacuum_naptime=1
    • ทำให้ vacuum วนทำงานแทบทุก 1 วินาที แม้แทบไม่มีงานจริงให้ทำ
  • ระหว่างนี้ยัง ลด maintenance_work_mem เหลือ 128kB และเปิด logging ของ autovacuum ทั้งหมด
  • ผลคือ TPS ลดลงเหลือ 293 (น้อยกว่า 1/20 ของเดิม)
  • ยืนยันผ่าน log แบบเรียลไทม์ของ autovacuum ว่างานเบื้องหลังที่ถี่ผิดปกติคือสาเหตุของประสิทธิภาพที่ลดลง

ทำให้งานเขียน WAL (Write-Ahead Log) แย่ที่สุด

  • ปรับ พารามิเตอร์ที่เกี่ยวข้องกับ WAL ให้แย่ที่สุดทั้งหมด
    • wal_writer_flush_after=0, wal_writer_delay=1, wal_sync_method=open_datasync เป็นต้น
    • บังคับ checkpoint ทุก 30 วินาที และคง min_wal_size/max_wal_size=32MB ให้ต่ำสุด
    • ตั้ง wal_level=logical, wal_log_hints=on เพื่อบันทึกข้อมูลที่ไม่จำเป็นลง WAL เพิ่มเติม
    • เปิดภาระเพิ่มเติมอย่าง track_wal_io_timing, summarize_wal
  • ผลคือ TPS ลดลงเหลือ 98 (น้อยกว่า 1/70 ของเดิม)
  • จาก log พบพฤติกรรมผิดปกติ เช่น checkpoint เกิดซ้ำทุกไม่กี่ร้อย ms

ตัดผลของอินเด็กซ์ออก

  • ตั้งค่าการใช้อินเด็กซ์ให้ถูก คำนวณต้นทุนสูงสุด (random_page_cost=1e300, cpu_index_tuple_cost=1e300) จนเท่ากับปิดการใช้อินเด็กซ์ในทางปฏิบัติ
  • เพิ่ม shared_buffers กลับเป็น 8MB (เพื่อความเสถียร) แล้ว TPS ลดลงเหลือ 0.87 (ช้าลง 7,000 เท่า)

บังคับ I/O แบบเธรดเดียว

  • ใช้ฟีเจอร์ใหม่ของ Postgres 18+
  • ตั้ง io_method=worker, io_workers=1 เพื่อ บังคับให้ I/O ทั้งหมดวิ่งผ่าน worker thread เดียว
  • TPS ลดลงต่อเหลือ 0.016 (ช้าลง 42,000 เท่า)
  • ในการทดลอง 100 คอนเนกชันเป็นเวลา 120 วินาที สำเร็จเพียง 11 ธุรกรรมเท่านั้น

บทสรุปและแนวทางการทำซ้ำ

  • พิสูจน์ว่าเพียงการปรับพารามิเตอร์ 32 รายการ ก็สามารถทำให้ฐานข้อมูล production อยู่ในสภาพเกือบ "เป็นอัมพาต" ได้
  • สามารถเร่งให้ประสิทธิภาพลดลงอย่างรุนแรงได้ด้วยการแตะเพียงค่าใน postgresql.conf
  • ผู้ที่ต้องการทำซ้ำการทดลองควรอ้างอิง BenchBase Postgres, สภาพแวดล้อม TPC-C ที่ระบุไว้ และรายการค่าตั้งค่าทั้งหมด
  • ยังไม่ได้รวมพารามิเตอร์เสริมหรือความพยายามอื่น ๆ ในการทำให้ช้าลงเพิ่มเติม

รายการพารามิเตอร์โดยสรุป

  • shared_buffers = 8MB
  • ค่า thresholds/scale_factor ที่เกี่ยวกับ autovacuum = ปรับต่ำสุดช่วง 0~1
  • ค่าใช้จ่าย, หน่วยความจำ และ log ที่เกี่ยวกับ vacuum: ปรับให้ต่ำสุด/สูงสุดตามกรณี
  • ค่าที่เกี่ยวกับ WAL เช่น sync/flush/log/level: ตั้งให้คงความช้า
  • ค่าอินเด็กซ์ random_page_cost, cpu_index_tuple_cost: ตั้งเป็น 1e300
  • io_method = worker, io_workers = 1
  • รายละเอียดค่าอื่น ๆ ดูจากรายการในเนื้อหา

ปิดท้าย

  • เพียงแค่ไฟล์ postgresql.conf ก็สามารถก่อให้เกิดการลดลงของประสิทธิภาพอย่างหนักได้
  • ในงานจริง ชุดค่านี้มีคุณค่าในฐานะตัวอย่างกลับทางสำหรับการปรับปรุงประสิทธิภาพอย่างมีประสิทธิผล
  • บทความจบลงด้วยการกล่าวถึงการหยุดทดลองเพราะผู้เขียนปวดหลัง

2 ความคิดเห็น

 
GN⁺ 2025-07-28
ความคิดเห็นจาก Hacker News
  • แนะนำแนวทางที่ลืมเรื่องดัชนี หลายตาราง ธุรกรรม ความสัมพันธ์ระหว่างเอนทิตี และความถูกต้องเชิงอ้างอิงไปให้หมด แล้วใช้ข้อมูลทั้งหมดในตารางเดียวเหมือนเวอร์ชันแรก ๆ ของ TRIRIGA ที่ใช้แบบ KVS NoSQL SQL
  • วิธีแบบนี้สนุกมากจนอยากให้มีหนังสือออกมาเป็นซีรีส์ต่อในแนว "ทำให้งานพังยิ่งขึ้นได้อย่างไร" เพราะเราสามารถเรียนรู้แล้วหาวิธีที่ดีกว่าในทางกลับกันได้ ถ้าเป็นสไตล์ O’Reilly ปกก็น่าจะเป็นสัตว์แฟนตาซีวาดแบบกะโหลกกะลา (เช่น ยูนิคอร์นสองหัวที่กำลังคุยผ่าน AirPods โอนเงินให้มิจฉาชีพ ทำ PowerPoint กินไม่ยั้ง และเสพยาไปพร้อมกัน)
    • มีกรณีที่ใช้กลยุทธ์แบบนี้จริงในช่วงสงครามโลกครั้งที่สอง เพื่อช่วยให้นักบินรอดชีวิต นักอุตุนิยมวิทยาจะหาสภาพอากาศที่ทำให้มีผู้เสียชีวิตมากที่สุดก่อน แล้วจึงวางแผนภารกิจให้หลีกเลี่ยงเงื่อนไขเหล่านั้น ลิงก์อ้างอิง Suppose I wanted to kill a lot of pilots
    • ในคลาสเขียนเชิงสร้างสรรค์ก็เคยมีแบบฝึกหัดให้อ่านและวิเคราะห์งานเขียนที่เขียนผิดระหว่างฝึก หรือจงใจเอางานเขียนที่ดีมาเขียนใหม่ให้แย่ลง ซึ่งนั่นเป็นแบบฝึกหัดการเขียนที่ช่วยได้มากที่สุด
    • ดู เว็บไซต์ล้อเลียน ORLYBooks ได้ด้วย
  • คิดว่าน่าจะดีมากถ้ามีแซนด์บ็อกซ์สภาพแวดล้อม production สำหรับทดลองเครื่องมือ observability มีระบบสไตล์ SaaS ขนาดพอดีพร้อมการจำลองการใช้งาน และสแตก postgres/rabbit แบบธรรมดา ๆ เพื่อใช้ทดสอบฝีมือด้านเครื่องมือหรือกลยุทธ์การดีบัก
  • ไอเดียนี้อัจฉริยะมาก ถ้าอยากทำ optimization ให้เก่ง ผมคิดว่าควรเริ่มด้วยการลองทำให้พังในทางตรงข้ามแบบสุด ๆ ก่อน ทั้งเพื่อใช้เป็นจุดตั้งต้นหรือเป็นกลุ่มควบคุม ต้องถามตัวเองด้วยว่ากำลังจัดการฐานข้อมูลหรือระบบอย่างเป็นวิทยาศาสตร์จริง ๆ หรือแค่ทำตาม ๆ กันไปแบบคลุมเครือ
    • ทุกครั้งที่ผมจะใช้บริการคลาวด์ใหม่ ผมก็ทำแบบนั้นเสมอ คือรีบใช้ Series A ให้เต็มที่ก่อน แล้วค่อยไปทำ optimization ค่าใช้จ่ายคลาวด์ทีหลัง
  • หนังสือ The Defence of Duffer's Drift เป็นตัวอย่างยุคแรกของแนวนี้ เรื่องแรกแสดงให้เห็นการใช้ยุทธวิธีระดับหมวดที่ย่ำแย่จนเสียกำลังพลไปเกือบหมด แล้วเรื่องต่อ ๆ มาก็ค่อย ๆ ปรับเงื่อนไขทางยุทธวิธีจนผลลัพธ์ดีขึ้น หนังสือยุทธวิธีสมัยใหม่อย่าง Musicians of Mars 2 ก็ใช้แนวทางเดียวกัน เรื่องแรกของ Team Badger คล้ายกับ Duffer's Drift มาก แต่ปรับตามตำแหน่ง อุปกรณ์ และเทคโนโลยี PDF ที่เกี่ยวข้องดูได้ที่ The Defence of Duffer's Drift และ Musicians of Mars 2 เนื้อหาที่ผู้บังคับบัญชา Team Badger ย้อนทบทวนว่าทำไมถึงแพ้อย่างยับเยิน ทั้งที่มั่นใจและเตรียมตัวมาดี ชวนประทับใจมาก
    • หนังที่อยู่ในอารมณ์คล้ายกันคือ Groundhog Day และโดยเฉพาะ Edge of Tomorrow อีกทั้งยังมีบทความ homage เวอร์ชันสมัยใหม่ในบล็อกทหารอังกฤษที่เพิ่งลงไม่นาน Defence Baltic Bridge Dreams
  • ประเด็นเรื่อง deadlock น่าสนใจดี เลยสงสัยว่ามีส่วนที่พูดถึงการปรับค่า transaction isolation level ด้วยหรือเปล่า
  • ดีใจที่เห็นการพูดถึง B Sanderson
  • ให้ความรู้สึกเหมือน Hyperbole and a Half ผสมกับ db admin อ่านแล้วอารมณ์ดีและได้เรียนรู้อะไรบางอย่างด้วย
  • สไตล์การเขียนและวิธีคลี่ความคิดออกมานั้นยอดเยี่ยมมาก อ่านได้อย่างเพลิดเพลิน
 
sonic0987 2025-07-29

ยอดเยี่ยมมากครับ ชอบแนวทางแบบนี้มาก