Wie ist das passiert?
Als klassische Datenbank- und Table-Sharding-Middleware gilt MyCat seit langem allgemein als effektive Lösung für die Verwaltung sehr großer MySQL-Datenbanksammlungen. Vor kurzem haben wir die Nachfrage von Kunden erhalten, den MyCat-Cluster auf GreatSQL zu migrieren und Daten innerhalb eines bestimmten Zeitraums in Echtzeit von MyCat mit GreatSQL zu synchronisieren. Die vollständige Datensynchronisierung ist relativ einfach zu bedienen, aber die inkrementelle Synchronisierung weist die folgenden zwei heiklen Probleme auf:
- Mehrere Server mit unterschiedlichen Bibliotheksnamen müssen mit einer GreatSQL-Bibliothek synchronisiert werden. Das heißt, die Synchronisierungsbeziehung ist wie folgt
server1:db1.tab->gdb:db.tab;
server2:db2.tab->gdb:db.tab;
server3:db3.tab->gdb:db.tab;
- Bei mehreren Ausführungen der DDL-Synchronisierung kommt es zu Konflikten. Wenn der MyCat-Tabelle ein Index und ein Feld hinzugefügt werden, führen alle Back-End-Datenbanken diese DDL tatsächlich aus. Wenn die DDL bei der Synchronisierung mit GreatSQL mehrmals ausgeführt wird, wird die Replikation abnormal unterbrochen.
Um die beiden oben genannten Probleme zu lösen, habe ich nach der Durchsuchung der Informationen festgestellt, dass es zwei Funktionen gibt, die nicht häufig verwendet werden und von den Behörden nicht empfohlen werden, sondern nur den Anforderungen gerecht werden können.
- Um das Problem der Bibliotheksnamenzuordnung zu lösen, müssen der Konfigurationsdatei Parameter hinzugefügt werden
replicate_rewrite_db="channel_1:test_rep1->test_rep"
replicate_rewrite_db="channel_2:test_rep2->test_rep"
replicate_rewrite_db="channel_3:test_rep3->test_rep"
- Um das Problem der Replikationsunterbrechung zu lösen, die durch wiederholte Ausführung nach der DDL-Synchronisierung verursacht wird, fügen Sie Folgendes hinzu:
slave-skip-errors=ddl_exist_errors
Überprüfen Sie es
Um das Problem zu vereinfachen, werden wir den MyCat-Cluster nicht erstellen und ihn zu einem synchronen Replikationsproblem mit mehreren Quellen vereinfachen.
1. Initialisieren Sie 4 Instanzen. Die Synchronisationsbeziehung ist wie folgt
Quellport | SourceDB_NAME | Zielport | Zielzuordnungs-DB | Kanal Name |
---|---|---|---|---|
3306 | test_rep1 | 3309 | test_rep | Kanal_3306 |
3307 | test_rep2 | 3309 | test_rep | Kanal_3307 |
3308 | test_rep3 | 3309 | test_rep | Kanal_3308 |
2. Fügen Sie in der Instanzkonfigurationsdatei von 3309 die Konfiguration der Bibliothekszuordnungsbeziehung und die Parameter zum Ignorieren von DDL-Konflikten hinzu.
replicate_rewrite_db="channel_3306:test_rep1->test_rep"
replicate_rewrite_db="channel_3307:test_rep2->test_rep"
replicate_rewrite_db="channel_3308:test_rep3->test_rep"
slave-skip-errors=ddl_exist_errors
4. Konfigurieren Sie in der 3309-Instanz drei Kanäle
greatsql> change master to MASTER_HOST = '172.17.137.91',MASTER_USER = 'greatsql',MASTER_PASSWORD = 'greatsql',MASTER_PORT = 3306,MASTER_AUTO_POSITION = 1 FOR CHANNEL 'channel_3306';
greatsql> change master to MASTER_HOST = '172.17.137.91',MASTER_USER = 'greatsql',MASTER_PASSWORD = 'greatsql',MASTER_PORT = 3307,MASTER_AUTO_POSITION = 1 FOR CHANNEL 'channel_3307';
greatsql> change master to MASTER_HOST = '172.17.137.91',MASTER_USER = 'greatsql',MASTER_PASSWORD = 'greatsql',MASTER_PORT = 3308,MASTER_AUTO_POSITION = 1 FOR CHANNEL 'channel_3308';
greatsql> start slave;
3. Überprüfen Sie den Status der Kanalkonfiguration
greatsql> show slave status \G
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: 172.17.137.91
Master_User: greatsql
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000002
Read_Master_Log_Pos: 1119
Relay_Log_File: relaylog-channel_3306.000007
Relay_Log_Pos: 397
Relay_Master_Log_File: binlog.000002
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 1119
Relay_Log_Space: 606
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 3306
Master_UUID: 5facacd7-9ed6-11ee-b76b-00163e5af5d6
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set: 49b66af0-9ed6-11ee-ae4f-00163e5af5d6:3,
5a369d0b-9ed6-11ee-b3d1-00163e5af5d6:3,
5facacd7-9ed6-11ee-b76b-00163e5af5d6:1-4,
9a5f9c26-4262-11ee-85fd-00163e5af5d6:1-16571224
Auto_Position: 1
Replicate_Rewrite_DB: (test_rep1,test_rep)
Channel_Name: channel_3306
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
*************************** 2. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: 172.17.137.91
Master_User: greatsql
Master_Port: 3307
Connect_Retry: 60
Master_Log_File: binlog.000002
Read_Master_Log_Pos: 1119
Relay_Log_File: relaylog-channel_3307.000004
Relay_Log_Pos: 1034
Relay_Master_Log_File: binlog.000002
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 1119
Relay_Log_Space: 1243
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 3307
Master_UUID: 5a369d0b-9ed6-11ee-b3d1-00163e5af5d6
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: 5a369d0b-9ed6-11ee-b3d1-00163e5af5d6:1-2:4
Executed_Gtid_Set: 49b66af0-9ed6-11ee-ae4f-00163e5af5d6:3,
5a369d0b-9ed6-11ee-b3d1-00163e5af5d6:3,
5facacd7-9ed6-11ee-b76b-00163e5af5d6:1-4,
9a5f9c26-4262-11ee-85fd-00163e5af5d6:1-16571224
Auto_Position: 1
Replicate_Rewrite_DB: (test_rep2,test_rep)
Channel_Name: channel_3307
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
*************************** 3. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: 172.17.137.91
Master_User: greatsql
Master_Port: 3308
Connect_Retry: 60
Master_Log_File: binlog.000002
Read_Master_Log_Pos: 1119
Relay_Log_File: relaylog-channel_3308.000004
Relay_Log_Pos: 1034
Relay_Master_Log_File: binlog.000002
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 1119
Relay_Log_Space: 1243
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 3308
Master_UUID: 49b66af0-9ed6-11ee-ae4f-00163e5af5d6
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: 49b66af0-9ed6-11ee-ae4f-00163e5af5d6:1-2:4
Executed_Gtid_Set: 49b66af0-9ed6-11ee-ae4f-00163e5af5d6:3,
5a369d0b-9ed6-11ee-b3d1-00163e5af5d6:3,
5facacd7-9ed6-11ee-b76b-00163e5af5d6:1-4,
9a5f9c26-4262-11ee-85fd-00163e5af5d6:1-16571224
Auto_Position: 1
Replicate_Rewrite_DB: (test_rep3,test_rep)
Channel_Name: channel_3308
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
3 rows in set, 1 warning (0.00 sec)
In der obigen Ausgabe können Sie sich auf die folgenden Feldinformationen konzentrieren, die darauf hinweisen, dass die Datenbankkonvertierungszuordnung erfolgreich war
$ MYSQL_PWD=greatsql mysql -ugreatsql -h127.0.0.1 -P3309 -e 'show replica status \G'| grep -wE 'Replica_IO_Running|Replica_SQL_Running|Replicate_Rewrite_DB|Channel_Name'
Replica_IO_Running: Yes
Replica_SQL_Running: Yes
Replicate_Rewrite_DB: (test_rep1,test_rep)
Channel_Name: channel_3306
Replica_IO_Running: Yes
Replica_SQL_Running: Yes
Replicate_Rewrite_DB: (test_rep2,test_rep)
Channel_Name: channel_3307
Replica_IO_Running: Yes
Replica_SQL_Running: Yes
Replicate_Rewrite_DB: (test_rep3,test_rep)
Channel_Name: channel_3308
Fragen Sie in der 3309-Instanz „replica_skip_errors“ ab, um den von der Replikationsausnahme übersprungenen Fehlercode zu bestätigen. Wenn Sie ihn auf „ddl_exist_errors“ setzen, wird er automatisch in den folgenden Fehlercode konvertiert.
greatsql> select @@replica_skip_errors;
+---------------------------------------------------+
| @@replica_skip_errors |
+---------------------------------------------------+
| 1007,1008,1050,1051,1054,1060,1061,1068,1091,1146 |
+---------------------------------------------------+
1 row in set (0.00 sec)
5. Überprüfung der Datensynchronisierung
- Erstellen Sie in der 3309-Bibliothek die Datenbank test_rep
Diese Bibliothek muss manuell erstellt werden. Tests haben ergeben, dass die Zuordnungsbeziehung nur für die Tabellen unter der Bibliothek wirksam wird und die Bibliothek nicht automatisch konvertiert und erstellt wird.
- Erstellen Sie in der 3306-Bibliothek die Datenbank test_rep1 und die Tabelle tab1
$ mysql -ugreatsql -h127.0.0.1 -p -P3306 -s
greatsql> create database test_rep1;
greatsql> use test_rep1;
greatsql> create table tab1(id int primary key auto_increment, cname varchar(10), age int);
- Erstellen Sie in der 3307-Bibliothek die Datenbank test_rep2 und die Tabelle tab1
$ mysql -ugreatsql -h127.0.0.1 -p -P3307 -s
greatsql> create database test_rep2;
greatsql> use test_rep2;
greatsql> create table tab1(id int primary key auto_increment, cname varchar(10), age int);
- Erstellen Sie in der 3308-Bibliothek die Datenbank test_rep3 und die Tabelle tab1
$ mysql -ugreatsql -h127.0.0.1 -p -P3308 -s
greatsql> create database test_rep3;
greatsql> use test_rep3;
greatsql> create table tab1(id int primary key auto_increment, cname varchar(10), age int);
- Bestätigen Sie die Synchronisierung von Datenbank und Tabellen in 3309
$ mysql -ugreatsql -h127.0.0.1 -p -P3309 -s
greatsql> show databases;
Database
information_schema
mysql
performance_schema
sys
test_db
test_rep
test_rep1
test_rep2
test_rep3
greatsql> show tables from test_rep;
Tables_in_test_rep
tab1
greatsql> show tables from test_rep1;
greatsql> show tables from test_rep2;
greatsql> show tables from test_rep3;
Wie aus den obigen Informationen ersichtlich ist, werden in 3309 die in 3306, 3307 und 3308 erstellten Bibliotheken alle gemäß ihren ursprünglichen Namen synchronisiert, die Tabelle wird jedoch nur in der von 3309 zugeordneten Bibliothek test_rep synchronisiert.
- Fügen Sie jeweils einen Datensatz in 3306, 3307 und 3308 ein
3306 : insert into test_rep1.tab1 values(1,'a',10);
3307 : insert into test_rep2.tab1 values(2,'b',20);
3308 : insert into test_rep3.tab1 values(3,'c',30);
Fragen Sie dann den Dateneinfügungsstatus an jedem Knoten ab
$ mysql -ugreatsql -h127.0.0.1 -p -P3306 -s test_rep1 -e 'select * from tab1'
id cname age
1 a 10
$ mysql -ugreatsql -h127.0.0.1 -p -P3307 -s test_rep2 -e 'select * from tab1'
id cname age
2 b 20
$ mysql -ugreatsql -h127.0.0.1 -p -P3308 -s test_rep3 -e 'select * from tab1'
id cname age
3 c 30
$ mysql -ugreatsql -h127.0.0.1 -p -P3309 -s test_rep -e 'select * from tab1'
id cname age
1 a 10
2 b 20
3 c 30
$ mysql -ugreatsql -h127.0.0.1 -p -P3309 -s test_rep1 -e 'select * from tab1'
ERROR 1146 (42S02) at line 1: Table 'test_rep1.tab1' doesn't exist
$ mysql -ugreatsql -h127.0.0.1 -p -P3309 -s test_rep2 -e 'select * from tab1'
ERROR 1146 (42S02) at line 1: Table 'test_rep2.tab1' doesn't exist
$ mysql -ugreatsql -h127.0.0.1 -p -P3309 -s test_rep3 -e 'select * from tab1'
ERROR 1146 (42S02) at line 1: Table 'test_rep3.tab1' doesn't exist
Wie aus der obigen Abfrage ersichtlich ist, gibt es nur einen Datensatz in den Knoten 3306, 3307 und 3308, und die Datensätze werden mit der Tabelle test_rep.tab1 von 3309 synchronisiert, und es gibt keine Tabellen in test_rep1, test_rep2 und test_rep3 von 3309.
- Erstellen Sie einen Index für die Tabellenregisterkarte bei 3306, 3307 bzw. 3308.
greatsql> alter table tab1 add index idx_cname(cname);
- Wenn Sie den Indexstatus der Tabelle in 3309 beobachten, können Sie sehen, dass der Index idx_cname synchronisiert wurde.
$ mysql -ugreatsql -h127.0.0.1 -p -P3309 -s
greatsql> use test_rep
greatsql> show create table tab1 \G
*************************** 1. row ***************************
Table: tab1
Create Table: CREATE TABLE `tab1` (
`id` int NOT NULL AUTO_INCREMENT,
`cname` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`age` int DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_cname` (`cname`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
1 row in set (0.00 sec)
- Führen Sie Aktualisierungs- und Löschvorgänge bei 3306, 3307 bzw. 3308 durch.
greatsql> update test_rep1.tab1 set age=110 where id=1;
greatsql> update test_rep2.tab1 set age=120 where id=2;
greatsql> update test_rep3.tab1 set age=130 where id=3;
greatsql> delete from test_rep1.tab1 where id=1;
greatsql> delete from test_rep2.tab1 where id=1;
greatsql> delete from test_rep3.tab1 where id=1;
Überprüfen Sie den Datensynchronisierungsstatus von 3309 und bestätigen Sie, dass die Daten bereinigt wurden.
$ mysql -ugreatsql -h127.0.0.1 -p -P3309 -s
Welcome to the MySQL monitor. Commands end with ; or \g.
greatsql> select * from test_rep.tab1;
- Wenn Sie die Synchronisierung der drei Kanäle beobachten, können Sie bestätigen, dass die drei Replikationssynchronisierungen normal sind.
$ mysql -ugreatsql -h127.0.0.1 -p -P3309 -e 'show replica status \G'| grep -E 'Replica_IO_Running|Replica_SQL_Running|Channel_Name'
greatsql: [Warning] Using a password on the command line interface can be insecure.
Replica_IO_Running: Yes
Replica_SQL_Running: Yes
Replica_SQL_Running_State: Replica has read all relay log; waiting for more updates
Channel_Name: channel_3306
Replica_IO_Running: Yes
Replica_SQL_Running: Yes
Replica_SQL_Running_State: Replica has read all relay log; waiting for more updates
Channel_Name: channel_3307
Replica_IO_Running: Yes
Replica_SQL_Running: Yes
Replica_SQL_Running_State: Replica has read all relay log; waiting for more updates
Channel_Name: channel_3308
Bisher wurde die DML- und DDL-Synchronisierung überprüft.
Planfehler
- Bei dieser Lösung ist der Tabellenname, den das Unternehmen für den Zugriff auf MyCat verwendet, genau derselbe wie der Tabellenname im Server-Backend, mit der Ausnahme, dass der Bibliotheksname unterschiedlich ist. Dann können der Name der MyCat-Proxytabelle und der tatsächliche Name der Servertabelle unterschiedlich sein . In diesem Fall kann die Mapping-Verarbeitung vorübergehend nicht durchgeführt werden.
- MyCat stellt tatsächlich mehrere separate Bibliotheken dar. Wenn diese Bibliotheken zuvor nicht die automatische Inkrementierung von Primärschlüsselschritten oder eine andere Strategie zur Nichtduplizierung von Primärschlüsseln während des Synchronisierungsprozesses implementiert haben, kommt es zu Primärschlüsselkonflikten, die dazu führen, dass die Datensynchronisierung unterbrochen wird . Dies muss im Voraus erfolgen. Bereiten Sie einen Behandlungsplan vor.
Anbei Referenzmaterialien am Ende
Viel Spaß mit GreatSQL :)
Über GreatSQL
Die GreatSQL-Datenbank ist eine kostenlose Open-Source- Datenbank, die Anwendungsszenarien auf finanzieller Ebene auf normaler Hardware erfüllen kann. Sie verfügt über Funktionen wie hohe Verfügbarkeit , hohe Leistung , hohe Kompatibilität und hohe Sicherheit . Sie kann ein idealer Ersatz für MySQL oder Percona Server sein MySQL.
verwandte Links
Technische Austauschgruppe
WeChat: Freunde hinzufügen GreatSQL社区助手
, WeChat-ID wanlidbc
sendet Verifizierungsinformationen加群
QQ-Gruppe: 533341697
Viel Spaß mit GreatSQL :)
Über GreatSQL
GreatSQL ist eine inländische unabhängige Open-Source-Datenbank, die für Anwendungen auf Finanzebene geeignet ist. Sie verfügt über viele Kernfunktionen wie hohe Leistung, hohe Zuverlässigkeit, hohe Benutzerfreundlichkeit und hohe Sicherheit. Sie kann als optionaler Ersatz für MySQL oder Percona Server verwendet werden und wird in Online-Produktionsumgebungen verwendet. , völlig kostenlos und kompatibel mit MySQL oder Percona Server.
Verwandte Links: GreatSQL Community Gitee GitHub Bilibili
GreatSQL-Community:
Vorschläge und Feedback zu Community-Belohnungen: https://greatsql.cn/thread-54-1-1.html
Details zur preisgekrönten Einreichung des Community-Blogs: https://greatsql.cn/thread-100-1-1.html
(Wenn Sie Fragen zu dem Artikel haben oder einzigartige Erkenntnisse gewinnen möchten, können Sie diese auf der offiziellen Community-Website stellen oder teilen~)
Technische Austauschgruppe:
WeChat- und QQ-Gruppe:
QQ-Gruppe: 533341697
WeChat-Gruppe: Fügen Sie GreatSQL Community Assistant (WeChat-ID:) wanlidbc
als Freund hinzu und warten Sie, bis der Community-Assistent Sie der Gruppe hinzufügt.