Beispiel für die Erschöpfung der MySQL-Auto-Increment-ID

Beispiel für die Erschöpfung der MySQL-Auto-Increment-ID

Anzeigedefinitions-ID

Wenn die in der Tabelle definierte Auto-Increment-ID die Obergrenze erreicht, bleibt der beim Beantragen der nächsten ID erhaltene Wert unverändert

-- (2^32-1) = 4.294.967.295
-- Es wird empfohlen, BIGINT UNSIGNED zu verwenden.
TABELLE ERSTELLEN t (id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY) AUTO_INCREMENT=4294967295;
EINFÜGEN IN t-WERTE (null);

- AUTO_INCREMENT hat mysql> SHOW CREATE TABLE t nicht geändert;
+-------+------------------------------------------------------+
| Tabelle | Tabelle erstellen |
+-------+------------------------------------------------------+
| t | TABELLE ERSTELLEN `t` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 PRIMÄRSCHLÜSSEL (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4294967295 DEFAULT CHARSET=utf8 |
+-------+------------------------------------------------------+

mysql> INSERT INTO t VALUES (null);
FEHLER 1062 (23000): Doppelter Eintrag „4294967295“ für Schlüssel „PRIMARY“

InnoDB Zeilen-ID

1. Wenn die erstellte InnoDB-Tabelle keinen Primärschlüssel angibt, erstellt InnoDB eine unsichtbare Row_ID mit einer Länge von 6 Bytes.

2. InnoDB verwaltet einen globalen dict_sys.row_id-Wert für alle InnoDB-Tabellen ohne Primärschlüssel.

  • Der aktuelle dict_sys.row_id-Wert wird als row_id zum Einfügen der Daten verwendet und dann der Wert von dict_sys.row_id + 1

3. In der Code-Implementierung ist row_id ein 8-Byte BIGINT UNSIGNED

  • Bei der Entwicklung von InnoDB waren jedoch nur 6 Byte Speicherplatz für die row_id reserviert und beim Schreiben in die Datentabelle wurden nur die letzten 6 Byte gespeichert.
  • Der Wertebereich von row_id ist: 0 ~ 2^48-1
  • Nach Erreichen der Obergrenze ist der nächste Wert 0

4. Schreiben Sie in InnoDB diese Datenzeile in die Tabelle, nachdem Sie row_id = N beantragt haben

  • Wenn in der Tabelle bereits eine Zeile mit row_id=N vorhanden ist, überschreibt die neu geschriebene Zeile die ursprüngliche Zeile.

5. Es wird empfohlen, einen automatisch inkrementierenden Primärschlüssel zu erstellen

  • Wenn die Auto-Increment-ID der Tabelle die Obergrenze erreicht, wird beim Einfügen von Daten ein Primärschlüsselkonfliktfehler gemeldet, der die Verfügbarkeit beeinträchtigt.
  • Das Überschreiben von Daten bedeutet Datenverlust, der die Zuverlässigkeit beeinträchtigt.
  • Generell gilt: Zuverlässigkeit ist besser als Verfügbarkeit

XID

1. Wenn Redolog und Binlog zusammen verwendet werden, gibt es ein gemeinsames Feld XID, das einer Transaktion entspricht

2. Logik generieren

  • MySQL verwaltet intern eine globale Variable global_query_id
  • Bei jeder Ausführung einer Anweisung wird global_query_id der Query_id zugewiesen und dann global_query_id+1
  • Wenn die aktuelle Anweisung die erste von dieser Transaktion ausgeführte Anweisung ist, weisen Sie der XID dieser Transaktion die Query_id zu.

3. global_query_id ist eine reine Speichervariable und wird nach dem Neustart gelöscht

  • Daher können in derselben Datenbankinstanz die XIDs verschiedener Transaktionen identisch sein.
  • Nach dem Neustart von MySQL wird ein neues Binlog generiert
    • Garantie: XID ist in derselben Binlog-Datei eindeutig
  • Wenn global_query_id die Obergrenze erreicht, wird von 0 an weiter gezählt.
    • Theoretisch erscheint daher dieselbe XID im selben Binärprotokoll, die Wahrscheinlichkeit ist jedoch äußerst gering.

4. global_query_id ist 8 Bytes groß, mit einer Obergrenze von 2^64-1

  • Führen Sie eine Transaktion aus, vorausgesetzt, XID ist A
  • Führen Sie als Nächstes die Abfrageanweisung 2^64 Mal aus und lassen Sie global_query_id zu A zurückkehren.
  • Starten Sie eine weitere Transaktion, die XID dieser Transaktion ist ebenfalls A

InnoDB trx_id

1. XID wird von der Serverschicht verwaltet

2. InnoDB verwendet trx_id intern, um InnoDB-Transaktionen mit der Serverschicht zu verknüpfen.

3. InnoDB verwaltet intern eine globale Variable max_trx_id

  • Jedes Mal, wenn Sie eine neue trx_id beantragen müssen, erhalten Sie den aktuellen Wert von max_trx_id und dann max_trx_id+1

4. Die Kernidee der InnoDB-Datensichtbarkeit

  • Jede Datenzeile zeichnet die trx_id auf, die sie aktualisiert hat.
  • Wenn eine Transaktion eine Datenzeile liest, ist die Methode zur Bestimmung der Datensichtbarkeit
    • Vergleichen Sie die konsistente Ansicht der Transaktion mit der trx_id dieser Datenzeile

5. Für die ausgeführte Transaktion können Sie die trx_id der Transaktion über information_schema.innodb_trx sehen

Ablauf

Zeit Sitzung A Sitzung B
T1 BEGINNEN;
WÄHLEN SIE * FROM t LIMIT 1;
T2 VERWENDEN Sie Informationsschema;
Wählen Sie trx_id, trx_mysql_thread_id aus innodb_trx;
T3 EINFÜGEN IN t-WERTE (null);
T4 Wählen Sie trx_id, trx_mysql_thread_id aus innodb_trx;

-- Bei T2, mysql> SELECT trx_id,trx_mysql_thread_id FROM innodb_trx;
+-----------------+---------------------+
| trx_id | trx_mysql_thread_id |
+-----------------+---------------------+
| 281479812572992 | 30 |
+-----------------+---------------------+

-- Bei T4, mysql> SELECT trx_id,trx_mysql_thread_id FROM innodb_trx;
+-----------------+---------------------+
| trx_id | trx_mysql_thread_id |
+-----------------+---------------------+
| 7417540 | 30 |
+-----------------+---------------------+

mysql> PROZESSLISTE ANZEIGEN;
+----+-----------------+--------------+--------------------+---------+--------+------------------------+------------------+
| ID | Benutzer | Host | db | Befehl | Zeit | Status | Info |
+----+-----------------+--------------+--------------------+---------+--------+------------------------+------------------+
| 4 | event_scheduler | localhost | NULL | Daemon | 344051 | Warte auf leere Warteschlange | NULL |
| 30 | root | localhost | test | Ruhezustand | 274 | | NULL |
| 31 | root | localhost | information_schema | Abfrage | 0 | wird gestartet | PROZESSLISTE ANZEIGEN |
+----+-----------------+--------------+--------------------+---------+--------+------------------------+------------------+

1. trx_mysql_thread_id=30 ist die Thread-ID, also der Thread, in dem sich Sitzung A befindet

2. Bei T1 ist der Wert von trx_id tatsächlich 0 und der große Wert dient nur zur Anzeige (unterscheidet sich von normalen Lese- und Schreibtransaktionen).

3. Zum Zeitpunkt T2 ist trx_id eine große Zahl, da Sitzung A zum Zeitpunkt T1 keine Aktualisierungsvorgänge umfasste und eine schreibgeschützte Transaktion war.

  • Für schreibgeschützte Transaktionen vergibt InnoDB keine trx_id

4. Wenn Sitzung A zum Zeitpunkt T3 die INSERT-Anweisung ausführt, weist InnoDB tatsächlich trx_id zu

Schreibgeschützte Transaktionen

1. Zum Zeitpunkt T2 oben wird die große trx_id vorübergehend vom System berechnet

  • Konvertieren Sie die Zeigeradresse der TRX-Variable der aktuellen Transaktion in eine Ganzzahl und addieren Sie 2 ^ 48

2. Während der Ausführung derselben schreibgeschützten Transaktion ändert sich ihre Zeigeradresse nicht

  • Ob in der Tabelle innodb_trx oder innodb_locks, die für dieselbe schreibgeschützte Transaktion gefundene trx_id ist dieselbe

3. Wenn mehrere schreibgeschützte Transaktionen parallel ausgeführt werden, muss die Zeigeradresse der TRX-Variablen jeder Transaktion unterschiedlich sein

  • Verschiedene gleichzeitige schreibgeschützte Transaktionen haben unterschiedliche TRX_IDs.

4. Der Zweck der Addition von 2 ^ 48 besteht darin, sicherzustellen, dass der von schreibgeschützten Transaktionen angezeigte trx_id-Wert relativ groß ist, was zur Unterscheidung gewöhnlicher Lese-/Schreibtransaktionen dient.

5. Die Logik von trx_id ähnelt der von row_id und die Länge ist als 8 Bytes definiert

  • Theoretisch ist es möglich, dass eine Lese-/Schreibtransaktion dieselbe trx_id anzeigt wie eine schreibgeschützte Transaktion.
  • Aber die Wahrscheinlichkeit ist extrem gering und es gibt keinen wirklichen Schaden

6. Vorteile, wenn trx_id nicht schreibgeschützten Transaktionen zugewiesen wird

  • Sie können die Größe des aktiven Arrays in der Transaktionsansicht reduzieren
    • Die aktuell laufende schreibgeschützte Transaktion hat keinen Einfluss auf die Sichtbarkeit der Daten.
    • Daher müssen Sie beim Erstellen einer konsistenten Ansicht einer Transaktion nur die trx_id der Lese- und Schreibtransaktion kopieren.
  • Kann die Anzahl der trx_id-Anwendungen reduzieren
    • Selbst wenn Sie in InnoDB nur eine gewöhnliche SELECT-Anweisung ausführen, entspricht dies während des Ausführungsprozesses einer schreibgeschützten Transaktion.
    • Wenn normale Abfrageanweisungen nicht für trx_id gelten, können Sperrkonflikte, die durch gleichzeitige Transaktionen verursacht werden, die für trx_id gelten, erheblich reduziert werden.
    • Da schreibgeschützte Transaktionen keine trx_id zuweisen, ist die Erhöhungsrate von trx_id langsamer

7. max_trx_id wird dauerhaft gespeichert und nach einem Neustart nicht auf 0 zurückgesetzt. Erst wenn die Obergrenze von 2^48-1 erreicht ist, wird es auf 0 zurückgesetzt.

Thread-ID

1. Die erste Spalte von SHOW PROCESSLIST ist thread_id

2. Das System speichert eine Umgebungsvariable thread_id_counter

  • Jedes Mal, wenn eine neue Verbindung erstellt wird, wird thread_id_counter der Thread-Variable der neuen Verbindung zugewiesen.

3. thread_id_counter ist als 4 Bytes definiert und wird daher nach Erreichen von 2^32-1 auf 0 zurückgesetzt.

  • Aber Sie werden nicht zwei identische Thread-IDs in SHOW PROCESSLIST sehen
  • Da MySQL eine einzigartige Array-Logik entwickelt hat, um neuen Threads thread_id zuzuweisen, lautet der Logikcode wie folgt
Tun {
  neue_ID= Thread-ID-Zähler++;
} während (!thread_ids.insert_unique(neue_id).Sekunde);

Verweise

„MySQL Praxis 45 Vorlesungen“

Zusammenfassen

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Lernwert für Ihr Studium oder Ihre Arbeit hat. Vielen Dank für Ihre Unterstützung von 123WORDPRESS.COM.

Das könnte Sie auch interessieren:
  • So ändern Sie den Startwert der MySQL-Auto-Increment-ID
  • So setzen Sie die MySQL-Auto-Increment-ID auf 0 zurück
  • Lösung für das Problem der Selbstinkrement-ID in der MySQL-Tabelle
  • Fehlerbehebung und Lösungen für das Problem der MySQL-Autoinkrement-ID-Übergröße
  • Was Sie über die automatische ID-Inkrementierung in MySQL wissen müssen
  • Lösung für das Ausgehen der Auto-Increment-ID (Primärschlüssel) von MySQL
  • Zusammenfassung einiger kleinerer Probleme mit der MySQL-Autoinkrement-ID
  • Was tun, wenn die selbstinkrementierende MySQL-ID ausgeht?

<<:  JavaScript zum Erzielen eines dynamischen Tabelleneffekts

>>:  JavaScript implementiert die Maussteuerung eines frei beweglichen Fensters

Artikel empfehlen

So implementieren Sie Leerzeichen in Taobao mit CSS3

Machen Sie einen leeren Bereich für Taobao: Wenn ...

Detaillierte Erklärung der Abkürzung von State in React

Vorwort Was ist Staat Wir alle sagen, dass React ...

CSS zum Implementieren von QQ-Browserfunktionen

Code Wissenspunkte 1. Kombinieren Sie fullpage.js...

Details der MySQL-Berechnungsfunktion

Inhaltsverzeichnis 2. Feldverkettung 2. Geben Sie...

Implementierung der Nginx-Arbeitsprozessschleife

Nach dem Start initialisiert der Worker-Prozess z...

Gruselige Halloween-Linux-Befehle

Auch wenn nicht Halloween ist, lohnt es sich, sic...

Verstehen Sie alle Aspekte von HTTP-Headern mit Bildern und Text

Was sind HTTP-Header HTTP ist eine Abkürzung für ...

WHMCS V7.4.2 Grafisches Installationstutorial

1. Einleitung WHMCS bietet eine Komplettlösung fü...

Implementierung von Nginx Hot Deployment

Inhaltsverzeichnis Semaphor Nginx-Hot-Bereitstell...