Nasıl yapılır: Bir mysql InnoDB depolama motorunu temizleme?


133

Bir mysql innodb depolama motorunu, silinen tablolardan veri depolamaması için temizlemek mümkün müdür?

Yoksa her seferinde yeni bir veri tabanı oluşturmam mı gerekiyor?


MySQL'in silinmiş tablolardan veri depoladığını düşündüren nedir?
Robert Munteanu

1
Bir grup büyük tabloyu düşürürsem, InnoDB depolama dosyalarım küçülmez
Bryan Field

2
@RobertMunteanu: bkz bugs.mysql.com/bug.php?id=1341
Max

Yanıtlar:


351

İşte InnoDB ile ilgili daha eksiksiz bir cevap. Bu biraz uzun bir süreçtir, ancak çabaya değer olabilir.

Bunun /var/lib/mysql/ibdata1InnoDB altyapısındaki en yoğun dosya olduğunu unutmayın . Normalde altı tür bilgi barındırır:

  • Tablo Verileri
  • Tablo Dizinleri
  • MVCC (Multiversioning Concurrency Control) Verileri
    • Geri Alma Segmentleri
    • Boşluğu Geri Al
  • Tablo Meta Verileri (Veri Sözlüğü)
  • Çift Yazma Arabelleği (işletim sisteminin önbelleğe alınmasına güvenmeyi önlemek için arka planda yazma)
  • Arabellek Ekle (benzersiz olmayan ikincil dizinlerdeki değişiklikleri yönetme)
  • Bakın Pictorial Representation of ibdata1

InnoDB Mimarisi

InnoDB Mimarisi

Birçok kişi ibdatadaha iyi disk alanı yönetimi ve performansı umuduyla birden çok dosya oluşturur , ancak bu inanç yanlıştır.

Ben çalıştırabilir miyim OPTIMIZE TABLE?

Ne yazık ki, OPTIMIZE TABLEpaylaşılan tablo alanı dosyasında depolanan bir InnoDB tablosuyla çalışmak ibdata1iki şey yapar:

  • Tablonun verilerini ve dizinlerini içinde bitişik hale getirir ibdata1
  • Markalar ibdata1bitişik veri ve dizin sayfaları çünkü büyümek eklenmiş içinibdata1

Bununla birlikte, Tablo Verileri ve Tablo Dizinlerini ayırabilir ibdata1ve bağımsız olarak yönetebilirsiniz.

Ben çalıştırabilir miyim OPTIMIZE TABLEile innodb_file_per_table?

Eklemek olduğunu varsayalım innodb_file_per_tableiçin /etc/my.cnf (my.ini). O zaman OPTIMIZE TABLEtüm InnoDB Masalarında koşabilir misin?

İyi Haber : Eğer çalıştırdığınızda OPTIMIZE TABLEile innodb_file_per_tableetkin, bu üretecek .ibdbu tablo için dosyayı. Örneğin, bir mydb.mytabledataya sahip tablonuz varsa /var/lib/mysql, aşağıdakileri üretecektir:

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

, Bu .ibdtablo için Veri Sayfalarını ve Dizin Sayfalarını içerecektir. Harika.

Kötü Haber : Tüm yaptığınız Veri Sayfalarını ve Dizin Sayfalarını içinde mydb.mytableyaşamaktan çıkarmak ibdata. Dahil olmak üzere her tablo için veri sözlüğü girişi mydb.mytablehala veri sözlüğünde kalır (ibdata1'in Resimli Temsili'ne bakın ).ibdata1BU NOKTADA SADECE SİLECEKSİNİZ !!! Lütfen bununibdata1hiç küçülmediğiniunutmayın.

InnoDB Altyapı Temizleme

