แปลงตารางขนาดใหญ่จาก MyISAM เป็น Innodb


10

ฉันมีตารางที่มีแถวประมาณ 300 ล้านแถวในรูปแบบ MyISAM ฉันต้องการแปลงเป็น Innodb

เป้าหมายดั้งเดิมของฉันคือลดการใช้งานโดยเปลี่ยน schema ของตารางให้มีดัชนีที่ง่ายขึ้น ฉันทิ้งตารางทั้งหมดทิ้งมันสร้างใหม่ด้วยดัชนีที่น้อยลงและตอนนี้ฉันก็นำเข้าอีกครั้ง อย่างไรก็ตามฉันลืมระบุว่าควรเป็น innodb แทนที่จะเป็น myisam

ฉันสามารถทำตาราง ALTER มาตรฐาน ... ENGINE = INNODB ได้ไหม มีอะไรพิเศษที่ฉันควรระวังเกี่ยวกับตารางที่มีขนาดใหญ่เช่นนี้หรือไม่?

การดำเนินการนำเข้าข้อมูลใช้เวลาประมาณ 12 ชั่วโมง - ฉันไม่กล้าทำเช่นนั้นอีก เหตุใดฉันจึงต้องการแปลงมัน


ด้วยแถว 300M MyISAM น่าจะเป็นแบบที่เร็วและดีกว่าสำหรับตารางขนาดนั้น!
Mark Henderson

คำตอบ:


14

exerpt ต่อไปนี้ออกมาจากหนังสือ " ประสิทธิภาพสูง MySQL รุ่นที่สอง "

นี่คือหนังสือที่ยอดเยี่ยมและฉันอยากจะแนะนำให้ทุกคน

คำตอบสั้น ๆ คือ:

ด้วยขนาดและเงื่อนไขของโต๊ะไม่ว่าคุณจะเลือกวิธีแบบใดฉันคิดว่าคุณอาจต้องรอนาน


การแปลงตาราง

มีหลายวิธีในการแปลงตารางจากเอนจินการจัดเก็บหนึ่งไปอีกอันแต่ละอันมีข้อดีและข้อเสีย

แก้ไขตาราง

mysql> ALTER TABLE mytable ENGINE = Falcon;

ไวยากรณ์นี้ใช้ได้กับเอนจิ้นการจัดเก็บข้อมูลทั้งหมด แต่มีข้อผิดพลาด: อาจต้องใช้เวลานาน MySQL จะทำการคัดลอกตารางเก่าของคุณไปยังตารางใหม่ ในช่วงเวลานั้นคุณอาจกำลังใช้ความจุดิสก์ I / O ทั้งหมดของเซิร์ฟเวอร์และตารางดั้งเดิมจะถูกล็อคการอ่านขณะที่การแปลงทำงาน

การถ่ายโอนข้อมูลและนำเข้า

เพื่อให้สามารถควบคุมกระบวนการแปลงได้มากขึ้นคุณอาจเลือกที่จะถ่ายโอนข้อมูลจากตารางไปยังไฟล์ข้อความก่อนโดยใช้ยูทิลิตี้ mysqldump เมื่อคุณทิ้งโต๊ะคุณสามารถแก้ไขไฟล์ดัมพ์เพื่อปรับคำสั่ง CREATE TABLE ที่มีอยู่ ตรวจสอบให้แน่ใจว่าได้เปลี่ยนชื่อตารางรวมทั้งชนิดเนื่องจากคุณไม่สามารถมีสองตารางที่มีชื่อเดียวกันในฐานข้อมูลเดียวกันแม้ว่าจะเป็นประเภทที่แตกต่างกันและค่าเริ่มต้น mysqldump จะเขียนคำสั่ง DROP TABLE ก่อนตาราง CREATE ดังนั้นคุณอาจสูญเสียข้อมูลของคุณหากคุณไม่ระวัง!

สร้างและเลือก

เทคนิคการแปลงที่สามคือการประนีประนอมระหว่างความเร็วของกลไกแรกและความปลอดภัยของวินาที แทนที่จะทิ้งทั้งตารางหรือแปลงทั้งหมดในครั้งเดียวสร้างตารางใหม่และใช้ไวยากรณ์ INSERT ... SELECT ของ MySQL เพื่อเติมข้อมูลดังต่อไปนี้:

mysql> CREATE TABLE innodb_table LIKE myisam_table;
mysql> ALTER TABLE innodb_table ENGINE=InnoDB;
mysql> INSERT INTO innodb_table SELECT * FROM myisam_table;

มันใช้งานได้ดีถ้าคุณไม่มีข้อมูลมากนัก แต่ถ้าคุณทำมันมักจะมีประสิทธิภาพมากกว่าในการเติมข้อมูลในตารางแบบค่อยเป็นค่อยไปการทำธุรกรรมระหว่างแต่ละก้อนเพื่อให้บันทึกการเลิกทำไม่เติบโตมากนัก สมมติว่า id นั้นเป็นคีย์หลักให้รันเคียวรีนี้ซ้ำ ๆ (โดยใช้ค่าที่ใหญ่กว่าของ x และ y ในแต่ละครั้ง) จนกว่าคุณจะคัดลอกข้อมูลทั้งหมดไปยังตารางใหม่:

mysql> START TRANSACTION;
mysql> INSERT INTO innodb_table SELECT * FROM myisam_table
-> WHERE id BETWEEN x AND y;
mysql> COMMIT;

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


2

คำสั่ง ALTER TABLE โดยพื้นฐานแล้วทำสิ่งเดียวกัน: เซิร์ฟเวอร์สร้างตารางชั่วคราวซึ่งจะคัดลอกแถวทั้งหมดแล้วจึงเปลี่ยนชื่อใหม่ รูปแบบบนดิสก์นั้นแตกต่างกันมากระหว่าง InnoDB และ MyISAM ดังนั้นฉันไม่คาดหวังให้คุณหาทางลัดใด ๆ

ข้อสังเกตอื่น (ซึ่งคุณอาจทราบ แต่มันจะช่วยให้ผู้อื่นอ่านข้อความนี้): รูปแบบบนดิสก์สำหรับ InnoDB นั้นขึ้นอยู่กับคีย์หลักเป็นอย่างมากเพราะเป็นกลุ่มที่บันทึกตามนั้น ดังนั้นเมื่อทำงานกับตาราง InnoDB ขนาดใหญ่ให้คิดสองครั้งก่อนเลือกคีย์หลักเนื่องจากการเปลี่ยนแปลงจะสร้างตารางทั้งหมดเหมือนปัญหาที่เกิดขึ้นในมือ

อย่างไรก็ตามฉันแนะนำให้ทำแบบทดสอบสองสามข้อก่อนบนโต๊ะที่มีขนาดปานกลางและเวลา


2
ตารางใด ๆ ที่เปลี่ยนแปลงการดำเนินการใน MySQL (และที่รวมถึงการเพิ่มดัชนี) จะสร้างตารางขึ้นใหม่
David Pashley
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.