Heim  >  Artikel  >  Datenbank  >  MySQL-Replikationstechnologie, asynchrone Replikation und halbsynchrone Replikation

MySQL-Replikationstechnologie, asynchrone Replikation und halbsynchrone Replikation

WBOY
WBOYnach vorne
2022-04-25 19:21:383670Durchsuche

Dieser Artikel vermittelt Ihnen relevantes Wissen über MySQL. Er stellt hauptsächlich Probleme im Zusammenhang mit der MySQL-Replikationstechnologie vor, einschließlich asynchroner Replikation, halbsynchroner Replikation usw. Ich hoffe, dass er für alle hilfreich ist. Hilfreich.

MySQL-Replikationstechnologie, asynchrone Replikation und halbsynchrone Replikation

Empfohlenes Lernen: MySQL-Video-Tutorial

Asynchrone Replikation

MySQL-Replikationstechnologie, asynchrone Replikation und halbsynchrone Replikation

Bei der asynchronen Replikation (asynchrone Replikation) muss sich der Master nicht darum kümmern, ob der Slave das Binärprotokoll empfängt, der Master also nicht irgendwelche Abhängigkeiten vom Slave haben. Sie können sich Master und Slave als zwei unabhängig voneinander arbeitende Server vorstellen, und die Daten werden letztendlich über das Binärprotokoll konsistent sein.

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 stellen zwar extrem hohe Leistungsanforderungen, aber Datenverlust wird 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

Master-Konfiguration

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)

Slave-Konfiguration

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

Halbsynchrone Replikation ist der halbsynchrone Replikationsmechanismus vor MySQL 5.7.

MySQL-Replikationstechnologie, asynchrone Replikation und halbsynchrone Replikation

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.

Erweiterte halbsynchrone Replikation

Die verbesserte halbsynchrone Replikation behebt die Mängel der halbsynchronen Replikation, die auftreten, bevor die Transaktion festgeschrieben wird. Selbst wenn der Slave das Binärprotokoll nicht empfängt, ist dies der Fall 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.

MySQL-Replikationstechnologie, asynchrone Replikation und halbsynchrone Replikation

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. Auf diese Weise sind die Daten sicher und garantiert, auch wenn es zu einem Ausfall kommt, verfügt die Slave-Maschine über eine vollständige Kopie der Daten.

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;

Warum wird nicht empfohlen, die Parameter der Halbsynchronisation in die Konfigurationsdatei zu schreiben

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.

Statusinformationen der Hauptdatenbank abfragen

mysql> show global status like "%semi%";
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 0     |
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 0     |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
| Rpl_semi_sync_master_tx_wait_time          | 0     |
| Rpl_semi_sync_master_tx_waits              | 0     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 0     |
| Rpl_semi_sync_slave_status                 | ON    |
+--------------------------------------------+-------+
15 rows in set (0.00 sec)

Wichtige Parameterbeschreibung:

  • Rpl_semi_sync_master_clients:支持和注册半同步复制的已连Slave数
  • Rpl_semi_sync_master_no_times:master关闭半同步复制的次数
  • Rpl_semi_sync_master_no_tx:master没有收到slave的回复而提交的次数,可以理解为master等待超时的次数,即半同步模式不成功提交数量
  • 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)</aba2eb12-7cbc-11ec-9c1d-0242ac110003>

可以发现半同步关闭了,变成异步模式。

推荐学习:mysql视频教程

Das obige ist der detaillierte Inhalt vonMySQL-Replikationstechnologie, asynchrone Replikation und halbsynchrone Replikation. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:csdn.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen