เรื่องราวของการลบบันทึก 300 ล้านบันทึกใน MySQL ทางกายภาพ

การแนะนำ

สวัสดี ฉันชื่อ ningenMe นักพัฒนาเว็บ

ดังที่ชื่อเรื่องกล่าวไว้ เรื่องราวของฉันเป็นเรื่องราวของการลบบันทึก 300 ล้านรายการใน MySQL

ฉันเริ่มสนใจสิ่งนี้ ดังนั้นฉันจึงตัดสินใจเตือนความจำ (คำแนะนำ)

หน้าแรก - การแจ้งเตือน

เซิร์ฟเวอร์แบตช์ที่ฉันใช้และบำรุงรักษามีกระบวนการปกติที่รวบรวมข้อมูลของเดือนที่แล้วจาก MySQL วันละครั้ง

โดยปกติแล้วกระบวนการนี้จะเสร็จสิ้นภายในประมาณ 1 ชั่วโมง แต่คราวนี้ไม่เสร็จสิ้นเป็นเวลา 7 หรือ 8 ชั่วโมง และการแจ้งเตือนก็ไม่หยุดแสดงขึ้นมา...

หาเหตุผล

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

hoge_table | 350'000'000 |

350 ล้านบันทึก ดูเหมือนว่าการจัดทำดัชนีจะทำงานได้อย่างถูกต้อง เพียงแต่ช้ามาก

การรวบรวมข้อมูลที่ต้องการต่อเดือนคือประมาณ 12 บันทึก ดูเหมือนว่าคำสั่ง select จะใช้เวลานานและธุรกรรมไม่ได้ถูกดำเนินการเป็นเวลานาน

DB

โดยพื้นฐานแล้วมันคือตารางที่เติบโตขึ้นประมาณ 400 รายการทุกวัน ฐานข้อมูลควรรวบรวมข้อมูลเฉพาะเดือนที่แล้ว ดังนั้นจึงคาดว่าจะทนทานต่อข้อมูลจำนวนเท่านี้ แต่น่าเสียดายที่ไม่รวมการดำเนินการหมุนเวียน

ฐานข้อมูลนี้ไม่ได้รับการพัฒนาโดยฉัน ฉันรับช่วงต่อจากนักพัฒนารายอื่น ดังนั้นจึงยังคงรู้สึกเหมือนเป็นหนี้ทางเทคนิค

มาถึงจุดหนึ่งที่ปริมาณข้อมูลที่แทรกในแต่ละวันมีขนาดใหญ่ขึ้นและในที่สุดก็ถึงขีดจำกัดแล้ว สันนิษฐานว่าเมื่อทำงานกับข้อมูลจำนวนมากจำเป็นต้องแยกข้อมูลเหล่านั้นออกจากกัน แต่น่าเสียดายที่ยังไม่เสร็จสิ้น

แล้วฉันก็ลงมือทำ

การแก้ไข

การลดขนาดของฐานข้อมูลและลดเวลาในการประมวลผลนั้นมีเหตุผลมากกว่าการเปลี่ยนตรรกะเอง

สถานการณ์น่าจะเปลี่ยนไปอย่างมากหากคุณลบบันทึก 300 ล้านรายการ ฉันก็เลยตัดสินใจทำ... เอ๊ะ ฉันคิดว่านี่คงจะได้ผลแน่นอน

การดำเนินการ 1

หลังจากเตรียมการสำรองข้อมูลที่เชื่อถือได้ ในที่สุดฉันก็เริ่มส่งคำขอ

「กำลังส่งคำขอ」

DELETE FROM hoge_table WHERE create_time <= 'YYYY-MM-DD HH:MM:SS';

“…”

“…”

“อืม... ไม่มีคำตอบ บางทีกระบวนการอาจใช้เวลานาน?” — ฉันคิดว่า แต่ในกรณีนี้ ฉันดูที่ Grafana และเห็นว่าโหลดของดิสก์เพิ่มขึ้นอย่างรวดเร็วมาก
“อันตราย” ฉันคิดอีกครั้งและหยุดคำขอทันที

การดำเนินการ 2

หลังจากวิเคราะห์ทุกอย่างแล้ว ฉันพบว่าปริมาณข้อมูลมีขนาดใหญ่เกินกว่าจะลบทุกอย่างได้ในคราวเดียว

ฉันตัดสินใจเขียนสคริปต์ที่สามารถลบบันทึกได้ประมาณ 1 รายการและเปิดใช้งาน

