Mengapa menggunakan innodb_file_per_table?

27

Ada banyak artikel yang melebih-lebihkan (IMHO tentu saja) kebutuhan innodb_file_per_table. Saya mengerti bahwa dengan innodb_file_per_table, harus ada kontrol yang lebih baik atas tabel individu; seperti cadangan setiap tabel secara terpisah. Namun, klaim untuk kinerja yang lebih baik masih dipertanyakan.

Dalam pengujian saya, tidak ada perbedaan dalam kinerja innodb_file_per_tabledan ibdata1untuk database 60GB. Tentu saja, itu adalah tes sederhana dengan pertanyaan normal, dan situasinya bisa berbeda untuk pertanyaan rumit dalam kehidupan nyata (ini adalah alasan mengapa saya mengajukan pertanyaan ini). Linux 64-bit dengan ext4efektif dapat menangani file besar.

Dengan innodb_file_per_table, lebih banyak operasi I / O disk diperlukan; dan ini penting dalam masalah JOINdan FOREIGN KEYkendala yang rumit .

Tablespace dibagi dalam satu ibdata; bagaimana tablespace khusus untuk tabel terpisah dapat menghemat ruang disk? Tentu saja, lebih mudah untuk mengosongkan ruang meja untuk setiap meja ALTER, tetapi masih merupakan proses yang mahal (dengan kunci meja).

PERTANYAAN: Apakah innodb_file_per_tableberpengaruh pada kinerja mysql yang lebih baik? Jika ya, mengapa?

Googlebot
sumber
Lihat jawaban ini untuk pertanyaan saya: dba.stackexchange.com/questions/7924/… mungkin membantu juga.
KM.

Jawaban:

19

Saya tidak berpikir ini masalah kinerja tetapi manajemen.

Dengan file terpisah per tabel, Anda dapat menyimpan basis data yang berbeda di perangkat penyimpanan yang berbeda misalnya.

Anda dapat menangani kasus basis data sangat besar dalam sistem file yang tidak dapat menangani file besar (setidaknya menunda masalah sampai satu tabel mencapai batas ukuran file).

Anda tidak memiliki pertumbuhan tablespace yang tidak terkendali. Jika Anda memiliki beberapa tabel besar yang Anda jatuhkan, ibdatafile tersebut tetap kecil.

Salah satu aspek yang mungkin memiliki beberapa efek pada kinerja adalah fragmentasi data tabel dan indeks, yang akan dibatasi per tabel. Tapi itu perlu pengujian untuk dikonfirmasi.

ypercubeᵀᴹ
sumber
Pertumbuhan tablespace adalah persis mengapa Anda inginkan innodb_file_per_table.
sjas
13

Mengapa menggunakan innodb_file_per_table?

Karena lebih mudah untuk mengelola individu karena dapat dilakukan di tingkat file. Ini berarti bahwa bahkan jika server sedang down, Anda masih dapat menyalin data dengan menyalin file tabel sedangkan menggunakan ruang tabel bersama berarti baik menyalin segala sesuatu yang bisa sangat besar, atau menemukan beberapa cara untuk membuat server berjalan untuk mengekstraksi data ( Anda benar-benar tidak ingin mengekstrak data secara manual dengan hex-editor).

Seseorang memperingatkan bahwa Anda tidak bisa hanya menyalin dan menempel .ibdfile dari satu server ke yang lain. Ini mungkin benar, tetapi seharusnya tidak berlaku untuk cadangan di server yang sama (Saya menggunakan istilah cadangan di sini dalam arti tradisional membuat salinan; yaitu, tidak secara drastis mengubah semuanya). Selain itu, ibdata1secara otomatis dibuat kembali saat startup (seperti terlihat pada langkah hapusibdata1 sebagian besar panduan "konversi ke file-per-tabel"). Dengan demikian, Anda tidak perlu menyalin ibdata1selain .ibdfile Anda (dan file yang sesuai .frm, dll.).

Jika mencoba memulihkan tabel yang hilang, itu harus cukup untuk menyalin .ibddan .frmfile-nya, dan juga information_schema(yang jauh lebih kecil dari ibdata1). Dengan begitu, Anda bisa meletakkannya di server dummy dan mengekstrak meja Anda tanpa harus menyalin keseluruhannya.

Namun, klaim untuk kinerja yang lebih baik masih dipertanyakan. … Dengan innodb_file_per_table, lebih banyak operasi I / O disk diperlukan; dan ini penting dalam kendala GABUNGAN dan KUNCI LUAR NEGERI yang rumit.

