MySQL InnoDB - innodb_file_per_table ข้อเสีย?


32

โดยค่าเริ่มต้น MySQL InnoDB จะจัดเก็บตารางของฐานข้อมูลทั้งหมดในไฟล์ส่วนกลาง คุณสามารถเปลี่ยนแปลงสิ่งนี้ได้โดยการตั้งค่า innodb_file_per_table ใน config ซึ่งจะสร้างไฟล์ข้อมูลหนึ่งไฟล์สำหรับแต่ละตาราง

ฉันสงสัยว่าทำไมinnodb_file_per_tableไม่เปิดใช้งานโดยค่าเริ่มต้น มีข้อเสียในการใช้หรือไม่

คำตอบ:


32

ฉันมีคำตอบที่สมบูรณ์สำหรับอันนี้

เมื่อใส่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ปกติไฟล์จะเก็บข้อมูลสี่ประเภท

  • ข้อมูลตาราง
  • ดัชนีตาราง
  • MVCC (Multiversioning Concurrency Control)ข้อมูล
    • ส่วนย้อนกลับ
    • เลิกทำ Space
  • ตารางข้อมูลเมตา (พจนานุกรมข้อมูล)
  • บัฟเฟอร์การเขียนซ้ำ (การเขียนพื้นหลังเพื่อป้องกันการพึ่งพาระบบปฏิบัติการแคช)
  • แทรกบัฟเฟอร์ (จัดการการเปลี่ยนแปลงดัชนีรองที่ไม่ซ้ำกัน)
  • ดู Pictorial Representation of 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.mytableOR 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 นั้นดีที่สุด


ข้อมูลยอดเยี่ยม - ขอบคุณ! 50GB >> 50MB - มันค่อนข้างน่าประทับใจ!
UpTheCreek

สวัสดีฉันพยายามทำทุกอย่างตามที่คุณเขียนไว้ที่นี่ปัญหา 'เพียงอย่างเดียวคือเซิร์ฟเวอร์ไม่ได้เริ่มทำงานหลังจากนั้น ถ้าฉันทำบริการ mysql เริ่มมันก็แค่แฮง ถ้าฉันเปลี่ยนกลับไฟล์ cnf เก่าของฉันทุกอย่างก็โอเค คุณมีเงื่อนงำเกี่ยวกับเรื่องนี้หรือไม่?
Nicola Peluchetti

คำถามนี้มีไว้สำหรับ Nicola: คุณทำขั้นตอนที่ 5 ???
RolandoMySQLDBA

คำถามอื่นสำหรับ @Nicola: คุณมี RAM เท่าใดในระบบของคุณ ???
RolandoMySQLDBA

2
ระวัง! ตัวเลือกinnodb_fast_shutdown=0จะต้องตั้งค่าใน MySQL ก่อนที่จะปิดมันเพื่อลบไฟล์บันทึก! ( ib_logfile0และib_logfile1) มิฉะนั้นคุณอาจสูญเสียข้อมูล!
Totor

12

ดูข้อผิดพลาด

มีข้อเสียในการใช้หรือไม่

  • เปิดไฟล์เพิ่มเติม
  • เปิด / เปิดค่าใช้จ่ายอีกครั้ง
  • ไฟล์. ibd ไม่ลดขนาด (ดู1 , 2 )

ฉันมักจะใช้ innodb_file_per_table กับฐานข้อมูลขนาดใหญ่


