> 데이터 베이스 > MySQL 튜토리얼 > MySQL 비동기 복제 및 반동기 복제 구현 방법

MySQL 비동기 복제 및 반동기 복제 구현 방법

PHPz
풀어 주다: 2023-06-01 10:28:26
앞으로
1341명이 탐색했습니다.

MySQL 비동기 복제 및 반동기 복제 구현 방법

비동기 복제

MySQL 비동기 복제 및 반동기 복제 구현 방법

비동기 복제(비동기 복제)에서는 마스터가 슬레이브가 바이너리 로그를 수신하는지 여부를 신경 쓸 필요가 없으므로 마스터는 슬레이브에 종속되지 않습니다. 마스터와 슬레이브는 독립적으로 작동하는 두 개의 서버로 간주될 수 있으며, 바이너리 로그의 도움으로 궁극적으로 데이터 일관성을 유지할 수 있습니다.

비동기 복제는 마스터-슬레이브 지연이 매우 크고 덤프 스레드가 많은 수의 바이너리 로그 파일을 읽어야 하는 경우를 제외하고는 데이터베이스 자체에 오버헤드가 거의 없기 때문에 최고의 성능을 발휘합니다.

비즈니스에서 데이터 일관성에 대한 요구 사항이 높지 않고 데이터 손실 또는 심지어 대량의 손실도 허용할 수 있는 경우 장애 발생 시 최고의 성능을 제공하는 비동기 복제를 사용하는 것이 좋습니다(예: Weibo와 같은 비즈니스는 성능 요구 사항이 매우 높지만 데이터 손실은 일반적으로 허용됩니다. 그러나 핵심 비즈니스 시스템은 모니터링 서비스 및 경보 시스템과 같은 데이터 보안에 가장 관심이 있는 경우가 많습니다.

비동기 복제 환경 계획:

  • master(docker), 포트 3310

  • slave(docker), 포트 3311

master 구성

configuration 파일 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을 시작하세요:

$ 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
로그인 후 복사

동기화를 위한 사용자 생성:

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)
로그인 후 복사

마스터에서 마스터의 바이너리 로그 보기:

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)
로그인 후 복사

마스터에서 프로세스 목록 보기:

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의 구성

구성 파일 my.cnf는 마스터의 구성과 일치합니다. 단, server-id 필드는 고유해야 합니다.

mysql 시작:

$ 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_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;
로그인 후 복사

슬레이브 시작, SQL 및 IO 스레드 시작:

mysql> start slave;Query OK, 0 rows affected (0.00 sec)
로그인 후 복사

슬레이브 상태 보기:

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)
로그인 후 복사

새로 추가된 데이터만 복사해야 합니다. 도구(예: mysqldump)를 사용하여 수동으로 동기화합니다.

슬레이브의 프로세스 목록 보기:

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)
로그인 후 복사

반동기 복제

반동기 복제는 MySQL 5.7 이전의 반동기 복제 메커니즘입니다.

MySQL 비동기 복제 및 반동기 복제 구현 방법

반동기 복제에서는 마스터 트랜잭션 제출 프로세스 중에 최소 N개의 슬레이브가 바이너리 로그를 수신해야 합니다. 이렇게 하면 마스터가 다운될 때 최소 N개의 슬레이브 서버의 데이터가 완료됩니다.

반동기 복제는 MySQL에 내장된 기능이 아닙니다. 대신 반동기 플러그인을 설치하고, 반동기 복제 기능을 활성화하고, 바이너리 로그를 성공적으로 수락하려면 N 슬레이브를 설정해야 합니다.

단점: user1이 기본 데이터베이스에 데이터를 삽입하고 데이터가 반환되기를 기다리고 있다고 가정합니다. 이때 User2가 이 데이터를 쿼리할 수 있습니다. 이때 마스터가 전화를 끊으면 user2는 이 데이터를 다시 찾을 수 없습니다. 팬텀 판독과 유사한 현상이 발생합니다.

향상된 반 동기 복제

향상된 반 동기 복제는 트랜잭션이 커밋되기 전에 WAIT 및 ACK가 발생하므로 슬레이브가 바이너리 로그를 수신하지 못하더라도 마스터는 마지막 거래로 인해 다운이 아직 제출되지 않았기 때문에 데이터 자체가 외부에 보이지 않으며, 손실의 문제도 없습니다.

MySQL 비동기 복제 및 반동기 복제 구현 방법

따라서 전자상거래의 핵심 주문 사업, 은행, 보험, 증권 및 기타 자금과 밀접하게 관련된 비즈니스 등 데이터 일관성 요구 사항이 있는 모든 비즈니스의 경우 향상된 반동기 복제를 사용해야 합니다. 가동 중단이 발생하더라도 슬레이브 머신은 완전한 데이터 백업을 가지므로 데이터는 안전하고 신뢰할 수 있습니다.

향상된 반동기 복제 환경은 비동기 복제를 기반으로 합니다.

플러그인 설치 마스터-슬레이브 전환 시나리오가 있으므로 마스터와 슬레이브 모두에 ​​설치하는 것이 좋습니다.

# master
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
# slave
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
로그인 후 복사

플러그인이 성공적으로 설치되었는지 확인하세요.

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)
로그인 후 복사

먼저 플러그인을 시작하세요. 슬레이브에서 반동기화:

mysql> set global rpl_semi_sync_slave_enabled = {0|1};  # 1:启用,0:禁止
로그인 후 복사

그런 다음 마스터에서 반동기화를 시작합니다:

mysql> set global rpl_semi_sync_master_enabled = {0|1};  # 1:启用,0:禁止
# mysql> set global rpl_semi_sync_master_timeout = 10000;    # 单位为ms,默认为10s
로그인 후 복사

라이브러리에서 io_thread를 다시 시작합니다:

mysql> stop slave io_thread;
mysql> start slave io_thread;
로그인 후 복사

반동기화 매개변수를 구성 파일에 기록하는 것이 권장되지 않는 이유는 무엇입니까

파라미터가 구성 파일에 기록되면 인스턴스는 시작 후 즉시 반동기화 모드로 전환됩니다. 장기간 연결 끊김이 발생할 경우 인스턴스를 다시 시작하면 기본 데이터베이스가 다운될 수 있습니다.

오랫동안 연결이 끊어진 슬레이브 데이터베이스를 다시 연결한 후에는 메인 데이터베이스에 영향을 미치지 않도록 시작 후 바로 전환하는 대신 모든 트랜잭션이 추적될 때까지 기다린 다음 수동으로 반동기 모드를 켜야 합니다.

마스터 데이터베이스 상태 정보 쿼리

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)
로그인 후 복사

중요 매개변수 설명:

  • Rpl_semi_sync_master_clients: 반동기 복제를 지원하고 등록하는 연결된 슬레이브 수

  • Rpl_semi_sync_master_no_times: 마스터가 반동기를 닫은 횟수 복제

  • Rpl_semi_sync_master_no_tx: 마스터가 슬레이브로부터 응답을 받지 못한 채 제출한 횟수는 마스터가 타임아웃을 기다린 횟수, 즉 반동기 모드에서 제출에 실패한 횟수로 이해할 수 있습니다.

  • 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)
로그인 후 복사

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

위 내용은 MySQL 비동기 복제 및 반동기 복제 구현 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:yisu.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