การปรับเปลี่ยนคอลัมน์ของตาราง mysql ที่มีขนาดใหญ่มากซึ่งมีการหยุดทำงานเพียงเล็กน้อยหรือไม่มีเลย


18

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

เนื่องจากฉันใช้ amazon RDS ฉันไม่สามารถมีเซิร์ฟเวอร์ทาสให้เล่นแล้วเลื่อนระดับเป็นโทได้ ดังนั้นคำถามของฉันคือถ้ามีวิธีการทำเช่นนี้ด้วยการหยุดทำงานน้อยที่สุด? ฉันไม่รังเกียจการดำเนินการที่ใช้เวลาเป็นชั่วโมงหรือเป็นวันถ้าผู้ใช้ยังคงสามารถใช้ฐานข้อมูลได้ ... อย่างน้อยพวกเขาสามารถอ่านได้ในขณะที่กำลังเพิ่มคอลัมน์หรือไม่? จะเกิดอะไรขึ้นถ้าแอพของฉันพยายามเขียน แทรกหรืออัปเดต ถ้ามันล้มเหลวทันทีนั่นก็ไม่เลวจริง ๆ ถ้ามันแค่แฮงค์และทำให้เกิดปัญหากับเซิร์ฟเวอร์ db นั่นเป็นปัญหาใหญ่ ..

นี่ต้องเป็นปัญหาเกี่ยวกับการปรับสเกลทั่วไปทุกคนต้องเพิ่มคอลัมน์ .. โดยทั่วไปแล้วฐานข้อมูลการผลิตจะทำอย่างไร Slave -> การย้ายข้อมูลหลักหรือไม่

อัปเดต - ฉันลืมที่จะพูดถึงฉันใช้เครื่องมือจัดเก็บข้อมูล Innodb


1
ในกรณีที่ใครบางคนยังคงมองหาคำตอบ .. blog.staginginstance.com/… ^^
Coder ไม่ระบุชื่อ

คำตอบ:


10

ฉันจำเป็นต้องทำการเปลี่ยนแปลงตารางเป็นระยะใน mysql 5.1 ส่วนใหญ่เป็นการเพิ่มคอลัมน์

อย่า ไม่มีจริงๆ. ทำไม่ได้ มันควรจะเป็นโอกาสที่หายากมากเมื่อนี้คือเคยจำเป็น

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

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

สุดท้ายถ้าสคีมาของคุณเป็นมาตรฐานจริงๆและคุณต้องเพิ่มคอลัมน์ต่อไป:

  1. ตรวจสอบให้แน่ใจว่าคุณมีคอลัมน์เวลาประทับบนฐานข้อมูลหรือกำลังสร้างบันทึกการจำลองแบบ
  2. สร้างสำเนา (B) ของตาราง (A)
  3. เพิ่มคอลัมน์ใหม่ใน B (จะยังคงบล็อกด้วย myisam)
  4. ปิดการใช้งานการทำธุรกรรม
  5. เปลี่ยนชื่อตารางต้นฉบับ (A) เป็นอย่างอื่น (สำรอง)
  6. เปลี่ยนชื่อตารางใหม่ (B) ด้วยชื่อของตารางเดิม (A)
  7. เล่นซ้ำธุรกรรมจากจุดเริ่มต้นของการดำเนินการจากบันทึกการจำลองแบบหรือจากตารางสำรอง
  8. เปิดใช้งานการทำธุรกรรม

2
ขอบคุณสำหรับแนวทางทีละขั้นตอน เป็นเรื่องผิดปกติหรือไม่ที่จะแก้ไขตาราง? ฉันเข้าใจว่าฉันสามารถเพิ่มตารางใหม่ด้วยคอลัมน์ใหม่แทนได้ (ในกรณีที่ต้องการเพิ่มคอลัมน์) และให้อ้างอิงตารางขนาดใหญ่ดั้งเดิมในความสัมพันธ์แบบ 1: 1 แต่ดูเหมือนจะไม่ถูกต้องที่จะมีตาราง 1: 1 ขนาดใหญ่มาก 15 ตารางเมื่อทุกตารางควรอยู่ใน ... ฉันไม่ใช่ผู้เชี่ยวชาญ แต่ฐานข้อมูลของฉันค่อนข้างปกติและดูเหมือนเป็นธรรมชาติที่ฉันต้องแก้ไขเป็นระยะ ..
apptree

2
"เป็นเรื่องผิดปกติหรือไม่ที่จะแก้ไขตาราง" - ใช่
symcbean

1
ไม่ แต่ใคร ๆ ก็สามารถแย้งได้ว่าถ้ามันเกิดขึ้นอย่างสม่ำเสมอ - ไม่ใช่เป็นส่วนหนึ่งของการอัพเกรดซอฟต์แวร์ครั้งใหญ่ - มีคนต้องถูกไล่ออกเพราะไม่รู้ว่าตารางทั้งหมดควรจะอยู่ที่นั่นในตอนแรก ปัญหา / เคล็ดลับที่นี่คือ "ปกติ" ไม่ใช่ "ทุกๆสองสามเดือน"
TomTom

22
ในฐานะที่เป็นนักพัฒนาซอฟต์แวร์โดยเฉพาะที่ทำงานใน บริษัท สตาร์ทอัพและ บริษัท เล็ก ๆ ฉันไม่สามารถเห็นด้วยกับ symcbean และ @TomTom ได้น้อยลง สิ่งต่าง ๆ เปลี่ยนแปลงผลิตภัณฑ์เปลี่ยนแปลงเป้าหมายธุรกิจเปลี่ยนแปลงและโครงสร้างฐานข้อมูลจำเป็นต้องเปลี่ยนแปลงกับพวกเขา การให้บริการ DBA ที่ดีหมายถึงการพูดว่า "ใช่" สำหรับการเปลี่ยนแปลงเหล่านั้นแล้วหาวิธีการใช้งานอย่างมีประสิทธิภาพ ฐานข้อมูลที่ทำให้เป็นมาตรฐานอย่างหนักเป็นแนวคิดที่เสียชีวิตไปนานแล้ว พวกเขาส่งผลให้ประสิทธิภาพไม่ดีและรอบ dev ช้า
pents90