แม้ว่าคุณจะไม่ได้ใช้งานก็ตามไฟล์ ibdata ก็จะไม่ย่อขนาดเช่น :(
minaev

1
ขอบคุณ ฉันยังสงสัยว่าทำไมไม่มีตัวเลือกที่จะมีไฟล์ต่อ db?
UpTheCreek

1
@UpTheCreek ตารางเป็นเอนทิตี ฐานข้อมูลเป็นกลุ่มของเอนทิตีแบบลอจิคัลแทนที่จะเป็นเอนทิตีในสิทธิ์ของตนเอง เป็นที่ชัดเจนยิ่งขึ้นด้วย MyISAM ซึ่งฐานข้อมูลเป็นไดเรกทอรีและตารางเป็นไฟล์
John Gardeniers

เพียงต้องการชี้ให้เห็นว่าในขณะที่ไฟล์. ibd ไม่หดตัวลงโดยอัตโนมัติไม่เช่นนั้นจะibdata1เป็นทางเลือกสำหรับไฟล์ต่อตาราง อย่างน้อยก็เป็นไปได้ที่จะลดขนาด. ibd โดยใช้optimize tableซึ่งน้อยมากเมื่อเทียบกับการย่อขนาด ibdata1
RomanSt

8

innodb_file_per_table ถูกเปิดใช้งานโดยค่าเริ่มต้นใน MariaDB


1
ไม่ใช่ของฉัน (เวอร์ชันเริ่มต้นใน CentOS 7) คุณต้องเทียบเท่ากับ MySQL 5.6.6 หรือใหม่กว่า มิฉะนั้นเริ่มต้นคือปิด
การแข่งขัน Lightness กับ Monica

2

เหตุผลที่ฉันเลือกที่จะไม่ใช้innodb_file_per_tableเป็นเพราะแต่ละตารางถูกใส่ไว้ในไฟล์ของตัวเองซึ่งหมายความว่าแต่ละตารางจะได้รับค่าใช้จ่ายแยกต่างหาก (ลายเซ็นไฟล์ ฯลฯ ) ซึ่งทำให้ขนาดโดยรวมของMySQLไดเรกทอรีเป็น ใหญ่กว่าถ้าใช้พื้นที่ตารางที่ใช้ร่วมกัน นอกจากนี้ยังมีพื้นที่ที่สิ้นเปลืองมากขึ้นเนื่องจากการหย่อนคลัสเตอร์เมื่อมีหลายไฟล์ขนาดเล็กแทนไฟล์เดียวที่มีขนาดใหญ่

ที่ได้รับค่าใช้จ่ายที่เพิ่มขึ้นไม่ได้เป็นขนาดใหญ่จำนวนเงินในโครงการใหญ่ของสิ่งโดยเฉพาะอย่างยิ่งถ้าคุณกำลังใช้ไดรฟ์ที่มีขนาดใหญ่หรือมีฐานข้อมูลขนาดยักษ์ แต่สำหรับตัวเอง (และอาจจะหลายบ้าน“ผู้ใช้”) มันทั้งหมดเพิ่มขึ้นและ ยังคงมากเกินไปสำหรับไดรฟ์ขนาดเล็กที่มีกลุ่มใหญ่ที่ฉันเก็บ MySQL ของฉัน

ตัวอย่างเช่นที่เก็บฐานข้อมูลของฉันกับฐานข้อมูล WordPress ของฉันและฐานข้อมูลขนาดเล็กอื่น ๆ (phpBB, dev, การทดสอบ AMP และอื่น ๆ ) การแปลงเป็นแบบตารางต่อตารางเปลี่ยนจาก 32MB เป็น 50MB และไม่ได้รวมถึงสิ่งibdata1ที่ยังต้องมีอย่างน้อย 10MBรวมอย่างน้อย 60MB

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


1
ฉันคิดว่าคุณเป็นถั่ว (ที่ใส่ใจประมาณสิบเมกะไบต์ ???) จนกว่าคุณจะได้รับจุดเกี่ยวกับโควต้าแน่นที่ผู้ให้บริการโฮสติ้ง จะไม่คิดอย่างนั้น
Dan Pritts

@DanPritts โดยเฉพาะโฮสต์ฟรี นอกจากนี้คุณอาจมีไดรฟ์ขนาดใหญ่ แต่ทุกคนไม่ได้ ฉันขยายพาร์ติชันข้อมูลหลักของฉันจาก 1GB เป็น 2GB ในปีที่แล้วเพราะมันแน่นเกินไป แต่ถึง 10MB ที่นี่และ 10MB ที่นั่น (โดยเฉพาะอย่างยิ่งกับไฟล์บันทึก) สามารถกินมันได้อย่างรวดเร็ว นอกจากนี้อย่าลืมว่าเพิ่มขยะคลัสเตอร์ด้วย สุดท้ายก็ไม่ได้จำเป็นต้องเป็นฮาร์ดไดรฟ์ ตัวอย่างเช่นขณะนี้ฉัน“ portablizing” เว็บไซต์ของฉันเพื่อให้ฉันสามารถโฮสต์จากระบบใด ๆ ดังนั้นแฟลชไดรฟ์ 2GB มี จำกัด แล้ว ดังนั้นการทำให้ขนาดเล็กและหลีกเลี่ยงการเขียนเป็นสิ่งสำคัญ แล้วมีระบบฝังตัว!
Synetech

นอกจากนี้ยังไม่ใช่ 10MB (นั่นคือขนาดที่เล็กที่สุดสำหรับIBDATA1) มันเปลี่ยนจาก 30MB เป็น ~ 85MB ด้วยการลบสิ่งทั้งหมดและนำเข้าดัมพ์จากศูนย์ฉันเลยจบด้วย 69MB แทนที่จะเป็น 30MB ก่อนหน้านี้ (หนึ่งเดาว่าฐานข้อมูลใดที่ใช้เกินครึ่งหนึ่งของมัน☺) ด้วยเหตุผลบางอย่างแม้จะใช้ต่อตารางฉันibdata1ยังคงเป็น 18MB ☹
Synetech

เสียงค่อนข้างเหมือนสิ่งที่ฉันมีเมื่อติดตั้ง CMS กับ vs. หนึ่งโดยไม่ต้องเปิดใช้งาน selinux โดยพิจารณาจากขนาดไฟล์ 32M กับ 50M ฉันไม่อยากเชื่อตัวเลขจริงๆคุณมีฐานข้อมูลจำนวนเท่าใดที่มีเมตาดาต้าของไฟล์บางไฟล์ที่สามารถเพิ่มขนาด MEGABYTES ให้กับระบบอื่น ๆ
sjas

2

เพียงเพิ่มข้อมูลอีกเล็กน้อย

ตั้งแต่ mysql 5.6.6 มันเปิดใช้งานโดยค่าเริ่มต้น


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