MySQL LOAD DATA INFILE, InnoDB motoruyla birkaç konser girdikten sonra% 80 yavaşlar


14

LOAD DATA INFILE üzerinden 100GB dosya yüklüyorum. MyISAM ile birkaç saat başarılı oldum ve yaptım.

Şimdi InnoDB kullanarak deniyorum. Yük, 10MB / saniyenin üzerinde hızla başlar (tablo dosyasının büyümesini izler file_per_table, açılır).

Ancak yaklaşık 5GB veri sonra 2-4MB / sn aralığına yavaşlar, 20GB'ın üzerine çıkarken 2MB / sn civarında azaldı.

InnoDB tampon havuzlarının boyutu 8G'dir. LOAD DATA INFILE komutunu çalıştırmadan önce aşağıdakileri yaptım:

SET @@session.sql_log_bin=0;
SET autocommit=0;
SET unique_checks=0;
SET foreign_key_checks=0;
alter table item_load disable keys;
//Run LOAD DATA INFILE....

Neden iyi başladığını ve zaman içinde yavaşladığını göremiyorum.

Ayrıca, aynı ayarları kullanarak, InnoDB ve MyISAM ve 5GB test veri kümesini kullanan tabloyla aynı LOAD DATA INFILE komutunu çalıştırdım, MyISAM 20 kat daha hızlıydı:

InnoDB'nin:

mysql> LOAD DATA CONCURRENT LOCAL INFILE '/tmp/item' REPLACE INTO TABLE item_load;
Query OK, 2630886 rows affected, 6 warnings (21 min 25.38 sec)
Records: 2630886  Deleted: 0  Skipped: 0  Warnings: 6

MyISAM:

mysql> LOAD DATA CONCURRENT LOCAL INFILE '/tmp/item' REPLACE INTO TABLE item_load;
Query OK, 2630886 rows affected, 6 warnings (1 min 2.52 sec)
Records: 2630886  Deleted: 0  Skipped: 0  Warnings: 6

Denemeyi düşünmem gereken başka bir şey var mı? MyISAM motoru, yük oranını daha iyi koruyabilir.


Ek detaylar:

  • Dosyaları tek tek yüklemeyi denedim, fark yok.

  • Bu arada, her biri 500MB'lık 150 dosyam var, her dosya içinde anahtarlar sıralanıyor.

  • Bir gece, 12 saat sonra 40 GB aldıktan sonra, yükleme hızı 0,5MB / sn'ye düştü, yani işlem pratik olarak imkansız.

  • Diğer forumlarda benzer sorulara başka cevap bulamadım, bana göre InnoDB, birkaç GB büyüklüğündeki tablolara büyük miktarda veri yüklemeyi desteklemiyor.

Yanıtlar:


7

GÖZLEM # 1

Kapattığını fark ettim autocommit. Bu ibdata1'de çok fazla veri biriktirecek. Neden?

İbdata1'de depolanan yedi (7) bilgi sınıfı vardır:

  • InnoDB Tabloları için Veri Sayfaları
  • InnoDB Tabloları için Dizin Sayfaları
  • Bilgi sözlüğü
  • Çift Yazma Tamponu
    • Veri Bozulmasını Önleyen Güvenlik Ağı
    • Önbellekleme için İşletim Sistemini Atlamaya Yardımcı Olur
  • Tampon Ekle (İkincil Dizinlerdeki Değişiklikleri Kolaylaştırır)
  • Geri Alma Bölümleri
  • Günlükleri Geri Al
  • Resimli Temsilini görmek için Buraya tıklayın ibdata1

Bu bilgilerin bir kısmı, izolasyon düzeyine bağlı olarak belirli işlemler tarafından görülebilir. Bu tür eylemler istenmeyen birincil anahtar kilitleri ve çok sayıda hayalet veri üretebilir . Bu iki şey arttıkça, adil bir yavaşlama beklemelisiniz.

Öneri: Otomatik taahhüdü açık bırakın

GÖZLEM # 2

Gördüğünüz gibi:

alter table item_load disable keys;

DISABLE KEYS, InnoDB ile çalışmaz . İşte nedeni:

  • MyISAM: DISABLE KEYSMyISAM tablosu için İkincil Dizin güncellemesini kapatır. Kitle INSERT anahtarları devre dışı bırakılmış bir MyISAM tabloya yerleştirdiğinizde, PRIMARY KEY ve tüm benzersiz dizinlerin oluşturulduğu bina ile birlikte hızlı bir tablo yüküyle sonuçlanır. Çalıştırdığınızda ENABLE KEYS, tüm İkincil Dizinler doğrusal olarak masaya oluşturulur ve .MYD.
  • InnoDB: InnoDB'nin dahili resminde gösterildiği gibi, sistem tablolar tablosu ibdata1İkincil Dizin Ekleme'ye adanmış bir yapıya sahiptir. Şu anda, MyISAM ile aynı dizinleri işlemek için bir hüküm yoktur.

Bunu göstermek için MySQL InnoDB tablosundaki DISABLE KEYS çalıştırma girişimimi not edin

mysql> show create table webform\G
*************************** 1. row ***************************
       Table: webform
