Neden innodb_file_per_table kullanıyorsunuz?


26

İhtiyacı olan abartılı (tabii ki IMHO) makaleler var innodb_file_per_table. innodb_file_per_tableAyrı ayrı masalar üzerinde daha iyi bir kontrolün olması gerektiğini anladım ; ayrı ayrı her tablo yedek gibi. Ancak, daha iyi performans iddiası sorgulanabilir.

Testimde performans innodb_file_per_tableve ibdata160GB veri tabanı için bir fark yoktur . Elbette normal sorgular ile basit bir testti ve gerçek hayatta karmaşık sorgular için durum farklı olabilir (bu soruyu sormamın nedeni budur). 64-bit linux ile ext4büyük dosyaları etkili bir şekilde işleyebilirsiniz.

Daha innodb_file_per_tablefazla disk G / Ç işlemi gerekir; ve bu karmaşık JOINs ve FOREIGN KEYkısıtlamalarda önemlidir .

Tablo alanı tek olarak paylaşılıyor ibdata; Ayrı tablolar için tahsis edilmiş masa alanları disk alanından nasıl tasarruf edebilir? Tabii ki, her masa için masa alanını boşaltmak daha kolaydır ALTER, ancak yine de pahalı bir işlemdir (masa kilidi ile).

SORU: MySQL'in innodb_file_per_tabledaha iyi performansa etkisi var mı? Evet ise neden?


Soruma bu cevaba bakınız: dba.stackexchange.com/questions/7924/… de yardımcı olabilir.
KM.

Yanıtlar:


19

Bunun performans değil yönetim meselesi olduğunu düşünüyorum.

Tablo başına ayrı bir dosyayla, örneğin farklı depolama cihazlarında farklı veritabanlarını saklayabilirsiniz.

Büyük dosyalarla başa çıkamayan dosya sistemlerinde çok büyük veritabanları ile ilgilenebilirsiniz (en azından bir tablo dosya boyutu sınırına ulaşana kadar sorunu erteleyin).

Kontrolsüz tablo alanı büyümesine sahip değilsiniz. Bıraktığınız bazı büyük tablolarınız varsa, ibdatadosya küçük kalır.

Performans üzerinde bir etkisi olabilecek bir özellik, tablo başına sınırlı olacak olan tablo verilerinin ve endekslerin parçalanmasıdır. Ancak bunun onaylanması için test yapılması gerekiyor.


Tablo alanı büyümesi tam olarak neden istediğiniz innodb_file_per_table.
sjas

13

Neden innodb_file_per_table kullanıyorsunuz?

Çünkü dosya düzeyinde yapılabildiğinden, bireyi yönetmek daha kolaydır. Bu, sunucu kapalı olsa bile, tablo dosyalarını kopyalayarak verileri kopyalayabileceğiniz anlamına gelir; oysa paylaşılan bir tablo alanı kullanmak , gereksiz yere büyük olabilecek her şeyi kopyalamak veya sunucunun veri ayıklamak için çalışmasını sağlamak için bir yol bulmak anlamına gelir ( verileri gerçekten bir hex-editor ile elle çıkarmak istemiyorsunuz).

Birisi , .ibddosyaları bir sunucudan diğerine kopyalayıp yapıştıramadığınız konusunda uyardı . Bu doğru olabilir, ancak aynı sunucudaki yedeklemeler için geçerli olmamalıdır ( burada geleneksel olarak bir kopya oluşturma anlamında yedekleme terimini kullanıyorum ; yani her şeyi büyük ölçüde değiştirmemek). Ayrıca, ibdata1başlangıçta otomatik olarak yeniden oluşturulur ( çoğu "tablo başına dosyaya dönüştürme" kılavuzlarının silmeibdata1 adımlarında görüldüğü gibi ). Bu nedenle, do not kopyalamanız gerekir ibdata1sizin ek olarak .ibddosyaları (ve onların tekabül .frmvb dosyaları).

Kayıp bir tablo kurtarmaya çalışırken, o onun kopyalamak yeterli olmalıdır .ibdve .frmdosyayı yanı sıra information_schema(ki çok daha küçük ibdata1). Bu şekilde, onları sahte bir sunucuya yerleştirebilir ve masif bir şeyi kopyalamak zorunda kalmadan masanızı çıkarabilirsiniz.

Ancak, daha iyi performans iddiası sorgulanabilir. … İnnodb_file_per_table ile daha fazla disk G / Ç işlemi gerekir; ve bu karmaşık JOIN'lerde ve DIŞ ANAHTAR kısıtlamalarında önemlidir.

