Heim Datenbank MySQL-Tutorial Beispielanalyse zur Fehlerbehebung bei MySQL-Deadlocks

Beispielanalyse zur Fehlerbehebung bei MySQL-Deadlocks

May 29, 2023 pm 12:22 PM
mysql

Das Problem tritt auf

Eines Nachmittags alarmierte das System plötzlich und löste eine Ausnahme aus:

Bei näherer Betrachtung schien es sich um eine Transaktions-Rollback-Ausnahme zu handeln. Es stellte sich heraus, dass es sich um ein Deadlock-Problem handelte. Da ich immer noch ein gewisses Verständnis für MySQL-Sperren habe, begann ich, dieses Problem proaktiv zu untersuchen .

Suchen Sie zunächst in der Datenbank nach Innodb Status. Die letzten Deadlock-Informationen werden in Innodb Status aufgezeichnet ENGINE INNODB STATUS ANZEIGEN

Die Deadlock-Informationen lauten wie folgt und die SQL-Informationen wurden einfach verarbeitet:

​------------------------

LETZTER ERKANNTER DEADLOCK

​------------------------

22.02.2019 15:10:56 0x7eec2f468700

*** (1) TRANSAKTION:

TRANSAKTION 2660206487, AKTIV 0 Sek. Startindex-Lesevorgang

 MySQL-Tabellen verwendet 1, gesperrt 1

LOCK WAIT 2 Sperrstruktur(en), Heap-Größe 1136, 1 Zeilensperre(n)

MySQL-Thread-ID 31261312, Betriebssystem-Thread-Handle 139554322093824, Abfrage-ID 11624975750 10.23.134.92 erp_crm__6f73 Aktualisierung

/*id:3637ba36*/UPDATEmieter_config SET

​open_card_point = 0

​wobeimieter_id = 123

*** (1) WARTEN AUF DIE GEWÄHRUNG DIESER SPERRE:

RECORD LOCKS Space-ID 1322 Seitennummer 534 n Bits 960 Index uidx_tenant der Tabelle ——erp_crm_member_plan——. ——tenant_config—— trx id 2660206487 lock_mode X sperrt rec, aber kein Gap Waiting

*** (2) TRANSAKTION:

TRANSAKTION 2660206486, AKTIV 0 Sek. Startindex-Lesevorgang

 MySQL-Tabellen verwendet 1, gesperrt 1

​3 Sperrstruktur(en), Heap-Größe 1136, 2 Zeilensperre(n)

MySQL-Thread-ID 31261311, Betriebssystem-Thread-Handle 139552870532864, Abfrage-ID 11624975758 10.23.134.92 erp_crm__6f73 Aktualisierung

/*id:3637ba36*/UPDATEmieter_config SET

​open_card_point = 0

​wobeimieter_id = 123

*** (2) HÄLT DAS SCHLOSS(E):

RECORD LOCKS Space-ID 1322 Seitennummer 534 n Bits 960 Index uidx_tenant der Tabelle ——erp_crm_member_plan——. ——tenant_config—— trx id 2660206486 Sperrmodus S

*** (2) WARTEN AUF DIE GEWÄHRUNG DIESER SPERRE:

RECORD LOCKS Space-ID 1322 Seitennummer 534 n Bits 960 Index uidx_tenant der Tabelle ——erp_crm_member_plan—–. ——tenant_config—— trx id 2660206486 lock_mode X sperrt rec, aber kein Gap Waiting

*** WIR ROLLEN TRANSAKTION (1) ZURÜCK.

​----------------

Lassen Sie mich dieses Deadlock-Protokoll kurz analysieren und erklären. Wenn Transaktion 1 die Update-Anweisung ausführt, muss sie den uidx_tenant-Index abrufen und dann die X-Sperre (Zeilensperre) für die Where-Bedingung ausführen uidx_tenant. Um die X-Sperre (Zeilensperre) zu erhalten, kam es zu einem Deadlock und Transaktion 1 wurde zurückgesetzt. Ich war damals sehr verwirrt und erinnerte mich an die notwendigen Bedingungen für das Auftreten eines Deadlocks:

Sich gegenseitig ausschließend.

Bedingungen anfordern und zurückhalten.

Kein Entzug von Bedingungen.

