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.
Ü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?
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:
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
.
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线程来解决,这是治标不治本的行为。我们应该尽量在应用端,也就是在编码的过程中避免。
有哪些可以避免死锁的方法呢?
推荐学习: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!