Şaşırtıcı olmayan bir şekilde, performans tamamen kullanımdaki spesifik veri tabanlarına bağlı olacaktır. Bir kişi diğerinden farklı sonuçlara sahip olacak

Tablo başına dosya ile daha fazla disk G / Ç işlemi olacağı doğrudur, ancak yalnızca biraz daha fazla. Sistemin nasıl çalıştığını düşünün.

  • Yekpare bir veritabanı için:

    1. Sunucu başlatıldı
    2. ibdata1 açık
    3. Başlık ve meta veri okunur
    4. Yapılar ve meta veriler bellekte önbelleğe alınır
    5. Sorgu gerçekleşti
      1. Sunucu diske erişir ve önceden açılmış olan verileri okur. ibdata1
      2. Sunucu verileri bellekte önbelleğe alabilir
  • Tablo başına bir veritabanı için:

    1. Sunucu başlatıldı
    2. ibdata1 açık
    3. Başlık ve meta veri okunur
    4. Her bir .ibddosya açıldı
    5. Başlık ve meta veriler her .ibddosyadan okunur
    6. Yapılar ve meta veriler bellekte önbelleğe alınır
    7. Sorgu gerçekleşti
      1. Sunucu diske erişir ve verileri önceden açılmış olan .ibddosyadan okur
      2. Sunucu verileri bellekte önbelleğe alabilir

Sunucu çalışırken, sunucuda açık tutamaçlar olduğundan veri dosyalarını taşıyamayacağınızı fark edeceksiniz. Bunun nedeni, başladığında, onları açıp, açık bırakmasıdır. Her bir sorgu için bunları açıp kapatmaz.

Bu nedenle, başlangıçta, sunucu başlatıldığında yalnızca biraz daha fazla G / Ç işlemi vardır; çalışırken değil. Ayrıca, her bir .ibddosyanın kendi ayrı ek yükü (dosya imzaları, yapıları vb.) Varken, bellekte önbelleğe alınır ve her sorgu için yeniden okunmaz. Dahası, aynı yapılar paylaşılan bir masa boşluğunda bile okunur, bu nedenle daha fazla (hiç bir şekilde) daha fazla hafıza gerekli değildir.

İnnodb_file_per_table, mysql'in daha iyi performansına etki eder mi?

Aslında, bir şey olursa, performans aslında daha kötü olabilir .

Paylaşılan bir tablo alanı kullanırken, okuma ve yazma işlemleri bazen / sıklıkla birleştirilebilir, böylece sunucu bir seferde birden fazla tablodan bir veri örneğini okuyabilir ibdata.

Ancak, veriler birden fazla dosya arasında dağıtılmışsa, her biri için ayrı ayrı ayrı bir G / Ç işlemi gerçekleştirmesi gerekir.

Tabii ki, bu yine tamamen söz konusu veritabanına bağlıdır; gerçek dünyadaki performansın etkisi, büyüklüğüne, sorgu sıklığına ve paylaşılan tablo alanının iç parçalanmasına bağlı olacaktır. Bazı insanlar büyük bir fark görebilirken, diğerleri hiç bir etki görmeyebilir.

Tablo alanı, tek ibdata üzerinde paylaşılır; Ayrı tablolar için tahsis edilmiş tablolar nasıl disk alanı kazanabilir?

O değil. Bir şey olursa, disk kullanımını biraz arttırır .

Test etmek için 60 GB'lık bir veritabanım yok, ancak WordPress kurulumumu ve kişisel kullanım ve geliştirme testi için paylaşılan bir masa alanını kullanırken ~ 30 MB'de tartılan bazı "küçük" masaları ve WordPress kurulumumu içeren "birinci sınıf" kişisel veritabanım var. Tablo başına dosyaya dönüştürdükten sonra, ~ 85MB'a şişirilmiş. Her şeyi bırakıp yeniden ithal ederek bile, hala> 60 MB'dı.

Bu artış iki faktörden kaynaklanmaktadır:

  • Bunun için mutlak asgari boyut ibdata1, bir nedenden ötürü, information_schemaiçinde saklanmış olan hiçbir şey olmasa bile, 10 MB'dir .

  • Paylaşılan bir tablo alanıyla, yalnızca ibdata1dosya imzaları, meta-veriler vb .ibd. Bu, toplamın (varsayımsal <10MB olsa bile ibdata1) en azından biraz daha büyük olacağı anlamına gelir :

    GetTotalSizeofOverhead() * GetNumTables()

