Mengapa InnoDB menyimpan semua database dalam satu file?

51

Itu nyaman bahwa MyISAM digunakan untuk menyimpan setiap tabel dalam file yang sesuai. InnoDB telah membuat kemajuan dalam banyak aspek, tetapi saya ingin tahu mengapa InnoDB menyimpan semua basis data dalam satu file ( ibdata1secara default).

Saya mengerti bahwa InnoDB akan memetakan lokasi data dalam file dengan file indeks individual untuk tabel, tapi saya tidak mengerti mengapa itu mencampur semua data dalam satu file. Dan yang lebih penting, mengapa mencampur data semua database di server?

Fitur menarik dari MyISAM adalah seseorang dapat menyalin / menempel folder database ke komputer lain dan kemudian menggunakan database (tanpa dump).

Googlebot
sumber

Jawaban:

67

Arsitektur InnoDB menuntut penggunaan empat tipe dasar halaman info

  • Halaman Data Tabel
  • Halaman Indeks Tabel
  • Tabel MetaData
  • Data MVCC (untuk mendukung Isolasi Transaksi dan Kepatuhan ACID )
    • Segmen kembalikan
    • Batalkan Spasi
    • Double Write Buffer (penulisan latar belakang untuk mencegah ketergantungan pada caching OS)
    • Masukkan Buffer (mengelola perubahan pada indeks sekunder yang tidak unik)

Lihat Representasi Pictorial dari ibdata1

Secara default, innodb_file_per_table dinonaktifkan. Ini menyebabkan keempat jenis halaman info mendaratkan satu file bernama ibdata1. Banyak orang mencoba menyebar data dengan membuat banyak file ibdata. Ini dapat menyebabkan fragmentasi data dan halaman indeks.

Inilah sebabnya saya sering merekomendasikan untuk membersihkan infrastruktur InnoDB, menggunakan file ibdata1 default dan tidak lebih .

Menyalin sangat berbahaya karena infrastruktur di mana InnoDB bekerja. Ada dua infrastruktur dasar

  • innodb_file_per_table dinonaktifkan
  • innodb_file_per_table diaktifkan

InnoDB ( innodb_file_per_table dinonaktifkan)

Dengan innodb_file_per_table dinonaktifkan, semua jenis info InnoDB ini tinggal di dalam ibdata1. Satu-satunya manifestasi dari setiap tabel InnoDB di luar ibdata1 adalah file .frm dari tabel InnoDB. Menyalin semua data InnoDB sekaligus membutuhkan menyalin semua / var / lib / mysql.

Menyalin tabel InnoDB individu sama sekali tidak mungkin. Anda harus dump MySQL untuk mengekstrak dump tabel sebagai representasi logis dari data dan definisi indeks yang sesuai. Anda kemudian akan memuat dump itu ke database lain di server yang sama atau server lain.

InnoDB ( innodb_file_per_table diaktifkan)

Dengan innodb_file_per_table diaktifkan, data tabel dan indeksnya tinggal di folder database di sebelah file .frm. Sebagai contoh, untuk tabel db1.mytable, manifestasi dari tabel InnoDB di luar ibdata1 adalah:

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

Tablespace Sistem ibdata1

Semua metadata untuk db1.mytable masih berada di ibdata1 dan sama sekali tidak ada jalan lain untuk itu . Redo log dan data MVCC juga masih hidup dengan ibdata1.

Ketika datang ke tabel fragmentasi, inilah yang terjadi pada ibdata1:

  • innodb_file_per_table diaktifkan : Anda dapat menyusutkan db1.mytables denganALTER TABLE db1.mytable ENGINE=InnoDB;atauOPTIMIZE TABLE db1.mytable;. Ini menghasilkan /var/lib/mysql/db1/mytable.ibd secara fisik lebih kecil tanpa fragmentasi.
  • innodb_file_per_table dinonaktifkan : Anda tidak dapat menyusutkan db1.mytables denganALTER TABLE db1.mytable ENGINE=InnoDB;atauOPTIMIZE TABLE db1.mytable;karena berada dengan ibdata1. Menjalankan perintah mana pun sebenarnya, membuat tabel berdekatan dan lebih cepat untuk membaca dan menulis. Sayangnya, itu terjadi pada akhir ibdata1. Ini membuat ibdata1 tumbuh dengan cepat. Ini sepenuhnya dibahas di Pos Pembersihan InnoDB saya .

PERINGATAN (atau BAHAYA Robot akan berkata dalam Lost in Space )

Jika Anda berpikir untuk hanya menyalin file .frm dan .ibd, Anda sejalan dengan dunia yang menyakitkan. Menyalin file .frm dan .ibd dari tabel InnoDB hanya baik jika dan hanya jika Anda dapat menjamin bahwa id tablespace dari file .ibd cocok dengan entri id tablespace dalam metadata file ibdata1 .

Saya menulis dua posting di DBA StackExchange tentang konsep id tablespace ini

Berikut ini adalah tautan yang sangat baik tentang cara memasang kembali file .ibd ke ibdata1 jika id tablespace tidak cocok: http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in-file . Setelah membaca ini, Anda harus segera menyadari bahwa menyalin file .ibd benar-benar gila.

Untuk InnoDB, Anda hanya perlu melakukan sesuatu ini untuk bergerak

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

untuk membuat salinan tabel InnoDB.

Jika Anda memigrasikannya ke server DB lain, gunakan mysqldump.

