Ich erstelle einen Trigger in MySQL und brauche ein wenig Hilfe.
Ich habe 2 Websites, 2 Datenbanken (gleicher Name) auf 2 verschiedenen Webservern, S1 & S2.
Diese Datenbanken haben dieselben Tabellennamen.
Ich möchte, dass beide Benutzerdaten auf beiden Websites gleich sind.
Wenn sich also ein Benutzer bei S1 registriert, sollten diese Benutzerregistrierungsinformationen an S2 übergeben werden.
Wenn eine Benutzerregistrierungsinformation auf S1 aktualisiert wird, sollten dieselben Informationen auf S2 aktualisiert werden.
Gleiches gilt für S2.
Wie kann ich einen Trigger erstellen, damit bei jedem Einfügen / Aktualisieren / Löschen in der Datenbank auf S1 auch die Benutzertabelle auf S2 automatisch aktualisiert wird?
Und jedes Mal, wenn in S2 ein Einfügen / Aktualisieren / Löschen in der Datenbank erfolgt, wird auch die Benutzertabelle in S1 automatisch aktualisiert.
Ist das möglich? Können Sie einige Beispiele nennen?
Antworten:
Um das zu erreichen, was Sie tun möchten, können Sie die
FEDERATED
Speicher-Engine auf beiden Servern in Verbindung mit Triggern verwenden, damit jeder Server die Datenbank des anderen Servers aktualisieren kann.Dies ist nicht gerade eine einfache Standardlösung, da hierfür zusätzliche Vorsichtsmaßnahmen erforderlich sind und Sie entscheiden müssen, ob Konsistenz oder Isolationstoleranz wichtiger sind, und die Abfragen fehlschlagen können, wenn der andere Server nicht verfügbar ist (mehr Konsistenz) ) oder verwenden Sie a
CONTINUE HANDLER
, um Fehler zu unterdrücken (Isolationstoleranz).Aber hier ist ein extrem vereinfachtes Beispiel.
Jeder Server hätte die gleiche Konfiguration.
Die lokale Benutzertabelle:
Eine lokale Tabelle, die mit der Benutzertabelle auf dem anderen Server verbunden ist.
Durch Auswahl von remote_user auf einem Server werden die Datensätze vom anderen Server abgerufen, und durch Einfügen / Aktualisieren / Löschen in dieser Tabelle werden die Daten auf dem anderen Server geändert.
Wir erstellen also Trigger, die den Zweck der Aktualisierung des Entfernungsservers erfüllen. Sie werden als
BEFORE
Auslöser geschrieben, mit der Idee, dass wir uns selbst nichts antun wollen, was wir dem anderen Server nicht antun können - zum Beispiel, wenn auf dem anderen Server bereits ein Benutzername vorhanden ist, aber nicht hier. Wir möchten, dass die Einfügung auf dem anderen Server einen Fehler auslöst, der uns daran hindert, den Benutzer hier zu erstellen ... im Gegensatz zum Erstellen eines Benutzers hier mit einem widersprüchlichen Benutzernamen. Dies ist natürlich eine der Kompromissentscheidungen, die Sie treffen müssen.Dies ist keine perfekte Lösung und keine Hochverfügbarkeitslösung, da sie auf einer soliden Konnektivität zwischen den beiden Systemen beruht. Selbst wenn Sie InnoDB und Transaktionen verwenden, sind die Aktionen, die Sie für die Zieltabelle ausführen, nicht Teil Ihrer lokalen Transaktion und kann nicht zurückgesetzt werden.
Ich benutze den
FEDERATED
Motor ziemlich oft; Es ist praktisch für eine Reihe kreativer Zwecke in meiner Umgebung, einschließlich einer Situation, in der ich eine von einem Auslöser gestartete Verbundabfrage verwendet habe, um einer fremden Datenquelle Fremdschlüsseleinschränkungen aufzuerlegen. Ich beschränke die Verwendung jedoch auf Back-End-Prozesse, bei denen unerwartete Probleme wie Zeitüberschreitungen, Codierungsfehler oder Server-zu-Server-Netzwerk- / Ausfall- / Isolationsereignisse nicht dazu führen können, dass der Endbenutzer auf einer unserer Websites Probleme hat . Ihre Fähigkeit, eine solche Situation zu tolerieren, wäre ein entscheidender Faktor dafür, ob dies eine geeignete Lösung ist.Eine Alternative wäre, Ihre beiden Server in der Master / Master-Replikation zu konfigurieren. Dazu müssten Sie auf jedem Server unterschiedliche Datenbanknamen verwenden, damit bei den meisten replizierenden Ereignissen die beiden Server möglicherweise nicht miteinander in Konflikt geraten können. Im schlimmsten Fall, wenn Sie die Konnektivität verlieren oder auf einen Replikationsfehler stoßen, werden die beiden Standorte weiterhin unabhängig voneinander ausgeführt und Sie können erneut synchronisieren und wiederherstellen. Die Konfiguration würde ungefähr so aussehen:
Dann in database_a und database_b:
MySQL behandelt database_a.user und database_b.user als Aliase für die "echte" Benutzertabelle database_c.user, sodass Sie Ihre Anwendung nur ändern müssen, wenn Sie die angegebene Datenbank verwenden (dh nicht konfigurieren müssen) um zu verstehen, dass sich die Benutzertabelle tatsächlich in einem anderen Schema befand, da die Ansicht mit dieser Konfiguration ziemlich transparent funktioniert). Wenn die Schemas Fremdschlüssel für die Benutzertabelle haben, würden Sie diese für die wahre Basistabelle database_c.user deklarieren.
Konfigurieren Sie die beiden Server zu replizieren alles, aber Satz
auto_increment_increment
und inauto_increment_offset
geeigneter Weise, so dass Sie nicht haben widerstreit Autoinkrement-Werte auf der gemeinsamen Tabelle (n), wenn Ihre Tabellen Autoinkrement verwenden. (Beachten Sie, dass in der Dokumentation angegeben ist, dass diese Variablen nur fürNDB
Tabellen gelten, dies jedoch nicht korrekt ist.)Ein zusätzlicher Vorteil dieses Setups besteht darin, dass Ihre beiden Server dann über ein vollständiges Duplikat der Daten der anderen Site verfügen, die Sie möglicherweise zu Ihrem Vorteil für die Wiederherstellung nach einem Hardwarefehler auf einem der Server verwenden könnten.
quelle
Es ist nur ein Tisch von vielen, der gleich sein sollte, nicht wahr?
Trigger funktionieren also nicht, da sie nur im selben Schema auf demselben Server ausgeführt werden können.
Vermutlich haben Sie 3 Möglichkeiten:
Manuelle Synchronisierung, z. B. durch Aufrufen eines Skripts, das alle Abfragen von Benutzerdaten auf S1 auf dem anderen Server ausführt. Ein bisschen hässlich.
Leiten Sie alle Abfragen in dieser Tabelle an einen Server weiter, z. B. S1 enthält die Benutzertabelle, und Ihre Anwendung fragt auf Server 2 nicht die lokale Benutzertabelle auf S2 ab, sondern remote auf S1. Nicht so besser.
Verwenden Sie den FEDERATED-Motor. Speichern Sie die Benutzerdaten auf S1 und erstellen Sie dieselbe Tabellenstruktur mit FEDERATED auf S2. Dies bedeutet, dass S2 nicht die physischen Benutzerdaten enthält, sondern eine Verbindung zur Tabelle auf S1. Alle an S2 durchgeführten Aktionen werden an S1 ausgeführt. Unter http://en.wikipedia.org/wiki/MySQL_Federated und http://dev.mysql.com/doc/refman/5.0/en/federated-storage-engine.html finden Sie heraus, ob dies Ihren Anforderungen entspricht.
In allen drei Szenarien ist es schwierig, eine Aussage über die Verzögerungen zwischen den Synchronisierungen zu machen. Option 3 ist die einzige, bei der Sie nur die Datenbank und nicht die Anwendung anpassen müssen, aber ich weiß wirklich nicht, ob das die große Sache ist.
quelle
Erstens eine kurze Einschränkung: Gehen Sie wahrscheinlich den Weg der anderen Antworten und verwenden Sie den Verbund für Ihr spezifisches Setup. Das heißt, es lohnt sich in Ihrem Namen darüber nachzudenken, ob die Aufteilung der Benutzerdaten in eine dritte Datenbank eine bessere Lösung wäre.
Es werden Duplikate aus den 2 Datenbanken entfernt, aber ich würde davon ausgehen, dass es auch einiges an Nacharbeit erfordern würde, damit die beiden Sites von einer zentralen Authentifizierungsdatenbank aus funktionieren
quelle
Erstellen Sie einen Verbindungsserver zwischen Ihren Servern und erstellen Sie eine gespeicherte Prozedur auf beiden Servern.
Beispiel:
Es kann Ihr Problem lösen.
quelle