เหตุใด InnoDB จึงจัดเก็บฐานข้อมูลทั้งหมดไว้ในไฟล์เดียว


51

มันสะดวกที่ MyISAM ใช้เก็บแต่ละตารางในไฟล์ที่เกี่ยวข้อง InnoDB มีความก้าวหน้าในหลาย ๆ ด้าน แต่ฉันสงสัยว่าทำไม InnoDB จึงเก็บฐานข้อมูลทั้งหมดไว้ในไฟล์เดียว ( ibdata1โดยค่าเริ่มต้น)

ฉันเข้าใจว่า InnoDB จะจับคู่ตำแหน่งของข้อมูลในไฟล์โดยแต่ละไฟล์ดัชนีสำหรับตาราง แต่ฉันไม่เข้าใจว่าทำไมมันจึงรวมข้อมูลทั้งหมดไว้ในไฟล์เดียว และที่สำคัญทำไมผสมข้อมูลของฐานข้อมูลทั้งหมดบนเซิร์ฟเวอร์

คุณลักษณะที่น่าสนใจของ MyISAM คือสามารถคัดลอก / วางโฟลเดอร์ฐานข้อมูลไปยังเครื่องอื่นแล้วใช้ฐานข้อมูล (โดยไม่ต้องถ่ายโอนข้อมูล)

คำตอบ:


66

สถาปัตยกรรมของ InnoDB ต้องการการใช้หน้าข้อมูลพื้นฐานสี่ประเภท

  • หน้าข้อมูลตาราง
  • หน้าดัชนีตาราง
  • ตาราง MetaData
  • ข้อมูล MVCC (เพื่อสนับสนุนการแยกธุรกรรมและความสอดคล้องกับกรด )
    • ส่วนย้อนกลับ
    • เลิกทำ Space
    • บัฟเฟอร์การเขียนซ้ำ (การเขียนพื้นหลังเพื่อป้องกันการพึ่งพาระบบปฏิบัติการแคช)
    • แทรกบัฟเฟอร์ (จัดการการเปลี่ยนแปลงดัชนีรองที่ไม่ซ้ำกัน)

ดูภาพการเป็นตัวแทนของ ibdata1

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

นี่คือเหตุผลที่ผมมักจะแนะนำให้ทำความสะอาดโครงสร้างพื้นฐาน InnoDB โดยใช้ไฟล์ ibdata1 เริ่มต้นและไม่มีอะไรเพิ่มเติม

การคัดลอกนั้นอันตรายมากเนื่องจากโครงสร้างพื้นฐานที่ InnoDB ทำงาน มีโครงสร้างพื้นฐานสองขั้นพื้นฐาน

  • innodb_file_per_table ถูกปิดใช้งาน
  • เปิดใช้งาน innodb_file_per_table

InnoDB ( innodb_file_per_tableถูกปิดใช้งาน)

เมื่อปิดใช้งานinnodb_file_per_tableข้อมูล InnoDB เหล่านี้ทั้งหมดจะเผยแพร่ภายใน ibdata1 การรวมตัวกันของตาราง InnoDB ใด ๆ ภายนอก ibdata1 คือไฟล์. frm ของตาราง InnoDB การคัดลอกข้อมูล InnoDB ทั้งหมดในครั้งเดียวจำเป็นต้องคัดลอกทั้งหมดของ / var / lib / mysql

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

InnoDB ( เปิดใช้งานinnodb_file_per_table )

เมื่อเปิดใช้งานinnodb_file_per_tableข้อมูลในตารางและดัชนีจะอยู่ในโฟลเดอร์ฐานข้อมูลถัดจากไฟล์. frm ตัวอย่างเช่นสำหรับตาราง db1.mytable การรวมตัวกันของตาราง InnoDB ภายนอก ibdata1 จะเป็น:

  • /var/lib/mysql/db1/mytable.frm
  • /var/lib/mysql/db1/mytable.ibd

ตารางระบบ ibdata1

ข้อมูลเมตาทั้งหมดสำหรับ db1.mytable ยังคงอยู่ใน ibdata1 และไม่มีทางแก้ไข ทำซ้ำบันทึกและข้อมูล MVCC ยังคงใช้งานได้กับ ibdata1