Wartezyklus. Aus dem Protokoll ist ersichtlich, dass Transaktion 1 und Transaktion 2 beide um die Zeilensperre derselben Zeile konkurrieren. Dies unterscheidet sich ein wenig vom vorherigen zyklischen Wettbewerb um Sperren, egal wie man es betrachtet die zirkuläre Wartebedingung. Nachdem ich von Kollegen daran erinnert wurde, kann das Problem nur anhand des Geschäftscodes und der Geschäftsprotokolle untersucht werden, da das Deadlock-Protokoll nicht untersucht werden kann. Die Logik dieses Codes ist wie folgt:

public int saveTenantConfig(PoiContext poiContext, TenantConfigDOmieterConfig) {

Versuchen Sie es mit {

​returnmieterConfigMapper.saveTenantConfig(poiContext.getTenantId(), poiContext.getPoiId(),mieterConfig);

} Catch (DuplicateKeyException e) {

​LOGGER.warn("[saveTenantConfig] Primärschlüsselkonflikt, aktualisieren Sie den Datensatz. context:{}, config:{}", poiContext,mieterConfig);

​returnmieterConfigMapper.updateTenantConfig(poiContext.getTenantId(),mieterConfig);

}

}

Die Bedeutung dieses Codes besteht darin, eine Konfigurationsdatei zu speichern, die aktualisiert wird. Natürlich ist die Schreibweise hier nicht sehr standardisiert, aber sie kann tatsächlich verwendet werden in …

einfügen zur Aktualisierung des Duplikatschlüssels

Der gleiche Effekt kann erzielt werden, aber selbst wenn dies verwendet wird, kommt es tatsächlich zu einem Deadlock. Nachdem ich den Code gelesen hatte, schickte mir mein Kollege das damalige Geschäftsprotokoll,

Sie können sehen, dass drei Protokolle gleichzeitig aufgetreten sind, was darauf hinweist, dass ein eindeutiger Indexkonflikt aufgetreten ist und die aktualisierte Anweisung eingegeben wurde und dann ein Deadlock aufgetreten ist. An diesem Punkt scheint die Antwort endlich etwas klarer zu sein.

Schauen wir uns zu diesem Zeitpunkt unsere Tabellenstruktur wie folgt an (vereinfacht):

TABELLE ERSTELLEN ——tenant_config——

​——id—— bigint(21) NOT NULL AUTO_INCREMENT,

——tenant_id—— int (11) NICHT NULL,

——open_card_point—— int (11) DEFAULT NULL,

​PRIMÄRSCHLÜSSEL (——id——),

​EINZIGARTIGER SCHLÜSSEL ——uidx_tenant—— (——tenant_id——)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT

Unsere „tenant_id“ wird als eindeutiger Index verwendet, und unsere Einfüge- und Aktualisierungsbedingungen basieren alle auf dem eindeutigen Index.

AKTUALISIEREN Sie den Tenant_config SET

​open_card_point = 0

​wobeimieter_id = 123

An diesem Punkt bin ich der Meinung, dass das Sperren des eindeutigen Index beim Einfügen damit zusammenhängt. Als Nächstes werden wir im nächsten Schritt eine eingehende Analyse durchführen.

Eingehende Analyse

Oben haben wir gesagt, dass drei Transaktionen in die Aktualisierungsanweisung eingehen. Um die Erklärung zu vereinfachen, benötigen wir nur zwei Transaktionen, um die Aktualisierungsanweisung gleichzeitig einzugeben. Die folgende Tabelle zeigt unseren gesamten Ereignisprozess:

Tipp: Die S-Sperre ist eine gemeinsame Sperre und die X-Sperre eine gegenseitige Ausschlusssperre. Im Allgemeinen schließen sich X-Sperren, S-Sperren und X-Sperren gegenseitig aus, S-Sperren und S-Sperren schließen sich jedoch nicht gegenseitig aus.

Aus dem obigen Prozess sehen wir, dass der Schlüssel zu diesem Deadlock darin besteht, die S-Sperre zu erwerben. Warum müssen wir die S-Sperre beim erneuten Einfügen erwerben? Weil wir einen eindeutigen Index erkennen müssen? Wenn Sie unter der RR-Isolationsstufe lesen möchten, handelt es sich um den aktuellen Lesevorgang, sodass Sie tatsächlich eine S-Sperre hinzufügen müssen. Hier wird festgestellt, dass der eindeutige Schlüssel bereits vorhanden ist. Zu diesem Zeitpunkt wird die Ausführung der Aktualisierung durch die S-Sperren der beiden Transaktionen blockiert, wodurch die obige Schleifenwartebedingung entsteht.

