InnoDB neden tüm veritabanlarını bir dosyada saklıyor?


51

MyISAM'in her bir tabloyu karşılık gelen bir dosyada saklamak kullanışlıydı. InnoDB birçok yönden ilerleme kaydetmiştir, ancak InnoDB'nin neden tüm veritabanlarını tek bir dosyada ( ibdata1varsayılan olarak) sakladığını merak ediyorum .

InnoDB'nin dosyadaki verilerin konumunu, tablolar için ayrı indeks dosyaları ile eşleyeceğini biliyorum, fakat neden tüm verileri tek bir dosyada karıştırdığını anlamıyorum. Ve daha önemlisi, neden sunucudaki tüm veritabanlarının verilerini karıştırıyorsunuz?

MyISAM'in ilginç bir özelliği, bir veritabanı klasörünü başka bir makineye kopyalayıp yapıştırıp ardından veritabanını kullanabilmesidir.

Yanıtlar:


66

InnoDB'nin mimarisi dört temel tür bilgi sayfasının kullanılmasını gerektirir.

  • Tablo Veri Sayfaları
  • Tablo Dizin Sayfaları
  • Tablo MetaData
  • MVCC Verileri (İşlem İzolasyonu ve ACID Uyumluluğunu desteklemek için )
    • Geri Alma Segmentleri
    • Boşluğu Geri Al
    • Çift Yazma Arabelleği (işletim sistemi önbelleğe alma güvenini önlemek için arka plan yazma)
    • Arabellek Ekle (benzersiz olmayan ikincil dizinlerde yapılan değişiklikleri yönetme)

İbdata1 Resimli Temsiline Bakın

Varsayılan olarak, innodb_file_per_table devre dışı bırakılmıştır. Bu, dört bilgi sayfası türünün hepsinin ibdata1 adlı tek bir dosyayı indirmesine neden olur. Birçok kişi, birden fazla ibdata dosyası oluşturarak verileri dağıtmaya çalışır. Bu, verilerin parçalanmasına ve dizin sayfalarına yol açabilir.

Bu nedenle, genellikle varsayılan ibdata1 dosyasını ve daha fazlasını kullanarak InnoDB altyapısını temizlemenizi öneririm .

InnoDB'nin çalıştığı altyapı nedeniyle kopyalama çok tehlikelidir. İki temel altyapı var.

  • innodb_file_per_table devre dışı
  • innodb_file_per_table etkin

InnoDB ( innodb_file_per_table devre dışı)

İle innodb_file_per_table engelli, InnoDB'nin bilgi tüm bu tür ibdata1 içinde yaşamaktadır. Herhangi bir InnoDB tablosunun ibdata1 dışındaki tek tezahürü, InnoDB tablosunun .frm dosyasıdır. Tüm InnoDB verilerini bir kerede kopyalamak, tüm / var / lib / mysql öğelerinin kopyalanmasını gerektirir.

Tek bir InnoDB masasını kopyalamak tamamen imkansızdır. Verilerin ve buna karşılık gelen indeks tanımlarının mantıksal bir temsili olarak tablonun bir dökümünü çıkarmak için MySQL dökümünü kullanmalısınız. Daha sonra o dökümü aynı sunucudaki veya başka bir sunucudaki başka bir veritabanına yüklersiniz.

InnoDB ( innodb_file_per_table etkin)

İle innodb_file_per_table etkin, tablo veri ve indeksleri sonraki .frm dosyaya veritabanı klasöründe yaşıyor. Örneğin, db1.mytable tablosu için, bu InnoDB tablosunun ibdata1 dışındaki tezahürü şöyle olacaktır:

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

Sistem Tablo Alanı ibdata1

Db1.mytable için tüm meta veriler hala ibdata1'de bulunur ve bunun kesinlikle bir yolu yoktur . Yinelenen kütükler ve MVCC verileri de yine de ibdata1 ile yaşıyor.

