เป็นไปได้หรือไม่ที่จะทำความสะอาดเอ็นจินการจัดเก็บ mysql innodb จึงไม่ได้จัดเก็บข้อมูลจากตารางที่ถูกลบ
หรือฉันต้องสร้างฐานข้อมูลใหม่ทุกครั้ง?
เป็นไปได้หรือไม่ที่จะทำความสะอาดเอ็นจินการจัดเก็บ mysql innodb จึงไม่ได้จัดเก็บข้อมูลจากตารางที่ถูกลบ
หรือฉันต้องสร้างฐานข้อมูลใหม่ทุกครั้ง?
คำตอบ:
นี่คือคำตอบที่สมบูรณ์ยิ่งขึ้นเกี่ยวกับ InnoDB เป็นกระบวนการที่ค่อนข้างยาว แต่คุ้มค่ากับความพยายาม
โปรดทราบว่า/var/lib/mysql/ibdata1
เป็นไฟล์ที่ยุ่งที่สุดในโครงสร้างพื้นฐาน InnoDB โดยปกติจะมีข้อมูลหกประเภท:
Pictorial Representation of ibdata1
หลายคนสร้างibdata
ไฟล์หลายไฟล์โดยหวังว่าจะมีการจัดการพื้นที่ดิสก์และประสิทธิภาพที่ดีขึ้นอย่างไรก็ตามความเชื่อนั้นผิดพลาด
OPTIMIZE TABLE
ไหม?น่าเสียดายที่การรันOPTIMIZE TABLE
กับตาราง InnoDB ที่เก็บไว้ในไฟล์พื้นที่ตารางที่ใช้ร่วมกันibdata1
ทำสองสิ่ง:
ibdata1
ibdata1
เติบโตขึ้นเนื่องจากข้อมูลที่ต่อเนื่องกันและหน้าดัชนีถูกผนวกเข้ากับibdata1
อย่างไรก็ตามคุณสามารถแยกข้อมูลตารางและดัชนีตารางออกจากกันibdata1
และจัดการได้อย่างอิสระ
OPTIMIZE TABLE
ด้วยได้innodb_file_per_table
ไหมสมมติว่าคุณกำลังจะเพิ่มไปinnodb_file_per_table
/etc/my.cnf (my.ini)
จากนั้นคุณสามารถรันOPTIMIZE TABLE
บน InnoDB Tables ทั้งหมดได้หรือไม่?
ข่าวดี : เมื่อคุณเรียกใช้OPTIMIZE TABLE
โดยinnodb_file_per_table
เปิดใช้งานสิ่งนี้จะสร้าง.ibd
ไฟล์สำหรับตารางนั้น ตัวอย่างเช่นหากคุณมีตารางที่มีmydb.mytable
ดาต้าเดอ/var/lib/mysql
ร์ก็จะสร้างสิ่งต่อไปนี้
/var/lib/mysql/mydb/mytable.frm
/var/lib/mysql/mydb/mytable.ibd
.ibd
จะมีหน้าข้อมูลและหน้าดัชนีสำหรับตารางที่ เยี่ยมมาก
ข่าวร้าย : สิ่งที่คุณต้องทำคือการดึงหน้าและดัชนีหน้าข้อมูลจากการใช้ชีวิตในmydb.mytable
ibdata
รายการพจนานุกรมข้อมูลสำหรับทุกตารางรวมถึงmydb.mytable
ยังคงอยู่ในพจนานุกรมข้อมูล (ดูภาพแทนของ ibdata1 ) คุณไม่สามารถลบเพียงแค่ibdata1
จุดนี้ !!! โปรดทราบibdata1
ว่าไม่ได้หดเลย
ในการย่อขนาดibdata1
ครั้งเดียวคุณต้องทำสิ่งต่อไปนี้:
ถ่ายโอนข้อมูล (เช่นกับmysqldump
) ฐานข้อมูลทั้งหมดลงใน.sql
ไฟล์ข้อความ ( SQLData.sql
ใช้ด้านล่าง)
ทิ้งฐานข้อมูลทั้งหมด (ยกเว้นmysql
และinformation_schema
) CAVEAT : เพื่อเป็นการป้องกันไว้ก่อนโปรดเรียกใช้สคริปต์นี้เพื่อให้แน่ใจว่าคุณได้รับสิทธิ์ผู้ใช้ทั้งหมด:
mkdir /var/lib/mysql_grants
cp /var/lib/mysql/mysql/* /var/lib/mysql_grants/.
chown -R mysql:mysql /var/lib/mysql_grants
เข้าสู่ระบบ mysql และเรียกใช้SET GLOBAL innodb_fast_shutdown = 0;
(สิ่งนี้จะล้างการเปลี่ยนแปลงธุรกรรมที่เหลือทั้งหมดจากib_logfile0
และib_logfile1
)
ปิดระบบ MySQL
เพิ่มบรรทัดต่อไปนี้ใน/etc/my.cnf
(หรือmy.ini
บน Windows)
[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
.
นอกจากนี้: innodb_flush_method=O_DIRECT
ไม่มีใน Windows)
ลบibdata*
และib_logfile*
เลือกคุณสามารถลบโฟลเดอร์ทั้งหมดในยกเว้น/var/lib/mysql
/var/lib/mysql/mysql
เริ่ม MySQL (ซึ่งจะสร้างใหม่ibdata1
[10MB ตามค่าเริ่มต้น] ib_logfile0
และib_logfile1
ที่ 1G ต่ออัน)
นำเข้า SQLData.sql
ตอนนี้ibdata1
จะยังคงเติบโต แต่เพียงประกอบด้วยข้อมูลเมตาตารางเพราะแต่ละตาราง InnoDB ibdata1
จะอยู่ด้านนอกของ ibdata1
จะไม่มีข้อมูล InnoDB และดัชนีสำหรับตารางอื่น ๆ อีกต่อไป
ตัวอย่างเช่นสมมติว่าคุณมีตาราง InnoDB mydb.mytable
ชื่อ หากคุณมองเข้าไป/var/lib/mysql/mydb
คุณจะเห็นไฟล์สองไฟล์ที่แสดงถึงตาราง:
mytable.frm
(ส่วนหัวของเครื่องมือจัดเก็บข้อมูล)mytable.ibd
(ข้อมูลตารางและดัชนี)ด้วยinnodb_file_per_table
ตัวเลือกใน/etc/my.cnf
คุณสามารถเรียกใช้OPTIMIZE TABLE mydb.mytable
และไฟล์/var/lib/mysql/mydb/mytable.ibd
จะหดตัวลง
ฉันทำสิ่งนี้หลายครั้งในอาชีพการทำงานของฉันในฐานะ MySQL DBA ในความเป็นจริงครั้งแรกที่ฉันทำสิ่งนี้ฉันลดขนาดไฟล์50GB ibdata1
ลงเหลือเพียง 500MB!
ให้มันลอง. หากคุณมีคำถามเพิ่มเติมเกี่ยวกับเรื่องนี้เพียงแค่ถาม เชื่อฉัน; สิ่งนี้จะใช้ได้ผลในระยะสั้นและในระยะยาว
ในขั้นตอนที่ 6 หาก mysql ไม่สามารถรีสตาร์ทได้เนื่องจากmysql
สคีมาเริ่มหลุดให้ย้อนกลับไปที่ขั้นตอนที่ 2 คุณได้สร้างสำเนาทางกายภาพของmysql
สคีมา คุณสามารถกู้คืนได้ดังนี้:
mkdir /var/lib/mysql/mysql
cp /var/lib/mysql_grants/* /var/lib/mysql/mysql
chown -R mysql:mysql /var/lib/mysql/mysql
กลับไปที่ขั้นตอนที่ 6 และดำเนินการต่อ
สำหรับการตั้งค่าinnodb_log_file_sizeเป็น 25% ของinnodb_buffer_pool_sizeในขั้นตอนที่ 5 นั้นกฎแบบครอบคลุมค่อนข้างเป็นโรงเรียนเก่า
ย้อนกลับไปในJuly 03, 2006
, Percona มีบทความที่ดีว่าทำไมการเลือก innodb_log_file_size ต่อมาเมื่อวันNov 21, 2008
, Percona ตามมาด้วยบทความอื่นในวิธีการคำนวณขนาดที่เหมาะสมขึ้นอยู่กับปริมาณงานที่ยอดการรักษามูลค่าหนึ่งชั่วโมงของการเปลี่ยนแปลง
ฉันได้เขียนโพสต์ใน DBA StackExchange เกี่ยวกับการคำนวณขนาดบันทึกและตำแหน่งที่ฉันอ้างถึงบทความ Percona ทั้งสองนี้
Aug 27, 2012
: การปรับแต่งที่เหมาะสมสำหรับตาราง InnoDB 30GB บนเซิร์ฟเวอร์ที่มี RAM 48GBJan 17, 2013
: MySQL 5.5 - Innodb - innodb_log_file_size สูงกว่า 4GB รวมกัน?โดยส่วนตัวฉันจะยังคงใช้กฎ 25% สำหรับการตั้งค่าเริ่มต้น จากนั้นเนื่องจากสามารถกำหนดปริมาณงานได้แม่นยำยิ่งขึ้นเมื่อเวลาผ่านไปในการผลิตคุณสามารถปรับขนาดบันทึกระหว่างรอบการบำรุงรักษาได้ในเวลาเพียงไม่กี่นาที
innodb_open_tables
ถ้าจำเป็น ค่าเริ่มต้นคือ 300
โปรแกรม InnoDB ไม่จัดเก็บข้อมูลที่ถูกลบ เมื่อคุณแทรกและลบแถวพื้นที่ที่ไม่ได้ใช้จะถูกจัดสรรไว้ภายในไฟล์หน่วยเก็บข้อมูล InnoDB เมื่อเวลาผ่านไปพื้นที่โดยรวมจะไม่ลดลง แต่เมื่อเวลาผ่านไปพื้นที่ 'ลบและว่าง' จะถูกใช้ซ้ำโดยอัตโนมัติโดยเซิร์ฟเวอร์ DB
คุณสามารถปรับแต่งและจัดการพื้นที่ที่เครื่องยนต์ใช้เพิ่มเติมได้ผ่านการ re-org ของตารางด้วยตนเอง ในการดำเนินการนี้ให้ถ่ายโอนข้อมูลในตารางที่ได้รับผลกระทบโดยใช้ mysqldump วางตารางรีสตาร์ทบริการ mysql จากนั้นสร้างตารางใหม่จากไฟล์ดัมพ์