Tidak mengherankan, kinerja akan bergantung sepenuhnya pada database tertentu yang digunakan. Satu orang akan memiliki (bahkan sangat) hasil yang berbeda dari yang lain.

Memang benar bahwa akan ada lebih banyak operasi I / O disk dengan file-per-tabel, tetapi hanya sedikit lebih banyak. Pikirkan tentang bagaimana sistem bekerja.

  • Untuk database monolitik:

    1. Server dimulai
    2. ibdata1 dibuka
    3. Header dan meta-data dibaca
    4. Struktur dan meta-data di-cache dalam memori
    5. Kueri terjadi
      1. Server mengakses disk dan membaca data dari yang sudah dibuka ibdata1
      2. Server dapat menyimpan data dalam cache
  • Untuk database per-tabel:

    1. Server dimulai
    2. ibdata1 dibuka
    3. Header dan meta-data dibaca
    4. Setiap .ibdfile individual dibuka
    5. Header dan meta-data dibaca dari setiap .ibdfile
    6. Struktur dan meta-data di-cache dalam memori
    7. Kueri terjadi
      1. Server mengakses disk dan membaca data dari .ibdfile yang sudah dibuka
      2. Server dapat menyimpan data dalam cache

Anda akan melihat bahwa ketika server sedang berjalan, Anda tidak dapat memindahkan file data karena server memiliki pegangan terbuka untuk mereka. Ini karena ketika dijalankan, itu akan membukanya dan membiarkannya terbuka. Itu tidak membuka dan menutup mereka untuk setiap permintaan individu.

Dengan demikian, hanya ada beberapa operasi I / O di awal, ketika server mulai; tidak saat sedang berjalan. Lebih lanjut, sementara masing-masing .ibdfile memiliki overhead yang terpisah (tanda tangan file, struktur, dll.), Mereka di-cache dalam memori dan tidak dibaca kembali untuk setiap permintaan. Selain itu, struktur yang sama dibaca bahkan dengan ruang tabel bersama, sehingga hampir tidak ada (jika ada sama sekali) lebih banyak memori yang diperlukan.

Apakah innodb_file_per_table berpengaruh pada kinerja mysql yang lebih baik?

Sebenarnya, jika ada, kinerja sebenarnya mungkin lebih buruk .

Saat menggunakan ruang tabel bersama, operasi baca dan tulis kadang-kadang dapat / sering digabungkan sehingga server membaca kumpulan data dari beberapa tabel sekaligus ibdata.

Namun, jika data tersebar di antara beberapa file, maka harus melakukan operasi I / O terpisah untuk masing-masing file secara individual.

Tentu saja ini sekali lagi sepenuhnya tergantung pada database yang dimaksud; dampak kinerja dunia nyata akan tergantung pada ukuran, frekuensi kueri, dan fragmentasi internal ruang tabel bersama. Beberapa orang mungkin melihat perbedaan besar sementara yang lain mungkin tidak melihat dampak sama sekali.

Tablespace dibagi pada ibdata tunggal; bagaimana tablespace khusus untuk tabel terpisah dapat menghemat ruang disk?

Itu tidak. Jika ada, itu meningkatkan penggunaan disk.

Saya tidak memiliki database 60GB untuk diuji, tetapi database pribadi "remeh" yang berisi instalasi WordPress saya dan beberapa tabel kecil untuk penggunaan pribadi dan pengujian pengembangan ditimbang pada ~ 30MB saat menggunakan ruang-tabel bersama. Setelah mengonversinya menjadi file-per-tabel, itu membengkak hingga ~ 85MB. Bahkan dengan menjatuhkan semuanya dan mengimpor kembali, itu masih> 60MB.

Peningkatan ini disebabkan oleh dua faktor:

  • The minimum absolut ukuran untuk ibdata1adalah-untuk beberapa alasan-10MB, bahkan jika Anda memiliki apa-apa selain information_schemayang tersimpan di dalamnya.

  • Dengan ruang tabel bersama, hanya ibdata1memiliki overhead seperti tanda tangan file, meta-data, dll, tetapi dengan per-tabel, setiap .ibdfile individu memiliki semua itu. Ini berarti bahwa total (bahkan dengan hipotetis <10MB ibdata1) akan sedikit lebih besar setidaknya:

    GetTotalSizeofOverhead() * GetNumTables()

Jelas ini tidak akan menjadi peningkatan besar (kecuali jika Anda menggunakan host yang membatasi ukuran database Anda atau menyimpannya di flash-drive, dll), tetapi mereka tetap meningkat, dan sambil beralih ( setiap ) tabel ke file -per-tabel Anda dapat menyusut ibdata1hingga 10MB, total keseluruhan akan selalu lebih dari itu.

