Heim >Datenbank >MySQL-Tutorial >So implementieren Sie die asynchrone und halbsynchrone Replikation von MySQL
Bei der asynchronen Replikation (asynchrone Replikation) muss sich der Master nicht darum kümmern, ob der Slave das Binärprotokoll empfängt, sodass der Master keine Abhängigkeiten vom Slave hat. Master und Slave können als zwei unabhängig arbeitende Server betrachtet werden. Mithilfe von Binärprotokollen können sie letztendlich die Datenkonsistenz aufrechterhalten.
Die asynchrone Replikation bietet die beste Leistung, da sie nahezu keinen Overhead für die Datenbank selbst verursacht, es sei denn, die Master-Slave-Verzögerung ist sehr groß und der Dump-Thread muss eine große Anzahl binärer Protokolldateien lesen.
Wenn das Unternehmen keine hohen Anforderungen an die Datenkonsistenz stellt und Datenverlust oder sogar einen großen Datenverlust tolerieren kann, wenn ein Fehler auftritt, wird empfohlen, die asynchrone Replikation zu verwenden, die die beste Leistung bietet (z. B Unternehmen wie Weibo haben zwar extrem hohe Leistungsanforderungen, Datenverluste werden jedoch in der Regel toleriert. Doch oft sind Kerngeschäftssysteme am meisten auf die Datensicherheit bedacht, etwa Überwachungsdienste und Alarmsysteme.
Planung der asynchronen Replikationsumgebung:
Master (Docker), Port 3310
Slave (Docker), Port 3311
Konfigurationsdatei my.cnf
$ sudo cat /home/mysql/docker-data/3311/conf/my.cnf # For advice on how to change settings please see # http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html [mysqld] # # Remove leading # and set to the amount of RAM for the most important data # cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%. # innodb_buffer_pool_size = 128M # # Remove leading # to turn on a very important data integrity option: logging # changes to the binary log between backups. # log_bin # # Remove leading # to set options mainly useful for reporting servers. # The server defaults are faster for transactions and fast SELECTs. # Adjust sizes as needed, experiment to find the optimal values. # join_buffer_size = 128M # sort_buffer_size = 2M # read_rnd_buffer_size = 2M #datadir=/home/mysql/docker-data/3307/data #socket=/home/mysql/docker-data/3307/mysql.sock character_set_server=utf8 init_connect='SET NAMES utf8' # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 #log-error=/home/mysql/docker-data/3307/logs/mysqld.log #pid-file=/home/mysql/docker-data/3307/mysqld.pid lower_case_table_names=1 # 表名是否小写 server-id=1403311 log-bin=mysql-bin # 开启binlog binlog-format=ROW # binlog的格式 auto_increment_increment=1 # 自增的步长,适用于主主复制,为了避免id冲突,步长设置为master的个数 auto_increment_offset=1 # 自增的偏移,主主复制每个master的偏移需要不一致 # binlog-do-db=mstest # 要同步的数据库 # binlog-ignore-db=mysql # 要忽略的数据库 #rpl_semi_sync_master_enabled=1 #rpl_semi_sync_master_timeout=10000
MySQL starten:
$ docker run --name mysql3310 -p 3310:3306 --privileged=true -ti -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=order -e MYSQL_USER=user -e MYSQL_PASSWORD=pass -v /home/mysql/docker-data/3310/conf:/etc/mysql/conf.d -v /home/mysql/docker-data/3310/data/:/var/lib/mysql -v /home/mysql/docker-data/3310/logs/:/var/log/mysql -d mysql:5.7
Erstellen Sie einen Benutzer für die Synchronisierung:
mysql> GRANT REPLICATION SLAVE,FILE,REPLICATION CLIENT ON *.* TO 'repluser'@'%' IDENTIFIED BY '123456'; Query OK, 0 rows affected, 1 warning (0.01 sec) mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.01 sec)
Sehen Sie sich das Binärprotokoll des Masters auf dem Master an:
mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000003 | 1147 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
Sehen Sie sich die Prozessliste auf dem Master an:
mysql> show processlist; +----+----------+------------------+-------+-------------+------+---------------------------------------------------------------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+----------+------------------+-------+-------------+------+---------------------------------------------------------------+------------------+ | 2 | root | localhost | order | Query | 0 | starting | show processlist | | 6 | repluser | 172.17.0.1:48450 | NULL | Binlog Dump | 448 | Master has sent all binlog to slave; waiting for more updates | NULL | +----+----------+------------------+-------+-------------+------+---------------------------------------------------------------+------------------+ 2 rows in set (0.00 sec)
Die Konfigurationsdatei my.cnf stimmt mit der Konfiguration des Masters überein , außer dass das Server-ID-Feld eindeutig sein muss.
MySQL starten:
$ docker run --name mysql3311 -p 3311:3306 --privileged=true -ti -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=order -e MYSQL_USER=user -e MYSQL_PASSWORD=pass -v /home/mysql/docker-data/3311/conf:/etc/mysql/conf.d -v /home/mysql/docker-data/3311/data/:/var/lib/mysql -v /home/mysql/docker-data/3311/logs/:/var/log/mysql -d mysql:5.7
Master-Informationen im Slave festlegen:
# master_log_file和master_log_pos取上面show master status显示的值mysql> change master to master_host='172.23.252.98',master_port=3310,master_user='repluser',master_password='123456',master_log_file='mysql-bin.000003',master_log_pos=1147;
Slave starten, SQL- und IO-Threads starten:
mysql> start slave;Query OK, 0 rows affected (0.00 sec)
Slave-Status anzeigen:
mysql> show slave status\G;*************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.54.214 Master_User: repluser Master_Port: 3310 Connect_Retry: 60 Master_Log_File: mysql-bin.000003 Read_Master_Log_Pos: 1147 Relay_Log_File: 2da789531bf3-relay-bin.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: mysql-bin.000003 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: 1147 Relay_Log_Space: 534 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: 0Master_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: 1403311 Master_UUID: cd2eaa0a-7a59-11ec-b3b4-0242ac110002 Master_Info_File: /var/lib/mysql/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave 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: Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version:1 row in set (0.00 sec)
Nur neu hinzugefügte Daten müssen kopiert werden manuell mit Tools (z. B. mysqldump) synchronisiert.
Sehen Sie sich die Prozessliste auf dem Slave an:
mysql> show processlist; +----+-------------+-----------+-------+---------+------+--------------------------------------------------------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+-------------+-----------+-------+---------+------+--------------------------------------------------------+------------------+ | 4 | root | localhost | order | Query | 0 | starting | show processlist | | 7 | system user | | NULL | Connect | 533 | Waiting for master to send event | NULL | | 8 | system user | | NULL | Connect | 127 | Slave has read all relay log; waiting for more updates | NULL | +----+-------------+-----------+-------+---------+------+--------------------------------------------------------+------------------+ 3 rows in set (0.00 sec)
Halbsynchrone Replikation ist der halbsynchrone Replikationsmechanismus vor MySQL 5.7.
Die halbsynchrone Replikation erfordert, dass während des Master-Transaktionsübermittlungsprozesses mindestens N Slaves Binärprotokolle empfangen. Dadurch wird sichergestellt, dass die Daten auf mindestens N Slave-Servern vollständig sind, wenn der Master ausfällt.
Die halbsynchrone Replikation ist keine integrierte Funktion von MySQL. Stattdessen müssen Sie das halbsynchrone Plug-in installieren, die halbsynchrone Replikationsfunktion aktivieren und N Slaves einrichten, um Binärprotokolle erfolgreich zu akzeptieren.
Nachteile: Angenommen, Benutzer1 fügt Daten in die Hauptdatenbank ein und wartet auf die Rückgabe der Daten. Wenn der Master zu diesem Zeitpunkt auflegt, kann Benutzer2 diese Daten nicht wiederfinden. Dies führt zu einem Phänomen, das dem Phantomlesen ähnelt.
Die verbesserte halbsynchrone Replikation behebt die Mängel der halbsynchronen Replikation, die auftreten, bevor die Transaktion festgeschrieben wird, sodass der Master dies auch dann tut, wenn der Slave das Binärprotokoll nicht empfängt aufgrund der letzten Transaktion ausgefallen Es wurde noch nicht übermittelt, sodass die Daten selbst für die Außenwelt nicht sichtbar sind und kein Verlustproblem besteht.
Für jedes Unternehmen, das Anforderungen an die Datenkonsistenz stellt, wie z. B. das Kernauftragsgeschäft E-Commerce, Banken, Versicherungen, Wertpapiere und andere Unternehmen, die eng mit Fonds verbunden sind, müssen Sie also die erweiterte halbsynchrone Replikation verwenden. Selbst bei einem Ausfall verfügt die Slave-Maschine über eine vollständige Datensicherung, sodass die Daten sicher und zuverlässig sind.
Die erweiterte halbsynchrone Replikationsumgebung basiert auf der asynchronen Replikation.
Installieren Sie das Plug-in. Es wird empfohlen, es sowohl auf dem Master als auch auf dem Slave zu installieren, da es zu einem Master-Slave-Umschaltszenario kommt:
# master mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so'; # slave mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Stellen Sie sicher, dass das Plug-in erfolgreich installiert wurde:
mysql> show plugins; ... ... | rpl_semi_sync_master | ACTIVE | REPLICATION | semisync_master.so | GPL | | rpl_semi_sync_slave | ACTIVE | REPLICATION | semisync_slave.so | GPL | +----------------------------+----------+--------------------+--------------------+---------+ 46 rows in set (0.00 sec)
Starten Sie zuerst das Halbsynchronisation auf dem Slave:
mysql> set global rpl_semi_sync_slave_enabled = {0|1}; # 1:启用,0:禁止
Dann starten Sie die Halbsynchronisation auf dem Master:
mysql> set global rpl_semi_sync_master_enabled = {0|1}; # 1:启用,0:禁止 # mysql> set global rpl_semi_sync_master_timeout = 10000; # 单位为ms,默认为10s
Starten Sie io_thread aus der Bibliothek neu:
mysql> stop slave io_thread; mysql> start slave io_thread;
Wenn die Parameter in die Konfigurationsdatei geschrieben werden, wechselt die Instanz sofort nach dem Start in den Halbsynchronisationsmodus. Wenn es zu einer längeren Unterbrechung der Verbindung kommt, kann ein Neustart der Instanz dazu führen, dass die Hauptdatenbank heruntergefahren wird.
Nachdem Sie die lange Zeit getrennte Slave-Datenbank wieder verbunden haben, müssen Sie warten, bis alle Transaktionen nachverfolgt wurden, und dann manuell den halbsynchronen Modus aktivieren, anstatt direkt nach dem Start zu wechseln, um Auswirkungen auf die Hauptdatenbank zu vermeiden.
Rpl_semi_sync_master_status:ON是活动状态(半同步),OFF是非活动状态(异步),用于表示主服务器使用的是异步复制模式,还是半同步复制模式
Rpl_semi_sync_master_tx_avg_wait_time:master花在每个事务上的平均等待时间
Rpl_semi_sync_master_tx_waits:master等待成功的次数,即master没有等待超时的次数,也就是成功提交的次数
Rpl_semi_sync_master_yes_tx:master成功接收到slave的回复的次数,即半同步模式成功提交数量。
mysql> show global variables like '%sync%'; +-------------------------------------------+------------+ | Variable_name | Value | +-------------------------------------------+------------+ | binlog_group_commit_sync_delay | 0 | | binlog_group_commit_sync_no_delay_count | 0 | | innodb_flush_sync | ON | | innodb_sync_array_size | 1 | | innodb_sync_spin_loops | 30 | | rpl_semi_sync_master_enabled | ON | | rpl_semi_sync_master_timeout | 10000 | | rpl_semi_sync_master_trace_level | 32 | | rpl_semi_sync_master_wait_for_slave_count | 1 | | rpl_semi_sync_master_wait_no_slave | ON | | rpl_semi_sync_master_wait_point | AFTER_SYNC | | rpl_semi_sync_slave_enabled | ON | | rpl_semi_sync_slave_trace_level | 32 | | sync_binlog | 1 | | sync_frm | ON | | sync_master_info | 10000 | | sync_relay_log | 10000 | | sync_relay_log_info | 10000 | +-------------------------------------------+------------+ 18 rows in set (0.01 sec)
重要参数说明:
rpl_semi_sync_master_enabled:(主库)是否启动半同步
rpl_semi_sync_master_timeout:等待多时毫秒后变成异步复制,默认是10000ms
rpl_semi_sync_master_wait_point:5.7默认AFTER_SYNC(增强版半同步复制,无损复制模式),在得到slave的应答后再commit,可选值AFTER_COMMIT,在master提交后同步数据给slave,然后master等待slave应答,应答成功返回客户端。
可以在slave端执行stop slave
,测试master端会发生什么情况?
在master上执行下面的sql:
mysql> insert into t_order values(3,"C");Query OK, 1 row affected (10.05 sec)
会发现这条语句会阻塞10s(对应上面的参数rpl_semi_sync_master_timeout),然后执行成功,最后看看看master的日志描述:
2022-01-25T02:31:57.016430Z 4 [Note] Start binlog_dump to master_thread_id(4) slave_server(1403312), pos(mysql-bin.000005, 154) 2022-01-25T02:31:57.016515Z 4 [Note] Start asynchronous binlog_dump to slave (server_id: 1403312), pos(mysql-bin.000005, 154) 2022-01-25T02:33:32.183819Z 2 [Note] Semi-sync replication initialized for transactions. 2022-01-25T02:33:32.183865Z 2 [Note] Semi-sync replication enabled on the master. 2022-01-25T02:33:32.184004Z 0 [Note] Starting ack receiver thread 2022-01-25T02:33:59.644444Z 5 [Note] While initializing dump thread for slave with UUID <aba2eb12-7cbc-11ec-9c1d-0242ac110003>, found a zombie dump thread with the same UUID. Master is killing the zombie dump thread(4). 2022-01-25T02:33:59.644612Z 5 [Note] Start binlog_dump to master_thread_id(5) slave_server(1403312), pos(mysql-bin.000005, 154) 2022-01-25T02:33:59.644632Z 4 [Note] Stop asynchronous binlog_dump to slave (server_id: 1403312) 2022-01-25T02:33:59.644727Z 5 [Note] Start semi-sync binlog_dump to slave (server_id: 1403312), pos(mysql-bin.000005, 154) 2022-01-25T02:38:02.847879Z 0 [ERROR] mysqld: Got an error reading communication packets 2022-01-25T02:38:27.228952Z 2 [Warning] Timeout waiting for reply of binlog (file: mysql-bin.000005, pos: 684), semi-sync up to file mysql-bin.000005, position 419. 2022-01-25T02:38:27.229063Z 2 [Note] Semi-sync replication switched OFF. 2022-01-25T02:39:47.230189Z 5 [Note] Stop semi-sync binlog_dump to slave (server_id: 1403312)
可以发现半同步关闭了,变成异步模式。
Das obige ist der detaillierte Inhalt vonSo implementieren Sie die asynchrone und halbsynchrone Replikation von MySQL. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!