Açıkçası, bunlar büyük artışlar olmayacak (veritabanı boyutunuzu sınırlayan bir ana bilgisayar kullanıyorsanız veya bir flash sürücüde saklıyorsanız vs.), ancak yine de ( her ) tabloyu dosyaya geçirerek artarlar. -per-masa 10 ibdata1MB'a kadar küçültebilir , toplam toplam kaçınılmaz olduğundan daha fazla olacaktır.


11

Bu benim HER ZAMAN innodb_file_per_table kullanarak nedenim:

Tablo başına dosya olmadan, ibdata dosyası asla uzayda hiç sıkıştırılmaz veya küçülmez veya küçülmez. Bir satırı sildiğinizde, bir tabloyu veya bir veritabanını bıraktığınızda. Aktif bir kuyruk sisteminiz varsa, 2GB veri kısa sürede 20 GB dosya olabilir.

Bir değişiklik yapmadan önce mevcut 1GB'lık masanızın yedeğini almak istediğinizi varsayalım, ardından bırakın. Ibdata'nızda bir GB kullanılmayan alanla sıkışıp kaldınız. Aylak.

Muhtemelen, geçici önlemlerin tek veri dosyasını şişirdiği sonsuz örnek örnekleri vardır, ancak bence, innodb_file_per_table'ı KULLANMAMANIZ için hiçbir neden olmadığını söylemek yeterlidir.

Ayrıca, işte okumak için iyi bir yazı: http://code.openark.org/blog/mysql/reasons-to-use-innodb_file_per_table


1
HER ZAMAN da yapmanın iyi olduğunu anladım. SSD'ler tarafından desteklenen manyetik depolama dizileri, tablolar için daha küçük dosyalara karşı okuma / yazma önbelleklerini daha etkin bir şekilde işleyebilir. Zamanın% 99,99'unun sadece 'okuduğu' ancak yazılmadığı bir sürü tablo için, yanıtlama süresinde büyük bir azalma olan her zaman depolama denetleyicisinin önbelleğindedir.
sdkks

5

Nedenini innodb_file_per_table kullanmamak neden performanstır.

MySQL 5.5.45 Linux CentOS sürüm 6.7 üzerinde 450 tablo ile veritabanımız için bazı testler yaptım.

İçin birim testlerin her testten önce veritabanına demirbaşlar ekler (ekler, güncelleme, siler, seçer) (tüm tabloları her şey kullanarak değil) ve aynı zamanda kendisi test veritabanı ile çok çalışır performans daha iyi 3-5x oldu veritabanı tabloları değilken daha fazla dosyaya ayrılmış.

Veritabanınızı innodb_file_per_table kullanmaya karar vermeden önce kullanmak istediğiniz sorgular ile test etmenizi ve karşılaştırmanızı öneririm

Belki üretim sunucusu için innodb_file_per_table kullanabilirsiniz, ancak birim testlerini başlatan (DB'yi çok kullanır) CI ortamı için (entegrasyona devam ediyor) ve ayrıca birim testlerini başlatan geliştiricilerin performans nedeniyle kullanmamanın daha iyi olduğunu öğrenebilirsiniz.


2
Bunun tek bir dosyayı tahsis etmedeki tüm 450 tabloya ilk dosyaları ayırması için gereken zamandan kaynaklandığını tahmin ediyorum. Üretimde bu yalnızca bir kez gerçekleşecek, bu yüzden bir sorun olmamalı, ancak hızlı bir şekilde veritabanı oluşturmak ve sonra onu tamamen yıkmak ve tek bir ibdata dosyasını tekrar tekrar tekrarlamaktan daha iyi olacağına dair iyi bir noktaya değiniyorsunuz.
ColinM

2

Verileri daha yönetilebilir kılar, çünkü kullanılmayan alanı geri kazanabilirsiniz, ki bu da hoş bir şey.

Veritabanınız çoğunlukla seçme sorguları için kullanılıyorsa, performansı çok fazla etkilemeyeceğini düşünüyorum. Hala aynı miktarda veri okumak zorunda. Hangi verileri okuduğunu çok fazla önemli sanmıyorum.

Ancak, performansı çok fazla ek ve güncelleme içeren bir veritabanında daha da kötüleştirebilir. Bunun nedeni, bir işlem yaptıktan sonra mysql dosyasının depolama dosyasındaki fsync () işlevini çağırmasıdır. Tek bir dosya varsa, bir arama yapar ve aramanın tamamlanmasını bekler. Çok sayıda dosya varsa aramayı birden çok kez yapmak ve commit komutunun geri dönebilmesi için tüm bu aramaların geri dönmesini beklemek zorundadır.

İşte bu sorunu yaşayan birinden bir mesaj: http://umangg.blogspot.com/2010/02/innodbfilepertable.html



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.