Küçültmek için ibdata1 kez ve tamamen için aşağıdakileri yapmanız gerekir:

  1. mysqldumpTüm veritabanlarını bir .sqlmetin dosyasına ( örn.SQLData.sql aşağıda kullanılmaktadır)

  2. Tüm veritabanlarını bırakın ( mysqlve hariç information_schema) CAVEAT : Bir önlem olarak, lütfen tüm kullanıcı izinlerini yerine getirdiğinizden kesinlikle emin olmak için bu komut dosyasını çalıştırın:

    mkdir /var/lib/mysql_grants
    cp /var/lib/mysql/mysql/* /var/lib/mysql_grants/.
    chown -R mysql:mysql /var/lib/mysql_grants
  3. Mysql'de oturum açın ve çalıştırın SET GLOBAL innodb_fast_shutdown = 0;(Bu, kalan tüm işlem değişikliklerini tamamen temizleyecektir.ib_logfile0 ve ib_logfile1)

  4. MySQL'i kapat

  5. Aşağıdaki satırları Windows'a ekleyin /etc/my.cnf(veya my.iniWindows'ta)

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

    (Sidenote: Setiniz ne olursa olsun innodb_buffer_pool_size, emin oluninnodb_log_file_size % 25'inininnodb_buffer_pool_size .

    Ayrıca: innodb_flush_method=O_DIRECT Windows'ta mevcut değildir)

  6. Sil ibdata*ve ib_logfile*İsteğe bağlı olarak, tüm klasörleri kaldırabilir /var/lib/mysqlhariç/var/lib/mysql/mysql .

  7. (Bu baştan yaratacak Başlangıç MySQL ibdata1[varsayılan olarak 10MB'yi] ve ib_logfile0ve ib_logfile11G her).

  8. İthalat SQLData.sql

Şimdi, ibdata1büyümeye devam edecek , ancak yalnızca tablo meta verilerini içerecek çünkü her InnoDB tablosu dışında var olacak ibdata1.ibdata1artık InnoDB verilerini ve diğer tablolar için dizinleri içermeyecektir.

Örneğin, adlı bir InnoDB tablonuz olduğunu varsayalım mydb.mytable. İçeri bakarsanız /var/lib/mysql/mydb, tabloyu temsil eden iki dosya göreceksiniz:

  • mytable.frm (Depolama Motoru Başlığı)
  • mytable.ibd (Tablo Verileri ve Dizinler)

İçerisindeki innodb_file_per_tableseçenek ile /etc/my.cnfkoşabilirsinizOPTIMIZE TABLE mydb.mytable ve dosya /var/lib/mysql/mydb/mytable.ibdaslında küçülecek.

Bunu kariyerim boyunca MySQL DBA olarak birçok kez yaptım. Aslında, bunu ilk yaptığımda 50 GB küçülttüm ibdata1 sadece 500MB dosya aşağı!

Bir şans ver. Bununla ilgili başka sorularınız varsa, sormanız yeterli. Güven Bana; bu kısa vadede olduğu kadar uzun vadede de işe yarayacaktır.

UYARI

Adım 6'da, mysql, mysqlşema başlangıcı düştüğü için yeniden başlatılamazsa , 2. Adıma geri bakın. Şemanın fiziksel kopyasını yaptınız mysql. Aşağıdaki şekilde geri yükleyebilirsiniz:

mkdir /var/lib/mysql/mysql
cp /var/lib/mysql_grants/* /var/lib/mysql/mysql
chown -R mysql:mysql /var/lib/mysql/mysql

6. Adıma geri dönün ve devam edin

GÜNCELLEME 2013-06-04 11:13 EDT

Ayarı ile ilgili olarak innodb_log_file_size % 25'ine innodb_buffer_pool_size 's battaniye kural oldukça eski okul olduğunu, 5. adımda.

Geri July 03, 2006döndüğümüzde, Percona'nın neden uygun bir innodb_log_file_size seçmesi gerektiğine dair güzel bir makalesi vardı . Daha sonra üzerine Nov 21, 2008, Percona başka bir makale üzerinde ile takip bir saatlik değişiklikleri koruyarak en yüksek iş yüküne göre uygun boyutun nasıl hesaplanacağına dair .

O zamandan beri DBA StackExchange'de günlük boyutunu hesaplamak ve bu iki Percona makalesine başvurduğum yer hakkında yazılar yazdım.

Şahsen ben yine de ilk kurulum için% 25 kuralı uygulayacaktım. Ardından, üretimde zaman içinde iş yükü daha doğru belirlenebildiğinden, bir bakım döngüsü sırasında günlükleri dakikalar içinde yeniden boyutlandırabilirsiniz .


9
Ayrıca innodb_file_per_table seçeneğini büyük bir etki için kullandım, her biri tek bir sunucuda 200 tabloya sahip 200 veritabanına sahip oldum, farklı bölümlere farklı veritabanlarını sembolik bağlayabildim, bu nedenle başka türlü mevcut olacak daha fazla GÇ arabelleği ve mili kullanarak :)
Dave Rix

2
@SeanDowney BTW innodb_open_tablesgerekirse yükseltmeyi unutmayın . Varsayılan değer 300'dür.
RolandoMySQLDBA

2
@ giorgio79 toplu girişinizi daha büyük bir değere ayarlamanız gerekir. Bu iyi bir nokta. Sorunuzun özünü cevabıma ekleyeceğim.
RolandoMySQLDBA

3
32 bit sistemlerde innodb_buffer_pool_size için 4 Gb değerine izin verilmez. Mysql, innodb devre dışı bırakılarak sessizce başlayacak ve geri yüklenen tablolar myisam olarak değiştirilecektir. Düzeltmek için biraz daha küçük bir değer kullanın.
David

5
İyi tanrı. Bunun belki de SO Damn fine job'ta gördüğüm en iyi cevaplardan biri olduğunu söylemek istiyorum efendim. 154 g db'yi içe aktarırken ERROR 2013 (HY000) alırken sorunuma bir çözüm bulmama yardımcı oldu. Mükemmel cevap için teşekkürler!
Josh Brown

4

InnoDB motoru silinmiş verileri saklamaz. Satırları ekleyip sildikçe, InnoDB depolama dosyaları içinde kullanılmayan alan ayrılır. Zamanla toplam alan azalmaz, ancak zamanla 'silinen ve boşaltılan' alan DB sunucusu tarafından otomatik olarak yeniden kullanılır.

Tabloların manuel olarak yeniden düzenlenmesi yoluyla motor tarafından kullanılan alanı daha fazla ayarlayabilir ve yönetebilirsiniz. Bunu yapmak için, mysqldump kullanarak etkilenen tablolardaki verileri boşaltın, tabloları bırakın, mysql hizmetini yeniden başlatın ve ardından döküm dosyalarından tabloları yeniden oluşturun.

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.