วิธีที่ดีที่สุดในการลดขนาดของ ibdata ใน mysql คืออะไร


63

ฉันมีเซิร์ฟเวอร์ผลิตจำนวนหนึ่งซึ่งibdataไฟล์เพิ่มขึ้นทุกวัน

มีการใช้พื้นที่ 290GB แล้ว

ตารางในเซิร์ฟเวอร์ส่วนใหญ่เป็น InnoDB และมีคำขออ่านและเขียนสูง

ขนาดไฟล์บันทึกเพิ่มขึ้นเช่นกัน มีข้อมูลจำนวนมากในตาราง

ฉันจะควบคุมขนาดที่เพิ่มขึ้นของทั้งสองได้อย่างไร

innodb_file_per_tableฉันไม่ได้ใช้

คำตอบ:


104

โปรดจำไว้ว่าไฟล์ที่คึกคักที่สุดในโครงสร้างพื้นฐาน InnoDB คือ / var / lib / mysql / ibdata1

โดยปกติไฟล์นี้จะมีข้อมูลจำนวนมาก (เมื่อinnodb_file_per_tableเป็น 0)

  • ข้อมูลตาราง
  • ดัชนีตาราง
  • ข้อมูล MVCC (การควบคุมการทำงานพร้อมกันหลายรายการ)
    • ส่วนย้อนกลับ
    • เลิกทำ Tablespace
  • ตารางข้อมูลเมตา
  • ดูภาพแทน

หลายคนสร้างไฟล์ ibdata หลายไฟล์โดยหวังว่าจะได้การจัดการพื้นที่ดิสก์และประสิทธิภาพที่ดีขึ้น มันไม่ได้ช่วยอะไร

น่าเสียดายที่ OPTIMIZE TABLE เทียบกับตาราง InnoDB ที่จัดเก็บใน ibdata1 ทำสองสิ่ง:

  • ทำให้ข้อมูลและดัชนีของตารางต่อเนื่องกันภายใน ibdata1
  • ทำให้ ibdata1 โตขึ้นเนื่องจากข้อมูลที่ต่อเนื่องกันถูกผนวกเข้ากับ ibdata1

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

ขั้นตอนที่ 01) MySQLDump ฐานข้อมูลทั้งหมดลงในไฟล์ข้อความ SQL (เรียกว่า SQLData.sql) ( รายละเอียดเพิ่มเติมที่นี่ )

ขั้นตอนที่ 02)วางฐานข้อมูลทั้งหมด (ยกเว้นmysql, performance_schemaและinformation_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

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 จะเพิ่มขึ้น แต่จะมีเฉพาะข้อมูลเมตาของตาราง

แต่ละตาราง 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

ให้มันลอง. หากคุณมีคำถามเพิ่มเติมเกี่ยวกับเรื่องนี้ส่งอีเมลฉัน เชื่อฉัน. สิ่งนี้จะใช้ได้ในระยะสั้นและระยะยาว !!!

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

SELECT IFNULL(B.engine,'Total') "Storage Engine",
CONCAT(LPAD(REPLACE(FORMAT(B.DSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Data Size", CONCAT(LPAD(REPLACE(
FORMAT(B.ISize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Index Size", CONCAT(LPAD(REPLACE(
FORMAT(B.TSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Table Size"
FROM (SELECT engine,SUM(data_length) DSize,SUM(index_length) ISize,
SUM(data_length+index_length) TSize FROM information_schema.tables
WHERE table_schema NOT IN ('mysql','information_schema','performance_schema')
AND engine IS NOT NULL GROUP BY engine WITH ROLLUP) B,
(SELECT 3 pw) A ORDER BY TSize;

แม้จะมีการตั้งค่าที่แนะนำสำหรับ my.cnf (ซึ่งฉันมีอยู่แล้ว) การลบ ib_logfile0 และ 1 จากนั้นเริ่ม mysql ไฟล์ใหม่จะถูกสร้างขึ้นและภายในไม่กี่วินาทีพวกเขาก็จะมีขนาดเท่ากับฐานข้อมูลตามที่แสดงไว้ข้างต้น ไม่แน่ใจว่า mysql กำลังคัดลอกตารางและดัชนีทั้งหมดไปยังไฟล์เหล่านี้หรือไม่ในขณะที่ดูแลแต่ละตารางในไฟล์แยกต่างหาก
อัลเลนคิง
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.