4
ผิดปกติในการเปลี่ยนตาราง ??? อาจจะอยู่ใน บริษัท ขนาดใหญ่ แต่ในทีมเปรียวที่เกิดขึ้นค่อนข้างบ่อยความต้องการเปลี่ยน ...
tibo

12

ฉันเพิ่งจะทำสิ่งนี้เมื่อเร็ว ๆ นี้ สิ่งที่ Amazon แนะนำคือการใช้ Percona Toolkit ฉันดาวน์โหลดมาแล้วและสามารถใช้งานบางอย่างเช่น:

./pt-online-schema-change h=databasenameHostName,D=databasename,t=tablename --recursion-method=none --execute --user username --password password --alter "MODIFY someColumn newDataType"

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

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


ทีม Percona มีข้อเขียนสั้น ๆ เกี่ยวกับการเปิดใช้งานคุณลักษณะ log_bin_trust_function_creators ผ่านกลุ่มพารามิเตอร์ RDS (เนื่องจาก SET GLOBAL log_bin_trust_function_creators ชุดที่ 1 ไม่ทำงานบน RDS) ซึ่งจำเป็นสำหรับเครื่องมือ pt-online-schema-change รายละเอียดเพิ่มเติม: percona.com/blog/2016/07/01/pt-online-schema-change-amazon-rds
user1652110

มันใช้งานได้สำหรับฉัน
Adiii

4

symcbeanมีบางส่วนข้อเสนอแนะที่เป็นของแข็ง

ในการตอบคำถามของคุณวิธีที่ง่ายที่สุดและดีที่สุดในการลดผลกระทบคือการมีฐานข้อมูลหลายแบบจำลอง Dual master พร้อมโพรซีเดอร์ failover ที่เหมาะสมหยุดการเรพลิเคทบนแอ็คทีฟซึ่งอนุญาตให้ทำการเปลี่ยนแปลงบนแอ็คทีฟโดยไม่ส่งผลกระทบต่อแอ็คทีฟ

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

ในที่สุดหากชุดข้อมูลของคุณมีขนาดใหญ่มากคุณจำเป็นต้องพิจารณาการเก็บถาวรระหว่างฐานข้อมูลOLTPและOLAP ชุดข้อมูลธุรกรรมของคุณไม่จำเป็นต้องมีขนาดใหญ่มากหากคุณออกแบบอย่างเหมาะสม


2

จากคู่มือ: http://dev.mysql.com/doc/refman/5.1/en/alter-table.html

ในกรณีส่วนใหญ่ ALTER TABLE สร้างสำเนาชั่วคราวของตารางดั้งเดิม MySQL รวมการเปลี่ยนแปลงในการคัดลอกจากนั้นลบตารางต้นฉบับและเปลี่ยนชื่อใหม่ ในขณะที่ ALTER TABLE กำลังทำงานตารางต้นฉบับสามารถอ่านได้โดยเซสชันอื่น การอัพเดตและการเขียนลงในตารางจะถูกหยุดรอจนกว่าตารางใหม่จะพร้อมใช้งานจากนั้นจะถูกเปลี่ยนเส้นทางไปยังตารางใหม่โดยอัตโนมัติโดยไม่มีการอัปเดตที่ล้มเหลว

ดังนั้นการอ่านจะทำงานได้ดี การเขียนจะถูกหยุดทำงาน แต่จะดำเนินการในภายหลัง หากคุณต้องการป้องกันสิ่งนี้คุณจะต้องแก้ไขซอฟต์แวร์ของคุณ


ดังนั้นฉันจึงทำสิ่งนี้และปิดการใช้งานส่วนต่างๆของเว็บไซต์ที่เขียนลงในตารางที่ฉันกำลังแก้ไขอยู่ในขณะนี้ จนถึงตอนนี้ฉันได้รับข้อยกเว้น "การรอการล็อคเกินกำหนดหลายครั้งลองรีสตาร์ทธุรกรรม" ข้อยกเว้นนั่นไม่เลวร้ายนัก อย่างไรก็ตามพวกเขากำลังดำเนินการอ่าน PURELY ...
apptree

0

ฉันอยู่ในสถานการณ์ที่คล้ายกันซึ่งฉันต้องแก้ไขตารางธุรกรรมของฉันที่เกือบ 65GB ฉันได้ยินทางออก 2 ข้อ

  1. ใช้ ALTER ตรงไปข้างหน้าและปล่อยให้มันรัน (จำนวน X ชั่วโมงหรือวัน)
  2. ตรวจสอบให้แน่ใจว่าคุณมีคอลัมน์เวลาประทับบนฐานข้อมูลหรือกำลังสร้างบันทึกการจำลองแบบ
    • สร้างสำเนา (B) ของตาราง (A)
    • เพิ่มคอลัมน์ใหม่ใน B (จะยังคงบล็อกด้วย myisam)
    • ปิดการใช้งานการทำธุรกรรม
    • เปลี่ยนชื่อตารางต้นฉบับ (A) เป็นอย่างอื่น (สำรอง)
    • เปลี่ยนชื่อตารางใหม่ (B) ด้วยชื่อของตารางเดิม (A)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.