MySQL异步复制和半同步复制怎么实现

网友投稿 294 2023-11-25

MySQL异步复制和半同步复制怎么实现

这篇文章主要介绍“MySQL异步复制和半同步复制怎么实现”,在日常操作中,相信很多人在MySQL异步复制和半同步复制怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MySQL异步复制和半同步复制怎么实现”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

异步复制

MySQL异步复制和半同步复制怎么实现

在异步复制(async replication)中,Master不用关心Slave是否接收到二进制日志,所以Master与Slave没有任何的依赖关系。你可以认为Master和Slave是分别独自工作的两台服务器,数据最终会通过二进制日志达到一致。

异步复制的性能最好,因为它对数据库本身几乎没有任何开销,除非主从延迟非常大,Dump Thread需要读取大量二进制日志文件。

如果业务对于数据一致性要求不高,当发生故障时,能容忍数据的丢失,甚至大量的丢失,推荐用异步复制,这样性能最好(比如像微博这样的业务,虽然它对性能的要求极高,但对于数据丢失,通常可以容忍)。但往往核心业务系统最关心的就是数据安全,比如监控业务、告警系统。

异步复制环境的规划:

master(docker),端口3310

slave(docker),端口3311

master的配置

配置文件my-f

$ sudo cat /home/mysql/docker-data/3311/conf/my-f# 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 *.* TOrepluser@% IDENTIFIED BY 123456;Query OK, 0 rows affected, 1 warning (0.01 sec)mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.01 sec)

在master上查看master的二进制日志:

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)

查看master上的进程列表:

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; waitingfor more updates | NULL             | +----+----------+------------------+-------+-------------+------+---------------------------------------------------------------+------------------+ 2 rowsin set (0.00 sec)

slave的配置

配置文件my-f与master的配置一致,除了server-id字段需唯一。

启动mysql:

$ docker run --name mysql3311 -p3311: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

在slave中设置master的信息:

#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,启动SQL和IO线程:

mysql> start slave;Query OK, 0 rows affected (0.00 sec)

查看slave的状态:

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)进行同步。

查看slave上的进程列表:

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版本前的半同步复制机制。

半同步复制要求Master事务提交过程中,至少有N个Slave接收到二进制日志,这样就能保证当Master发生宕机,至少有N 台Slave服务器中的数据是完整的。

半同步复制并不是MySQL内置的功能,而是要安装半同步插件,并启用半同步复制功能,设置N个Slave接受二进制日志成功。

缺点:假设user1在主库插入了一条数据,正在等待数据返回,user2这时就能查询到这条数据了,如果此时master挂了,user2又查不到这条数据了,产生了类似幻读的现象。

增强半同步复制

增强半同步复制解决了半同步复制的缺点,WAIT和ACK发生在事务提交之前,这样即便Slave没有收到二进制日志,但是 Master宕机了,由于最后一个事务还没有提交,所以本身这个数据对外也不可见,不存在丢失的问题。

所以,对于任何有数据一致性要求的业务,如电商的核心订单业务、银行、保险、证券等与资金密切相关的业务,务必使用增强半同步复制。这样数据才是安全的、有保障的、即使发生宕机,从机也有一份完整的数据。

增强半同步复制环境是基于异步复制的基础上进行的。

安装插件,建议master和slave都安装,因为会有主从切换的情景:

# master mysql>install plugin rpl_semi_sync_master sonamesemisync_master.so; # slave mysql>install plugin rpl_semi_sync_slave sonamesemisync_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)

先启动slave上的半同步:

mysql> setglobal rpl_semi_sync_slave_enabled = {0|1};# 1:启用,0:禁止

再启动master上的半同步:

mysql> setglobal 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:支持和注册半同步复制的已连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 rowsin 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:

mysqlinsert into t_order values(3,"C");Query OK1 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.000005154) 2022-01-25T02:31:57.0165154 [Note] Start asynchronous binlog_dump to slave (server_id: 1403312), pos(mysql-bin.000005154) 2022-01-25T02:33:32.1838192 [Note] Semi-sync replication initialized for transactions. 2022-01-25T02:33:32.1838652 [Note] Semi-sync replication enabled onthe master.2022-01-25T02:33:32.1840040 [Note] Starting ack receiver thread 2022-01-25T02:33:59.6444445[Note]While initializing dump thread for slave with UUID <aba2eb12-7cbc-11ec-9c1d-0242ac110003>, founda zombie dumpthread with the same UUID. Master is killing the zombie dump thread(4). 2022-01-25T02:33:59.6446125[Note]Start binlog_dump to master_thread_id(5) slave_server(1403312), pos(mysql-bin.000005154) 2022-01-25T02:33:59.6446324 [Note] Stop asynchronous binlog_dump to slave (server_id: 1403312) 2022-01-25T02:33:59.6447275 [Note] Start semi-sync binlog_dump to slave (server_id: 1403312), pos(mysql-bin.000005154) 2022-01-25T02:38:02.8478790 [ERROR] mysqld: Got an error reading communication packets 2022-01-25T02:38:27.2289522 [WarningTimeout waiting for reply of binlog (file: mysql-bin.000005, pos: 684), semi-sync up to file mysql-bin.000005position 419. 2022-01-25T02:38:27.2290632 [Note] Semi-sync replication switched OFF. 2022-01-25T02:39:47.2301895 [Note] Stop semi-sync binlog_dump to slave (server_id: 1403312)

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

到此,关于“MySQL异步复制和半同步复制怎么实现”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:「悦数图数据库」亮相中国国际信息通信展览会,推进图技术产业化发展
下一篇:图数据库有哪些:知名图数据库产品和应用场景介绍
相关文章

 发表评论

暂时没有评论,来抢沙发吧~