Voraussetzung: Percona 5.6 Version, Transaktionsisolationsebene ist RR mysql> zeigen erstellen Tabelle test_autoinc_lock\G *************************** 1. Reihe *************************** Tabelle: test_autoinc_lock Tabelle erstellen: CREATE TABLE `test_autoinc_lock` ( `id` int(11) NICHT NULL AUTO_INCREMENT, `a` int(11) DEFAULT NULL, Primärschlüssel (`id`), SCHLÜSSEL `idx_a` (`a`) ) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8 1 Zeile im Satz (0,00 Sek.) mysql> wähle * aus test_autoinc_lock; +----+------+ | Ich würde | ein | +----+------+ | 1 | 1 | | 12 | 2 | | 2 | 3 | | 3 | 5 | | 4 | 7 | | 5 | 7 | | 6 | 9 | | 7 | 10 | +----+------+ 8 Zeilen im Satz (0,00 Sek.) Bedingung 1 innodb_autoinc_lock_mode ist auf 0 gesetzt Sitzung1 begin;delete from test_autoinc_lock where a>7;//session2 wird zu diesem Zeitpunkt nicht übermittelt mysql> insert into test_autoinc_lock(a) values(100); //Gap-Sperre vorhanden, und die Sperre wartet auf Sitzung 3 mysql> insert into test_autoinc_lock(a) values(2); //Dies ist auch im Wartezustand. Theoretisch ist dies nicht der Sperrbereich der Lückensperre, also worauf wartet es? session4 mysql> wähle * aus information_schema.innodb_trx\G *************************** 1. Reihe *************************** trx_id: 2317 trx_state: SPERRE WARTEN trx_started: 31.10.2016 19:28:05 trx_requested_lock_id: 2317:20 trx_wait_started: 31.10.2016 19:28:05 trx_gewicht: 1 trx_mysql_thread_id: 9 trx_query: in test_autoinc_lock(a) Werte(2) einfügen trx_operation_state: Auto-Inc-Sperre festlegen trx_tables_in_use: 1 trx_tables_locked: 1 trx_lock_structs: 1 trx_lock_memory_bytes: 360 trx_rows_locked: 0 trx_rows_modified: 0 trx_concurrency_tickets: 0 trx_isolation_level: WIEDERHOLBARES LESEN trx_unique_checks: 1 trx_foreign_key_checks: 1 trx_last_foreign_key_error: NULL trx_adaptive_hash_latched: 0 trx_adaptive_hash_timeout: 10000 trx_ist_schreibgeschützt: 0 trx_autocommit_non_locking: 0 Überprüfen Sie zu diesem Zeitpunkt, dass Sitzung 3 auf die Auto-Inkrement-Sperre wartet und sich im Status der Einstellung der Auto-Inkrement-Sperre befunden hat. Sitzung2 FEHLER 1205 (HY000): Wartezeit für Sperre überschritten; versuchen Sie, die Transaktion neu zu starten. Zu diesem Zeitpunkt wird Sitzung 3 gesperrt und wartet auf das Timeout, um beendet zu werden. Sitzung3 Schauen Sie sich nun Sitzung 3 an und Sie können sehen, dass die Einfügung abgeschlossen ist. mysql> wähle * aus test_autoinc_lock; +----+------+ | Ich würde | ein | +----+------+ | 1 | 1 | | 12 | 2 | | 13 | 2 | | 2 | 3 | | 3 | 5 | | 4 | 7 | | 5 | 7 | | 6 | 9 | | 7 | 10 | +----+------+ 9 Zeilen im Set (0,00 Sek.) //Beachten Sie, dass der maximale Autoinkrementwert zu diesem Zeitpunkt 13 beträgt, was dem vorherigen maximalen Autoinkrementwert + 1 entspricht. Mit anderen Worten, Sitzung2 hat später die erwartete Autoinkrement-ID freigegeben und 13 Sitzung3 überlassen. Die Anwendung von Autoinkrement-ID-Werten ist vollständig seriell. Fazit: Wenn innodb_autoinc_lock_mode 0 ist, wird es offiziell als traditionell bezeichnet Ebene: Die Autoinkrementsperre befindet sich auf der Ebene der Tabellensperre und muss warten, bis das aktuelle SQL ausgeführt oder zurückgesetzt wird, bevor sie freigegeben wird. Auf diese Weise ist es denkbar, dass bei hoher Parallelität der Wettbewerb um die Autoinkrementsperre relativ groß ist. Bedingung 2: innodb_autoinc_lock_mode ist auf 1 gesetzt Sitzung1 mysql> beginnen; Abfrage OK, 0 Zeilen betroffen (0,00 Sek.) mysql> löschen aus test_autoinc_lock, wobei a>7; Abfrage OK, 2 Zeilen betroffen (0,00 Sek.) mysql> wähle * aus test_autoinc_lock; +----+------+ | Ich würde | ein | +----+------+ | 1 | 1 | | 12 | 2 | | 13 | 2 | | 2 | 3 | | 3 | 5 | | 4 | 7 | | 5 | 7 | | 6 | 9 | | 7 | 10 | +----+------+ 9 Zeilen im Satz (0,00 Sek.) //Beachten Sie, dass die maximale automatische Inkrementierung zu diesem Zeitpunkt 13 beträgt Sitzung2 mysql> insert into test_autoinc_lock(a) values(100); //Die gleiche Lückensperre existiert und die Sperre wartet auf Sitzung 3 mysql> in test_autoinc_lock(a) Werte(5) einfügen; Abfrage OK, 1 Zeile betroffen (0,00 Sek.) mysql> wähle * aus test_autoinc_lock; +----+------+ | Ich würde | ein | +----+------+ | 1 | 1 | | 12 | 2 | | 13 | 2 | | 2 | 3 | | 3 | 5 | | 15 | 5 | | 4 | 7 | | 5 | 7 | | 6 | 9 | | 7 | 10 | +----+------+ 10 Zeilen im Set (0,00 Sek.) //session3 wird direkt abgeschlossen. Beachten Sie, dass der eingefügte Auto-Increment-ID-Wert 15 ist, was bedeutet, dass die 14, die Session2 zugewiesen werden sollte, übersprungen wird. Sie können sehen, dass der Auto-Increment-ID-Wert sofort Session3 zugewiesen wird, ohne dass Sie warten müssen, bis Session2 die Ausführung abgeschlossen hat. Fazit: Wenn innodb_autoinc_lock_mode 1 ist, wird es offiziell als aufeinanderfolgend bezeichnet Auf dieser Ebene kann, wenn es sich um ein einzelnes Insert-SQL handelt, die Sperre sofort erworben und freigegeben werden, ohne auf die Ausführung des aktuellen SQL warten zu müssen (es sei denn, eine Sitzung hat die Auto-Increment-Sperre bereits in anderen Transaktionen erworben). Darüber hinaus handelt es sich auch dann noch um eine Sperre auf Tabellenebene, wenn es sich bei dem SQL um eine Art Batch-Insert-SQL handelt, wie etwa „insert into ...select ...“, „load data“, „replace ..select ...“. Dies kann so verstanden werden, dass man auf die Ausführung des aktuellen SQL warten muss, bevor man es freigeben kann. Man kann davon ausgehen, dass es sich bei einem Wert von 1 um eine relativ leichte Sperre handelt und die Replikation nicht beeinträchtigt wird. Der einzige Nachteil besteht darin, dass der generierte Autoinkrementwert möglicherweise nicht vollständig kontinuierlich ist (aber ich persönlich denke, dass dies oft nicht sehr wichtig ist und es nicht erforderlich ist, die Anzahl der Zeilen basierend auf dem Autoinkrement-ID-Wert zu zählen). Bedingung 3: innodb_autoinc_lock_mode ist auf 2 gesetzt Lassen Sie mich zunächst die Schlussfolgerung ziehen: Wenn innodb_autoinc_lock_mode auf 2 gesetzt ist, können alle SQL-Anweisungen vom Typ „Insert“ sofort Sperren erwerben und freigeben, was am effizientesten ist. Es wird jedoch ein neues Problem eingeführt: Wenn binlog_format eine Anweisung ist, kann die Sicherheit der Replikation nicht garantiert werden, da Batch-Einfügungen, wie z. B. Einfügen ..select...-Anweisungen, in diesem Fall auch sofort eine große Anzahl von automatisch inkrementierten ID-Werten erhalten können, ohne die gesamte Tabelle zu sperren. Der Slave wird beim Wiedergeben dieses SQL zwangsläufig verwirrt. Führen wir einen Test durch, um zu überprüfen, ob die Replikation nicht sicher ist. Master-Sitzung1 mysql> Variablen wie „%binlog_for%“ anzeigen; +---------------+-----------+ | Variablenname | Wert | +---------------+-----------+ | binlog_format | ANWEISUNG | +---------------+-----------+ 1 Zeile im Satz (0,00 Sek.) mysql> einfügen in test_autoinc_lock(a) select * from test_auto; Abfrage OK, 8388608 Zeilen betroffen, 1 Warnung (29,85 Sek.) Datensätze: 8388608 Duplikate: 0 Warnungen: 1 Master-Sitzung2 (beachten Sie, dass Sitzung2 ausgeführt wird, bevor Sitzung1 abgeschlossen ist) mysql> in test_autoinc_lock(a) Werte(2) einfügen; Abfrage OK, 1 Zeile betroffen (0,01 Sek.) mysql> wähle * aus test_autoinc_lock, wobei a=2; +---------+------+ | Ich würde | ein | +---------+------+ | 1376236 | 2 | +---------+------+ 1 Zeile im Satz (0,00 Sek.) Slave-Sitzung1 (zu diesem Zeitpunkt sind 1376236 Primärschlüsselkonflikte zu sehen) mysql> Slave-Status anzeigen\G *************************** 1. Reihe *************************** Slave_IO_State: Wartet darauf, dass der Master ein Ereignis sendet Master_Host: 10.9.73.139 Master_Benutzer: ucloudbackup Master_Port: 3306 Verbindungswiederholung: 60 Master_Log_File: mysql-bin.000006 Read_Master_Log_Pos: 75823243 Relay-Logdatei:mysql-relay.000002 Relay_Log_Pos: 541 Relay_Master_Log_File: mysql-bin.000006 Slave_IO_Running: Ja Slave_SQL_Running: Nein Replicate_Do_DB: Replikat_Ignorieren_DB: Tabelle_replizieren: Tabelle_Ignorieren_replizieren: Wild_Do_Tabelle replizieren: Tabelle_Wild_Ignore_replizieren: Letzte_Fehlernummer: 1062 Last_Error: Fehler „Doppelter Eintrag „1376236“ für Schlüssel „PRIMARY“ bei Abfrage. Standarddatenbank: „test“. Abfrage: „insert into test_autoinc_lock(a) select * from test_auto“ Skip_Counter: 0 Exec_Master_Log_Pos: 75822971 Wir können die Ursache des Problems leicht finden, indem wir das Binärprotokoll der Master-Datenbank analysieren. Als der erste Batch-Eintrag nicht abgeschlossen wurde, erhielt der zweite einfache Eintrag eine Sperre mit einem Auto-Increment-ID-Wert von 1376236. Beim Schreiben in die Master-Datenbank gibt es zu diesem Zeitpunkt kein Problem, aber wenn es in der Slave-Datenbank widergespiegelt wird, tritt zwangsläufig ein Primärschlüsselkonflikt auf, da es sich um eine anweisungsbasierte Replikation handelt. SETZEN SIE INSERT_ID=1376236/*!*/; #161031 21:44:31 Server-ID 168380811 End-Log-Pos 75822940 CRC32 0x65797f1c Abfrage Thread-ID = 20 Exec-Zeit = 0 Fehlercode = 0 verwende „test“/*!*/; ZEITSTEMPEL FESTLEGEN=1477921471/*!*/; in test_autoinc_lock(a) Werte einfügen(2) /*!*/; # bei 75822940 #161031 21:44:31 Server-ID 168380811 end_log_pos 75822971 CRC32 0xbb91449d Xid = 274 BEGEHEN /*!*/; # bei 75822971 #161031 21:44:26 Server-ID 168380811 End-Log-Pos 75823050 CRC32 0xa297b57b Abfrage Thread-ID = 57 Exec-Zeit = 30 Fehlercode = 0 ZEITSTEMPEL EINSTELLEN=1477921466/*!*/; BEGINNEN /*!*/; # bei 75823050 # bei 75823082 #161031 21:44:26 Server-ID 168380811 end_log_pos 75823082 CRC32 0xa5aa31a1 Intvar SETZEN SIE INSERT_ID=1/*!*/; #161031 21:44:26 Server-ID 168380811 End-Log-Pos 75823212 CRC32 0x470282ba Abfrage Thread-ID = 57 Exec-Zeit = 30 Fehlercode = 0 ZEITSTEMPEL EINSTELLEN=1477921466/*!*/; in test_autoinc_lock(a) einfügen, * aus test_auto auswählen Zusammenfassen: 1 Beim Kopieren von InnoDB-Zeilen können Sie innodb_autoinc_lock_mode auf 2 setzen, wodurch die Parallelität der Tabelle in allen Einfügesituationen maximiert wird. 2 Beim Replizieren von InnoDB-Anweisungen können Sie innodb_autoinc_lock_mode auf 1 setzen, um die Replikationssicherheit zu gewährleisten und gleichzeitig maximale Parallelität für einfache Einfügeanweisungen zu erreichen. 3 Im Fall der MyISAM-Engine ist das Festlegen des Parameters innodb_autoinc_lock_mode ungültig (Test ausgelassen), unabhängig davon, welche Art von automatisch inkrementeller ID-Sperre eine Sperre auf Tabellenebene ist. 4 Tatsächlich erwähnte der Fragesteller, dass bei Verwendung des Auto-Increment-ID-Werts als Primärschlüssel unter der InnoDB-Engine die Einfügegeschwindigkeit im Vergleich zu UUID oder einem benutzerdefinierten Primärschlüssel verbessert werden kann, da InnoDB ein Primärschlüssel-Clusterindex ist und auf den tatsächlichen Primärschlüsselwert in der Reihenfolge des Primärschlüssels zugegriffen werden muss. Dann erfolgt die Auto-Increment-ID selbst in aufsteigender Reihenfolge, sodass beim Einfügen von Daten die darunterliegende Ebene keine zusätzlichen Sortiervorgänge durchführen muss und die Anzahl der Indexseitenaufteilungen reduziert wird, wodurch die Einfügegeschwindigkeit erheblich erhöht wird (es sei denn, andere Lösungen können auch sicherstellen, dass der Primärschlüssel vollständig automatisch inkrementiert wird). Die obige kurze Diskussion über die Manifestation und die Referenzmethode zur Wertauswahl von innodb_autoinc_lock_mode ist der gesamte Inhalt, den der Editor mit Ihnen teilt. Ich hoffe, er kann Ihnen als Referenz dienen. Ich hoffe auch, dass Sie 123WORDPRESS.COM unterstützen. |
>>: Anfangseinstellungen nach der Installation von Ubuntu 16 in der Entwicklungsumgebung
Wenn es um das Verständnis von Webdesign geht, sc...
Was ist ein Baum im Webdesign? Einfach ausgedrückt...
Lassen Sie uns keine weitere Zeit verschwenden un...
html Code kopieren Der Code lautet wie folgt: <...
React-Lebenszyklus Zwei Bilder zum besseren Verst...
Aus beruflichen Gründen habe ich vor Kurzem einig...
1. Formular 1. Die Rolle des Formulars HTML-Formu...
Inhaltsverzeichnis Vorwort 1. Herkömmliche Vue-Ko...
Was ist ein MIME-TYP? 1. Zunächst müssen wir verst...
Vorwort Der Grund für das Schreiben dieses Artikel...
Passwortmodus PDO::__construct(): Der Server hat ...
Vorwort Aufgrund der Projektanforderungen werden ...
Einführung in die MySQL CURDATE-Funktion Bei Verw...
In diesem Artikelbeispiel wird der spezifische Co...
Das Schreiben von XHTML erfordert eine saubere HTM...