Die Datenbankdaten im kürzlich gestarteten Projekt nähern sich der Sättigung. Die größten Tabellendaten liegen nahe bei 3000 W, und es gibt mehrere Tabellen mit Millionen von Daten. Das Projekt verlangt, dass die Datenlesezeit 0,05 Sekunden nicht überschreiten, aber die tatsächliche Situation entspricht nicht den Anforderungen. Erklären Sie die Indexierung und Verwendung von Redis- und EHCACHE -Cache -Technologie können die Anforderungen nicht mehr erfüllen. Daher haben wir begonnen, Les- und Schreib -Trennungstechnologie zu verwenden. Wenn das Datenvolumen in Zukunft 100 Millionen oder mehr überschreitet, müssen wir die Bereitstellung verteilter Datenbanken berücksichtigen. Lesen und Schreiben Sie derzeit Trennung + Cache + Index + Tabelle Partition + SQL -Optimierung + Lastausgleich können die Abfragearbeiten von 100 Millionen Datenvolumina erfüllen. Schauen wir uns die Schritte an, um Spring zu verwenden, um Lesen- und Schreibabtrennung zu erreichen:
1. Hintergrund
Unsere allgemeine Anwendung ist es, "mehr zu lesen und weniger für Datenbanken zu schreiben", was bedeutet, dass der Druck auf die Datenbank zum Lesen von Daten relativ hoch ist. Eine Idee ist die Verwendung einer Datenbankclusterlösung.
Eine von ihnen ist die Hauptbibliothek, die für das Schreiben von Daten verantwortlich ist, die wir nennen: Bibliothek schreiben;
Die anderen stammen alle aus der Bibliothek, die für das Lesen von Daten verantwortlich ist, die wir nennen: Bibliothek lesen;
Die Anforderungen für uns sind also:
1. Die Daten der Lesebibliothek und der Schreibbibliothek sind konsistent; (Dies ist ein sehr wichtiges Problem. Die Verarbeitung der Geschäftslogik sollte in der Serviceschicht und nicht auf DAO- oder Mapper -Ebene verarbeitet werden.)
2. Wenn Sie Daten schreiben, müssen Sie sie in die Schreibbibliothek schreiben.
3. Sie müssen in die Lesebibliothek gehen, um die Daten zu lesen.
2. Plan
Es gibt zwei Lösungen zur Lösung der Trennung von Lesen und Schreiben: Anwendungsschichtlösung und Middleware-Lösung.
2.1. Anwendungsschichtlösung:
Vorteil:
1. Mehrere Datenquellen sind einfach zu wechseln und werden vom Programm automatisch abgeschlossen.
2. Es ist keine Middleware erforderlich;
3. Theoretisch unterstützen Sie jede Datenbank;
Mangel:
1. Von Programmierern abgeschlossen und Betrieb und Wartung sind nicht beteiligt;
2. dynamisch erhöhen Datenquellen können nicht erreicht werden;
2.2. Middleware -Lösung
Für und Wider:
Vorteil:
1. Das Quellprogramm kann ohne Änderungen eine Lektüre und Schreiben von Trennung erreichen.
2. Das dynamische Hinzufügen von Datenquellen erfordert kein Neustart des Programms.
Mangel:
1. Programme stützen sich auf Middleware, was es schwierig macht, Datenbanken zu wechseln.
2. Die Middleware wird als Transitagent verwendet, und die Leistung ist zurückgegangen.
3.. Verwenden Sie Spring, um basierend auf der Anwendungsschicht zu implementieren
3.1. Prinzip
Verwenden Sie vor dem Eintritt in den Dienst AOP, um ein Urteil zu fällen, ob eine Schreibbibliothek oder eine Lesebibliothek verwendet werden soll, die Beurteilungsbasis kann anhand des Methodennamens beurteilt werden, wie z. B. die mit Abfrage, Finden, Get usw. und einer anderen Schreibbibliothek.
3.2. DynamicDataSource
import org.springframework.jdbc.datasource.lookup.abstractRoutingDataSource;/*** Definieren Sie dynamische Datenquellen und implementieren Sie AbstractroutingDataSource, die von Integration Spring bereitgestellt werden. Sie müssen nur die methode für die determinische Leuchten implementieren * * Da DynamicDataSource ein Singleton- und Thread-Insecure ist, wird ThreadLocal verwendet, um die Thread-Sicherheit zu gewährleisten, die von DynamicDataSourceHolder vervollständigt wird. * * @Author Zhijun * * */public class dynamicDataSource erweitert AbstractroutingDataSource {@Override geschützte Objekt DeterminencurrentLookupkey () {// verwenden DynamicDataSourceHolder.getHolder. }} 3.3. DynamicDataSourceholder
/** * * Verwenden Sie ThreadLocal -Technologie, um den Schlüssel der Datenquelle im aktuellen Thread aufzuzeichnen // Lesen Sie die Datenquelle, die der Bibliothek private statische endgültige String Slave = "Slave" entspricht. // Verwenden Sie ThreadLocal, um die Datenquelle des aktuellen Thread -Threads -Final ThreadLocal <String> Holder = New ThreadLocal <string> () aufzuzeichnen. / ** * Setzen Sie den Datenquellenschlüssel * @param Key */ public static void putDataSourceKey (String -Schlüssel) {Holder.set (Key); } / ** * den Datenquellenschlüssel abrufen * @return * / public static String getDataSourceKey () {return Holder.get (); } / *** Markup Write Library* / public static void markmaster () {putDataSourceKey (Master); } / *** markup les bibliothek* / public static void markslave () {putDataSourceKey (Sklave); }} 3.4. DataSourcectect
import org.apache.commons.lang3.stringUtils; import org.aspespecy.lang.joinpoint;/** * Definieren Sie den AOP -Abschnitt der Datenquelle, ob es an der Zeit ist, die Bibliothek zu lesen oder die Bibliothek über den Methodennamen des Dienstes zu schreiben. void vor (JoinPoint Point) {// Erhalten Sie den aktuell ausgeführten Methodennamen String methodname = point.getSignature (). getName (); if (issLave (methodName)) {// als les als les les bibliothek dynamicDataSourceHolder.markSlave (); } else {// als Schreibbibliothek dynamicDataSourceholder.Markmaster (); }} / ** * Bestimmen Sie, ob es sich um eine gelesene Bibliothek handelt. }}3.5. Konfigurieren Sie 2 Datenquellen
3.5.1. jdbc.properties
jdbc.master.driver = com.mysql.jdbc.driverjdbc.master.url = jdbc: mysql: //127.0.0.1: 3306/mybatis_1128? useUnicode = true & ch ARACTERCODING = UTF8 & AUTORECONNECT = TRUE & ABGEHALTMULTIQUERIES = truejdbc.master.username = rootjdbc.master.password = 123456jd bc.slave01.driver = com.mysql.jdbc.driverjdbc.slave01.url = jdbc: mysql: //127.0.0.1: 3307/mybatis_1128? useUnicode = true & ch ARACTERNECODING = UTF8 & AUTORECONNECT = TRUE & ABGEHALTMULTIQUELLEs = truejdbc.slave01.username = rootjdbc.slave01.Password = 123456
3.5.2. Verknüpfungspool definieren
<!-Konfigurieren Sie den Verbindungspool-> <bean id = "MasterDataSource" Destroy-method = "close"> <!-Datenbanktreiber-> <Eigenschaft name = "driverClass" value = "$ {jdbc.master.driver}" /> <!-Der entsprechende Treiber jdbcurl-{Jdbc.m.M. /> <!-Der Benutzername der Datenbank-> <Eigenschaft name = "userername" value = "$ {jdbc.master.username}" /> <!-Das Kennwort der Datenbank-> <Eigenschaft name = "Passwort" value = "$ {jdbc.master.password}} <! Das Gerät ist ein Bruch. Der Standardwert beträgt 240. Wenn Sie abbrechen möchten, setzen Sie auf 0. Das Gerät ist ein Bruch. Der Standardwert ist 60. Wenn Sie für immer überleben möchten, setzen Sie auf 0.-> <Eigenschaft name = "idlemaxage" value = "30" /> <! Die minimale Anzahl von Verbindungen pro Partition-> <Eigenschaftsname = "MaxConnectionSperPartition" value = "150" /> <! driver--> <property name="driverClass" value="${jdbc.slave01.driver}" /> <!-- jdbcUrl for the corresponding driver --> <property name="jdbcUrl" value="${jdbc.slave01.url}" /> <!-- Database username--> <property name="username" value = "$ {jdbc.slave01.username}" /> <!-Das Kennwort der Datenbank-> <Eigenschaft name = "password" value = "$ {jdbc.slave01.Password}" /> <!-Überprüfen Sie die Intervallzeit von Leerlaufverbindungen im Datenbankverbindungs-Pool. Das Gerät ist ein Bruch. Der Standardwert beträgt 240. Wenn Sie abbrechen möchten, setzen Sie auf 0. Das Gerät ist ein Bruch. Der Standardwert ist 60. Wenn Sie für immer überleben möchten, setzen Sie auf 0.-> <Eigenschaft name = "idlemaxage" value = "30" /> <! 3.5.3. DataSource definieren
<!-Definieren Sie die Datenquelle und verwenden Sie die von Ihnen implementierte Datenquelle-> <bean id = "dataSource"> <!-Setzen Sie mehrere Datenquellen-> <Eigenschaft name = "targetDataSources"> <MAP-Schlüsseltype = "Java.lang.String"> <! Key = "Slave" Value-ref = "Slave01DataSource"/> </map> </property> <!-Setzen Sie die Standarddatenquelle, hier die Standard-Schreibbibliothek-> <Eigenschaft name = "defaultTargetDataSource" Ref = "MasterDataSource"/> </Bean>
3.6. Konfigurieren Sie die Transaktionsverwaltung und wechseln Sie die Datenquellenflächen dynamisch
3.6.1. Definieren des Transaktionsmanagers
<!-Definition Transaktionsmanager-> <bean id = "TransactionManager"> <Eigenschaft name = "dataSource" ref = "dataSource" /> < /bean>
3.6.2. Definieren Sie Transaktionsrichtlinien
<!-Transaktionspolitik definieren-> <tx: Ratschläge id = "txadvice" transaktionsmanager = "transactionManager"> <tx: Attribute> <!-Define Abfragethoden sind nur schreibgeschützt-> <tx: method name = "query*" read-on-only "true" /> <tx: method name = "les" true ". /> <!-Die Hauptbibliothek führt Operationen aus, und das Transaktionsausbreitungsverhalten ist definiert als das Standardverhalten-> <tx: method name = "speichern*" Propagation = "Erforderlich" /> <tx: method name = "update </tx: Attribute> </tx: Ratschläge>
3.6.3. Definieren Sie die Facette
<!-AOP-Abschnitt-Prozessor definieren-> <bean id = "dataSourceAwp" /> <aOP: config> <!-Definieren Sie Abschnitte, alle Methoden aller Dienste-> <aOP: pointcut id = "txpoints" Expression = "Ausführung (*xx.xxx.xxxxx.service. <AOP: Advisor Ratschläge-ref = "txadvice" pointcut-ref = "txpointcut"/> <! /> </aoP: Aspekt> </aop: config>
4. Verbessern Sie die Implementierung des Abschnitts und verwenden Sie die Übereinstimmung der Transaktionsrichtlinienregel
In der vorherigen Implementierung werden wir mit dem Method -Namen übereinstimmen, anstatt die Definition in der Transaktionsrichtlinie zu verwenden, und wir werden die Regelung in der Transaktionsverwaltungsrichtlinie verwenden.
4.1. Verbesserte Konfiguration
<!-AOP-Abschnitt-Prozessor definieren-> <bean id = "dataSourceAwp"> <!-Transaktionsrichtlinie angeben-> <Eigenschaft name = "txadvice" ref = "txadvice"/> <!
4.2. Verbesserte Implementierung
importieren java.lang.reflect.field; import java.util.arraylist; import Java.util.list; import Java.util.map; org.apache.commons.lang3.Stringutils; org.springframework.transaction.Interceptor.transactionAttribute; import org.springframework.transaction.Interceptor.transactionTributeSource; org.springframework * * Wenn eine Transaktionsrichtlinie im Transaktionsmanagement konfiguriert ist, besteht die Methode zur markierten Markierung in der konfigurierten Transaktionsrichtlinie darin, Slave zu verwenden, und der andere verwendet Master. * * Wenn es keine Richtlinie gibt, um das Transaktionsmanagement zu konfigurieren, wird das Prinzip der Methodennamen -Übereinstimmung übernommen, und Slave wird mit Abfrage, Finden und Get verwendet, und andere Methoden werden als Master verwendet. * * @Author Zhijun * * */public class dataSourceEtspekte {private list <string> slavemethodpattern = new ArrayList <string> (); private statische endgültige String [] defaultSlavemethodstart = new String [] {"Query", "find", "get"}; private String [] Slavemethodstart; / ** * Richtlinien im Transaktionsmanagement lesen * * @param txadvice * @throws Exception */ @Suppresswarnings ("Unbekämpft") public void settxadvice (TransactionInterceptor txadvice) löst eine Ausnahme aus {if (txadvice == null) {// Die Transaktionsmanagement -Richtlinie wird nicht konfiguriert; } // Richtlinienkonfigurationsinformationen von txadvice transactionAttributesource transactionAttributesource = txadvice.getTransactionTributesource () erhalten; if (! (transactionAttributesource -Instanz von namematchtransactionAttributesource)) {return; } // Verwenden Sie die Reflexionstechnologie, um den Namemap -Attributwert im NamematchtransactionAttributesource -Objekt NamematchtransactionAttributesource MatchTransactionAttributeSource = (NamematchtransactributeSource) TransactionAttributeSource zu erhalten. Field Namemapfield = Reflectionutils.findfield (NamematchtransactionAttributesource.class, "Namemap"); namemapfield.setAccessible (true); // Setzen Sie dieses Feld auf Zugriff // den Wert von Namemap <String, TransactionAttribute> map = (MAP <String, TransactionAttribute>) namemapfield.get (matchtransactionattributesource); // TransactionAttribute> Eintrag: map.entrySet ()) {if (! Eintrag.getValue (). IsReadonly ()) {// Nach dem Urteil wird die Readonly -Richtlinie definiert, bevor es Slavemethodpattern weiter hinzugefügt wird; } slavemethodpattern.add (Entry.getKey ()); }} / *** Führen Sie vor Eingabe der Service -Methode* @param Point Face -Objekt* / public void vor (JoinPoint Point) {// Erhalten Sie den aktuell ausgeführten Methodennamen String methodname = point.getSignature (). GetName () ab; boolean isslave = false; if (slavemethodpattern.iseMpty ()) {// Es gibt keine Transaktionsrichtlinie im aktuellen Feder -Container und die Methodenname Matching -Methode isslave = isslave (methodName); } else {// Richtlinienregeln verwenden, um zu übereinstimmen (String MapedName: slaveThodpattern) {if (isMatch (methodName, MapedName)) {isslave = true; brechen; }}}} if (isslave) {// als les als lesende Bibliothek dynamicDataSourceHolder.markSlave (); } else {// als Schreibbibliothek dynamicDataSourceholder.Markmaster (); }} / ** * Bestimmen Sie, ob es sich um eine Lesebibliothek handelt. } /** * Wildcard -Matching * * Gibt zurück, wenn der angegebene Methodenname mit dem zugeordneten Namen übereinstimmt. *<p>*Die Standardimplementierungsprüfungen für "xxx*", "*xxx" und "*xxx*" übereinstimmen sowie direkte*Gleichheit. Kann in Unterklassen überschrieben werden. * * @param methodName the method name of the class * @param mappedName the name in the descriptor * @return if the names match * @see org.springframework.util.PatternMatchUtils#simpleMatch(String, String) */ protected boolean isMatch(String methodName, String mappedName) { return PatternMatchUtils.simpleMatch(mappedName, methodName); } / *** Das Präfix des vom Benutzer angegebenen Slave* @param slaveThodstart* / public void setSlavemethodstart (String [] slavemethodstart) {this.slavemethodstart = slavemethodstart; } public String [] GetSlavemethodstart () {if (this.slavemethodstart == null) {// Nicht angegeben, verwenden Sie die Standard -Rückgabe -DefaultSlavemethodstart; } return slavemethodstart; }}5. Implementierung eines Meisters und mehrere Sklaven
In vielen praktischen Nutzungsszenarien verwenden wir die Architektur "One Master, Multiple Slave", daher unterstützen wir diese Architektur jetzt und müssen derzeit nur die DynamicDataSource ändern.
5.1. Durchführung
Import Java.lang.reflect.field; Import Java.util.ArrayList; Import Java.util.List; Import Java.util.map; org.springframework.jdbc.datasource.lookup.abstractroutingDataSource; org.springFramework.util.reflectionutils;/** * Definieren Sie dynamische Datenquellen und implementieren Sie die AbstroctroutingDataSource -Bereitstellung durch Integration. Singleton und Thread-Iscure, ThreadLocal wird verwendet, um die Gewinne zu gewährleisten, die von DynamicDataSourceholder abgeschlossen wird. * * @Author Zhijun * * */public class dynamicDataSource erweitert AbstractroutingDataSource {private statische endgültige Logger logger = loggerfactory.getLogger (dynamicDataSource.class); private Ganzzahl slavecount; // Umfragenzahl, zunächst -1, Atomicinger ist, fadenspeicherer privater Atomicinterer-Zähler = neuer Atomicinteger (-1); // Notieren Sie die wichtige private Liste <Object> slavedataSources = new ArrayList <Object> (0); @Override Protected Object DeterminecurrentLookupkey () {// DynamicDataSourceHolder verwenden, um die Sicherheit der Thread sicherzustellen und den Datenquellenschlüssel im aktuellen Thread zu erhalten, wenn (DynamicDataSourceHolder.ismaster ()) {Object key = dynamicDataSourceHolder.getDataSourceKey (); if (logger.isdebugenabled ()) {logger.debug ("Der Schlüssel der aktuellen DataSource ist:" + Schlüssel); } Rückgabeschlüssel; } Object key = getSlavekey (); if (logger.isdebugenabled ()) {logger.debug ("Der Schlüssel der aktuellen DataSource ist:" + Schlüssel); } Rückgabeschlüssel; } @SuppressWarnings ("Deaktiviert") @Override public void AfterPertieSt () {Super.afterPropertieStieSt (); // Da es sich bei der Eigenschaft von gelöstesDataSources der übergeordneten Klasse um eine private Unterklasse handelt, die nicht erhalten werden kann, müssen Sie Reflection verwenden, um Feld Feld zu erhalten field.setAccessible (true); // Barrierefreiheit setzen {map <objekt, dataSource> creparedDataSources = (map <objekt, dataSource>) field.get (this); // Die Datenmenge in der Lesebibliothek entspricht der Gesamtzahl der Datenquellen abzüglich der Anzahl der Schreibbibliotheken. für (map.entry <Objekt, DataSource> Eintrag: coledDataSources.EntrySet ()) {if (dynamicDataSourceHolder.master.equals (Entry.getKey ()) {Fortsetzung; } SlavedataSources.Add (Entry.getKey ()); }} catch (Ausnahme e) {logger.Error ("AfterPertieStet -Fehler!", E); }} / ** * Polling -Algorithmus -Implementierung * * @return * / public Object getSlavekey () {// Die resultierenden Indexs sind: 0, 1, 2, 3 ... Integer index = counter.incrementandget () % slavecount; if (counter // retouren} return slavedatasources.get (Index); }}6. Mysql Master-Slave-Replikation
6.1. Prinzip
Das Prinzip des Kopierens von MySQL -Meister (als Meister) Sklave (als Sklave bezeichnet):
1. Die Master-Datensätze Die Datenänderungen in das Binärprotokoll, dh die vom Konfigurationsdateiprotokoll angegebene Datei (diese Datensätze werden Binärprotokollereignisse, Binärprotokollereignisse bezeichnet)
2. Slave Copy Copy Master -Binärprotokollvents in sein Relaisprotokoll (Relaisprotokoll)
3. Die Slave -Überarbeitungsereignisse im Relay -Protokoll ändern die Daten, die sich selbst widerspiegeln (Datenreplays).
6.2. Was sollte darauf geachtet werden, wenn die Mach -Konfiguration konfiguriert wird
1. Die Versionen des primären DB -Servers und der Slave DB -Serverdatenbank sind gleich
2. Die Datenbankdaten des Master -DB -Servers und des Slave DB -Servers sind gleich [hier können Sie die Sicherung des Masters auf dem Slave wiederherstellen oder das Datenverzeichnis des Master -Datenverzeichnisses direkt in das entsprechende Datenverzeichnis des Slave kopieren]
3. Der Haupt -DB -Server ermöglicht Binärprotokolle, und der Haupt -DB -Server und der Slave -DB -Server müssen eindeutig sein.
6.3. Hauptbibliothekskonfiguration (ähnlich wie Windows, Linux)
Einige Freunde haben möglicherweise keine sehr klare IP -Adresse, Benutzername und Kontokonfiguration der Master- und Slave -Datenbank. Das Folgende ist die Master- und Slave -Konfiguration, die ich getestet habe. Die IPs sind alle 127.0.0.1. Nachdem ich mein Beispiel fertiggestellt hatte, werde ich es schreiben.
Eine Master-Slave-IP ist ein Beispiel für verschiedene Konfigurationen. Sie können dieses Beispiel verwenden, um die Konfigurationsmethode intuitiver zu verstehen.
Ändern Sie unter my.ini [MySQLD] (sowie aus der Bibliothek):
#Enable Master-Slave-Replikation, Die Konfiguration des Hauptbibliotheksprotokolls = MySQL3306-BIN#Geben Sie die Hauptbibliotheksserver-server-id = 101#Geben Sie die synchronisierte Datenbank an. Wenn nicht angegeben, sind alle Datenbanken synchronisiertes BinLog-do-db = mybatis_1128
(Die in my.ini eingegebenen Befehle müssen unten eine Reihe von Platz haben, ansonsten erkennt MySQL es nicht.)
Führen Sie die SQL -Anweisung Abfragestatus aus: Master -Status anzeigen
Der Positionswert muss aufgezeichnet werden, und der Synchronisierungsstartwert muss in der Bibliothek festgelegt werden.
Lassen Sie mich noch etwas sagen. Wenn Sie den Master -Status in MySQL ausführen und feststellen, dass der in my.ini konfigurierte Inhalt nicht funktioniert hat. Es kann sein, dass Sie die my.ini -Datei nicht ausgewählt haben oder dass Sie den Dienst nicht neu gestartet haben. Es ist sehr wahrscheinlich, dass es durch letztere verursacht wird.
Um die Konfiguration in Kraft zu setzen, müssen Sie den MySQL -Dienst ausschalten und neu starten.
So schließen Sie den Service:
Öffnen Sie den Gewinnschlüssel, geben Sie dienste.msc ein, um den Service anzurufen:
Starten Sie SQLYOG erneut und stellen Sie fest, dass die Konfiguration wirkt hat.
6.4. Erstellen Sie einen synchronen Benutzer in der Hauptbibliothek
#Authorized User SLAVE01 verwendet 123456 Passwort, um sich in MySqlgrant Replication Slave auf *. * Zu 'Slave01'@'127.0.0.1' identifiziert durch '123456'; Flush -Privilegien;
6.5. Konfiguration aus der Bibliothek
Ändern in my.ini:
#Specify ServerID, solange es nicht wiederholt wird, gibt es nur eine Konfiguration aus der Bibliothek, und die anderen werden in der SQL-Anweisung Server-ID = 102 betrieben
Im Folgenden wird SQL ausgeführt (führt mit dem Stammkonto des Slave aus):
Changematertomater_hot = '127.0.0.1', // Die IP -Adresse des Hosts material_uer = 'LAVE01', // Der Benutzer des Host ql) mater_paword = '123456', mater_port = 3306, mater_log_file = 'myql3306-Bin.000006', // filemate_log_po = 1120; // poition
#Start Slave Synchronization Start Slave; #View -Synchronisationsstatus anzeigen Slave Status;
Hier sind die Master- und Slave -Konfigurationsmethoden für zwei verschiedene IP -Computer:
Das Betriebssystem, in dem sich die Hauptdatenbank befindet: Win7
Version der primären Datenbank: 5.0
Die IP -Adresse der Hauptdatenbank: 192.168.1.111
Aus dem Betriebssystem, in dem sich die Datenbank befindet: Linux
Aus der Version der Daten: 5.0
IP -Adresse aus Datenbank: 192.168.1.112
Lassen Sie uns nach der Einführung der Umgebung über die Konfigurationsschritte sprechen:
1. Stellen Sie sicher, dass die Master -Datenbank genau der Slave -Datenbank übereinstimmt.
Zum Beispiel: Die Datenbank von A in der Hauptdatenbank verfügt über Tabellen B, C und D, sodass die Datenbank von A und Tabellen B, C und D mit einer Form graviert werden sollten.
2. Erstellen Sie ein synchrones Konto in der Hauptdatenbank.
Die Codekopie lautet wie folgt:
Replikation Sklave Grant, Datei auf *. * An 'mstest'@'192.168.1.112' identifiziert von '123456';
192.168.1.112: Es ist die IP -Adresse, die mit dem Benutzer ausgeführt wird
MSTEST: Ist der neu erstellte Benutzername
123456: Es ist das Passwort des neu erstellten Benutzernamens
Die detaillierte Erklärung des obigen Befehls finden Sie am besten auf Baidu. Wenn Sie zu viel schreiben, wird es es unklarer machen.
3. Konfigurieren Sie my.ini der Hauptdatenbank (weil sie sich unter dem Fenster befindet, ist es my.ini nicht my.cnf).
[MySQLD] Server-ID = 1Log --Bin = LogBinLog-do-db = MStest // Um die MStest-Datenbank zu synchronisieren, fügen Sie ein paar weitere Binlog-db = Datenbankname hinzu, wenn Sie mehrere Datenbanken synchronisieren möchten, um die Datenbank zu ignorieren, um die Datenbank zu ignorieren, um die Datenbank zu ignorieren
4. Konfigurieren Sie my.cnf aus der Datenbank.
[mysqld]server-id=2master-host=192.168.1.111master-user=mstest //Step 1. Create the username of the account master-password=123456 //Step 1. Create the password of the account master-port=3306master-connect-retry=60replicate-do-db=mstest //To synchronize the mstest database, to synchronize Mehrere Datenbanken fügen Sie ein paar weitere Replikat-do-db = Datenbankname Replicate-IGNORE-DB = MySQL // Die zu ignorierende Datenbank hinzu
5. Überprüfen Sie, ob es erfolgreich ist
Geben Sie MySQL ein und geben Sie den Befehl ein: Sklavenstatus/g anzeigen. Das folgende Bild wird angezeigt. Wenn sowohl slave_io_running als auch slave_sql_running Ja sind, bedeutet dies, dass die Synchronisation erfolgreich sein kann
6. Synchrone Daten testen.
Geben Sie die Hauptdatenbank ein und geben Sie den Befehl ein: In einen (Namen) Werte einfügen ('Peking');
Geben Sie dann den Befehl Eingabe aus der Datenbank ein: Wählen Sie * aus einem aus;
Wenn Daten zu diesem Zeitpunkt aus der Datenbank abgerufen werden, bedeutet dies, dass die Synchronisation erfolgreich war und der Master und der Slave implementiert werden.
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.