ฉันได้รับการแก้ไขใน StackOverflow กลับมาในเดือนตุลาคม 2010
โปรดจำไว้ว่าไฟล์ที่คึกคักที่สุดในโครงสร้างพื้นฐาน InnoDB: / var / lib / mysql / ibdata1
ไฟล์นี้เป็นที่เก็บข้อมูลสี่ประเภท
- ข้อมูลตาราง
- ดัชนีตาราง
- ข้อมูล MVCC (การควบคุมการทำงานพร้อมกันหลายรายการ)
- ตารางข้อมูลเมตา (รายการของ tablespace IDs)
การรันOPTIMIZE TABLE
กับตาราง InnoDB ที่จัดเก็บใน ibdata1 ทำสองสิ่ง:
- ทำให้ข้อมูลและดัชนีของตารางต่อเนื่องกันภายใน ibdata1 ทำให้เข้าถึงได้เร็วขึ้น
- มันทำให้ ibdata1 โตขึ้นเนื่องจากข้อมูลและหน้าดัชนีที่ต่อเนื่องกันถูกผนวกเข้ากับ ibdata1
ในขณะที่คุณสามารถแยกข้อมูลตารางและดัชนีตารางจาก ibdata1 และจัดการพวกมันอย่างอิสระโดยใช้innodb_file_per_tableแต่พื้นที่ดิสก์ขนาดใหญ่ที่อ้าปากค้างทั้งหมดใน ibdata1 ก็จะไม่หายไปและไม่สามารถเรียกคืนได้ คุณต้องทำมากกว่านี้
หากต้องการย่อขนาด ibdata1 เพียงครั้งเดียวคุณต้องทำสิ่งต่อไปนี้:
1) MySQLDump ฐานข้อมูลทั้งหมดลงในไฟล์ข้อความ SQL (เรียกว่า /root/SQLData.sql)
2) ดร็อปฐานข้อมูลทั้งหมด (ยกเว้นสคีมา mysql)
3) ปิด mysql
4) เพิ่มบรรทัดต่อไปนี้ใน /etc/my.cnf
[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G
Sidenote: ไม่ว่าชุดของคุณสำหรับ innodb_buffer_pool_size จะต้องแน่ใจว่า innodb_log_file_size นั้นเท่ากับ 25% ของ innodb_buffer_pool_size
5) ลบ ibdata1, ib_logfile0 และ ib_logfile1
ณ จุดนี้ควรมี schema mysql ใน / var / lib / mysql เท่านั้น
6) เริ่ม mysql ใหม่
สิ่งนี้จะสร้าง ibdata1 ที่ 10 หรือ 18MB (ขึ้นอยู่กับรุ่นของ MySQL), ib_logfile0 และ ib_logfile1 ที่ 1G
7) โหลด /root/SQLData.sql ไปที่ mysql ใหม่
ibdata1 จะเพิ่มขึ้น แต่จะมีเฉพาะข้อมูลเมตาของตาราง ในความเป็นจริงมันจะเติบโตช้ามากในช่วงหลายปี วิธีเดียวที่ ibdata1 จะเติบโตอย่างรวดเร็วคือถ้าคุณมีสิ่งใดสิ่งหนึ่งต่อไปนี้:
- จำนวนมากของ DDL (
CREATE TABLE
, DROP TABLE
, ALTER TABLE
)
- การทำธุรกรรมจำนวนมาก
- มีการเปลี่ยนแปลงมากมายที่จะส่งมอบต่อธุรกรรม
แต่ละตาราง 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;
และไฟล์ /var/lib/mysql/mydb/mytable.ibd จะลดขนาดลง
ฉันทำมาแล้วหลายครั้งในอาชีพการงานของฉันในฐานะ MySQL DBA
ในความเป็นจริงครั้งแรกที่ฉันทำสิ่งนี้ฉันยุบไฟล์ 50GB ibdata1 เป็น 500MB
ให้มันลอง. หากคุณมีคำถามเพิ่มเติมเกี่ยวกับเรื่องนี้ส่งอีเมลฉัน เชื่อฉัน. สิ่งนี้จะใช้ได้ในระยะสั้นและระยะยาว !!!
อัพเดท 2012-04-19 09:23 EDT
หลังจากรันขั้นตอนข้างต้นคุณจะทราบได้อย่างไรว่าตารางใดบ้างที่จำเป็นต้องจัดเรียงข้อมูล เป็นไปได้ที่จะทราบ แต่คุณจะมีสคริปต์
นี่คือตัวอย่าง: mydb.mytable
สมมติว่าคุณมีตาราง เมื่อเปิดใช้งาน innodb_file_per_table คุณจะมีไฟล์ /var/lib/mysql/mydb/mytable.ibd
คุณจะต้องดึงตัวเลขสองตัว
ไฟล์จากระบบปฏิบัติการ: คุณสามารถตรวจสอบขนาดไฟล์จากระบบปฏิบัติการเช่นนี้
ls -l /var/lib/mysql/mydb/mytable.ibd | awk '{print $5}'
FILESIZE จาก INFORMATION_SCHEMA: คุณสามารถตรวจสอบขนาดไฟล์จาก information_schema.tables ดังนี้:
SELECT (data_length+index_length) tblsize FROM information_schema.tables
WHERE table_schema='mydb' AND table_name='mytable';
เพียงลบค่า Information_SCHEMA จากค่าระบบปฏิบัติการแล้วหารด้วยส่วนแตกต่างด้วยค่า Information_SCHEMA
จากนั้นคุณจะตัดสินใจว่าเปอร์เซ็นต์เห็นว่าจำเป็นในการจัดระเบียบตารางนั้น แน่นอนคุณจัดเรียงข้อมูลโดยใช้หนึ่งในคำสั่งต่อไปนี้:
OPTIMIZE TABLE mydb.mytable;
หรือ
ALTER TABLE mydb.mytable ENGINE=InnoDB;