Sehubungan dengan mencampur semua tabel InnoDB dari semua database, saya benar-benar dapat melihat kebijaksanaan dalam melakukannya. Di perusahaan hosting DB / Web perusahaan saya, saya memiliki satu Klien MySQL yang memiliki tabel di satu basis data yang batasannya dipetakan ke tabel lain di basis data lain dalam instance MySQL yang sama. Dengan satu repositori metadata yang umum, itu membuat dukungan transaksional dan pengoperasian MVCC mungkin di beberapa basis data.

RolandoMySQLDBA
sumber
Apakah ini berarti ketika saya menggunakan file innodb per tabel diaktifkan dan Jika saya perlu mengimpor data saya dari satu server ke yang lain, saya harus menggunakan hanya mysqldump dan bukan alat lain seperti Percona xtrabackup?
tesla747
14

Anda dapat mengaktifkan InnoDB untuk menyimpan tabel per file dengan menambahkan innodb-file-per-tabel ke cnf Anda.

Innodb benar-benar hanya peduli tentang halaman data di tingkat dasar. Bahkan, Anda dapat mengatur InnoDB hanya menggunakan perangkat blok mentah tanpa sistem file apa pun! http://dev.mysql.com/doc/refman/5.5/en/innodb-raw-devices.html

Ada kemudahan untuk menyimpan tabel untuk file seperti bisa lebih mudah mendapatkan kembali ruang yang digunakan melalui optimisasi.

Bahkan dengan file per tabel, Anda tidak bisa begitu saja menyalin file ibd dengan mudah karena InnoDB bersifat transaksional dan menyimpan informasi tentang statusnya dalam file ibdata / log yang dibagikan secara global.

Bukan berarti tidak bisa dilakukan. Jika tabel offline, Anda dapat membuang / mengimpor tablespace dan menyalin .idbs di sekitar http://dev.mysql.com/doc/refman/5.5/id/innodb-multiple-tablespaces.html

atxdba
sumber
Tidak diragukan lagi bahwa InnoDB adalah mesin yang fleksibel, tetapi saya tidak mengerti bagaimana menyimpan semua data dalam satu file bermanfaat (karena struktur baru ini telah diimplementasikan dalam InnoDB dibandingkan dengan MyISAM).
Googlebot
Saya pikir itu lebih dari satu di belakang adalah 20/20 hal. Opsi file per tabel ditambahkan setelah innodb pertama kali digulirkan dari rak. Di luar memberikannya itu perangkat blok sendiri untuk menghindari overhead sistem file Saya tidak dapat memberikan alasan mengapa membuang semuanya bersama-sama lebih baik (dan seluruh hal perangkat blok adalah perdebatan itu sendiri). Semua pengaturan innodb saya mengaktifkan file per tabel.
atxdba
Itulah intinya, tidak bergantung pada sistem file bisa menjadi sangat berharga tetapi tidak aktif secara default. Dengan demikian, beberapa pengguna akan menggunakannya.
Googlebot
1
Satu file per opsi tabel dapat membahayakan jika Anda memiliki banyak tabel dan tidak banyak RAM (toko Magento misalnya mungkin memiliki sekitar 1000 tabel). Dan pengaturan file terbuka juga harus dioptimalkan (mengingat keterbatasan OS). Jadi, gunakan dengan hati-hati.
ypercubeᵀᴹ
Ini tentu saja dapat meredam upaya pemulihan. Ya, Anda harus memiliki cadangan, tetapi jika tidak, InnoDB membuat segalanya lebih sulit karena struktur ini.
mikato
10

Ini adalah perilaku default tetapi tidak wajib. Dari MySQL docs, Menggunakan Per-Table Tablespace :

Secara default, semua tabel dan indeks InnoDB disimpan di tablespace sistem. Sebagai alternatif, Anda dapat menyimpan setiap tabel InnoDB dan indeksnya dalam file sendiri . Fitur ini disebut "multiple tablespaces" karena setiap tabel yang dibuat ketika pengaturan ini berlaku memiliki tablespace sendiri.

Mengapa, alasannya mungkin adalah arsitektur yang berbeda dari dua mesin (MyISAM dan InnoDB). Misalnya, di InnoDB, Anda tidak bisa hanya menyalin file .ibd ke database atau instalasi lain. Penjelasan (dari halaman yang sama):

Pertimbangan Portabilitas untuk File .ibd

Anda tidak dapat dengan bebas memindahkan file .ibd di antara direktori database seperti yang Anda bisa dengan file tabel MyISAM. Definisi tabel yang disimpan dalam tablespace bersama InnoDB termasuk nama database. ID transaksi dan nomor urutan log yang disimpan dalam file tablespace juga berbeda di antara basis data.

ypercubeᵀᴹ
sumber
Jawabannya sangat informatif dan mengklarifikasi masalah ini, tetapi saya masih penasaran bagaimana file besar yang berisi semua database dapat meningkatkan kinerja (jika ada).
Googlebot
Performanya tidak lebih baik karena memiliki satu file untuk semua. Berbagai karakteristik, seperti penguncian tingkat baris, alih-alih tingkat tabel, membantu kinerja. Dan tentu saja keuntungan utama adalah kendala transaksi dan FK (dan dengan demikian integritas basis data).
ypercubeᵀᴹ
1
Anda benar tentang integritas! Saya mengerti mengapa lebih baik untuk meletakkan semua tabel database dalam satu file menghanguskan; tapi saya tidak mengerti mengapa meletakkan semua database (yang sepenuhnya independen) pada file yang sama. InnoDB secara default hanya menggunakan satu file untuk menyimpan data.
Googlebot