ทำไมต้องใช้ innodb_file_per_table


26

มีบทความจำนวนมากเกินความจริง (IMHO ของหลักสูตร) innodb_file_per_tableจำเป็นที่จะต้องมี ฉันเข้าใจว่าด้วยinnodb_file_per_tableควรมีการควบคุมที่ดีกว่าตารางบุคคล เช่นการสำรองข้อมูลแต่ละตารางแยกจากกัน อย่างไรก็ตามการเรียกร้องเพื่อประสิทธิภาพที่ดีขึ้นเป็นที่น่าสงสัย

ในการทดสอบของฉันไม่มีความแตกต่างของประสิทธิภาพinnodb_file_per_tableและibdata1ฐานข้อมูล 60GB แน่นอนว่ามันเป็นแบบทดสอบง่ายๆที่มีคำสั่งปกติและสถานการณ์อาจแตกต่างกันไปสำหรับการค้นหาที่ซับซ้อนในชีวิตจริง (นี่คือเหตุผลที่ฉันถามคำถามนี้) Linux 64 บิตพร้อมกับext4สามารถจัดการไฟล์ขนาดใหญ่ได้อย่างมีประสิทธิภาพ

ด้วยinnodb_file_per_tableการดำเนินการดิสก์ I / O เพิ่มเติมจำเป็น และสิ่งนี้มีความสำคัญในข้อ จำกัดJOINและความซับซ้อนFOREIGN KEY

Tablespace ใช้งานร่วมกันบน single ibdata; พื้นที่ตารางเฉพาะสำหรับตารางแยกต่างหากสามารถประหยัดพื้นที่ดิสก์ได้อย่างไร แน่นอนว่ามันเป็นเรื่องง่ายกว่าที่จะเพิ่มพื้นที่ว่างสำหรับแต่ละตารางด้วยALTERแต่ก็ยังเป็นกระบวนการที่มีราคาแพง (ด้วยการล็อคตาราง)

คำถาม:ไม่innodb_file_per_tableมีผลกระทบต่อผลการดำเนินงานที่ดีขึ้นของ MySQL? ถ้าใช่ทำไม


ดูคำตอบสำหรับคำถามของฉันนี้: dba.stackexchange.com/questions/7924/…อาจช่วยได้เช่นกัน
กม.

คำตอบ:


19

ฉันไม่คิดว่ามันเป็นเรื่องของประสิทธิภาพ แต่เป็นการจัดการ

ด้วยไฟล์แยกต่างหากต่อตารางคุณสามารถจัดเก็บฐานข้อมูลที่แตกต่างกันในอุปกรณ์จัดเก็บข้อมูลที่แตกต่างกันเช่น

คุณสามารถจัดการกับกรณีของฐานข้อมูลที่มีขนาดใหญ่มากในระบบไฟล์ที่ไม่สามารถจัดการไฟล์ขนาดใหญ่ได้ (อย่างน้อยก็เลื่อนปัญหาออกไปจนกว่าตารางหนึ่งจะมีขนาดถึงขีด จำกัด ขนาดไฟล์)

คุณไม่มีการเติบโตของพื้นที่ตารางที่ไม่สามารถควบคุมได้ หากคุณมีตารางขนาดใหญ่ที่คุณวางibdataไฟล์จะมีขนาดเล็ก

ด้านหนึ่งที่อาจมีผลกระทบต่อประสิทธิภาพการทำงานคือการกระจายตัวของข้อมูลตารางและดัชนีซึ่งจะถูก จำกัด ต่อตาราง แต่นั่นต้องมีการทดสอบเพื่อยืนยัน


การเติบโตของพื้นที่ตารางเป็นสิ่งที่คุณต้องการinnodb_file_per_tableอย่างแท้จริง
sjas

13

ทำไมต้องใช้ innodb_file_per_table

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

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

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