เมื่อพูดถึงการแตกแฟรกเมนต์ของตารางนี่คือสิ่งที่เกิดขึ้นกับ ibdata1:

  • innodb_file_per_tableเปิดการใช้งาน : คุณสามารถหด db1.mytables ด้วยหรือALTER TABLE db1.mytable ENGINE=InnoDB; OPTIMIZE TABLE db1.mytable;ซึ่งส่งผลให้ /var/lib/mysql/db1/mytable.ibd มีขนาดเล็กลงโดยไม่มีการแตกแฟรกเมนต์
  • innodb_file_per_tableถูกปิดใช้งาน : คุณไม่สามารถย่อ db1.mytables ด้วยALTER TABLE db1.mytable ENGINE=InnoDB;หรือOPTIMIZE TABLE db1.mytable;เพราะมันอยู่กับ ibdata1 เรียกใช้คำสั่งทั้งสองจริงทำให้ตารางต่อเนื่องกันและเร็วกว่าในการอ่านและเขียน น่าเสียดายที่เกิดขึ้นในตอนท้ายของ ibdata1 สิ่งนี้ทำให้ ibdata1 เติบโตอย่างรวดเร็ว นี้เป็น addressed อย่างเต็มที่ในการล้างข้อมูล InnoDB โพสต์ของฉัน

คำเตือน (หรืออันตรายเป็นหุ่นยนต์จะพูดในที่หายไปในอวกาศ )

หากคุณกำลังคิดที่จะคัดลอกไฟล์. frm และ. ibd คุณจะเข้าสู่โลกแห่งความเจ็บปวด คัดลอก .frm และไฟล์ .ibd ของตาราง InnoDB เป็นดีเท่านั้นและถ้าหากคุณสามารถรับประกันได้ว่ารหัส tablespace ของแฟ้ม .ibd ตรงกันกับรายการ tablespace ID ในข้อมูลเมตาของไฟล์

ฉันเขียนสองโพสต์ใน DBA StackExchange เกี่ยวกับแนวคิด id tablespace นี้

นี่คือการเชื่อมโยงที่ดีเกี่ยวกับวิธีการใส่กลับเข้าไปไฟล์ .ibd ใด ๆ ที่จะ ibdata1 ในกรณีของรหัส tablespace ไม่ตรงกัน: http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in-file หลังจากอ่านสิ่งนี้แล้วคุณควรตระหนักทันทีว่าการคัดลอกไฟล์. ibd เป็นสิ่งที่ธรรมดามาก

สำหรับ InnoDB คุณจะต้องทำสิ่งนี้เพื่อย้ายเท่านั้น

CREATE TABLE db2.mytable LIKE db1.mytable;
INSERT INTO db2.mytable SELECT * FROM db1.mytable;

เพื่อสร้างสำเนาของตาราง InnoDB

หากคุณย้ายข้อมูลไปยังเซิร์ฟเวอร์ฐานข้อมูลอื่นให้ใช้ mysqldump

ในเรื่องของการผสมตาราง InnoDB ทั้งหมดจากฐานข้อมูลทั้งหมดฉันสามารถเห็นภูมิปัญญาในการทำเช่นนั้น ที่ บริษัท ผู้ให้บริการโฮสต์ DB / เว็บของฉันฉันมีไคลเอนต์ MySQL หนึ่งตัวที่มีตารางในฐานข้อมูลหนึ่งซึ่งมีข้อ จำกัด ถูกแมปกับตารางอื่นในฐานข้อมูลอื่นภายในอินสแตนซ์ MySQL เดียวกัน ด้วยที่เก็บข้อมูลเมตาทั่วไปหนึ่งรายการทำให้การสนับสนุนธุรกรรมและความสามารถในการทำงานของ MVCC สามารถทำได้ในหลายฐานข้อมูล


มันหมายความว่าเมื่อฉันใช้ไฟล์ innodb ต่อการเปิดใช้งานตารางและถ้าฉันต้องการนำเข้าข้อมูลจากเซิร์ฟเวอร์หนึ่งไปยังอีกเซิร์ฟเวอร์หนึ่งฉันจะต้องใช้ mysqldump เท่านั้นและไม่ใช่เครื่องมืออื่น ๆ เช่น Percona xtrabackup?
tesla747

14

คุณสามารถสลับ InnoDB เพื่อจัดเก็บตารางต่อไฟล์โดยเพิ่ม innodb-file-per-table ใน cnf ของคุณ

Innodb ให้ความสำคัญกับหน้าข้อมูลในระดับพื้นฐานจริงๆ ในความเป็นจริงคุณสามารถตั้งค่า InnoDB ให้ใช้เพียงแค่อุปกรณ์ raw block ที่ไม่มีระบบไฟล์อย่างที่เคยเป็นมา! http://dev.mysql.com/doc/refman/5.5/en/innodb-raw-devices.html

