MySql - canlı bir db için innodb_file_per_table değiştirme


18

Ben büyük bir MySql DB (150GB) var ve sadece şimdi fark ettim ki tüm DB tek bir dosya ( ) barındırılması neden olur innodb_file_per_tableayarlanır . Etkinleştirmek ve geriye dönük olarak DB birkaç dosyaya bölmek istiyorum , bunu yapmanın en iyi yolu nedir?offibdata1innodb_file_per_table

Yanıtlar:


32

Bunu çekmenin tek bir yolu var. Verileri mysqldumps kullanarak dışa aktarmak, tüm veritabanlarını bırakmak, mysqld'i kapatmak, ib_logfile0'ı silmek, ib_logfile1'i silmek, ibdata1'i silmek innodb_file_per_table, [mysqld]başlığın altına eklemek, mysql'yi başlatmak zorunda kalacaksınız .

Bu cevabı Ekim 2010'da StackOverflow'a gönderdim

Dikey olarak listelenen adımlar şunlardır:

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

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

Adım 03) Kapatma mysql

CAVEAT : Teslim edilmemiş işlemleri InnoDB Dosyalarından tamamen temizlemek için şunu çalıştırın:

mysql -uroot -p... -Ae"SET GLOBAL innodb_fast_shutdown = 0;"
service mysql stop

Adım 04) /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.

Adım 05) ibdata1, ib_logfile0 ve ib_logfile1 öğelerini silin

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

Adım 06) MySQL'i yeniden başlatın

Bu ibdata1'i 10MB, ib_logfile0 ve ib_logfile1'i her biri 1G'de yeniden oluşturacak

Adım 07) SQLData.sql dosyasını mysql'ye yeniden yükleyin

ibdata1 büyüyecek, ancak yalnızca tablo meta verilerini içerecek

Her InnoDB tablosu ibdata1 dışında bulunur

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 Dizinleri artık içermeyecek.

/Etc/my.cnf içindeki innodb_file_per_table seçeneğiyle OPTIMIZE TABLE mydb.mytable dosyasını çalıştırabilirsiniz 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 boyunca işe yarayacaktır. !!!

Ibdata1'i daraltmadan InnoDB tablosunu çıkaracak bir alternatif var.

Adım 01) /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

Adım 02) service mysql restart

Adım 03) mydb.mytable adlı tek bir InnoDB tablosu ayıklamak için şunu yapın:

ALTER TABLE mydb.mytable ENGINE=InnoDB;

Bu orijinal yapı dosyasını tutmak bir dosya pleus yaratacaktır

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

Bunu her InnoDB tablosu için yapabilirsiniz. Ne yazık ki, ibdata1 150GB kalacak.


.sql dosyalarından yeniden yükleme çalışırken aşağıdaki hatayı ERROR 1071 (42000) at line 25: Specified key was too long; max key length is 1000 bytesherhangi bir fikir var mı?
koştu

@ Lütfen bunu ayrı bir soru olarak gönderin.
RolandoMySQLDBA


Her bir tabloyu ayarlayıp innodb_file_per_tableyaparsanız, ALTER TABLEgeri yüklemek zorunda kalmadan alanı geri almak için ibdata1 dosyasını silebilir misiniz?
SystemParadox

1
@SystemParadox KESİNLİKLE DEĞİL !!!!!!!! Veri sözlüğünü kaybedeceksiniz.
RolandoMySQLDBA

5

Eğer ibdata ait alanını geri kazanmak istiyorsanız gibi bir dökümü /, tek tercihiniz geri Rolando işaret ediyor. Performansın bunu yapması da muhtemelen en iyisidir.

Ancak, sadece kayıplarınızı azaltmak ve sabit diskte 150 GB'ı 'kaybetmek' istiyorsanız innodb_file_per_table, my.cnf içinde etkinleştirebilir ve sunucunuzu yeniden başlatabilirsiniz.

Sonra her tablo için sorun:

ALTER TABLE x DISABLE KEYS;
ALTER TABLE x ENGINE=InnoDB;
ALTER TABLE x ENABLE KEYS; 

Buradaki sorun, büyük tablo alanlarının biraz zaman alacağıdır.

Ne öneririm canlı db bir köle kurmak, köle üzerinde dönüşüm çalıştırmak, daha sonra ya master / slave kapatın ve yeni veri master'a kopyalamak, ya da köle yakaladı kez master olması teşvik .

Kesinti olmadan bu değişikliği yapmakta zorluk çekeceksiniz.


Acımasızca dürüst olmak ve 'kayıplarınızı kesin' demek için +1. 'Kurşunu ısır' da diyebilirdin.
RolandoMySQLDBA

Değiştirme tablosunu çalıştırırken kapalı kalma süresini önlemek için pt-online-schema-change kullanabilirsiniz.
cornernote
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.