Tablo parçalanmasına gelince, işte ibdata1'e ne olur:

  • innodb_file_per_table etkin : db1.mytables dosyasınıALTER TABLE db1.mytable ENGINE=InnoDB;veyaile daraltabilirsinizOPTIMIZE TABLE db1.mytable;. Bu, /var/lib/mysql/db1/mytable.ibd dosyasında fiziksel olarak daha küçük parçalanma olmadan sonuçlanır.
  • innodb_file_per_table devre dışı bırakıldı : db1.mytables dosyasınıALTER TABLE db1.mytable ENGINE=InnoDB;ya daibdata1 ileOPTIMIZE TABLE db1.mytable;bulunduğundan daraltamazsınız. Her iki komutu da çalıştırarak masayı okumaya ve yazmaya hızlı ve bitişik hale getirin. Ne yazık ki, bu ibdata1 sonunda gerçekleşir. Bu, ibdata1'in hızla büyümesini sağlar. Bu tamamen InnoDB Temizleme Görevimde ele alındı .

UYARI (veya Robotun Uzayda Kayıpta dediği gibi TEHLİKE )

Sadece .frm ve .ibd dosyalarını kopyalamayı düşünüyorsanız, incinecek dünya için aynı çizgidesiniz. Bir InnoDB tablosunun .frm ve .ibd dosyasını kopyalamak, yalnızca .ibd dosyasının tablo alanı kimliğinin ibdata1 dosyasının meta verilerindeki tablo alanı kimliği girişi ile tam olarak eşleştiğini garanti edebiliyorsanız iyidir .

Bu tablo alanı kimliği kavramı hakkında DBA StackExchange'te iki yazı yazdım

Eşleşmeyen tablo alanı kimlikleri durumunda, herhangi bir .ibd dosyasını ibdata1'e yeniden eklemek için mükemmel bir bağlantı: http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in-file . Bunu okuduktan sonra, .ibd dosyalarını kopyalamanın sadece delice olduğunu hemen fark etmeniz gerekiyor.

InnoDB için, sadece bunu hareket ettirecek bir şeye ihtiyacınız var.

CREATE TABLE db2.mytable LIKE db1.mytable;
INSERT INTO db2.mytable SELECT * FROM db1.mytable;

InnoDB tablonun bir kopyasını almak için.

Başka bir DB sunucusuna geçiriyorsanız, mysqldump kullanın.

Tüm InnoDB tablolarını tüm veritabanlarından karıştırmakla ilgili olarak, bunu yaparken bilgeliği gerçekten görebiliyorum. İşverenimin DB / Web barındırma şirketinde, aynı MySQL örneği içinde başka bir veritabanındaki kısıtlamaları başka bir veritabanında eşlenen bir veritabanında bir tablo bulunan bir MySQL İstemcisi var. Bir ortak meta veri deposuyla, birden çok veritabanında işlem desteğini ve MVCC çalışabilirliğini mümkün kılar.


Bu tablo başına innodb dosyasını etkinleştirdiğimde ve verilerimi bir sunucudan diğerine içe aktarmam gerekirse, yalnızca mysqldump kullanmak zorunda kalacağım, Percona xtrabackup gibi başka araçlar kullanmam gerekecek mi?
tesla747,

14

Cnf'nize tablo başına innodb dosyası ekleyerek dosya başına tablo depolamak için InnoDB'i değiştirebilirsiniz.

Innodb gerçekten sadece temel düzeyde veri sayfalarını önemser. Aslında, InnoDB'yi, hiçbir zaman bir dosya sistemine sahip olmayan sadece ham bir blok cihaz kullanacak şekilde ayarlayabilirsiniz! http://dev.mysql.com/doc/refman/5.5/en/innodb-raw-devices.html

Tabloları dosyalamak için kullanılan alanı optimize etmek yoluyla daha kolay bir şekilde yeniden kazanabilmek gibi kolaylıklar vardır.

Tablo başına dosyalarda bile, ibd dosyalarını o kadar kolay kopyalayamazsınız çünkü InnoDB işlemseldir ve durumuyla ilgili bilgileri genel paylaşılan ibdata / log dosyalarında saklar.