Tipps: In MVCC besteht der Unterschied zwischen aktuellem Lesevorgang und Snapshot-Lesevorgang: Der aktuelle Lesevorgang muss jedes Mal gesperrt werden (Sie können eine gemeinsame Sperre oder eine Mutex-Sperre verwenden), um die neuesten Daten zu erhalten, während der Snapshot-Lesevorgang die zu diesem Zeitpunkt gestartete Transaktion liest. Der Snapshot wurde durch Undo-Log implementiert.

Dies ist der Grund für den gesamten Deadlock. Eine andere Situation, in der ein solcher Deadlock auftreten kann, besteht darin, dass drei Einfügevorgänge gleichzeitig ausgeführt werden. Wenn die zuerst eingefügte Transaktion am Ende zurückgesetzt wird, passiert dies auch bei den anderen beiden Transaktionen.

Lösung

Das Kernproblem besteht hier darin, die S-Sperre loszuwerden. Hier sind drei Lösungen als Referenz:

Reduzieren Sie die RR-Isolationsstufe auf die RC-Isolationsstufe. Hier verwendet die RC-Isolationsstufe das Snapshot-Lesen, sodass keine S-Sperre hinzugefügt wird.

Beim erneuten Einfügen verwenden Sie „select *“ für „Update“, um die X-Sperre hinzuzufügen, sodass die S-Sperre nicht hinzugefügt wird.

Sie können verteilte Sperren im Voraus hinzufügen, Sie können Redis oder ZK usw. verwenden. Informationen zu verteilten Sperren finden Sie in diesem Artikel von mir. Lassen Sie uns über verteilte Sperren sprechen

Die erste Methode ist nicht sehr realistisch, da die Isolationsstufe nicht einfach geändert werden kann. Die dritte Methode ist problematischer. Also haben wir uns letztendlich für die zweite Methode entschieden.

Das obige ist der detaillierte Inhalt vonBeispielanalyse zur Fehlerbehebung bei MySQL-Deadlocks. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Die Beziehung zwischen MySQL -Benutzer und Datenbank Die Beziehung zwischen MySQL -Benutzer und Datenbank Apr 08, 2025 pm 07:15 PM

In der MySQL -Datenbank wird die Beziehung zwischen dem Benutzer und der Datenbank durch Berechtigungen und Tabellen definiert. Der Benutzer verfügt über einen Benutzernamen und ein Passwort, um auf die Datenbank zuzugreifen. Die Berechtigungen werden über den Zuschussbefehl erteilt, während die Tabelle durch den Befehl create table erstellt wird. Um eine Beziehung zwischen einem Benutzer und einer Datenbank herzustellen, müssen Sie eine Datenbank erstellen, einen Benutzer erstellen und dann Berechtigungen erfüllen.

MySQL: Die einfache Datenverwaltung für Anfänger MySQL: Die einfache Datenverwaltung für Anfänger Apr 09, 2025 am 12:07 AM

MySQL ist für Anfänger geeignet, da es einfach zu installieren, leistungsfähig und einfach zu verwalten ist. 1. Einfache Installation und Konfiguration, geeignet für eine Vielzahl von Betriebssystemen. 2. Unterstützung grundlegender Vorgänge wie Erstellen von Datenbanken und Tabellen, Einfügen, Abfragen, Aktualisieren und Löschen von Daten. 3. Bereitstellung fortgeschrittener Funktionen wie Join Operations und Unterabfragen. 4. Die Leistung kann durch Indexierung, Abfrageoptimierung und Tabellenpartitionierung verbessert werden. 5. Backup-, Wiederherstellungs- und Sicherheitsmaßnahmen unterstützen, um die Datensicherheit und -konsistenz zu gewährleisten.

Kann ich das Datenbankkennwort in Navicat abrufen? Kann ich das Datenbankkennwort in Navicat abrufen? Apr 08, 2025 pm 09:51 PM

Navicat selbst speichert das Datenbankkennwort nicht und kann das verschlüsselte Passwort nur abrufen. Lösung: 1. Überprüfen Sie den Passwort -Manager. 2. Überprüfen Sie Navicats "Messnot Password" -Funktion; 3.. Setzen Sie das Datenbankkennwort zurück; 4. Kontaktieren Sie den Datenbankadministrator.