อย่างไรก็ตามการเรียกร้องเพื่อประสิทธิภาพที่ดีขึ้นเป็นที่น่าสงสัย …ด้วย innodb_file_per_table จำเป็นต้องใช้การทำงานของดิสก์ I / O เพิ่มเติม และสิ่งนี้มีความสำคัญในการเข้าร่วมที่ซับซ้อนและข้อ จำกัด ที่สำคัญของต่างประเทศ

ไม่น่าแปลกใจที่ประสิทธิภาพจะขึ้นอยู่กับฐานข้อมูลเฉพาะที่ใช้งานทั้งหมด คนคนหนึ่งจะมีผลลัพธ์ที่แตกต่างจากคนอื่น

มันเป็นความจริงว่าจะมีผมดิสก์มากขึ้น / O การดำเนินงานที่มีโต๊ะไฟล์ต่อ แต่เพียงเล็กน้อยมากขึ้น คิดว่าระบบทำงานอย่างไร

  • สำหรับฐานข้อมูลเสาหิน:

    1. เซิร์ฟเวอร์เริ่มทำงาน
    2. ibdata1 เปิดแล้ว
    3. อ่านส่วนหัวและเมตาดาต้า
    4. โครงสร้างและเมตาดาต้าถูกแคชในหน่วยความจำ
    5. คำค้นหาเกิดขึ้น
      1. เซิร์ฟเวอร์เข้าถึงดิสก์และอ่านข้อมูลจากที่เปิดอยู่แล้ว ibdata1
      2. เซิร์ฟเวอร์อาจแคชข้อมูลในหน่วยความจำ
  • สำหรับฐานข้อมูลต่อตาราง:

    1. เซิร์ฟเวอร์เริ่มทำงาน
    2. ibdata1 เปิดแล้ว
    3. อ่านส่วนหัวและเมตาดาต้า
    4. แต่ละ.ibdไฟล์ถูกเปิด
    5. ส่วนหัวและข้อมูลเมตาจะอ่านจากแต่ละ.ibdไฟล์
    6. โครงสร้างและเมตาดาต้าถูกแคชในหน่วยความจำ
    7. คำค้นหาเกิดขึ้น
      1. เซิร์ฟเวอร์เข้าถึงดิสก์และอ่านข้อมูลจาก.ibdไฟล์ที่เปิดอยู่แล้ว
      2. เซิร์ฟเวอร์อาจแคชข้อมูลในหน่วยความจำ

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

ดังนั้นจึงมีการดำเนินการ I / O เพียงเล็กน้อยเท่านั้นในตอนเริ่มต้นเมื่อเซิร์ฟเวอร์เริ่มทำงาน ไม่ใช่ในขณะที่กำลังทำงาน นอกจากนี้ในขณะที่แต่ละ.ibdไฟล์มีค่าใช้จ่ายแยกต่างหาก (ลายเซ็นไฟล์โครงสร้าง ฯลฯ ) พวกเขาจะถูกเก็บไว้ในหน่วยความจำและไม่อ่านอีกครั้งสำหรับแต่ละแบบสอบถาม นอกจากนี้โครงสร้างเดียวกันจะถูกอ่านแม้จะมีพื้นที่ตารางที่ใช้ร่วมกันดังนั้นจึงแทบไม่มีหน่วยความจำเพิ่มเติมใด ๆ (ถ้ามีเลย)

innodb_file_per_table มีผลต่อประสิทธิภาพที่ดีขึ้นของ mysql หรือไม่?

อันที่จริงถ้ามีอะไรที่ผลการดำเนินงานในความเป็นจริงอาจจะเลวร้ายยิ่ง

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

อย่างไรก็ตามหากข้อมูลถูกกระจายออกไปในหลาย ๆ ไฟล์มันจะต้องทำการแยก I / O แยกสำหรับแต่ละไฟล์

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

Tablespace ใช้งานร่วมกันบน ibdata เดียว พื้นที่ตารางเฉพาะสำหรับตารางแยกต่างหากสามารถประหยัดพื้นที่ดิสก์ได้อย่างไร