Create Table: CREATE TABLE `webform` (
  `nid` int(10) unsigned NOT NULL,
  `confirmation` text NOT NULL,
  `confirmation_format` tinyint(4) NOT NULL DEFAULT '0',
  `redirect_url` varchar(255) DEFAULT '<confirmation>',
  `status` tinyint(4) NOT NULL DEFAULT '1',
  `block` tinyint(4) NOT NULL DEFAULT '0',
  `teaser` tinyint(4) NOT NULL DEFAULT '0',
  `allow_draft` tinyint(4) NOT NULL DEFAULT '0',
  `submit_notice` tinyint(4) NOT NULL DEFAULT '1',
  `submit_text` varchar(255) DEFAULT NULL,
  `submit_limit` tinyint(4) NOT NULL DEFAULT '-1',
  `submit_interval` int(11) NOT NULL DEFAULT '-1',
  PRIMARY KEY (`nid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql> alter table webform disable keys;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> show warnings;
+-------+------+-------------------------------------------------------------+
| Level | Code | Message                                                     |
+-------+------+-------------------------------------------------------------+
| Note  | 1031 | Table storage engine for 'webform' doesn't have this option |
+-------+------+-------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select version();
+------------+
| version()  |
+------------+
| 5.5.27-log |
+------------+
1 row in set (0.00 sec)

mysql>

GÖZLEM # 3

MyISAM'ın InnoDB'den 20 kat daha hızlı yüklendiğini fark ettiniz. Bunun 24-25 kat daha hızlı olmasını ister misiniz? Ardından aşağıdakileri çalıştırın:

ALTER TABLE item_load ROW_FORMAT=Fixed;

Bu, başka DDL Değişiklikleri olmadan INSERT'leri% 20-25 oranında hızlandıracaktır . Yan etki: MyISAM tablosu% 80-% 100 büyüyebilir, muhtemelen daha büyük olabilir.

Bunu bir InnoDB tablosunda da çalıştırabilirsiniz, ancak InnoDB'nin ACID uyumlu davranışı ve MVCC'si , özellikle VARCHAR alanları önemli ölçüde artarsa, performansının tıkanıklığı olmaya devam edecektir ibdata1.


İlk 2 gözlem, ilk fark ettikten sonra sorunu düzeltmek için eklemeye çalıştığım şeylerdi, ilk denemem doğal olarak innodb'u yalnız bırakmaktı (sadece bin günlüğünü kapat). 3. gözlemde, veri boyutumun uzunluğu oldukça değişkendir, bunun bir sorun olacağını varsayalım? Bu masayı tutmam gerekmiş gibi hissediyorum.
David Parks

6

Bu sorunun son cevabı büyük bir referans tablosu için InnoDB'yi kullanmamaktı. MyISAM hızlı bir şekilde çığlık atıyor, tüm yük için disk hızının tam çıktısına yakın, InnoDB düşüyor. MyISAM basittir, ancak bu durumda bu tablonun gereksinimleri de geçerlidir. LOAD DATA INFILE üzerinden toplu yükleri olan basit bir referans tablosu için, MyISAM şimdiye kadar iyi bir yoldur.

Ancak, MyISAM ve InnoDB tablolarını çalıştırırsanız, her ikisinin de 2 önbellek mekanizması için bellek ayırmayı dikkate almanız gerektiğini unutmayın, her motorun ayrı bellek ayırma gerektiren kendi benzersiz önbelleğe sahip olması gerekir.


5

Giriş dosyalarınızı daha küçük parçalara bölmeyi deneyebilirsiniz.

Şahsen http://www.percona.com/doc/percona-toolkit/2.1/pt-fifo-split.html adresini kullanıyorum .

İçe aktarma sırasında tablo için bir masa kilidi alırsanız ne olur? Belki de InnoDB'nin satır düzeyinde kilitlenmesi onu yavaşlatır (MyISAM bir tablo kilidi kullanır).

Daha fazla fikir için de okuyabilirsiniz: http://derwiki.tumblr.com/post/24490758395/loading-half-a-billion-rows-into-mysql


Dosyalarım zaten 500 MB'lık parçalar halinde, yükü kolaylaştırmak için hepsini tek bir adlandırılmış borudan geçiriyordum, ama şimdi bu yaklaşımı deneyeceğim.
David Parks

Burada herhangi bir fark görmüyorum, oldukça hızlı bir şekilde DB dosyasının 11MB / sn genişlemesinden 6MB (yaklaşık 2GB sonra) veriye hız düşüşünü görüyorum ve düşmeye devam ediyor. Bir for döngüsü, mysql çağrıları tüm dosyaları yüklüyorum.
David Parks

İlk dosya 54s, 3m39s içinde 2, 3m9s içinde 3, 4m7s, 5m21s, vb. tüm dosyalar aynı boyuttadır.
David Parks

2

PK'nız AUTO_INCREMENT değilse veya csv dosyasındaki veriler PK'da sıralanmamışsa, veri yükünün performansını etkiliyor olabilir. MySQL'deki tablo bir indeks olduğundan, tüm veriler sıralı olarak saklanır, PK değeri AUTO_INCREMENT üzerinde değilse MySQL sıralı bir şekilde saklanan verileri almak için çok fazla veri kaydırma yapmak zorunda kalır. Tablo boyutu büyümeye başladığında veri yükünün yavaşlamasının nedeni budur.

LOAD DATA INFILE kullanarak AUTO_INCREMENT üzerinde PK ile 91GB csv dosyası yüklüyorum ve iş akışımda herhangi bir düşüş görmüyorum. Saniyede 140 ila 145 bin kesici uç alıyorum. Percona MySQL 5.6.38 Kullanımı

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.