MySQL Innodb'u saatte 1000 eki işleyecek şekilde nasıl yapılandırabilirim?


10

Çok yüksek bir trafik web sitem var, burada her saatte 1000 yeni kayıt ekleniyor.

Bu bir hata siteyi engelliyor:

PDOException: SQLSTATE[40001]: Serialization failure: 1213 
Deadlock found when trying to get lock; 
try restarting transaction: INSERT INTO {location_instance} 
(nid, vid, uid, genid, lid) VALUES (:db_insert_placeholder_0, 
:db_insert_placeholder_1, :db_insert_placeholder_2, 
:db_insert_placeholder_3, :db_insert_placeholder_4); 
Array ( [:db_insert_placeholder_0] => 1059 [:db_insert_placeholder_1] => 
1059 [:db_insert_placeholder_2] => 0 [:db_insert_placeholder_3] => 
cck:field_item_location:1059 [:db_insert_placeholder_4] => 1000 )

MySQL bu tür yükleri kaldıramazsa çok şaşırırdım. Yani, benim sorularım, bu bir veritabanı sorunu ve MySQL bu kadar trafik işlemek için nasıl yapılandırabilirim?

Web sitemin, web sitesine eklenen içeriğin yükünü taklit eden komut dosyaları içeren bir geliştirme sunucusunda bir kopyası var. 16 GB RAM ile Ubuntu, LAMP yığını çalıştırıyorum.

Kuşkusuz, veritabanları hakkında çok bilgili değilim. Aslında, 'apt-get install' bittikten sonra onunla birlikte gelen varsayılan my.cnf ile başlıyorum. Tabloların hepsi Innodb. Bu sorunu çözmeye başlamak için hangi başlangıç ​​yapılandırma ayarlarını ve yaklaşımını önerirsiniz?

Daha fazla bilgiye ihtiyacınız olabileceğini bana bildirin.

Teşekkürler


Üretim için varsayılan my.cnf ile mi başlıyorsunuz? Dostum, daha fazla optimize etmelisin. Cevabımda daha fazla ayrıntı vereceğim. :-)

Yanıtlar:


11

Bir performans darboğazıyla değil, bir kilitlenme ile uğraşıyorsunuz.

Saatte bin yeni kaydınız varsa, MySQL sınırlarına ulaşmaktan çok uzaktasınız. MySQL yükünüzün en az 50 katını kaldırabilir.

Kilitlenmeler uygulama kodundan kaynaklanır ve veritabanı sunucusunun hatası değildir. Bazı özel durumlar dışında, kilitlenmeler MySQL sunucu tarafında düzeltilemez.

InnoDBSHOW ENGINE INNODB STATUSMySQL komut isteminde çalışarak veya ile ayrıntılı kilitlenme bilgilerini gösterebilir mysql -uroot -p... -e "SHOW ENGINE INNODB STATUS".

Ancak, bu yalnızca gerçekleşen son kilitlenmeyi gösterir, kilitlenme günlüğü yoktur.

Neyse ki, bu sorunla ilgilenen bir pt-deadlock-logger aracı var , yoklama InnoDBdurumunu halleder ve yeni bir kilitlenme ile yenilenmeden önce tüm ayrıntılı kilitlenme bilgilerini kaydeder.


Bunu bildiğim iyi oldu! Show status komutunda kilit ve ilgili sorgu ve tablo ile ilgili bilgileri görüyorum. Bunun kodumda olduğu göz önüne alındığında, bu durumu hata ayıklamaya başlamak için status komutundaki bu bilgileri nasıl kullanabilirim? PHP PDO sorgusu oldukça basittir - bağlayın, hazırlayın, yürütün, tekrarlayın. Yardımcı olursa, herhangi bir kod veya durum mesajı göndermekten memnuniyet duyarım.
user658182

@ user658182 kilitlenme ile nasıl başa çıkılacağı konusunda stackoverflow bu yazıyı kontrol edin: kilit almaya çalışırken bulundu mysql kilitlenme önlemek için nasıl
Valor

1
@ max-vernon sözdizimi düzenleme için teşekkürler, açıkça ingilizce benim ana dilim değil :-).
Valor

1
-e "MOTOR INNODB DURUMUNU GÖSTER"
glif

8

Bu, kodunuzun bir işlemi çalıştıran bir bölümü kadar basit olabilir:

insert into t1...
insert into t2...
commit;

kodunuzun başka bir kısmı aynı tabloları farklı bir sırada değiştirir:

delete from t2 where...
delete from t1 where...
commit;

Bu işlemlerin her ikisi de aynı anda çalışıyorsa, bir yarış durumu oluşabilir: ilk işlem t2, ikinci işlem tarafından kilitlendiği için değiştirilemez ; ikinci işlem de benzer şekilde engellenir çünkü t1ilk işlem tarafından kilitlenir. MySQL, bir işlemi INSERT / UPDATE / DELETE işleminin başarısız olduğu "kurban" olarak seçer. Uygulamanın bu hatayı yakalaması ve ifadeyi yeniden denemesi gerekir - belki bir duraklamadan sonra diğer işlemin bitmesi için zaman vardır. Kapasite sınırları ile ilgisi yoktur, sadece kodun düzenlenme şekli ile daha da şiddetlendirilebilecek talihsiz zamanlama. İşlem # 2'deki DELETE'ler veya işlem # 1'deki INSERT'ler arasında geçiş yapın ve ardından çakışma olmaz - her işlem ihtiyaç duyduğu tablolara erişmek için bekler.

MySQL 5.6 sürümünde , MySQL hata günlüğünde tüm kilitlenmeler hakkında bilgi toplamak için etkin olan innodb_print_all_deadlocks seçeneğiyle çalışabilirsiniz .

[Zorunlu Uyarı: Ben bir Oracle çalışanıyım. Yukarıdaki resmi görüşüm değil kişisel görüşü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.