MySQL InnoDB - kontra innodb_file_per_table?


32

Secara default, MySQL InnoDB menyimpan semua tabel dari semua DB dalam satu file global. Anda dapat mengubah ini dengan menetapkan innodb_file_per_table di konfigurasi, yang kemudian membuat satu file data untuk setiap tabel.

Saya bertanya-tanya mengapa innodb_file_per_tabletidak diaktifkan secara default. Apakah ada kerugian untuk menggunakannya?

Jawaban:


32

Saya punya jawaban lengkap untuk yang ini.

Setelah innodb_file_per_table dimasukkan, dan tabel InnoDB baru dapat menyusut menggunakan ALTER TABLE <innodb-table-name> ENGINE=InnoDB';Ini akan menyusutkan .ibdfile baru DIJAMIN.

Jika Anda menjalankan ALTER TABLE <innodb-table-name> ENGINE=InnoDB';tabel InnoDB yang dibuat sebelum Anda menggunakan innodb_file_per_table, itu akan menarik data dan indeks untuk tabel itu dari file ibdata1 dan menyimpannya dalam .ibdfile, Ini akan meninggalkan seluruh merpati permanen di dalam ibdata1 yang tidak pernah dapat digunakan kembali. .

The ibdata1berkas biasanya rumah empat jenis informasi

Inilah cara yang dijamin untuk menyusutkan file ibdata1 cukup lama ...

LANGKAH 01) MySQLDump semua database menjadi file teks SQL (sebut saja SQLData.sql)

LANGKAH 02) Letakkan semua basis data (kecuali skema mysql, information_schema, dan performance_schema)

LANGKAH 03) Matikan mysql

LANGKAH 04) Tambahkan baris berikut ke /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: Apa pun yang Anda atur untuk innodb_buffer_pool_size, pastikan innodb_log_file_size adalah 25% dari innodb_buffer_pool_size.

  • LANGKAH 05) Hapus ibdata1, ib_logfile0 dan ib_logfile1 ( lihat pembaruan di bawah ini sebelum menghapus! )

Pada titik ini, seharusnya hanya ada skema mysql di / var / lib / mysql

  • LANGKAH 06) Mulai kembali mysql

Ini akan membuat ulang ibdata1 pada 10MB (tidak mengkonfigurasi opsi), ib_logfile0 dan ib_logfile1 masing-masing 1G

  • LANGKAH 07) Muat ulang SQLData.sql ke mysql

ibdata1 akan tumbuh tetapi hanya berisi metadata tabel dan data MVCC intermiten.

Setiap tabel InnoDB akan ada di luar ibdata1

Misalkan Anda memiliki tabel InnoDB bernama mydb.mytable. Jika Anda masuk ke /var/lib/mysql/mydb, Anda akan melihat dua file yang mewakili tabel

  • mytable.frm (Header Mesin Penyimpan)
  • mytable.ibd(Rumah Data Tabel dan Indeks Tabel untuk mydb.mytable)

ibdata1 tidak akan lagi berisi data dan Indeks InnoDB.

Dengan opsi innodb_file_per_table di /etc/my.cnf, Anda dapat menjalankan OPTIMIZE TABLE mydb.mytableATAU ALTER TABLE mydb.mytable ENGINE=InnoDB;dan file /var/lib/mysql/mydb/mytable.ibdakan benar-benar menyusut.

Saya telah melakukan ini berkali-kali dalam karir saya sebagai DBA MySQL tanpa banyak masalah setelahnya. Bahkan, pertama kali saya melakukan ini, saya menciutkan file ibdata1 50GB menjadi 50MB.

Cobalah. Jika Anda memiliki pertanyaan lebih lanjut tentang ini, email saya. Percayalah kepadaku. Ini akan bekerja dalam jangka pendek dan jangka panjang.

UPDATE 2013-07-02 15:08 EDT

Ada peringatan yang saya miliki dalam hal ini yang saya perbarui di posting saya yang lain tetapi saya melewatkan ini: Saya memperbarui jawaban saya sedikit lagi dengan innodb_fast_shutdown karena saya digunakan untuk me-restart mysql dan menghentikan mysql untuk melakukan ini. Sekarang, satu langkah ini sangat penting karena setiap transaksi yang tidak berkomitmen dapat memiliki bagian bergerak lainnya di dalam dan di luar Log Transaksi InnoDB ( Lihat Infrastruktur InnoDB ).

Harap dicatat bahwa pengaturan innodb_fast_shutdown ke 2 akan membersihkan log juga, tetapi lebih banyak bagian yang bergerak masih ada dan dipilih pada Crash Recovery selama startup mysqld. Pengaturan 0 adalah yang terbaik.


Info hebat - terima kasih! 50GB >> 50MB - itu cukup mengesankan!
UpTheCreek

Hai, saya sudah mencoba melakukan persis seperti yang Anda tulis di sini, satu-satunya masalah adalah bahwa server tidak memulai setelah itu. jika saya melakukan servis mysql mulai saja hang di sana. Jika saya beralih kembali file cnf lama saya semuanya ok. Apakah Anda punya petunjuk tentang ini?
Nicola Peluchetti

Pertanyaan ini untuk Nicola: Apakah Anda melakukan Langkah 5 ???
RolandoMySQLDBA

Pertanyaan lain untuk @Nicola: Berapa banyak RAM yang Anda miliki di sistem Anda ???
RolandoMySQLDBA