มีความสะดวกในการจัดเก็บตารางสำหรับไฟล์เช่นสามารถคืนพื้นที่ใช้งานได้ง่ายขึ้นผ่านการปรับให้เหมาะสม

แม้จะมีไฟล์ต่อตารางคุณก็ไม่สามารถคัดลอกไฟล์ ibd ได้อย่างง่ายดายเนื่องจาก InnoDB เป็นธุรกรรมและเก็บข้อมูลเกี่ยวกับสถานะในไฟล์ ibdata / log ที่ใช้ร่วมกันทั่วโลก

ไม่ได้หมายความว่าจะทำไม่ได้ หากตารางออฟไลน์คุณสามารถยกเลิก / นำเข้าพื้นที่ตารางและคัดลอก. idbs รอบ ๆhttp://dev.mysql.com/doc/refman/5.5/en/innodb-multiple-tablespaces.html


ไม่ต้องสงสัยเลยว่า InnoDB นั้นเป็นเอ็นจิ้นที่มีความยืดหยุ่น แต่ฉันไม่เข้าใจว่าการจัดเก็บข้อมูลทั้งหมดในไฟล์เดียวมีประโยชน์อย่างไร (เนื่องจากโครงสร้างใหม่นี้มีการใช้งานใน InnoDB เปรียบเทียบกับ MyISAM)
Googlebot

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

นั่นคือจุดที่ไม่ต้องพึ่งพาระบบไฟล์อาจเป็นสิ่งที่มีค่า แต่มันจะไม่ทำงานตามค่าเริ่มต้น ดังนั้นผู้ใช้ไม่กี่คนจะใช้มัน
Googlebot

1
ตัวเลือกหนึ่งไฟล์ต่อหนึ่งตารางอาจทำให้เกิดอันตรายได้หากคุณมีหลายตารางและ RAM ไม่มาก (ตัวอย่างเช่นที่เก็บ Magento อาจมีประมาณ 1,000 ตาราง) และการตั้งค่าไฟล์แบบเปิดจะต้องได้รับการปรับให้เหมาะสมเช่นกัน ดังนั้นควรใช้ด้วยความระมัดระวัง
ypercubeᵀᴹ

แน่นอนว่ามันสามารถลดการสั่นสะเทือนได้ ใช่คุณควรมีการสำรองข้อมูล แต่ถ้าคุณไม่มี InnoDB จะทำให้สิ่งต่าง ๆ ยากขึ้นเนื่องจากโครงสร้างนี้
mikato

10

นี่เป็นพฤติกรรมเริ่มต้น แต่ไม่บังคับ จากเอกสาร MySQL, การใช้ตารางต่อตาราง :

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

สาเหตุที่เป็นไปได้คือสถาปัตยกรรมที่แตกต่างกันของทั้งสองเครื่องยนต์ (MyISAM และ InnoDB) ตัวอย่างเช่นใน InnoDB คุณไม่สามารถคัดลอกไฟล์. ibd ไปยังฐานข้อมูลหรือการติดตั้งอื่นได้ คำอธิบาย (จากหน้าเดียวกัน):

ข้อควรพิจารณาในการพกพาสำหรับไฟล์. ibd

คุณไม่สามารถย้ายไฟล์. ibd ได้อย่างอิสระระหว่างไดเรกทอรีฐานข้อมูลเช่นเดียวกับไฟล์ตาราง MyISAM คำจำกัดความของตารางที่เก็บอยู่ในพื้นที่ตารางที่ใช้ร่วมกันของ InnoDB มีชื่อฐานข้อมูล ID ธุรกรรมและหมายเลขลำดับการบันทึกที่เก็บในไฟล์ tablespace จะแตกต่างกันระหว่างฐานข้อมูล


คำตอบที่ให้ข้อมูลมากและชี้แจงปัญหา แต่ฉันก็ยังสงสัยว่าไฟล์ขนาดใหญ่ที่มีฐานข้อมูลทั้งหมดสามารถปรับปรุงประสิทธิภาพได้อย่างไร (ถ้ามี)
Googlebot

ประสิทธิภาพไม่ดีขึ้นเนื่องจากมีไฟล์เดียวสำหรับทุกคน คุณสมบัติต่าง ๆ เช่นการล็อคระดับแถวแทนระดับตารางช่วยเพิ่มประสิทธิภาพ ประโยชน์หลักคือธุรกรรมและข้อ จำกัด FK (และความสมบูรณ์ของฐานข้อมูล)
ypercubeᵀᴹ

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