Synetech
sumber
11

Ini adalah alasan saya SELALU menggunakan innodb_file_per_table:

Tanpa file per tabel, file ibdata tidak pernah kompres atau menyusut atau mengecil dalam ruang. Tidak ketika Anda menghapus baris, menjatuhkan tabel, atau database. Data 2GB dapat menjadi file 20GB dalam waktu singkat jika Anda memiliki sistem antrian aktif.

Katakanlah Anda ingin membuat cadangan tabel 1GB Anda saat ini sebelum perubahan, lalu letakkan setelahnya. Anda terjebak dengan GB ruang yang sekarang tidak digunakan di ibdata Anda. Gelandangan.

Mungkin ada contoh contoh tak berujung di mana tindakan sementara mengembang file data tunggal, tapi cukuplah untuk mengatakan bahwa menurut pendapat saya, tidak pernah ada alasan untuk TIDAK menggunakan innodb_file_per_table

Juga, inilah posting yang bagus untuk dibaca: http://code.openark.org/blog/mysql/reason-to-use-innodb_file_per_table

randomx
sumber
1
Saya menyadari itu baik untuk SELALU melakukannya juga. Array penyimpanan magnetik yang didukung oleh SSD dapat menangani cache baca / tulis secara lebih efektif terhadap file yang lebih kecil untuk tabel. Untuk banyak tabel yang% 99,99 waktunya hanya dibaca 'tetapi tidak ditulis, mereka selalu ada dalam cache pengontrol penyimpanan, yang merupakan pengurangan besar dalam waktu respons.
SDK
5

Alasan saya mengapa tidak menggunakan innodb_file_per_table adalah kinerja.

Saya melakukan beberapa tes untuk database kami dengan 450 tabel pada mysql 5.5.45 Linux CentOS rilis 6.7

Untuk tes unit yang memasukkan perlengkapan ke dalam basis data sebelum setiap tes (tidak menggunakan semua tabel setiap kali) dan juga tes itu sendiri banyak bekerja dengan basis data (memasukkan, memperbarui, menghapus, memilih) kinerjanya 3-5x lebih baik ketika tabel database tidak dipisahkan menjadi lebih banyak file.

Saya merekomendasikan untuk menguji basis data Anda dengan kueri yang ingin Anda gunakan dan membandingkannya sebelum Anda memutuskan untuk menggunakan innodb_file_per_table

Mungkin Anda dapat mengetahui bahwa untuk server produksi Anda dapat menggunakan innodb_file_per_table tetapi untuk lingkungan CI (integrasi terus-menerus) yang memulai tes unit (menggunakan banyak DB) dan juga pengembang yang memulai tes unit banyak lebih baik tidak menggunakannya karena kinerja.

Tomor
sumber
2
Saya menduga ini karena waktu yang diperlukan untuk mengalokasikan file awal untuk semua 450 tabel vs mengalokasikan satu file tunggal. Dalam produksi ini hanya akan terjadi sekali jadi seharusnya tidak menjadi masalah, tetapi Anda membuat poin yang baik bahwa untuk dengan cepat membuat database dan kemudian benar-benar merobohkannya dan mengulangi berulang-ulang satu file ibdata lebih baik.
ColinM
2

Itu membuat data lebih mudah dikelola karena Anda bisa mendapatkan kembali ruang yang tidak digunakan, yang bagus.

Saya pikir jika database Anda digunakan sebagian besar untuk pertanyaan pilih itu tidak akan banyak mempengaruhi kinerja. Masih harus membaca tentang jumlah data yang sama. Saya tidak berpikir itu penting apa file dari membaca data.

Namun, itu dapat membuat kinerja lebih buruk pada database yang melakukan banyak sisipan dan pembaruan. Ini karena mysql memanggil fsync () pada file penyimpanan setelah Anda melakukan transaksi. Jika ada satu file itu membuat satu panggilan dan menunggu panggilan selesai. Jika ada banyak file itu harus membuat panggilan beberapa kali dan menunggu semua panggilan kembali sebelum perintah komit dapat kembali.

Berikut adalah pos dari seseorang yang mengalami masalah ini: http://umangg.blogspot.com/2010/02/innodbfilepertable.html

Sarel Botha
sumber
2

Seperti artikel di bawah ini, kinerja bukan tentang mengelola data (operasi kasar itu sendiri) melainkan tentang membuat dan menjatuhkan objek.

innodb_file_per_table membuat kreasi besar dan menjatuhkan objek lebih lambat dari penyimpanan ibdata dan untuk produksi tidak berlaku tetapi untuk pengujian berkelanjutan harus relevan.

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

Flavio Peinado
sumber