2
Hati-hati! Opsi innodb_fast_shutdown=0harus diatur dalam MySQL, sebelum mematikannya untuk menghapus file log! ( ib_logfile0dan ib_logfile1) Jika tidak, Anda bisa kehilangan data!
Totor

12

Lihat bug .

Apakah ada kerugian untuk menggunakannya?

  • lebih banyak file yang terbuka
  • buka / buka kembali overhead
  • File .ibd tidak menyusut (lihat 1 , 2 )

Saya selalu menggunakan innodb_file_per_table pada database besar.


Bahkan jika Anda tidak menggunakannya, file ibdata tidak akan menyusut, baik :(
minaev

1
Terima kasih. Saya juga heran mengapa tidak ada opsi untuk memiliki file per db?
UpTheCreek

1
@UpTheCreek, tabel adalah entitas. Database adalah kelompok logis dari entitas, bukan entitas dalam hak mereka sendiri. Ini lebih jelas dengan MyISAM, di mana database adalah direktori dan tabel adalah file.
John Gardeniers

Hanya ingin menunjukkan bahwa sementara file .ibd tidak menyusut secara otomatis , tidak juga ibdata1, alternatif untuk file-per-tabel. Setidaknya dimungkinkan untuk mengecilkan penggunaan .ibd optimize table, yang sepele dibandingkan dengan menyusut ibdata1.
RomanSt

8

innodb_file_per_table diaktifkan secara default di MariaDB.


1
Bukan milikku (versi default di CentOS 7). Anda memerlukan yang setara dengan MySQL 5.6.6 atau yang lebih baru. Kalau tidak, standarnya mati .
Lightness Races dengan Monica

2

Alasan mengapa saya memilih untuk tidak menggunakan innodb_file_per_table, adalah karena setiap tabel diletakkan di file sendiri, yang berarti setiap tabel mendapatkan sendiri, overhead terpisah (file-signature, dll.) Yang menyebabkan total, ukuran keseluruhan MySQLdirektori menjadi lebih besar daripada jika menggunakan tablespace bersama. Selain itu, ada lebih banyak ruang terbuang karena cluster-slack ketika memiliki banyak file kecil, bukan satu file besar.

Memang, biaya tambahan bukan jumlah besar dalam skema besar hal, terutama jika Anda menggunakan drive besar atau memiliki database raksasa, tetapi untuk diri saya sendiri (dan mungkin banyak "pengguna rumah"), semuanya ditambahkan dan masih terlalu banyak untuk drive kecil dengan kelompok besar di mana saya menyimpan toko MySQL saya.

Sebagai contoh, toko database saya dengan database WordPress saya dan beberapa database kecil lainnya (phpBB, dev, beberapa tes AMP, dll.), Mengonversi ke per-tabel mengubahnya dari 32MB menjadi 50MB, dan itu bahkan tidak termasuk ibdata1yang masih membutuhkan sebuah minimal 10MB , untuk total setidaknya 60MB.

Seperti yang saya katakan, ini mungkin tidak terlalu menjadi masalah bagi sebagian orang, terutama perusahaan, tetapi jika Anda adalah pengguna rumahan yang hanya meng-hosting situs, blog, dll. Maka itu memang bisa menjadi faktor dalam hal-hal seperti memilih penyedia host karena banyak host membatasi ukuran basis data Anda di samping total penggunaan disk.


1
Saya berpikir Anda gila (siapa yang peduli tentang sepuluh megabyte ???) sampai Anda mendapatkan poin tentang kuota ketat di penyedia hosting. Tidak akan pernah memikirkan itu.
Dan Pritts

@DanPritts, terutama host gratis. Selain itu, Anda mungkin memiliki drive raksasa, tetapi tidak semua orang memilikinya. Saya telah memperluas partisi data utama saya dari 1GB menjadi 2GB pada tahun lalu karena terlalu ketat, tetapi bahkan 10MB di sini dan 10MB di sana (terutama dengan file log) dapat memakannya dengan cepat. Selain itu, jangan lupa menambahkan juga cluster-waste. Akhirnya, itu bahkan tidak harus berupa hard drive . Sebagai contoh, saya saat ini "portablizing" situs web saya sehingga saya dapat meng-host-nya dari sistem apa pun, jadi 2GB flash-drive sudah terbatas. Dengan demikian, menjaga ukuran kecil dan menghindari penulisan sangat penting. Dan kemudian ada sistem tertanam!
Synetech

Plus, ini bukan 10MB (itu ukuran minimum absolut untuk IBDATA1). Mulai dari 30MB hingga ~ 85MB. Dengan menghapus semuanya dan mengimpor dump dari awal, saya berakhir dengan 69MB daripada 30MB sebelumnya (satu tebak database mana yang mengambil lebih dari setengahnya ☺). Untuk beberapa alasan, meskipun menggunakan per-tabel, saya ibdata1masih 18MB. ☹
Synetech

Kedengarannya seperti sesuatu yang saya miliki dengan menginstal CMS dengan vs. satu tanpa selinux diaktifkan, dilihat dari filesizes 32M vs 50M. Saya benar-benar tidak percaya angka-angkanya, berapa banyak database yang Anda miliki sehingga metadata beberapa file dapat bertambah hingga MEGABYTES dalam ukuran pada sistem yang identik?
sjas

2

Hanya untuk menambahkan sedikit info lebih lanjut

Sejak mysql 5.6.6 diaktifkan secara default


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.