Die Abfrageoptimierung in MySQL ist für die Verbesserung der Datenbankleistung von wesentlicher Bedeutung, insbesondere im Umgang mit großen Datensätzen Die Abfrageoptimierung in MySQL ist für die Verbesserung der Datenbankleistung von wesentlicher Bedeutung, insbesondere im Umgang mit großen Datensätzen Apr 08, 2025 pm 07:12 PM

1. Verwenden Sie den richtigen Index, um das Abrufen von Daten zu beschleunigen, indem die Menge der skanierten Datenmenge ausgewählt wird. Wenn Sie mehrmals eine Spalte einer Tabelle nachschlagen, erstellen Sie einen Index für diese Spalte. Wenn Sie oder Ihre App Daten aus mehreren Spalten gemäß den Kriterien benötigen, erstellen Sie einen zusammengesetzten Index 2. Vermeiden Sie aus. Auswählen * Nur die erforderlichen Spalten. Wenn Sie alle unerwünschten Spalten auswählen, konsumiert dies nur mehr Serverspeicher und veranlasst den Server bei hoher Last oder Frequenzzeiten, beispielsweise die Auswahl Ihrer Tabelle, wie beispielsweise die Spalten wie innovata und updated_at und Zeitsteuer und dann zu entfernen.

So erstellen Sie Navicat Premium So erstellen Sie Navicat Premium Apr 09, 2025 am 07:09 AM

Erstellen Sie eine Datenbank mit Navicat Premium: Stellen Sie eine Verbindung zum Datenbankserver her und geben Sie die Verbindungsparameter ein. Klicken Sie mit der rechten Maustaste auf den Server und wählen Sie Datenbank erstellen. Geben Sie den Namen der neuen Datenbank und den angegebenen Zeichensatz und die angegebene Kollektion ein. Stellen Sie eine Verbindung zur neuen Datenbank her und erstellen Sie die Tabelle im Objektbrowser. Klicken Sie mit der rechten Maustaste auf die Tabelle und wählen Sie Daten einfügen, um die Daten einzufügen.

Wie man MySQL sieht Wie man MySQL sieht Apr 08, 2025 pm 07:21 PM

Zeigen Sie die MySQL -Datenbank mit dem folgenden Befehl an: Verbindung zum Server: MySQL -U -Benutzername -P -Kennwort ausführen STEILE -Datenbanken; Befehl zum Abrufen aller vorhandenen Datenbanken auswählen Datenbank: Verwenden Sie den Datenbanknamen. Tabelle Ansicht: Tabellen anzeigen; Tabellenstruktur anzeigen: Beschreiben Sie den Tabellennamen; Daten anzeigen: Wählen Sie * aus Tabellenname;

Wie kann ich das Datenbankkennwort in Navicat für Mariadb anzeigen? Wie kann ich das Datenbankkennwort in Navicat für Mariadb anzeigen? Apr 08, 2025 pm 09:18 PM

Navicat für MariADB kann das Datenbankkennwort nicht direkt anzeigen, da das Passwort in verschlüsselter Form gespeichert ist. Um die Datenbanksicherheit zu gewährleisten, gibt es drei Möglichkeiten, Ihr Passwort zurückzusetzen: Setzen Sie Ihr Passwort über Navicat zurück und legen Sie ein komplexes Kennwort fest. Zeigen Sie die Konfigurationsdatei an (nicht empfohlen, ein hohes Risiko). Verwenden Sie Systembefehlsleitungs -Tools (nicht empfohlen, Sie müssen die Befehlszeilen -Tools beherrschen).

So kopieren Sie Tabellen in MySQL So kopieren Sie Tabellen in MySQL Apr 08, 2025 pm 07:24 PM

Durch das Kopieren einer Tabelle in MySQL müssen neue Tabellen erstellt, Daten eingefügt, Fremdschlüssel festgelegt, Indizes, Auslöser, gespeicherte Verfahren und Funktionen kopiert werden. Zu den spezifischen Schritten gehören: Erstellen einer neuen Tabelle mit derselben Struktur. Fügen Sie Daten aus der ursprünglichen Tabelle in eine neue Tabelle ein. Legen Sie die gleiche fremde Schlüsselbeschränkung fest (wenn die Originaltabelle eine hat). Erstellen Sie den gleichen Index. Erstellen Sie denselben Auslöser (wenn die ursprüngliche Tabelle eine hat). Erstellen Sie dieselbe gespeicherte Prozedur oder Funktion (wenn die ursprüngliche Tabelle verwendet wird).

See all articles