มันไม่ใช่. หากมีสิ่งใดจะเพิ่มการใช้งานดิสก์ได้บ้าง

ฉันไม่มีฐานข้อมูล 60GB ที่จะทดสอบ แต่ฐานข้อมูลส่วนบุคคล“ paltry” ของฉันซึ่งมีการติดตั้ง WordPress ของฉันและมีตารางเล็ก ๆ น้อย ๆ สำหรับการทดสอบการใช้งานส่วนตัวและการพัฒนาที่มีน้ำหนักประมาณ ~ 30MB ในขณะที่ใช้พื้นที่ตารางร่วม หลังจากแปลงเป็นไฟล์ต่อตารางแล้วมันจะขยายเป็น ~ 85MB แม้จะวางทุกอย่างและนำเข้าอีกครั้งก็ยังคง> 60MB

การเพิ่มขึ้นนี้เกิดจากสองปัจจัย:

  • น้อยที่สุดขนาดibdata1เป็น-ด้วยเหตุผลบางอย่าง-10MB, แม้ว่าคุณจะมีอะไร แต่information_schemaเก็บไว้ในนั้น

  • ด้วยพื้นที่ตารางที่ใช้ร่วมกันจะibdata1มีค่าใช้จ่ายเช่นเดียวกับลายเซ็นไฟล์ meta-data เป็นต้น แต่ด้วยตารางต่อ.ibdไฟล์แต่ละไฟล์จะมีทั้งหมดนั้น ซึ่งหมายความว่ายอดรวม (แม้จะมี <10MB สมมุติibdata1) จะค่อนข้างใหญ่กว่าอย่างน้อย:

    GetTotalSizeofOverhead() * GetNumTables()

เห็นได้ชัดว่าสิ่งเหล่านี้จะไม่เพิ่มขึ้นอย่างมาก (เว้นแต่ว่าคุณกำลังใช้โฮสต์ที่ จำกัด ขนาดฐานข้อมูลของคุณหรือเก็บไว้ในแฟลชไดรฟ์ ฯลฯ ) แต่จะเพิ่มขึ้นอย่างมากและในขณะที่สลับตารางทุกไฟล์ ต่อหนึ่งตารางคุณสามารถหดตัวibdata1ลงไป 10MB, รวมโดยรวมอย่างสม่ำเสมอจะมีมากขึ้นกว่าเดิม


11

นี่คือเหตุผลของฉันสำหรับการใช้ innodb_file_per_table เสมอ:

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

สมมติว่าคุณต้องการสำรองข้อมูลของตาราง 1GB ปัจจุบันก่อนที่จะทำการเปลี่ยนแปลงจากนั้นจึงวางลงในภายหลัง คุณติดพื้นที่ว่างที่ไม่ได้ใช้ใน GB ของคุณในขณะนี้ คนเกียจคร้าน

อาจมีตัวอย่างที่ไม่มีที่สิ้นสุดของกรณีที่การวัดชั่วคราวขยายไฟล์ข้อมูลเดียว แต่พอเพียงที่จะบอกว่าในความคิดของฉันไม่มีเหตุผลที่จะไม่ใช้ innodb_file_per_table

และนี่คือโพสต์ที่ดีที่ควรอ่าน: http://code.openark.org/blog/mysql/reasons-to-use-innodb_file_per_table


1
ฉันรู้ว่ามันดีที่จะทำเช่นนั้นเสมอ อาร์เรย์หน่วยเก็บข้อมูลแม่เหล็กที่สนับสนุนโดย SSD สามารถจัดการแคชการอ่าน / เขียนได้อย่างมีประสิทธิภาพยิ่งขึ้นเมื่อเทียบกับไฟล์ขนาดเล็กลงสำหรับตาราง สำหรับกลุ่มตารางที่% 99.99 ของเวลาเพิ่งได้รับ 'อ่าน' แต่ไม่ได้เขียนพวกเขาจะอยู่ในแคชของตัวควบคุมหน่วยเก็บข้อมูลเสมอซึ่งเป็นการลดเวลาตอบสนองที่ยอดเยี่ยม
sdkks

