MySQL异步复制和半同步复制怎么实现
这篇文章主要介绍“MySQL异步复制和半同步复制怎么实现”,在日常操作中,相信很多人在MySQL异步复制和半同步复制怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MySQL异步复制和半同步复制怎么实现”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
异步复制在异步复制(async replication)中,Master不用关心Slave是否接收到二进制日志,所以Master与Slave没有任何的依赖关系。你可以认为Master和Slave是分别独自工作的两台服务器,数据最终会通过二进制日志达到一致。
异步复制的性能最好,因为它对数据库本身几乎没有任何开销,除非主从延迟非常大,Dump Thread需要读取大量二进制日志文件。
如果业务对于数据一致性要求不高,当发生故障时,能容忍数据的丢失,甚至大量的丢失,推荐用异步复制,这样性能最好(比如像微博这样的业务,虽然它对性能的要求极高,但对于数据丢失,通常可以容忍)。但往往核心业务系统最关心的就是数据安全,比如监控业务、告警系统。
异步复制环境的规划:
master(docker),端口3310
slave(docker),端口3311
master的配置配置文件my.cnf
$sudocat/home/mysql/docker-data/3311/conf/my.cnf#Foradviceonhowtochangesettingspleasesee#http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html[mysqld]##Removeleading#andsettotheamountofRAMforthemostimportantdata#cacheinMySQL.Startat70%oftotalRAMfordedicatedserver,else10%.#innodb_buffer_pool_size=128M##Removeleading#toturnonaveryimportantdataintegrityoption:logging#changestothebinarylogbetweenbackups.#log_bin##Removeleading#tosetoptionsmainlyusefulforreportingservers.#TheserverdefaultsarefasterfortransactionsandfastSELECTs.#Adjustsizesasneeded,experimenttofindtheoptimalvalues.#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.sockcharacter_set_server=utf8init_connect='SETNAMESutf8'#Disablingsymbolic-linksisrecommendedtopreventassortedsecurityriskssymbolic-links=0#log-error=/home/mysql/docker-data/3307/logs/mysqld.log#pid-file=/home/mysql/docker-data/3307/mysqld.pidlower_case_table_names=1#表名是否小写server-id=1403311log-bin=mysql-bin#开启binlogbinlog-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:
$dockerrun--namemysql3310-p3310:3306--privileged=true-ti-eMYSQL_ROOT_PASSWORD=root-eMYSQL_DATABASE=order-eMYSQL_USER=user-eMYSQL_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-dmysql:5.7
创建用于同步的用户:
mysql>GRANTREPLICATIONSLAVE,FILE,REPLICATIONCLIENTON*.*TO'repluser'@'%'IDENTIFIEDBY'123456';QueryOK,0rowsaffected,1warning(0.01sec)mysql>FLUSHPRIVILEGES;QueryOK,0rowsaffected(0.01sec)
在master上查看master的二进制日志:
mysql>showmasterstatus;+------------------+----------+--------------+------------------+-------------------+|File|Position|Binlog_Do_DB|Binlog_Ignore_DB|Executed_Gtid_Set|+------------------+----------+--------------+------------------+-------------------+|mysql-bin.000003|1147||||+------------------+----------+--------------+------------------+-------------------+1rowinset(0.00sec)
查看master上的进程列表:
mysql>showprocesslist;+----+----------+------------------+-------+-------------+------+---------------------------------------------------------------+------------------+|Id|User|Host|db|Command|Time|State|Info|+----+----------+------------------+-------+-------------+------+---------------------------------------------------------------+------------------+|2|root|localhost|order|Query|0|starting|showprocesslist||6|repluser|172.17.0.1:48450|NULL|BinlogDump|448|Masterhassentallbinlogtoslave;waitingformoreupdates|NULL|+----+----------+------------------+-------+-------------+------+---------------------------------------------------------------+------------------+2rowsinset(0.00sec)slave的配置
配置文件my.cnf与master的配置一致,除了server-id字段需唯一。
启动mysql:
$dockerrun--namemysql3311-p3311:3306--privileged=true-ti-eMYSQL_ROOT_PASSWORD=root-eMYSQL_DATABASE=order-eMYSQL_USER=user-eMYSQL_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-dmysql:5.7
在slave中设置master的信息:
#master_log_file和master_log_pos取上面showmasterstatus显示的值mysql>changemastertomaster_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>startslave;QueryOK,0rowsaffected(0.00sec)
查看slave的状态:
mysql>showslavestatus\G;***************************1.row***************************Slave_IO_State:WaitingformastertosendeventMaster_Host:192.168.54.214Master_User:repluserMaster_Port:3310Connect_Retry:60Master_Log_File:mysql-bin.000003Read_Master_Log_Pos:1147Relay_Log_File:2da789531bf3-relay-bin.000002Relay_Log_Pos:320Relay_Master_Log_File:mysql-bin.000003Slave_IO_Running:YesSlave_SQL_Running:YesReplicate_Do_DB:Replicate_Ignore_DB:Replicate_Do_Table:Replicate_Ignore_Table:Replicate_Wild_Do_Table:Replicate_Wild_Ignore_Table:Last_Errno:0Last_Error:Skip_Counter:0Exec_Master_Log_Pos:1147Relay_Log_Space:534Until_Condition:NoneUntil_Log_File:Until_Log_Pos:0Master_SSL_Allowed:NoMaster_SSL_CA_File:Master_SSL_CA_Path:Master_SSL_Cert:Master_SSL_Cipher:Master_SSL_Key:Seconds_Behind_Master:0Master_SSL_Verify_Server_Cert:NoLast_IO_Errno:0Last_IO_Error:Last_SQL_Errno:0Last_SQL_Error:Replicate_Ignore_Server_Ids:Master_Server_Id:1403311Master_UUID:cd2eaa0a-7a59-11ec-b3b4-0242ac110002Master_Info_File:/var/lib/mysql/master.infoSQL_Delay:0SQL_Remaining_Delay:NULLSlave_SQL_Running_State:Slavehasreadallrelaylog;waitingformoreupdatesMaster_Retry_Count:86400Master_Bind:Last_IO_Error_Timestamp:Last_SQL_Error_Timestamp:Master_SSL_Crl:Master_SSL_Crlpath:Retrieved_Gtid_Set:Executed_Gtid_Set:Auto_Position:0Replicate_Rewrite_DB:Channel_Name:Master_TLS_Version:1rowinset(0.00sec)
只有新增的数据才会进行复制,存量的数据需要手动使用工具(如mysqldump)进行同步。
查看slave上的进程列表:
mysql>showprocesslist;+----+-------------+-----------+-------+---------+------+--------------------------------------------------------+------------------+|Id|User|Host|db|Command|Time|State|Info|+----+-------------+-----------+-------+---------+------+--------------------------------------------------------+------------------+|4|root|localhost|order|Query|0|starting|showprocesslist||7|systemuser||NULL|Connect|533|Waitingformastertosendevent|NULL||8|systemuser||NULL|Connect|127|Slavehasreadallrelaylog;waitingformoreupdates|NULL|+----+-------------+-----------+-------+---------+------+--------------------------------------------------------+------------------+3rowsinset(0.00sec)半同步复制
半同步复制是MySQL 5.7版本前的半同步复制机制。
半同步复制要求Master事务提交过程中,至少有N个Slave接收到二进制日志,这样就能保证当Master发生宕机,至少有N 台Slave服务器中的数据是完整的。
半同步复制并不是MySQL内置的功能,而是要安装半同步插件,并启用半同步复制功能,设置N个Slave接受二进制日志成功。
缺点:假设user1在主库插入了一条数据,正在等待数据返回,user2这时就能查询到这条数据了,如果此时master挂了,user2又查不到这条数据了,产生了类似幻读的现象。
增强半同步复制增强半同步复制解决了半同步复制的缺点,WAIT和ACK发生在事务提交之前,这样即便Slave没有收到二进制日志,但是 Master宕机了,由于最后一个事务还没有提交,所以本身这个数据对外也不可见,不存在丢失的问题。
所以,对于任何有数据一致性要求的业务,如电商的核心订单业务、银行、保险、证券等与资金密切相关的业务,务必使用增强半同步复制。这样数据才是安全的、有保障的、即使发生宕机,从机也有一份完整的数据。
增强半同步复制环境是基于异步复制的基础上进行的。
安装插件,建议master和slave都安装,因为会有主从切换的情景:
#mastermysql>installpluginrpl_semi_sync_mastersoname'semisync_master.so';#slavemysql>installpluginrpl_semi_sync_slavesoname'semisync_slave.so';
确保插件安装成功:
mysql>showplugins;......|rpl_semi_sync_master|ACTIVE|REPLICATION|semisync_master.so|GPL||rpl_semi_sync_slave|ACTIVE|REPLICATION|semisync_slave.so|GPL|+----------------------------+----------+--------------------+--------------------+---------+46rowsinset(0.00sec)
先启动slave上的半同步:
mysql>setglobalrpl_semi_sync_slave_enabled={0|1};#1:启用,0:禁止
再启动master上的半同步:
mysql>setglobalrpl_semi_sync_master_enabled={0|1};#1:启用,0:禁止#mysql>setglobalrpl_semi_sync_master_timeout=10000;#单位为ms,默认为10s
从库重启io_thread:
mysql>stopslaveio_thread;mysql>startslaveio_thread;半同步的参数为什么不建议写入配置文件
参数写入配置文件的话,会使实例启动后立即进入半同步模式,如果发生长时间断连的实例重新运行启动,有可能导致主库被拖垮。
长时间断开的从库,重新连接后,要等待追完全部事务后,手动开启半同步模式,而不是启动后直接切换,防止冲击主库。
查询主库状态信息mysql>showglobalstatuslike"%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|+--------------------------------------------+-------+15rowsinset(0.00sec)
重要参数说明:
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>showglobalvariableslike'%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|+-------------------------------------------+------------+18rowsinset(0.01sec)
重要参数说明:
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>insertintot_ordervalues(3,"C");QueryOK,1rowaffected(10.05sec)
会发现这条语句会阻塞10s(对应上面的参数rpl_semi_sync_master_timeout),然后执行成功,最后看看看master的日志描述:
2022-01-25T02:31:57.016430Z4[Note]Startbinlog_dumptomaster_thread_id(4)slave_server(1403312),pos(mysql-bin.000005,154)2022-01-25T02:31:57.016515Z4[Note]Startasynchronousbinlog_dumptoslave(server_id:1403312),pos(mysql-bin.000005,154)2022-01-25T02:33:32.183819Z2[Note]Semi-syncreplicationinitializedfortransactions.2022-01-25T02:33:32.183865Z2[Note]Semi-syncreplicationenabledonthemaster.2022-01-25T02:33:32.184004Z0[Note]Startingackreceiverthread2022-01-25T02:33:59.644444Z5[Note]WhileinitializingdumpthreadforslavewithUUID<aba2eb12-7cbc-11ec-9c1d-0242ac110003>,foundazombiedumpthreadwiththesameUUID.Masteriskillingthezombiedumpthread(4).2022-01-25T02:33:59.644612Z5[Note]Startbinlog_dumptomaster_thread_id(5)slave_server(1403312),pos(mysql-bin.000005,154)2022-01-25T02:33:59.644632Z4[Note]Stopasynchronousbinlog_dumptoslave(server_id:1403312)2022-01-25T02:33:59.644727Z5[Note]Startsemi-syncbinlog_dumptoslave(server_id:1403312),pos(mysql-bin.000005,154)2022-01-25T02:38:02.847879Z0[ERROR]mysqld:Gotanerrorreadingcommunicationpackets2022-01-25T02:38:27.228952Z2[Warning]Timeoutwaitingforreplyofbinlog(file:mysql-bin.000005,pos:684),semi-syncuptofilemysql-bin.000005,position419.2022-01-25T02:38:27.229063Z2[Note]Semi-syncreplicationswitchedOFF.2022-01-25T02:39:47.230189Z5[Note]Stopsemi-syncbinlog_dumptoslave(server_id:1403312)
可以发现半同步关闭了,变成异步模式。
到此,关于“MySQL异步复制和半同步复制怎么实现”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。