Saya memiliki situs web lalu lintas yang sangat tinggi di mana ada kemungkinan ribuan catatan baru dimasukkan setiap jam.
Kesalahan yang satu ini melumpuhkan situs:
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 )
Saya akan sangat terkejut jika MySQL tidak dapat menangani beban jenis ini. Jadi, pertanyaan saya kemudian, apakah ini masalah database dan bagaimana saya bisa mengkonfigurasi MySQL untuk dapat menangani lalu lintas sebanyak ini?
Saya memiliki salinan situs web saya disiapkan di server pengembangan dengan skrip yang mensimulasikan beban konten yang ditambahkan ke situs web. Saya menjalankan Ubuntu, LAMP stack, dengan 16GB RAM.
Memang, saya tidak begitu paham tentang basis data. Bahkan, saya mulai dengan my.cnf default yang datang dengannya setelah 'apt-get install' selesai. Tabel adalah semua Innodb. Apa yang memulai pengaturan dan pendekatan konfigurasi yang Anda rekomendasikan untuk mulai menyelesaikan masalah ini?
Beri tahu saya informasi apa lagi yang mungkin Anda butuhkan.
Terima kasih
Jawaban:
Anda berhadapan dengan jalan buntu, bukan masalah bottleneck kinerja.
Jika Anda memiliki seribu catatan baru per jam, Anda jauh sekali jauh dari jangkauan batas MySQL. MySQL dapat menangani setidaknya 50 kali beban Anda.
Kebuntuan disebabkan oleh kode aplikasi dan bukan kesalahan server database. Deadlock tidak dapat diperbaiki di sisi server MySQL, kecuali dalam beberapa situasi tertentu.
InnoDB
dapat menampilkan informasi kebuntuan terperinci dengan menjalankanSHOW ENGINE INNODB STATUS
di prompt MySQL, atau denganmysql -uroot -p... -e "SHOW ENGINE INNODB STATUS"
.Namun, ini hanya menunjukkan kebuntuan terakhir yang terjadi, tidak ada kebuntuan log.
Untungnya, ada alat pt-deadlock-logger yang menangani masalah itu, mengurus
InnoDB
status polling dan menyimpan semua informasi kebuntuan sebelum disegarkan dengan kebuntuan baru.sumber
Ini bisa sesederhana salah satu bagian dari kode Anda menjalankan transaksi:
sementara bagian lain dari kode Anda memodifikasi tabel yang sama dalam urutan berbeda:
Jika kedua transaksi tersebut berjalan pada saat yang sama, kondisi lomba dapat terjadi: transaksi pertama tidak dapat dimodifikasi
t2
karena dikunci oleh transaksi kedua; sedangkan transaksi kedua juga diblokir karenat1
dikunci oleh transaksi pertama. MySQL memilih satu transaksi untuk menjadi "korban" di mana INSERT / UPDATE / DELETE gagal. Aplikasi perlu menangkap kesalahan itu, dan coba lagi pernyataan - mungkin setelah jeda sehingga transaksi lain memiliki waktu untuk menyelesaikannya. Tidak ada hubungannya dengan batas kapasitas, hanya waktu yang tidak menguntungkan yang dapat diperburuk dengan cara kode diatur. Beralih di sekitar HAPUS dalam transaksi # 2, atau INSERT dalam transaksi # 1, dan kemudian tidak ada konflik - setiap transaksi akan menunggu akses ke tabel yang dibutuhkan.Di MySQL 5.6, Anda dapat menjalankan dengan opsi innodb_print_all_deadlocks diaktifkan untuk mengumpulkan info tentang semua deadlock (bukan hanya yang terbaru) di log kesalahan MySQL.
[Penafian Wajib: Saya adalah karyawan Oracle. Di atas adalah pandangan pribadi saya bukan pernyataan resmi.]
sumber