5

เหตุผลของฉันทำไมไม่ใช้ innodb_file_per_tableคือประสิทธิภาพ

ฉันทำการทดสอบบางอย่างสำหรับฐานข้อมูลของเราโดยมี 450 ตารางบน mysql 5.5.45 Linux CentOS รีลีส 6.7

สำหรับการทดสอบหน่วยที่แทรกตัวติดตั้งลงในฐานข้อมูลก่อนการทดสอบแต่ละครั้ง (ไม่ได้ใช้ตารางทั้งหมดทุกครั้ง) และการทดสอบตัวเองทำงานกับฐานข้อมูลได้มาก (ส่วนแทรกอัพเดตลบเลือก) ประสิทธิภาพการทำงานดีขึ้น 3-5 เท่าเมื่อตารางฐานข้อมูลไม่ แยกออกเป็นไฟล์เพิ่มเติม

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

บางทีคุณอาจพบว่าสำหรับเซิร์ฟเวอร์ที่ใช้งานจริงคุณสามารถใช้ innodb_file_per_table แต่สำหรับสภาพแวดล้อม CI (รวมต่อไป) ซึ่งเริ่มการทดสอบหน่วย (ใช้ฐานข้อมูลจำนวนมาก) และนักพัฒนาที่เริ่มทดสอบหน่วยจำนวนมากจะไม่ควรใช้เพราะประสิทธิภาพ


2
ฉันเดาว่านี่เป็นเพราะเวลาที่ต้องใช้ในการจัดสรรไฟล์เริ่มต้นสำหรับ 450 ตารางทั้งหมดเทียบกับการจัดสรรหนึ่งไฟล์ ในการผลิตสิ่งนี้จะเกิดขึ้นเพียงครั้งเดียวเท่านั้นดังนั้นจึงไม่ควรเป็นปัญหา แต่คุณควรสร้างจุดที่ดีสำหรับการสร้างฐานข้อมูลอย่างรวดเร็วและจากนั้นให้ฉีกและทำซ้ำอย่างสมบูรณ์ซ้ำแล้วซ้ำอีกไฟล์ ibdata เดียวดีกว่า
ColinM

2

ทำให้ข้อมูลสามารถจัดการได้มากขึ้นเพราะคุณสามารถเรียกคืนพื้นที่ที่ไม่ได้ใช้ซึ่งดีมาก

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

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

นี่คือโพสต์จากคนที่พบปัญหานี้: http://umangg.blogspot.com/2010/02/innodbfilepertable.html


2

ตามบทความด้านล่างประสิทธิภาพไม่ได้เกี่ยวกับการจัดการข้อมูล (การดำเนินการ crud เอง) แต่เกี่ยวกับการสร้างและวางวัตถุ

innodb_file_per_table ทำให้การสร้างและวางวัตถุขนาดใหญ่ช้ากว่าที่เก็บข้อมูล ibdata และสำหรับการผลิตไม่สามารถใช้ได้ แต่สำหรับการทดสอบอย่างต่อเนื่องควรเกี่ยวข้องกัน

https://www.percona.com/blog/2015/02/24/mysqls-innodb_file_per_table-slowing/


1

IMHO มันจะดีกว่าถ้าใช้ innodb_file_per_table จะปลอดภัยยิ่งขึ้น หากคุณไม่ได้ใช้งานคุณอาจมีปัญหากับระบบ FAT32 ซึ่งอนุญาตให้ใช้ไฟล์ขนาด 4 GB เท่านั้น ฉันเขียนบทความเกี่ยวกับเรื่องนี้ในภาษาสโลวัก ( https://www.itsoft.sk/preco-sa-neuvolni-miesto-na-disku-po-zmazani-mysql-tabulky/ )

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