Bagaimana cara mengecilkan file innodb ibdata1 tanpa membuang semua database?

24

InnoDB menyimpan semua tabel dalam satu file besar ibdata1.

Setelah menjatuhkan meja besar, file tetap ukurannya tidak peduli seberapa besar tabel itu. Bagaimana saya bisa mengecilkan file itu tanpa harus membuang dan mengimpor kembali seluruh database (yang memiliki total beberapa ratus GB)?

Saya pikir alasannya adalah karena Anda masih dapat mengembalikan dropping. Dalam kasus saya, saya tidak perlu melakukannya.

rubo77
sumber

Jawaban:

30

Ini adalah salah satu topik paling kontroversial yang pernah saya tangani selama bertahun-tahun sebagai MySQL DBA dan di DBA StackExchange.

Untuk membuatnya lebih sedikit, tidak hanya ada cara lain untuk mengecilkan ibdata1 . Dengan innodb_file_per_table dinonaktifkan, setiap kali Anda menjalankan OPTIMIZE TABLEtabel InnoDB, ibdata1 tumbuh dengan cepat. Data yang dijatuhkan menggunakan DROP TABLEdan DROP DATABASEtidak dapat digulirkan kembali karena mereka DDL, bukan DML. Saya percaya Oracle dan MSSQL dapat mengembalikan DDL. MySQL tidak bisa melakukan itu.

Ada beberapa kelas informasi yang berada di ibdata1

  • Tabel Data
  • Indeks Tabel
  • Tabel MetaData
  • Data Kontrol MVCC
  • Double Write Buffer (Penulisan latar belakang untuk mencegah ketergantungan pada caching OS)
  • Masukkan Buffer (Mengelola perubahan pada indeks sekunder yang tidak unik)

Menggunakan innodb_file_per_table=1akan memungkinkan Anda untuk membuat tabel baru dengan data tabel dan indeks tabel dibuat di luar ibdata1. Anda bisa mengekstrak tabel apa pun yang masih ada di dalam ibdata1 menggunakan ALTER TABLE ... ENGINE=InnoDB;atau OPTIMIZE TABLEtetapi itu akan meninggalkan ruang besar yang tidak terpakai yang kosong di ibdata1.

Meskipun demikian, Anda harus membersihkan infrastruktur InnoDB. Saya sudah menulis posting StackExchange tentang bagaimana dan mengapa melakukan ini:

Kabar baik

Anda hanya perlu membuang data, memuat ulang sekali lagi dan tidak pernah mengunjungi lagi masalah ini . Menjalankan OPTIMIZE TABLEsesudahnya memang akan mengecilkan .ibdfile tablespace untuk setiap tabel InnoDB.

RolandoMySQLDBA
sumber
1
Koreksi kecil: MSSQL dan PostgreSQL dapat mengembalikan DDL. Oracle tidak bisa. Bahkan Oracle mengeluarkan komit implisit ketika melihat DDL!
Chris Travers
1
@RolandoMySQLDBA sejak apa versi MySQL ini "kabar baik" karya menyusut otomatis?
Gavriel
@ Gavriel - Saya pikir Anda salah membaca. Anda masih harus membuang; hapus ibdata1; mengulang kembali; dan memuat ulang. No-autoshrink dari ibdata1. (Mengubah iblog * sekarang lebih mudah.)
Rick James
2

InnoDB hanya menyimpan semua tabel InnoDB Anda di ibdata1 jika Anda tidak menggunakan pengaturan berikut di file default my.cnf Anda:

innodb_file_per_table = 1

DROP TABLE (dan DROP DATABASE) tidak dapat dibatalkan.

Itu bukan alasan kamu tidak bisa menyusutkan ibdata1.

Ini adalah penjelasan singkat, tetapi ibdata1 berisi InnoDB internal di samping data tabel Anda. Dari pemahaman saya, untuk mengecilkannya akan membutuhkan defragmenting, yang bukan operasi yang didukung.

Michael - sqlbot
sumber