「ฉันใช้สคริปต์」

“ตอนนี้มันจะได้ผลแน่นอน” ฉันคิด

การดำเนินการ 3

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

นี่คือสิ่งที่ฉันตัดสินใจทำ:

คัดลอกตารางและเปลี่ยนชื่อ

จากขั้นตอนที่แล้ว ฉันพบว่าการลบข้อมูลจำนวนมากเช่นนี้จะสร้างภาระงานจำนวนมากพอๆ กัน ดังนั้นฉันจึงตัดสินใจสร้างตารางใหม่ตั้งแต่ต้นโดยใช้การแทรก และย้ายข้อมูลที่ฉันจะลบไปไว้ที่นั่น

| hoge_table     | 350'000'000|
| tmp_hoge_table |  50'000'000|

หากคุณสร้างตารางใหม่ให้มีขนาดเท่ากับด้านบน ความเร็วในการประมวลผลข้อมูลก็ควรจะเร็วขึ้น 1/7 เช่นกัน

หลังจากสร้างตารางและเปลี่ยนชื่อแล้ว ฉันก็เริ่มใช้เป็นตารางหลัก ตอนนี้ถ้าฉันทิ้งตารางด้วยบันทึก 300 ล้านรายการทุกอย่างก็น่าจะเรียบร้อยดี
ฉันพบว่าการตัดทอนหรือปล่อยทำให้เกิดค่าใช้จ่ายน้อยกว่าการลบและตัดสินใจใช้วิธีนี้

การปฏิบัติ

「กำลังส่งคำขอ」

INSERT INTO tmp_hoge_table SELECT FROM hoge_table create_time > 'YYYY-MM-DD HH:MM:SS';

“…”
“…”
“เอม…?”

การดำเนินการ 4

ฉันคิดว่าแนวคิดก่อนหน้านี้น่าจะได้ผล แต่หลังจากส่งคำขอแทรกแล้ว มีข้อผิดพลาดหลายอย่างปรากฏขึ้น MySQL ไม่ยอมให้อภัย

ฉันเหนื่อยมากจนเริ่มคิดว่าไม่อยากทำแบบนี้อีกแล้ว

ฉันนั่งคิดและพบว่าอาจมีการแทรกข้อความค้นหามากเกินไปในคราวเดียว...
ฉันพยายามส่งคำขอแทรกสำหรับจำนวนข้อมูลที่ฐานข้อมูลควรประมวลผลใน 1 วัน เกิดขึ้น!

หลังจากนั้นเราก็ส่งคำขอข้อมูลจำนวนเท่าเดิมต่อไป เนื่องจากเราจำเป็นต้องลบข้อมูลจำนวนหนึ่งเดือน เราจึงดำเนินการนี้ซ้ำประมาณ 35 ครั้ง

การเปลี่ยนชื่อตาราง

โชคเข้าข้างฉัน: ทุกอย่างดำเนินไปอย่างราบรื่น

การแจ้งเตือนหายไป

ความเร็วในการประมวลผลแบบแบตช์เพิ่มขึ้น

ก่อนหน้านี้กระบวนการนี้ใช้เวลาประมาณหนึ่งชั่วโมง ตอนนี้ใช้เวลาประมาณ 2 นาที

หลังจากที่ฉันแน่ใจว่าปัญหาทั้งหมดได้รับการแก้ไขแล้ว ฉันก็ทิ้งบันทึก 300 ล้านแผ่น ฉันลบโต๊ะออกและรู้สึกเหมือนได้เกิดใหม่

สรุป

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

คุณคิดเกี่ยวกับการโหลดระหว่างการจำลองข้อมูลเมื่อทำการลบบันทึกออกจากฐานข้อมูลหรือไม่? อย่าให้ MySQL ทำงานหนักเกินไป

ผู้ที่มีความรอบรู้ด้านฐานข้อมูลจะไม่มีปัญหาดังกล่าวแน่นอน สำหรับพวกคุณที่เหลือ ฉันหวังว่าบทความนี้จะมีประโยชน์

ขอบคุณที่อ่าน!

เราจะดีใจมากหากคุณแจ้งให้เราทราบว่าคุณชอบบทความนี้หรือไม่ การแปลมีความชัดเจน มีประโยชน์กับคุณหรือไม่?

ที่มา: will.com

เพิ่มความคิดเห็น