Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Kesalahan Kebuntuan MySQL

Setelah melakukan beberapa bacaan lagi, saya menemukan bahwa, karena InnoDB menggunakan penguncian tingkat baris, kebuntuan dapat terjadi ketika hanya memasukkan atau memperbarui satu baris karena tindakannya tidak atomik. Saya berlari:

SHOW ENGINE INNODB STATUS

untuk mencari informasi tentang kebuntuan terakhir. Saya menemukan:

------------------------
LATEST DETECTED DEADLOCK
------------------------
140106 17:22:41
*** (1) TRANSACTION:
TRANSACTION 63EB5222A, ACTIVE 0 sec starting index read
mysql tables in use 3, locked 3
LOCK WAIT 9 lock struct(s), heap size 3112, 6 row lock(s), undo log entries 2
MySQL thread id 4304350, OS thread handle 0x7fd3b74d3700, query id 173460207 192.168.0.2 sharecash Updating
UPDATE `click_rollups` SET `clicks` = `clicks` + 1, `last_updated` = '1389046961' WHERE `camp_id` = '27739' AND `country` = 'US' AND `clicks` < '1000' AND `time_created` = '1389046866'
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 186 page no 407 n bits 1272 index `country` of table `sharecash`.`click_rollups` trx id 63EB5222A lock_mode X waiting
*** (2) TRANSACTION:
TRANSACTION 63EB52225, ACTIVE 0 sec fetching rows
mysql tables in use 3, locked 3
177 lock struct(s), heap size 31160, 17786 row lock(s), undo log entries 2
MySQL thread id 4304349, OS thread handle 0x7fd6961c8700, query id 173460194 192.168.0.1 sharecash Updating
UPDATE `click_rollups` SET `clicks` = `clicks` + 1, `last_updated` = '1389046961' WHERE `camp_id` = '30949' AND `country` = 'US' AND `clicks` < '1000' AND `time_created` = '1388964767'
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 186 page no 407 n bits 1272 index `country` of table `sharecash`.`click_rollups` trx id 63EB52225 lock_mode X
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 186 page no 512 n bits 384 index `PRIMARY` of table `sharecash`.`click_rollups` trx id 63EB52225 lock_mode X locks rec but not gap waiting
*** WE ROLL BACK TRANSACTION (1)

Anda dapat melihat bahwa dua kueri yang menyebabkan kebuntuan sebenarnya sama persis. Ini menunjukkan bahwa ada juga parameter yang berbeda untuk kolom dalam klausa WHERE, sehingga baris aktual yang dikunci berbeda, yang tampaknya agak kontra-intuitif bagi saya - bagaimana mungkin operasi pada set baris yang berbeda menyebabkan kebuntuan?

Jawabannya tampaknya kebuntuan muncul dari entri penguncian mesin kueri dalam struktur pengindeksan. Jika Anda melihat output di atas, Anda dapat melihat bahwa satu transaksi memiliki kunci pada bagian tertentu dari halaman tertentu di country indeks dan membutuhkan kunci pada bagian dari indeks kunci utama, sedangkan transaksi lainnya pada dasarnya adalah kasus sebaliknya.

Invarian di bagian aplikasi kami ini bahwa hanya satu baris yang memiliki kurang dari 1000 klik, jadi saya yakin dengan memperbaiki masalah itu, masalah kebuntuan akan diminimalkan, karena secara keseluruhan penguncian yang dilakukan akan lebih sedikit. Dokumentasi MySQL menyarankan pengkodean aplikasi Anda untuk selalu menerbitkan ulang transaksi jika terjadi rollback karena kebuntuan, yang akan mencegah masalah ini karena menyebabkan kesalahan halaman. Namun, jika ada yang punya ide lain tentang cara menghindari kebuntuan ini, sekali lagi, kirimkan di komentar!

EDIT -

country indeks tidak perlu digunakan oleh transaksi, karena untuk setiap camp_id nilai hanya ada beberapa (biasanya hanya 1) nilai yang berbeda dari country , yang masing-masing hanya berkorespondensi dengan satu baris. Saya telah menambahkan petunjuk indeks ke kueri untuk menghentikannya menggunakan indeks ini, dan masalah ini sekarang telah diperbaiki tanpa ada peningkatan kinerja (mungkin sedikit keuntungan).




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Symfony2:Daftar kota menurut negara

  2. Melakukan perhitungan di MySQL vs PHP

  3. Bagaimana cara menyimpan LocalTime di hibernate

  4. $wpdb->update atau $wpdb->insert menghasilkan garis miring yang ditambahkan di depan tanda kutip

  5. Re-Slaving Server Master MySQL yang Rusak dalam Pengaturan Replikasi Semisinkron