การทำ Migration ที่จะไม่ทำให้ระบบ Production พัง
การทำ migration ทำงานได้อย่างสมบูรณ์แบบบนเครื่องของคุณ คุณตัดสินใจ deploy ในวันศุกร์ตอน 6 โมงเย็นเพราะคิดว่ามันเป็นงานเล็กๆ จากนั้นการ deploy ก็ค้าง หรือที่แย่กว่านั้นคือ ตารางที่มีข้อมูล 8 ล้านแถวเกิดการ lock นานถึง 40 วินาที จนทำให้เว็บไซต์ของคุณล่ม
Migration ทำงานแตกต่างกันเมื่ออยู่ในระบบ production ฐานข้อมูลในเครื่อง (local) นั้นว่างเปล่าและทำงานรวดเร็ว แต่ฐานข้อมูลบน production มีข้อมูลจริงและมีผู้ใช้งานที่กำลังใช้งานอยู่
ปฏิบัติตามกฎเหล่านี้เพื่อหลีกเลี่ยงหายนะบน production
เขียน method
downให้ใช้งานได้เสมอ ทุก migration จำเป็นต้องมีฟังก์ชันupและdownโดยฟังก์ชันdownจะต้องย้อนกลับการทำงานของฟังก์ชันupได้อย่างแม่นยำ หากคุณไม่สามารถเขียน rollback ได้ แสดงว่า migration ของคุณซับซ้อนเกินไป ควรทดสอบบนเครื่องของคุณด้วยคำสั่งmigrateตามด้วยmigrate:rollbackก่อนที่จะ push งานอย่าแก้ไข migration เก่า คุณอาจต้องการแก้ไขขนาดของ column ในไฟล์ migration เก่า แต่อย่าทำเช่นนั้น เพราะ Laravel จะไม่รันไฟล์นั้นซ้ำบน server ให้ใช้วิธีสร้าง migration ใหม่เพื่อเปลี่ยนโครงสร้างแทน เพราะ migration คือประวัติของการเปลี่ยนแปลง คุณควรเพิ่มบทใหม่แทนที่จะกลับไปแก้ไขบทเก่า
ใช้ค่า nullable หรือค่า default การเพิ่ม column แบบ
NOT NULLลงในตารางที่มีข้อมูลอยู่แล้วจะทำให้เกิดข้อผิดพลาด เนื่องจากฐานข้อมูลไม่รู้ว่าจะต้องใส่ค่าอะไรลงในแถวเก่าๆ
ใช้แนวทางเหล่านี้แทน:
• กำหนดให้ column ใหม่เป็น nullable
• กำหนดค่า default
• หาก column นั้นจำเป็นต้องมีค่า (required) ให้ทำเป็น 3 ขั้นตอน: สร้างแบบ nullable ก่อน, ใส่ข้อมูลให้ครบ, แล้วจึงเปลี่ยนเป็น NOT NULL
การสูญเสียข้อมูลนั้นเรียกคืนไม่ได้ คำสั่ง
dropColumnจะลบข้อมูลทิ้งไปตลอดกาล แม้การ rollback จะสามารถสร้าง column กลับมาใหม่ได้ แต่ข้อมูลข้างในจะหายไปหมด ก่อนที่จะสั่ง drop column ควรตรวจสอบ backup ของคุณให้แน่ใจ วิธีที่ปลอดภัยกว่าคือการหยุดใช้งาน column นั้นใน code ของคุณก่อน รอสักสองสามสัปดาห์ แล้วจึงค่อยลบออกจากฐานข้อมูลแยกการเปลี่ยน schema ออกจากการอัปเดตข้อมูล การรัน
User::all()ภายใน migration อาจทำให้ข้อมูลหลายล้านแถวถูกโหลดเข้าสู่ memory จนทำให้การ deploy ล่ม หากคุณจำเป็นต้องอัปเดตข้อมูลระหว่างทำ migration ให้ใช้chunkByIdเพื่อประมวลผลข้อมูลเป็นชุดเล็กๆ (batches)ใช้ flag
--forceใน pipeline ระบบ automated deployment pipeline จะค้างหาก Laravel ถามเพื่อขอการยืนยัน ให้ใช้คำสั่งนี้ใน deployment scripts ของคุณ:php artisan migrate --forceระวังเรื่อง table locks การเปลี่ยน column หรือการเพิ่ม index ในตารางที่มีขนาดใหญ่มากจะทำให้เกิดการ lock ตาราง ซึ่งส่งผลให้เกิด downtime สำหรับตารางที่มีขนาดใหญ่มาก ควรศึกษาเครื่องมือประเภท online schema change หรือเลือกดำเนินการในช่วงเวลาที่มีผู้ใช้งานน้อย (low traffic)
รายการตรวจสอบก่อนที่คุณจะ push:
• method down ใช้งานได้จริงหรือไม่?
• ฉันได้ทดสอบ rollback ในเครื่องแล้วหรือยัง?
• ฉันกำลังสร้าง migration ใหม่แทนที่จะแก้ไขอันเก่าใช่ไหม?
• column ใหม่เป็น nullable หรือมีค่า default หรือไม่?
• ฉันมี backup ก่อนที่จะสั่ง drop column หรือไม่?
ที่มา: https://dev.to/denisgusto1/migrations-que-nao-quebram-em-producao-o-guia-que-ninguem-te-deu-363o
