Saya memiliki Database yang memiliki sejumlah tabel.
Saya ingin menghapus beberapa catatan dari tabel mengatakan tidak ada catatan lebih dari 20 ribu atau 50 ribu.
Semua Tabel adalah InnoDB. Dan file_per_table
adalah off .
Ketika saya akan menghapus catatan dari sejumlah tabel akan ada fragmentasi dalam tabel.
Apakah ada cara untuk menghapus fragmentasi.?
Pembaruan Pada 17 April
mysql> select TABLE_NAME, TABLE_SCHEMA, Data_free from information_schema.TABLES where TABLE_SCHEMA NOT IN ('information_schema', 'mysql') and Data_Free >0;
+-----------------+--------------+-----------+
| TABLE_NAME | TABLE_SCHEMA | Data_free |
+-----------------+--------------+-----------+
| City | world_innodb | 5242880 |
| City_Copy | world_innodb | 5242880 |
| Country | world_innodb | 5242880 |
| CountryLanguage | world_innodb | 5242880 |
| a | world_innodb | 5242880 |
| t1 | world_innodb | 5242880 |
| t2 | world_innodb | 5242880 |
+-----------------+--------------+-----------+
7 rows in set (0.00 sec)
Jadi Sekarang Pertanyaan saya adalah bagaimana saya akan memutuskan bahwa tabel saya terfragmentasi atau tidak.
Jawaban:
Saya telah membahas ini di StackOverflow pada Oktober 2010 .
Ingatlah file tersibuk di infrastruktur InnoDB: / var / lib / mysql / ibdata1
File ini biasanya menampung empat jenis informasi
Berlari
OPTIMIZE TABLE
melawan tabel InnoDB yang disimpan di ibdata1 melakukan dua hal:Meskipun Anda dapat memisahkan Data Tabel dan Indeks Tabel dari ibdata1 dan mengelolanya secara independen menggunakan innodb_file_per_table , seluruh ruang disk yang besar di ibdata1 tidak akan hilang dan tidak dapat direklamasi. Anda harus berbuat lebih banyak.
Untuk menyusutkan ibdata1 sekali dan untuk semua Anda harus melakukan hal berikut:
1) MySQLDump semua database menjadi file teks SQL (sebut saja /root/SQLData.sql)
2) Jatuhkan semua basis data (kecuali skema mysql)
3) Matikan mysql
4) Tambahkan baris berikut ke /etc/my.cnf
Sidenote: Apa pun yang Anda atur untuk innodb_buffer_pool_size, pastikan innodb_log_file_size adalah 25% dari innodb_buffer_pool_size.
5) Hapus ibdata1, ib_logfile0 dan ib_logfile1
Pada titik ini, seharusnya hanya ada skema mysql di / var / lib / mysql
6) Mulai ulang mysql
Ini akan membuat ulang data ib di 10 atau 18MB (tergantung pada versi MySQL), ib_logfile0 dan ib_logfile1 masing-masing 1G
7) Muat ulang /root/SQLData.sql ke mysql
ibdata1 akan tumbuh tetapi hanya berisi tabel metadata. Bahkan, itu akan tumbuh sangat lambat selama bertahun-tahun. Satu-satunya cara pertumbuhan ibdata1 dengan cepat adalah jika Anda memiliki satu atau lebih hal berikut ini:
CREATE TABLE
,DROP TABLE
,ALTER TABLE
)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
ibdata1 tidak akan pernah lagi memuat data dan Indeks InnoDB.
Dengan opsi innodb_file_per_table di /etc/my.cnf, Anda dapat menjalankan
OPTIMIZE TABLE mydb.mytable;
dan file /var/lib/mysql/mydb/mytable.ibd akan menyusut.Saya telah melakukan ini berkali-kali dalam karir saya sebagai DBA MySQL
Faktanya, pertama kali saya melakukan ini, saya menciutkan file ibdata1 50GB menjadi 500MB.
Cobalah. Jika Anda memiliki pertanyaan lebih lanjut tentang ini, email saya. Percayalah kepadaku. Ini akan bekerja dalam jangka pendek dan jangka panjang !!!
UPDATE 2012-04-19 09:23 EDT
Setelah menjalankan langkah-langkah di atas, bagaimana Anda bisa menentukan tabel apa yang perlu didefragmentasi? Dimungkinkan untuk mengetahuinya, tetapi Anda akan memiliki skripnya.
Berikut ini sebuah contoh: Misalkan Anda memiliki tabel
mydb.mytable
. Dengan diaktifkan innodb_file_per_table, Anda memiliki file /var/lib/mysql/mydb/mytable.ibdAnda harus mengambil dua angka
MEMASANG DARI OS: Anda dapat memastikan ukuran file dari OS seperti ini
FILESIZE DARI INFORMATION_SCHEMA: Anda dapat memastikan filesize dari information_schema.tabel seperti ini:
Cukup kurangi nilai INFORMATION_SCHEMA dari nilai OS dan bagilah selisihnya dengan nilai INFORMATION_SCHEMA.
Dari sana Anda akan memutuskan berapa persen yang dianggap perlu untuk men-defrag tabel itu. Tentu saja, Anda defrag menggunakan salah satu dari perintah berikut:
atau
sumber
Jika Anda sering menghapus baris (atau memperbarui baris dengan tipe data panjang variabel), Anda bisa berakhir dengan banyak ruang kosong di file data Anda, mirip dengan fragmentasi sistem file.
Jika Anda tidak menggunakan
innodb_file_per_table
opsi, satu-satunya hal yang dapat Anda lakukan adalah mengekspor dan mengimpor basis data, prosedur intensif-waktu dan disk.Tetapi jika Anda menggunakan
innodb_file_per_table
, Anda dapat mengidentifikasi dan mendapatkan kembali ruang ini!Sebelum 5.1.21, penghitung ruang kosong tersedia dari kolom table_comment dari information_schema.tables. Berikut adalah beberapa SQL untuk mengidentifikasi tabel dengan setidaknya 100M (sebenarnya 97.65M) ruang kosong:
Dimulai dengan 5.1.21, ini dipindahkan ke kolom data_free (tempat yang jauh lebih tepat):
Anda bisa mendapatkan kembali ruang yang hilang dengan membangun kembali tabel. Cara terbaik untuk melakukan ini adalah menggunakan 'alter table' tanpa benar-benar mengubah apa pun:
Inilah yang dilakukan MySQL di balik layar jika Anda menjalankan 'optimalkan tabel' pada tabel InnoDB. Ini akan menghasilkan kunci baca, tetapi bukan kunci tabel penuh. Berapa lama waktu yang dibutuhkan sepenuhnya tergantung pada jumlah data dalam tabel (tetapi tidak pada ukuran file data). Jika Anda memiliki tabel dengan banyak penghapusan atau pembaruan, Anda mungkin ingin menjalankan ini setiap bulan, atau bahkan setiap minggu.
sumber