นักพัฒนาสาธิตวิธีทำให้ PostgreSQL ช้าลง 42,000 เท่าด้วยการเปลี่ยนแปลงการกำหนดค่าเท่านั้น

ทีมชุมชน BigGo
นักพัฒนาสาธิตวิธีทำให้ PostgreSQL ช้าลง 42,000 เท่าด้วยการเปลี่ยนแปลงการกำหนดค่าเท่านั้น

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

การเรียนรู้ผ่านการวิศวกรรมย้อนกลับ

การทดลองนี้ได้รับการตอบรับอย่างดีจากชุมชนนักพัฒนา ซึ่งเห็นคุณค่าทางการศึกษาของแนวทางย้อนกลับนี้ นักพัฒนาหลายคนสังเกตว่าการเข้าใจสิ่งที่ทำให้ระบบล้มเหลวมักจะให้ข้อมูลเชิงลึกมากกว่าการทำตามคู่มือการปรับแต่งทั่วไป เทคนิคการเรียนรู้จากพื้นที่เชิงลบนี้มีประวัติศาสตร์ที่ใช้มาก่อน - มันถูกใช้ในช่วงสงครามโลกครั้งที่สองเมื่อนักอุตุนิยมวิทยาระบุสภาพอากาศที่เลวร้ายที่สุดเพื่อช่วยผู้บัญชาการภารกิจหลีกเลี่ยงสภาพอากาศเหล่านั้น ซึ่งท้ายที่สุดช่วยชีวิตนักบินได้

แนวทางนี้สะท้อนเทคนิคที่ใช้ในชั้นเรียนการเขียนเชิงสร้างสรรค์ ที่นักเรียนวิเคราะห์การเขียนที่แย่และจงใจเขียนเนื้อหาที่ดีให้แย่ลง แบบฝึกหัดเหล่านี้มักจะให้ความรู้มากกว่าวิธีการแบบดั้งเดิม เพราะมันบังคับให้ผู้เรียนเข้าใจหลักการพื้นฐานแทนที่จะจดจำแนวปracticeที่ดีเท่านั้น

กระบวนการทำลายอย่างเป็นระบบ

วิธีการของนักพัฒนาเกี่ยวข้องกับสี่ด้านหลักของการทำลาย ประการแรก พวกเขาลดบัฟเฟอร์แคชอย่างรุนแรงจาก 128MB ลงเหลือเพียง 8MB บังคับให้ PostgreSQL อ่านจากดิสก์อย่างต่อเนื่องแทนที่จะใช้การแคช RAM ที่มีประสิทธิภาพ สิ่งนี้เพียงอย่างเดียวสร้างการตีประสิทธิภาพอย่างมีนัยสำคัญโดยการกำจัดหนึ่งในข้อได้เปรียบด้านความเร็วหลักของฐานข้อมูล

ต่อมาเป็นการจัดการกระบวนการพื้นหลังอย่างรุนแรง โดยการกำหนดค่า autovacuum ให้ทำงานอย่างต่อเนื่อง - อย่างแท้จริงสิบครั้งต่อวินาทีในทุกตาราง ระบบกลายเป็นที่ถูกครอบงำด้วยงานการบำรุงรักษาที่ไม่จำเป็น การดำเนินการเหล่านี้ใช้ทรัพยากรมหาศาลในขณะที่ทำสิ่งที่มีประโยชน์แทบไม่มีเลย เนื่องจากข้อมูลเปลี่ยนแปลงน้อยมากระหว่างการทำงาน

การโจมตีครั้งที่สามเป้าหมายระบบ Write-Ahead Log (WAL) โดยการบังคับให้มีการตรวจสอบบ่อยและเพิ่มความละเอียดของ WAL ให้สูงสุด นักพัฒนาสร้างสถานการณ์ที่ PostgreSQL ใช้เวลาในการเขียนล็อกมากกว่าการประมวลผลธุรกรรมจริง การตรวจสอบเกิดขึ้นห่างกันเพียง 0.7 มิลลิวินาที บ่อยกว่าการกำหนดค่าที่สมเหตุสมผลใดๆ

Write-Ahead Log (WAL): ระบบที่ PostgreSQL เขียนการเปลี่ยนแปลงลงในไฟล์ล็อกก่อนที่จะนำไปใช้กับฐานข้อมูลจริง เพื่อให้แน่ใจว่าข้อมูลมีความสมบูรณ์ในกรณีที่ระบบขัดข้อง

