InnoDB tablolarından parçalanma nasıl kaldırılır?


13

Tablo sayısı olan bir veritabanı var.

Tablolardan bazı kayıtları silmek istiyorum, kayıtların sayısı 20K veya 50K'dan fazladır.

Tüm Tablolar InnoDB'dir. Ve file_per_tableolan kapalı .

Kayıtları birkaç tablodan sildiğimde tablolarda parçalanma olacak.

Parçalanmayı kaldırmanın herhangi bir yolu var mı?

17 Nisan'da Güncelleme

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)

Şimdi benim sorum şu tablolarım parçalanmış veya değil karar nasıl olacaktır.



1
Ve bir makale InnoDB: Percona'nın blog sitesinden parçalanmalara dikkat edin.
ypercubeᵀᴹ

Yanıtlar:


14

Bu Ekim 2010'da StackOverflow geri ele .

InnoDB altyapısındaki en yoğun dosyayı unutmayın: / var / lib / mysql / ibdata1

Bu dosya normalde dört tür bilgi içerir

  • Tablo Verileri
  • Tablo Dizinleri
  • MVCC (Çoklu Sürüm Eşzamanlılık Kontrolü) Verileri
  • Tablo Meta Verileri (Tablo alanı kimliklerinin listesi)

OPTIMIZE TABLEİbdata1'de saklanan bir InnoDB tablosuna karşı çalıştırmak iki şey yapar:

  • Tablonun verilerini ve dizinlerini ibdata1 içinde bitişik hale getirir, böylece daha hızlı erişim sağlar
  • Bitişik veri ve dizin sayfaları ibdata1'e eklendiğinden ibdata1'in büyümesini sağlar

Eğer ibdata1 gelen Tablo Veri ve Tablo Dizinleri'ni ayırmak ve onlara kullanarak bağımsız yönetmek iken innodb_file_per_table , büyük basitçe ibdata1 içinde disaapear bir disk alanına tamamı olmaz şaşkın ve ıslah edilemez. Daha fazlasını yapmalısınız.

İbdata1'i bir kez ve herkes için küçültmek için aşağıdakileri yapmanız gerekir:

1) MySQLTüm veritabanlarını bir SQL metin dosyasına dökün (/root/SQLData.sql olarak adlandırın)

2) Tüm veritabanlarını bırakın (mysql şeması hariç)

3) Kapatma mysql

4) /etc/my.cnf dosyasına aşağıdaki satırları ekleyin

[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G

Sidenote: innodb_buffer_pool_size için setiniz ne olursa olsun, innodb_log_file_size'nin innodb_buffer_pool_size değerinin% 25 olduğundan emin olun.

5) ibdata1, ib_logfile0 ve ib_logfile1 dosyalarını silin

Bu noktada, sadece / var / lib / mysql içinde mysql şeması olmalıdır

6) MySQL'i yeniden başlatın

Bu, ibdata1'i 10 veya 18MB'de (MySQL sürümüne bağlı olarak), ib_logfile0 ve ib_logfile1'i her biri 1G'de yeniden oluşturur

7) /root/SQLData.sql dosyasını mysql dosyasına yeniden yükleyin

ibdata1 büyüyecek, ancak yalnızca tablo meta verilerini içerecektir. Aslında, yıllar içinde çok yavaş büyüyecek. İbdata1'in hızlı büyümesinin tek yolu, aşağıdakilerden bir veya daha fazlasına sahip olmanızdır:

  • DDL bir çok ( CREATE TABLE, DROP TABLE, ALTER TABLE)
  • Birçok işlem
  • İşlem başına yapılacak birçok değişiklik

Her InnoDB tablosu ibdata1 dışında mevcut olacaktır

Mydb.mytable adlı bir InnoDB tablonuz olduğunu varsayalım. / Var / lib / mysql / mydb dosyasına giderseniz, tabloyu temsil eden iki dosya göreceksiniz

  • mytable.frm (Depolama Motoru Başlığı)
  • mytable.ibd (mydb.mytable için Tablo Verileri ve Tablo Dizinlerinin Ana Sayfası)

ibdata1 artık InnoDB verilerini ve Endekslerini artık içermeyecek.

/Etc/my.cnf içindeki innodb_file_per_table seçeneğiyle çalıştırabilirsiniz OPTIMIZE TABLE mydb.mytable;ve /var/lib/mysql/mydb/mytable.ibd dosyası gerçekte küçülür.

Bunu MySQL DBA olarak kariyerimde birçok kez yaptım

Aslında, bunu ilk kez yaptığımda, 50GB ibdata1 dosyasını 500MB'ye daralttım.

Bir şans ver. Bununla ilgili başka sorularınız varsa, bana e-posta gönderin. Güven Bana. Bu kısa vadede ve uzun mesafe üzerinde çalışacaktır !!!

GÜNCELLEME 2012-04-19 09:23 EDT

Yukarıdaki adımları uyguladıktan sonra, hangi tabloların birleştirilmesi gerektiğini nasıl belirleyebilirsiniz? Öğrenmek mümkündür, ancak senaryonuz olacak.

