Kann AUTO_INCREMENT sicher in einem BEFORE TRIGGER in MySQL verwendet werden

9

Instagrams Postgres-Methode zum Implementieren benutzerdefinierter IDs für das Sharding ist großartig, aber ich brauche die Implementierung in MySQL.

Also habe ich die Methode am Ende dieses Blogs konvertiert, hier: Ссылка

MySQL-Version:

%Vor%

Die Tabelle sieht ungefähr so ​​aus:

%Vor%

Frage:

  1. Es gibt hier ein Nebenläufigkeitsproblem. Beim Erstellen von 100 Threads und laufenden Einfügungen erhalte ich doppelte Sequenzwerte, was bedeutet, dass zwei Trigger denselben auto_increment-Wert erhalten. Wie kann ich das beheben?

Ich habe versucht, eine neue Tabelle zu erstellen, z. "tablename_seq", mit einer Zeile, einem Zähler, um meine eigenen auto_increment Werte zu speichern, dann Aktualisierungen an dieser Tabelle im TRIGGER, aber das Problem ist, dass ich die Tabelle in einer Stored Procedure (trigger) nicht LOCKEN kann, also habe ich die Genau dasselbe Problem, ich kann nicht garantieren, dass ein Zähler zwischen Triggern einzigartig ist: (.

Ich bin ratlos und würde mich über Tipps freuen!

Mögliche Lösung:

  1. MySQL 5.6 hat UUID_SHORT (), das eindeutige inkrementierende Werte generiert, die garantiert eindeutig sind. Es erscheint in der Praxis, wenn dies aufgerufen wird, dass jeder Aufruf den Wert +1 erhöht. Mit: SET seq_id = (SELECT UUID_SHORT ()); Es scheint, das Concurrency-Problem zu entfernen. Der Nebeneffekt davon ist, dass jetzt (ungefähr) nicht mehr als 1024 Einfügungen pro Millisekunde im gesamten System auftreten können. Wenn mehr tun, dann ist es möglich, einen DUPLICATE PRIMARY KEY-Fehler. Die gute Nachricht ist, dass ich in Benchmarks auf meinem Rechner ~ 3.000 Einfügungen / s mit oder ohne den Auslöser, der UUID_SHORT () enthält, bekomme, so dass es nicht so aussieht, als würde es überhaupt langsamer werden.
jsidlosky 05.09.2014, 01:49
quelle

2 Antworten

2

Die folgende SQL Fiddle generiert eine Ausgabe wie folgt:

%Vor%

Akzeptieren Sie die Antwort, wenn sie Ihre Bedürfnisse wirklich löst.

AKTUALISIEREN

%Vor%

Siehe db-fiddle .

    
wchiquito 09.09.2014, 00:45
quelle
2

Eine Alternative besteht darin, Blöcke mit Autoinkrement-Nummern zu erfassen. Wenn Sie MySQL automatisches Inkrementinkrement auf etwas wie 1000 setzen, Ein Prozess kann ein Einfügen in die Tabelle "Sequenz" ausführen und den Wert für die automatische Erhöhung abrufen. Der Prozess weiß dann, dass er über 1000 fortlaufende Nummern verfügen kann, beginnend mit dieser Nummer, die frei von Konflikten ist. Sie müssen nicht jedes Inkrement in einer zentralen Tabelle aufzeichnen, wenn Sie nur eine Nummer aufnehmen.

Dies wird am häufigsten in mehreren Master-Setups zusätzlich zum Auto-Inkrement-Offset verwendet. Sie könnten auch die Mehrfachmaster-Route verwenden und die verschiedenen Master einfügen. Die automatische Inkrementinkrementierung und -verschiebung würde keine Konflikte sicherstellen. Dies würde fundiertes Wissen über die MySQL-Replikation erfordern.

    
Brent Baisley 09.09.2014 03:00
quelle