การเปลี่ยนแปลงการกำหนดค่าหลักที่ทำ:

  • shared_buffers: ลดลงจาก 128MB เหลือ 8MB (ต่อมาเหลือ 1MB)
  • การตั้งค่า Autovacuum: เพิ่มความถี่ให้สูงสุดและลดค่าขีดจำกัดให้น้อยที่สุด
  • การตั้งค่า WAL: บังคับให้มี checkpoint บ่อยครั้งและแสดงรายละเอียดสูงสุด
  • ค่าใช้จ่าย Query planner: ปรับ random_page_cost และ seq_page_cost เพื่อปิดการใช้งาน index
  • การกำหนดค่า I/O: io_method = worker พร้อม io_workers = 1 (คุณสมบัติของ PostgreSQL 16)

การโจมตีครั้งสุดท้าย: I/O แบบเธรดเดียว

การเปลี่ยนแปลงที่ทำลายล้างที่สุดมาจากตัวเลือกการกำหนดค่า I/O ใหม่ของ PostgreSQL 16 โดยการบังคับให้การดำเนินการ input/output ทั้งหมดผ่านเธรดผู้ปฏิบัติงานเพียงตัวเดียว นักพัฒนาสร้างคอขวดขนาดใหญ่ สิ่งนี้ทำให้ระบบหลายคอร์สมัยใหม่กลายเป็นเซิร์ฟเวอร์ฐานข้อมูลแบบเธรดเดียว ทำให้ธุรกรรมต้องเข้าคิวและล้มเหลว

ผลลัพธ์ที่ได้น่าทึ่ง: จากพื้นฐาน 7,582 ธุรกรรมต่อวินาทีลดลงเหลือแทบจะ 0.1 TPS จากการเชื่อมต่อ 100 รายการที่ทำงาน 120 วินาที มีเพียง 11 ธุรกรรมที่เสร็จสิ้นสำเร็จ ส่วนที่เหลือล้มเหลวเนื่องจากข้อผิดพลาดหน่วยความจำเต็มหรือหมดเวลา

ผลลัพธ์การลดประสิทธิภาพ:

  • ค่าพื้นฐาน: 7,582 TPS (ธุรกรรมต่อวินาที)
  • หลังจากลด buffer cache: ความเร็วประมาณ 1/60 ของความเร็วเดิม
  • หลังจากปรับแต่ง autovacuum: 293 TPS (ประมาณ 1/700 ของความเร็วเดิม)
  • หลังจากเปลี่ยนการกำหนดค่า WAL: TPS ลงเหลือเลขหลักเดียว
  • หลังจากปรับแต่งค่าใช้จ่าย index: <1 TPS (ช้ากว่าเดิมมากกว่า 7,600 เท่า)
  • ผลลัพธ์สุดท้ายด้วย single-threaded I/O: 0.1 TPS (ช้ากว่าเดิม 42,000 เท่า)

การตอบสนองของชุมชนและการประยุกต์ใช้ในทางปฏิบัติ

ชุมชนนักพัฒนายอมรับแนวทางที่แปลกใหม่นี้ต่อการศึกษาฐานข้อมูล หลายคนรับรู้ว่าการทำลายระบบโดยเจตนาให้ข้อมูลเชิงลึกที่มีค่าเกี่ยวกับการทำงานปกติของระบบ บางคนแนะนำว่าสิ่งนี้อาจกลายเป็นวิธีการสอน โดยมีหนังสือที่อุทิศให้กับวิธีการทำให้สิ่งต่างๆ แย่ลงเป็นเส้นทางสู่ความเข้าใจในการปรับปรุง

หากคุณจะเข้าใจการปรับแต่งสิ่งใดสิ่งหนึ่ง ทำไมไม่ลองทำสิ่งตรงกันข้ามก่อนหรือใช้เป็นฉากหลัง?

การทดลองยังเน้นย้ำถึงความเสียหายที่สามารถเกิดขึ้นได้ผ่านการกำหนดค่าเพียงอย่างเดียว โดยไม่ต้องแตะดัชนี ฮาร์ดแวร์ หรือโค้ดแอปพลิเคชัน สิ่งนี้ทำหน้าที่เป็นทั้งคำเตือนเกี่ยวกับพลังของการกำหนดค่าฐานข้อมูลและคู่มือสำหรับสิ่งที่ควรหลีกเลี่ยงในสภาพแวดล้อมการผลิต

แบบฝึกหัดแสดงให้เห็นว่าการเข้าใจขอบเขตของระบบและโหมดความล้มเหลวสามารถมีค่าเท่ากับการรู้เทคนิคการปรับแต่ง สำหรับผู้ดูแลฐานข้อมูลและนักพัฒนา การเห็นจุดแตกหักของ PostgreSQL ให้บริบทที่สำคัญสำหรับการตัดสินใจปรับแต่งอย่างมีข้อมูลในสถานการณ์จริง

อ้างอิง: Making Postgres 42,000x slower because I am unemployed