Rumah  >  Artikel  >  pangkalan data  >  Penjelasan terperinci tentang penggunaan MySQL deadlock dan kaedah pengesanan dan pengelakan

Penjelasan terperinci tentang penggunaan MySQL deadlock dan kaedah pengesanan dan pengelakan

WBOY
WBOYke hadapan
2022-09-09 13:43:562534semak imbas

Pembelajaran yang disyorkan: tutorial video mysql

Apabila kita menggunakan kunci, terdapat masalah yang perlu diberi perhatian dan dielakkan. Kita tahu bahawa kunci eksklusif mempunyai ciri-ciri yang saling eksklusif. Apabila urus niaga atau utas memegang kunci, ia akan menghalang utas lain daripada memperoleh kunci Ini akan menyebabkan sekatan menunggu Jika anda menunggu dalam gelung, ia mungkin menyebabkan jalan buntu.

Kita perlu menganalisis masalah ini dari beberapa aspek Salah satunya ialah mengapa kunci tidak dilepaskan, yang kedua ialah apa yang perlu dilakukan jika ia disekat, dan yang ketiga ialah bagaimana kebuntuan berlaku dan bagaimana untuk mengelakkannya.

Pelepasan dan penyekatan kunci

Semakan: Bilakah kunci akan dilepaskan?
Transaksi tamat (komit, tarik balik)﹔
Sambungan pelanggan diputuskan.

Jika urus niaga tidak pernah melepaskan kunci, berapa lamakah urus niaga lain akan disekat selama-lamanya?
Jika ya, apabila akses serentak agak tinggi, jika sejumlah besar transaksi berlaku? disekat kerana Kegagalan mendapatkan kunci yang diperlukan serta-merta dan tergantung akan menduduki banyak sumber komputer, menyebabkan masalah prestasi yang serius, dan juga menyeret merentasi pangkalan data.

Adakah anda takut kesilapan ini dalam talian?

[Err] 1205 - Lock wait timeout exceeded; try restarting transaction

MySQL mempunyai parameter untuk mengawal masa menunggu untuk memperoleh kunci, lalai ialah 50 saat.

show VARIABLES like "innodb_lock_wait_timeout";

Untuk kebuntuan, tidak kira berapa lama anda menunggu, anda tidak boleh mendapatkan kunci Dalam kes ini, adakah anda juga perlu menunggu 50 saat itu tidak sia-sia?

Kejadian dan pengesanan kebuntuan

Tunjukkan dan buka dua sesi:

Untuk memudahkan penarikan garis masa, gambar digunakan di sini untuk mereka yang sedang berminat Anda boleh menirunya

Chestnut satu:

Chestnut dua:

Dalam transaksi pertama, kebuntuan dikesan dan keluar serta-merta Transaksi kedua memperoleh kunci dan tidak perlu menunggu 50 saat:

[Err] 1213 - Deadlock found when trying to get lock; try restarting transaction

Mengapa ia boleh berlaku. dilakukan secara terus Dikesan? Kerana berlakunya kebuntuan perlu memenuhi syarat-syarat tertentu Bagi kami pengaturcara, mempunyai syarat yang jelas bermakna kami boleh menentukan Oleh itu, apabila kebuntuan berlaku, InnoDB secara amnya boleh melepasi algoritma (graf tunggu) secara automatik. .

Jadi apakah syarat yang perlu dipenuhi untuk kebuntuan berlaku, kerana kunci itu sendiri adalah saling eksklusif:

  • (1) Sahaja Terdapat urus niaga yang memegang kunci ini;
  • (2) Urus niaga lain perlu melepaskan kunci sebelum transaksi ini boleh memperoleh kunci itu, dan tidak boleh melucutkannya secara paksa
  • (3) Apabila berbilang Apabila transaksi membentuk gelung menunggu, kebuntuan berlaku.

Kedai gunting rambut mempunyai dua pengarah. Ada Cikgu Tony yang bertanggungjawab menggunting rambut, dan Cikgu Kelvin yang bertanggungjawab mencuci rambut. Cikgu Tony tak boleh potong rambut dua orang serentak, ini namanya 互斥.

Apabila Tony memotong rambut orang lain, anda tidak boleh memintanya berhenti dan memotong rambut anda. Ini dipanggil 不能强行剥夺.
Jika pelanggan Tony berkata kepada Kelvin: Bagaimana saya boleh memotong rambut saya jika anda tidak mencucinya untuk saya. Pelanggan Kelvin berkata kepada Tony: Bagaimana saya boleh mencuci rambut saya jika anda tidak memotongnya untuk saya? dipanggil 形成等待环路.
Sebenarnya, terdapat banyak situasi di mana kebuntuan berlaku, tetapi semuanya memenuhi tiga syarat di atas.
Ini juga sebabnya kunci meja tidak akan menyebabkan kebuntuan, kerana sumber kunci meja diperoleh pada satu masa .

Jika kunci belum dilepaskan, ia mungkin menyebabkan banyak sekatan atau kebuntuan, mengakibatkan penurunan daya pengeluaran sistem Pada masa ini, anda perlu menyemak transaksi mana yang memegang kunci.

Lihat maklumat kunci (log)

Pertama sekali, arahan SHOw STATUS termasuk beberapa maklumat kunci baris:

show status like 'innodb_row_lock_%';

lnnodb_row_lock_current_waits: bilangan kunci yang sedang menunggu kunci;
lnnodb_row_lock_time: jumlah tempoh masa kunci dari permulaan sistem hingga sekarang, dalam ms;
Innodb_row_lock_time_avg: purata masa menunggu: setiap kali ;
Innodb_row_lock_time_max: Masa menunggu paling lama dari permulaan sistem hingga sekarang;
lnnodb_row_lock_waits: Jumlah bilangan menunggu dari permulaan sistem hingga sekarang.

Arahan SHOW ialah maklumat ringkasan. InnoDB juga menyediakan tiga jadual untuk menganalisis transaksi dan kunci:

select * from information_schema.INNODB_TRX; --当前运行的所有事务﹐还有具体的语句

select* from information_schema.INNODB_LOCKS; --当前出现的锁

select * from information_schema.INNODB_LOCK_WAITS; --锁等待的对应关系

更加详细的锁信息,开启标准监控和锁监控:

额外的监控肯定会消耗额外的性能

set GLOBAL innodb_status_output=ON;
set GLOBAL innodb_status_output_locks=ON;

通过分析锁日志,找出持有锁的事务之后呢?
如果一个事务长时间持有锁不释放,可以kill事务对应的线程ID,也就是INNODB_TRX表中的trx_mysql_thread_id,例如执行kill 4,kill 7, kill 8。
当然,死锁的问题不能每次都靠kill线程来解决,这是治标不治本的行为。我们应该尽量在应用端,也就是在编码的过程中避免。
有哪些可以避免死锁的方法呢?

死锁的避免

  • 1、在程序中,操作多张表时,尽量以相同的顺序来访问(避免形成等待环路)
  • 2、批量操作单张表数据的时候,先对数据进行排序(避免形成等待环路);
  • 3、申请足够级别的锁,如果要操作数据,就申请排它锁;
  • 4、尽量使用索引访问数据,避免没有where条件的操作,避免锁表;
  • 5、如果可以,大事务化成小事务;
  • 6、使用等值查询而不是范围查询查询数据,命中记录,避免间隙锁对并发的影响。

推荐学习:mysql视频教程

Atas ialah kandungan terperinci Penjelasan terperinci tentang penggunaan MySQL deadlock dan kaedah pengesanan dan pengelakan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:jb51.net. Jika ada pelanggaran, sila hubungi admin@php.cn Padam