İşte bir örnek: Varsayalım tablonuz var mydb.mytable. İnnodb_file_per_table etkinken, /var/lib/mysql/mydb/mytable.ibd dosyasına sahipsiniz

İki numara almanız gerekecek

İşletim Sisteminden DOSYA BOYUTU: İşletim sisteminden dosya boyutunu şu şekilde belirleyebilirsiniz

ls -l /var/lib/mysql/mydb/mytable.ibd | awk '{print $5}'

BİLGİ_SCHEMA'DAN DOSYA BOYUTU: Dosya boyutunu aşağıdaki gibi information_schema.tables adresinden öğrenebilirsiniz:

SELECT (data_length+index_length) tblsize FROM information_schema.tables
WHERE table_schema='mydb' AND table_name='mytable';

BİLGİ_SCHEMA değerini OS değerinden çıkarın ve farkı BİLGİ_SCHEMA değerine bölün.

Oradan, bu yüzdeyi birleştirmek için yüzde kaçının gerekli olduğuna karar vereceksiniz. Tabii ki, aşağıdaki komutlardan birini kullanarak birleştirebilirsiniz:

OPTIMIZE TABLE mydb.mytable;

veya

ALTER TABLE mydb.mytable ENGINE=InnoDB;

/ var / lib / mysql / ibdata1, önerilen innodb_file_per_table = 1 seçeneğini kullanıyorsanız çok meşgul olduğunu düşünmüyorum
CrackerJack9 4:13

1
@ CrackerJack9 ibdata1, içine ne girdiğinden dolayı inanılmaz derecede aşırı derecede: 1) Çift yazma arabellek bilgisi, 2) İkincil Dizinler için Tampon Ekle, 3) Veri sözlüğü, 4) Geri Alma Segmentleri, 5) Tabloyu Geri Al. Bunların resimli bir temsili için lütfen scribd.com/doc/31337494/XtraDB-InnoDB-internals-in-drawing adresine gidin . InnoDB tabloları için veri ve dizin sayfalarının kaldırılmasıyla bile, ibdata1 yüksek işlem ortamında hala önemli ölçüde büyüyebilir.
RolandoMySQLDBA

1
: CrackerJack9 @ ı ibdata1 etrafında ek aktivitesi tartışan ek yayını bilgisi dba.stackexchange.com/a/23367/877
RolandoMySQLDBA

Hala çok yoğun kullanıldığını fark etmemiştim. Oldukça memnun olarak!
CrackerJack9

@RolandoMySQLDBA Zamanınız olduğunda Heap'de patlayabilir misiniz?
ypercubeᵀᴹ

5

Sık sık satırları silerseniz (veya değişken uzunluktaki veri türlerine sahip satırları güncellerseniz), veri dosyalarınızda dosya sistemi parçalanmasına benzer şekilde boşa harcanan alanla sonuçlanabilir.

innodb_file_per_tableSeçeneği kullanmıyorsanız, zaman ve disk açısından yoğun bir prosedür olan veritabanını dışa ve içe aktarmaktır.

Ancak kullanıyorsanız innodb_file_per_table, bu alanı tanımlayabilir ve geri alabilirsiniz!

5.1.21'den önce boş alan sayacı, information_schema.tables öğesinin table_comment sütununda bulunabilir. En az 100M (aslında 97.65M) boş alana sahip tabloları tanımlamak için bazı SQL'ler:

Table_schema, table_name, table_comment FROM
information_schema.tables 'INnoDB' NEREDE VE INCHDB 'VE table_comment RLIKE' InnoDB içermiyor: ([0-9] {6,}). * ';

5.1.21 ile başlayarak, data_free sütununa taşındı (çok daha uygun bir yer):

Table_schema, table_name, data_free / 1024/1024 data_free_MB AS bilgi_schema.tables NEREDE MOTOR NEREDE 'InnoDB' VE data_free> 100 * 1024 * 1024;

Tabloyu yeniden oluşturarak kayıp alanı geri alabilirsiniz. Bunu yapmanın en iyi yolu, hiçbir şeyi değiştirmeden 'tabloyu değiştir' kullanmaktır:

ALTER TABLE `TableName` ENGINE=InnoDB;

InnoDB tablosunda 'tabloyu optimize et' seçeneğini çalıştırırsanız MySQL'in perde arkasında yaptığı şey budur. Bu bir okuma kilidiyle sonuçlanır, ancak tam bir masa kilidiyle sonuçlanmaz. Ne kadar zaman alacağı tamamen tablodaki veri miktarına bağlıdır (ancak veri dosyasının boyutuna bağlı değildir). Yüksek miktarda silme veya güncelleme içeren bir tablonuz varsa, bunu aylık veya hatta haftalık olarak çalıştırmak isteyebilirsiniz.


Bir şey daha ben data_free> 100 * 1024 * 1024 .. ne anlama geldiğini anlayamıyorum .. Ve sonucu görünce ben bu tablo parçalanmış ya da değil karar veremiyorum .. ?? tablonun parçalanmış veya parçalanmamış olduğunu söyleyebilir.
Abdul Manaf

güncelleme bölümüme bir göz atın.
Abdul Manaf
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.