ฉันมีคำตอบที่สมบูรณ์สำหรับอันนี้
เมื่อใส่Innodb_file_per_tableไว้และตาราง InnoDB ใหม่สามารถหดได้โดยใช้วิธีALTER TABLE <innodb-table-name> ENGINE=InnoDB';
นี้จะย่อขนาด.ibd
ไฟล์ใหม่ที่รับประกัน
หากคุณเรียกใช้ALTER TABLE <innodb-table-name> ENGINE=InnoDB';
บนตาราง InnoDB ที่สร้างขึ้นก่อนที่คุณจะใช้ innodb_file_per_table มันจะดึงข้อมูลและดัชนีสำหรับตารางนั้นออกจากไฟล์ ibdata1 และเก็บไว้ใน.ibd
ไฟล์ซึ่งจะทำให้นกพิราบถาวรทั้งหมดใน ibdata1 ที่ไม่สามารถนำกลับมาใช้ใหม่ได้ .
โดยibdata1
ปกติไฟล์จะเก็บข้อมูลสี่ประเภท
นี่เป็นวิธีที่รับประกันการย่อขนาดไฟล์ ibdata1 ตลอดไป ...
ขั้นตอนที่ 01) MySQLDump ฐานข้อมูลทั้งหมดลงในไฟล์ข้อความ SQL (เรียกว่า SQLData.sql)
ขั้นตอนที่ 02) ปล่อยฐานข้อมูลทั้งหมด (ยกเว้น mysql, data_schema และสกีมา performance_schema)
ขั้นตอนที่ 03) การปิด mysql
ขั้นตอนที่ 04) เพิ่มบรรทัดต่อไปนี้ลงใน /etc/my.cnf
[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G
innodb_data_file_path=ibdata1:10M:autoextend
Sidenote: ไม่ว่าชุดของคุณสำหรับ innodb_buffer_pool_size จะต้องแน่ใจว่า innodb_log_file_size นั้นเท่ากับ 25% ของ innodb_buffer_pool_size
- ขั้นตอนที่ 05) ลบ ibdata1, ib_logfile0 และ ib_logfile1 ( ดูการอัปเดตด้านล่างก่อนที่จะลบ! )
ณ จุดนี้ควรมี schema mysql ใน / var / lib / mysql เท่านั้น
- ขั้นตอนที่ 06) เริ่ม mysql ใหม่
สิ่งนี้จะสร้าง ibdata1 ที่ 10MB (ห้ามกำหนดค่าตัวเลือก), ib_logfile0 และ ib_logfile1 ที่ 1G
- ขั้นตอนที่ 07) โหลด SQLData.sql ไปที่ mysql
ibdata1
จะเติบโต แต่มีเฉพาะข้อมูลเมตาของตารางและข้อมูล MVCC เป็นระยะ
แต่ละตาราง InnoDB จะมีอยู่นอก ibdata1
สมมติว่าคุณมีตาราง InnoDB ชื่อ mydb.mytable ถ้าคุณเข้าไป/var/lib/mysql/mydb
คุณจะเห็นสองไฟล์ที่แสดงถึงตาราง
mytable.frm
(ส่วนหัวของเครื่องมือจัดเก็บข้อมูล)
mytable.ibd
(หน้าแรกของข้อมูลตารางและดัชนีตารางสำหรับmydb.mytable
)
ibdata1
จะไม่มีข้อมูล InnoDB และดัชนีอีกต่อไป
ด้วยตัวเลือกinnodb_file_per_table/etc/my.cnf
คุณสามารถเรียกใช้OPTIMIZE TABLE mydb.mytable
OR ALTER TABLE mydb.mytable ENGINE=InnoDB;
และไฟล์/var/lib/mysql/mydb/mytable.ibd
จะย่อขนาดลง
ฉันทำมาหลายครั้งแล้วในอาชีพของฉันในฐานะ MySQL DBA โดยไม่มีปัญหาใด ๆ หลังจากนั้น ในความเป็นจริงครั้งแรกที่ฉันทำสิ่งนี้ฉันยุบไฟล์ 50GB ibdata1 เป็น 50MB
ให้มันลอง. หากคุณมีคำถามเพิ่มเติมเกี่ยวกับเรื่องนี้ส่งอีเมลฉัน เชื่อฉัน. สิ่งนี้จะใช้ได้ในระยะสั้นและระยะยาว
อัพเดท 2013-07-02 15:08 EDT
มีข้อแม้ที่ฉันมีในเรื่องนี้ว่าฉันอัปเดตในโพสต์อื่น ๆ ของฉัน แต่ฉันพลาดนี้: ฉันกำลังปรับปรุงคำตอบของฉันอีกเล็กน้อยด้วยinnodb_fast_shutdownเพราะฉันเคยรีสตาร์ท mysql และหยุด mysql เพื่อทำสิ่งนี้ ตอนนี้ขั้นตอนเดียวนี้มีความสำคัญเนื่องจากทุกธุรกรรมที่ไม่มีข้อผูกมัดอาจมีชิ้นส่วนที่เคลื่อนไหวอื่น ๆ ทั้งภายในและภายนอกบันทึกการทำธุรกรรมของ InnoDB ( ดูโครงสร้างพื้นฐานของ InnoDB )
โปรดทราบว่าการตั้งค่าinnodb_fast_shutdownเป็น 2 จะช่วยล้างบันทึกออกเช่นกัน แต่ยังมีชิ้นส่วนที่เคลื่อนไหวอยู่จำนวนมากและยังได้รับเลือกใน Crash Recovery ระหว่างการเริ่มต้นของ mysqld การตั้งค่า 0 นั้นดีที่สุด