Bu yapılamaz demek değildir. Tablo çevrimdışıysa, tablo alanlarını atabilir / alabilir ve http://dev.mysql.com/doc/refman/5.5/en/innodb-multiple-tablespaces.html .idbs dosyasını kopyalayabilirsiniz.


Hiç şüphe yok ki InnoDB esnek bir motordur, ancak tüm verilerin tek bir dosyada saklanmasının ne kadar yararlı olduğunu anlamıyorum (bu yeni yapının InnoDB'de MyISAM ile karşılaştırmalı olarak uygulandığı için).
Googlebot,

Sanırım bu görüşlerin çoğunda 20/20 şey daha var. Tablo başına dosya seçeneği, innodb ilk raflardan çıkarıldıktan sonra eklendi. Dosya sistemi yükü önlemek için kendi blok aygıtı vermenin dışında, hepsini bir araya getirmenin neden daha iyi olduğunu (ve tüm blok aygıtı meselesinin kendi tartışması olduğu) için bir neden sağlayamıyorum. Tüm innodb kurulumlarımda tablo başına etkin dosya var.
atxdba

Mesele şu ki, dosya sistemine güvenmemek paha biçilemez olabilir ama varsayılan olarak aktif değildir. Böylece, birkaç kullanıcı onu kullanacaktır.
Googlebot,

1
Tablo başına bir dosya seçeneği, çok fazla tablonuz varsa ve çok fazla RAM yoksa (örneğin bir Magento mağazasında yaklaşık 1000 masa olabilir) zarar verebilir. Açık dosyalar ayarı da optimize edilmelidir (işletim sistemi sınırlamaları dikkate alınarak). Bu yüzden dikkatli kullanın.
ypercubeᵀᴹ

İyileşme çabalarına kesinlikle engel olabilir. Evet, bir yedeğiniz olmalı, ancak yoksa, InnoDB bu yapı nedeniyle işleri zorlaştırır.
mikato

10

Varsayılan davranış budur ancak zorunlu değildir. Gönderen MySQL dokümanlar, tablespaces-Tablo Başına Kullanılması :

Varsayılan olarak, tüm InnoDB tabloları ve dizinleri sistem tablo alanında depolanır. Alternatif olarak, her InnoDB tablosunu ve dizinlerini kendi dosyasında saklayabilirsiniz . Bu özelliğe “çoklu tablo alanları” adı verilir, çünkü bu ayar etkinken oluşturulan her tablonun kendi tablo alanı vardır.

Neden olarak, neden muhtemelen iki motorun farklı mimarileridir (MyISAM ve InnoDB). Örneğin, InnoDB'de .ibd dosyasını başka bir veritabanına veya kurulumuna kopyalayamazsınız. Açıklama (aynı sayfadan):

.İbd Dosyaları için Taşınabilirlik Hususları

MyISAM tablo dosyalarıyla mümkün olduğu kadar .ibd dosyalarını veritabanı dizinleri arasında serbestçe taşıyamazsınız. InnoDB paylaşılan tablo alanında depolanan tablo tanımı, veritabanı adını içerir. Tablo alanı dosyalarında saklanan işlem kimlikleri ve günlük sıra numaraları da veritabanları arasında farklılık gösterir.


Çok bilgilendirici cevap ve sorunu açıklığa kavuşturmakla birlikte hala tüm veritabanlarını içeren büyük bir dosyanın performansı nasıl artırabileceğini merak ediyorum.
Googlebot,

Herkes için bir dosya olması nedeniyle performans daha iyi değil. Tablo düzeyinde yerine satır düzeyinde kilitleme gibi çeşitli özellikler performansa yardımcı olur. Elbette ana avantaj, işlemler ve FK kısıtlamalarıdır (ve böylece veritabanının bütünlüğüdür).
ypercubeᵀᴹ

1
Bütünlük konusunda oldukça haklısın! Bir veritabanındaki tüm tabloları tek bir dosyaya koymanın neden daha iyi olduğunu anlıyorum; ancak neden bütün veritabanlarını (tamamen bağımsız) aynı dosyaya koyduğumu anlamıyorum. InnoDB varsayılan olarak veri depolamak için sadece bir dosya kullanır.
Googlebot,
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.