이 글은 mysql에 대한 관련 지식을 제공합니다. 비동기 복제, 반동기 복제 등 MySQL 복제 기술과 관련된 문제를 주로 소개합니다. 모두에게 도움이 되기를 바랍니다. 도움이 되는.
추천 학습: mysql 동영상 튜토리얼
비동기 복제(async 복제)에서는 마스터가 슬레이브가 바이너리 로그를 수신하는지 여부를 신경 쓸 필요가 없으므로 마스터는 그렇지 않습니다. 슬레이브에 대한 종속성이 있습니다. 마스터와 슬레이브는 독립적으로 작동하는 두 개의 서버로 생각하면 되고, 결국 바이너리 로그를 통해 데이터가 일관되게 됩니다.
비동기 복제는 마스터-슬레이브 지연이 매우 크고 덤프 스레드가 많은 수의 바이너리 로그 파일을 읽어야 하는 경우를 제외하고는 데이터베이스 자체에 오버헤드가 거의 없기 때문에 최고의 성능을 발휘합니다.
비즈니스에서 데이터 일관성에 대한 요구 사항이 높지 않고 데이터 손실 또는 심지어 대량의 손실도 허용할 수 있는 경우 장애 발생 시 최고의 성능을 제공하는 비동기 복제를 사용하는 것이 좋습니다(예: Weibo와 같은 비즈니스는 성능 요구 사항이 매우 높지만 데이터 손실은 일반적으로 허용됩니다. 그러나 핵심 비즈니스 시스템은 모니터링 서비스 및 경보 시스템과 같은 데이터 보안에 가장 관심이 있는 경우가 많습니다.
비동기 복제 환경 계획:
master(docker), 포트 3310
slave(docker), 포트 3311
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)
구성 파일 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 이전의 반동기 복제 메커니즘입니다.
반동기 복제에서는 마스터 트랜잭션 제출 프로세스 중에 최소 N개의 슬레이브가 바이너리 로그를 수신해야 합니다. 이렇게 하면 마스터가 다운될 때 최소 N개의 슬레이브 서버의 데이터가 완료됩니다.
반동기 복제는 MySQL에 내장된 기능이 아닙니다. 대신 반동기 플러그인을 설치하고, 반동기 복제 기능을 활성화하고, 바이너리 로그를 성공적으로 수락하려면 N 슬레이브를 설정해야 합니다.
단점: user1이 기본 데이터베이스에 데이터를 삽입하고 데이터가 반환되기를 기다리고 있다고 가정합니다. 이때 User2가 이 데이터를 쿼리할 수 있습니다. 이때 마스터가 전화를 끊으면 user2는 이 데이터를 다시 찾을 수 없습니다. 팬텀 판독과 유사한 현상이 발생합니다.
향상된 반 동기 복제는 트랜잭션이 커밋되기 전에 WAIT 및 ACK가 발생하므로 슬레이브가 바이너리 로그를 수신하지 못하더라도 마스터는 마지막 거래로 인해 다운이 아직 제출되지 않았기 때문에 데이터 자체가 외부에 보이지 않으며, 손실의 문제도 없습니다.
따라서 전자상거래의 핵심 주문 사업, 은행, 보험, 증권 및 기타 자금과 밀접하게 관련된 비즈니스 등 데이터 일관성 요구 사항이 있는 모든 비즈니스의 경우 향상된 반동기 복제를 사용해야 합니다. 이러한 방식으로 데이터는 안전하고 보장됩니다. 가동 중지 시간이 발생하더라도 슬레이브 시스템은 데이터의 완전한 복사본을 갖게 됩니다.
향상된 반동기 복제 환경은 비동기 복제를 기반으로 합니다.
플러그인 설치 마스터-슬레이브 전환 시나리오가 있으므로 마스터와 슬레이브 모두에 설치하는 것이 좋습니다.
# 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)
중요 매개변수 설명:
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)
重要参数说明:
可以在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视频教程
위 내용은 MySQL 복제 기술 비동기 복제 및 반동기 복제의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!