MyISAM'ın InnoDB'ye dönüşümünü hızlandırma


15

4GB kadar alan yaklaşık 450 tablodan oluşan bir veritabanı ile mysql 5.1 sunucum var. Bu tabloların büyük çoğunluğu (2 hariç) MyIsam'dır. Bu çoğunlukla iyi olmuştur (işlemlere gerek yoktur), ancak uygulama trafik kazanmaktadır ve güncellemelerdeki tablo kilitleme nedeniyle bazı tablolar etkilenmiştir. Tabloların 2'sinin şimdi InnoDB olmasının nedeni budur.

Daha küçük tablolardaki (100 bin satır) dönüşüm hiç uzun sürmez ve minimum duruş süresine neden olur. Ancak izleme tablolarımdan bazıları 50 milyon satıra yaklaşıyor. ALTER TABLE...ENGINE InnoDBBüyük masalarda hızlandırmanın bir yolu var mı ? Değilse, bu ağır yazma tablolarında kesinti süresini en aza indirgemek için başka yöntemler var mı?


1
Akılda tutulması gereken bir şey: tek bir gönderide birden fazla soru, sorulardan birini yanıt gönderebilecek kişilerden caydırma eğilimindedir.
BenV

Ben VtC bu cevaplamak oldukça karmaşıktır. Bireysel olarak birkaç soru açmalısınız.
jcolebrand

Memnuniyetle tek bir soru yapmak için tavsiye alacağım, ancak bu soruyu silmek ve sadece yeni bir soru açmak için tavsiye edilir? yeniden yazma çoğunlukla ikinci 2 mermiyi kaldırıyor ve ilkini değiştiriyor (başlığı hangi depolama motorlarını da yansıtacak şekilde güncelledim)
Derek Downey

Her ikisi de iyi olur. Diğer iki soruyu yazmak ve bu soruyu silmek genellikle daha kolaydır . Ancak, bunu kolayca "referans" için bırakabilir ve diğer ikisinin de "bu benim genel hedefim" sorusu olarak geri dönmesini sağlayabilirsiniz.
jcolebrand

bunu tek bir madde işaretine dönüştürün, ardından takip sorularını gönderin.
Brian Ballsun-Stanton

Yanıtlar:


10

Söylememe izin verin, ALTER'den nefret ediyorum. Bu kötü, IMHO.

Diyelim ki bu geçerli tablo şemanız -

CREATE TABLE my_table_of_love (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
my_value VARCHAR(40),
date_created DATE,
PRIMARY KEY(id)
) ENGINE=MyISAM CHARSET=utf8;

İşte önerdiğim yol -

Eskisinin yerini alacak yeni bir tablo nesnesi oluşturun:

CREATE TABLE my_table_of_love_NEW (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
my_value VARCHAR(40),
date_created DATE,
PRIMARY KEY(id)
) ENGINE=InnoDB CHARSET=utf8

Eski tablodaki tüm satırları ada göre yeni tabloya ekleyin:

INSERT INTO my_table_of_love_NEW (id,my_value,date_created)
SELECT id,my_value,date_created FROM my_table_of_love;

Duman göçünüzü test edin:

SELECT COUNT(*) FROM my_table_of_love_NEW;
SELECT COUNT(*) FROM my_table_of_love;
SELECT a.id,a.my_value,a.date_created FROM my_table_of_love_NEW a
LEFT JOIN my_table_of_love b ON (b.id = a.id)
WHERE a.my_value != b.my_value;

Geri almanız gerektiğinde yedeklemeyi sürdürebilmeniz için tablo adlarını değiştirin.

RENAME TABLE my_table_of_love TO my_table_of_love_OLD;
RENAME TABLE my_table_of_love_NEW TO my_table_of_love;

Regresyon testine devam edin.

Bu yaklaşım, birden çok dizine ve milyonlarca satıra sahip tablolarda giderek daha fazla tercih edilir hale gelmektedir.

Düşünceler?


1
Anlaşıldı ... çok fazla işlem yapsa da, bunu yaparken veritabanını kaldırmanız gerekebilir. (ancak bir değişiklik tablosu size daha uzun bir kesinti süresi verecektir, büyük olasılıkla)
Joe

Evet, daha aktif masalar için aksama süresi gerektireceğini düşündüm. Bazı testler yapmam gerekecek, ama neden 50 milyon satırdan ALTER TABLEdaha uzun sürecek INSERT INTO...SELECT?
Derek Downey

Olmaz. Temel olarak MySQL, bu posterin önerdiği gibi dahili olarak yapar. Tanımın bir kopyasını oluşturur ve kopyaya yükler damlar.
Morgan Tocker

Büyük tablolar için biraz zaman alabilir "tmp kopyala" bölümünü atlar, çünkü bu yöntemi seviyorum.
Haluk

Şimdi ekleyeyim ki, MySQL 5.7'de ALTER'lerle başa çıkmak çok daha hızlı ve kolaydır.
randomx

7

1) Kayıp koruması paranoya fonksiyonudur. Daima yedekleyin. Gerçekten paranoyaksanız, bir yedekleme yapın ve yedeklemeden geri yükleyin.

2) MySQL kılavuzunun bu sayfasında tablo türlerini dönüştürme talimatları vardır.

Bir tabloyu InnoDB olarak değiştirmenin en hızlı yolu, ekleri doğrudan bir InnoDB tablosuna yapmaktır. Yani, ALTER TABLE ... ENGINE = INNODB kullanın veya aynı tanımlarla boş bir InnoDB tablosu oluşturun ve INSERT INTO ... SELECT * FROM ile satırları ekleyin ...

3) PostgreSQL tam metin araması yapar , Sphinx Engine bunu MySQL için yapıyor gibi görünüyor


Sfenks'e kesinlikle bakacağım, sadece son zamanlarda duyduğum gibi.
Derek Downey

3

Yalnızca bir motorunuz olduğunda sunucunun tamamını (bellek yapılandırması, önbellekler, dizinler) optimize etmek X kat daha kolaydır. Myisam'ın büyük veritabanlarında innodb ile karıştırılması her zaman her iki motorun da iyi çalışması için zorlayıcı bir noktada sıkışmış olacaktır (ama mükemmel değil :)

Sfenks , lucene ( solr ) gibi bazı tam metin arama motorlarına ilgi duymanızı ve veritabanı katmanından kurtulmanızı öneririm .

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.