Heim  >  Artikel  >  Datenbank  >  Ausführliche Erläuterung der Verwendung von MySQL-Deadlocks sowie der Erkennungs- und Vermeidungsmethoden

Ausführliche Erläuterung der Verwendung von MySQL-Deadlocks sowie der Erkennungs- und Vermeidungsmethoden

WBOY
WBOYnach vorne
2022-09-09 13:43:562540Durchsuche

Empfohlenes Lernen: MySQL-Video-Tutorial

Bei der Verwendung von Sperren gibt es ein Problem, das beachtet und vermieden werden muss. Wir wissen, dass sich exklusive Sperren gegenseitig ausschließen. Wenn eine Transaktion oder ein Thread eine Sperre hält, verhindert dies, dass andere Threads die Sperre erhalten. Dies führt zu blockierendem Warten. Wenn Sie in einer Schleife warten, kann dies zu einem Deadlock führen.

Wir müssen dieses Problem unter mehreren Gesichtspunkten analysieren. Erstens, warum die Sperre nicht aufgehoben wird, zweitens, was zu tun ist, wenn sie blockiert ist, und drittens, wie es zu einem Deadlock kommt und wie man ihn vermeidet.

Sperrenfreigabe und -blockierung

Überprüfung: Wann wird die Sperre aufgehoben?
Transaktion endet (Commit, Rollback)﹔
Client-Verbindung getrennt.

Wenn eine Transaktion die Sperre nicht aufgehoben hat, wie lange werden andere Transaktionen dann blockiert?
Wenn ja, wenn der gleichzeitige Zugriff relativ hoch ist und eine große Anzahl von Transaktionen die erforderlichen Sperren nicht sofort erhalten kann beanspruchen viele Computerressourcen, verursachen ernsthafte Leistungsprobleme und belasten sogar die Datenbank.

Haben Sie Angst vor diesem Fehler im Internet?

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

MySQL verfügt über einen Parameter zur Steuerung der Wartezeit bis zum Erhalt der Sperre. Der Standardwert beträgt 50 Sekunden.

show VARIABLES like "innodb_lock_wait_timeout";

Bei einem Deadlock können Sie die Sperre nicht erhalten, egal wie lange Sie warten. Müssen Sie in diesem Fall 50 Sekunden warten?

Das Auftreten und Erkennen eines Deadlocks

Lassen Sie uns zwei Sitzungen demonstrieren und eröffnen:

Um den Rückzug der Zeitleiste zu erleichtern, werden hier Bilder verwendet. Wenn Sie Interesse haben, können Sie diese nachahmen.

Kastanie eins:

Kastanie zwei :

Bei der ersten Transaktion wurde ein Deadlock erkannt und sofort beendet. Die zweite Transaktion erhielt die Sperre, ohne 50 Sekunden zu warten:

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

Warum kann es direkt erkannt werden, weil ein Deadlock aufgetreten ist? . Für uns Programmierer bedeutet klare Bedingungen, dass InnoDB einen Deadlock im Allgemeinen automatisch erkennen kann (Wartediagramm).

Welche Bedingungen müssen also erfüllt sein, damit ein Deadlock auftritt, da sich die Sperre gegenseitig ausschließt:

  • (1) Nur eine Transaktion kann diese Sperre gleichzeitig halten
  • ( 2) Andere Transaktionen müssen die Sperre erhalten, nachdem diese Transaktion die Sperre aufgehoben hat, und können nicht gewaltsam entzogen werden
  • (3) Wenn mehrere Transaktionen eine Warteschleife bilden, kommt es zu einem Deadlock.

Der Friseurladen hat zwei Direktoren. Es gibt Lehrer Tony, der für das Haareschneiden zuständig ist, und Lehrer Kelvin, der für das Haarewaschen zuständig ist. Lehrer Tony kann nicht zwei Personen gleichzeitig die Haare schneiden. Dies wird als gegenseitig ausschließend bezeichnet. 互斥

Tony在给别人在剪头的时候,你不能让他停下来帮你剪头,这个叫不能强行剥夺
如果Tony的客户对Kelvin说:你不帮我洗头我怎么剪头? Kelvin 的客户对Tony说:你不帮我剪头我怎么洗头?这个就叫形成等待环路
Wenn Tony jemand anderem die Haare schneidet, können Sie ihn nicht bitten, anzuhalten und Ihnen die Haare zu schneiden. Das nennt man kann nicht mit Gewalt weggenommen werden.
Wenn Tonys Kunde zu Kelvin sagt: Wie kann ich mir die Haare schneiden, wenn du sie nicht für mich wäschst? Kelvins Kunde sagt zu Tony: Wie kann ich meine Haare waschen, wenn du sie mir nicht schneidest? >Bilden einer Warteschleife. Tatsächlich gibt es viele Situationen, in denen ein Deadlock auftritt, aber alle erfüllen die oben genannten drei Bedingungen. Dies ist auch der Grund, warum

Tabellensperren keinen Deadlock verursachen, da die Ressourcen von Tabellensperren gleichzeitig erworben werden

.

Wenn die Sperre nicht aufgehoben wurde, kann es zu starken Blockierungen oder Deadlocks kommen, wodurch der Systemdurchsatz abnimmt. Zu diesem Zeitpunkt müssen Sie überprüfen, welche Transaktionen die Sperre halten.

View -Sperrinformationen (Protokoll)

First von allen, der Befehl show status enthält einige Zeilensperrinformationen:

show status like 'innodb_row_lock_%';



lnnodb_row_lock_current_waits: Die Anzahl der Schlösser, die derzeit auf Sperren warten; bis Die gesamte Sperrzeit in ms;
Innodb_row_lock_time_avg: die durchschnittliche Wartezeit jedes Mal;
Innodb_row_lock_time_max: die längste Wartezeit vom Systemstart bis jetzt; Frequenz. Der Befehl

SHOW ist eine zusammenfassende Information. InnoDB bietet außerdem drei Tabellen zur Analyse von Transaktionen und Sperren:

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视频教程

Das obige ist der detaillierte Inhalt vonAusführliche Erläuterung der Verwendung von MySQL-Deadlocks sowie der Erkennungs- und Vermeidungsmethoden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:jb51.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen