mysql主从延迟 mysql transfer 解决方案

越雨泽
2023-12-01

公司目前用的一主多从,当从库读压力过大时,会遇到主从延迟的问题 ,最近测试了主从延迟的方案 ,这是第二个方案,第一个方案请看 《relay fetch解决mysql replication 主从延迟》。                                                                                                             

Transfer总体介绍

Mysql-transfer是一个基于msyql+patch后得到的一个主从同步工具。主要目的是为了解决mysql,从库单线程应用主库的binlog,导致的延迟。

 

总体结构

1、  transfer 可以注册成多个master的从库

2、  transfer接受多个master传入的binlog后将更新执行到slave上

3、  transfer 本地没有数据

4、  如果没有多主的需求,结构是Master->Transfer ->Slave

内部结构

 

slave由于sql_thread单线程的原因,导致主从延迟,那么提升用多线程来实现。

 

环境搭建

 

安装 mysql主从复制(略)

可以实现架构及配置模式,主要实现slave和transfer模式

 

Slave模式配置

 

 前提主从环境搭建好,用提供的相对应mysql-transfer 可执行文件,替换slave下mysqld文件,并把mysql-transfer的可执行文件改名为mysqld, Slave的配置文件my.cnf做如下修改mysqld 下

 默认值:

 transfer_slave_thread =16

slave_skip_errors=1062,1032

 transfer_slave_thread是只读参数,控制有多少个线程并发更新,一般建议配置为系统核数2倍。

 

Transfer 模式

 

前提是主从环境搭建好,在salve所在物理机上安装另一mysql实例,替换mysqld文件,并把mysql-transfer的可执行文件改名mysqld ,作为transfer ,transfer注册(change master)到master。Transfer的配置文件my.cnf 增加如下配置

 transfer_slave_thread =

slave_skip_errors=1062,1032

remote_slave_hostname=

remote_slave_username=

remote_slave_password=

remote_slave_port=

 1)这里配置的账号必须有slave的超级权限

  2) transfer和slave如果在同一台机器上,创建的账号权限限制remote_slave_hostname=127.0.0.1

  3)使用transfer模式时,在环境搭建过程中,需要将slave的表结构导入到transfer中

  4)主从环境中, 1062和1032错误配置

 

测试性能效果

 

在master上准备数据,此时stop slave,sysbench 插入数据完毕后,start slave ,查看复制这些数据需要的时间

配置256内存虚拟机

 

10万

30万

50万

Mysql 主从

60秒

120秒

210秒

Transfer同步slave_sql线程32个

22秒

60秒

160秒

 

测试过程问题:

1 发现 Seconds_Behind_Master值有时不太准确: 数据已经复制完毕,seconds_Behind_Master显示大于0 。这个是多线程问题导致的。

影响:通过second_behind_master判断主从延迟的方式,有时会误报。

 

Transfer主从严重延迟后迁移transfer注意事项

 

背景

       正常情况下,若要从原来的主从切换成Transfer 模式,只需要作如下步骤:

1、在slave相同机器上部署一个Transfer,并配置好各种remote_slave参数

2、在slave上stop slave

3、把slave的表结构dump给transfer

4、从slave中查看当前执行到master的位置

5、在transfer执行change master xxxxx; start slave 即可。

状况描述

       线上某个项目主从延迟很多天(>7)。由于主库的binlog只保存一周,导致在要切换到Transfer的时候,从slave上show slave status得到的master_log_file在主库已经不存在了。

       这样无法通过上述的步骤5来实现切换到原来的位置。

 

这样的情况下,原来的主从怎么保证最终一致性?

实际上从库上是有两个线程协同工作的,io_thread 已经把主库的更新命令,都接收并保存在本地的relay-log了。 只是sql_thread处理速度太慢没有执行这些命令而已。

 

注意

需要特别注意:change master是会删除本地的relay log的。因此在上面的情况下,执行change master要谨慎,以防主库没有binlog的情况下删除备库的relaylog

 

解决方案

       从上面的说明看出,Slave上其实有足够的信息能够重放主库的命令(relaylog).因此在切换到transfer时需要换一个步骤:

1、 在slave相同机器上部署一个Transfer,并配置好各种remote参数

2、在slave上stop slave

3、把slave的表结构dump给transfer

(前面几个步骤不变)

4、将slave上的master.info、 master.info 和 mysqld-relay-bin.* (就是跟从库有关的数据) 都拷贝到transfer的对应目录下

5、在transfer直接执行start slave (重申,不能change master)

 

由于transfer重新启动以后,读到的是从slave上拷贝过来的数据,因此以为是之前自己的io_thread已经读取的数据,start以后就“继续”读取relaylog来更新slave。

 

情况还可能更糟

       如果这时候刚好主库出了点什么问题,导致连都连不了。那么上面改进步骤的第5点,就改成start slavesql_thread,这样tranfer不连主库,先把本地的relaylog都重放一遍。

      

 

Mysqltransfer FAQ:

 Q: Transfer是什么

A: 是一个解决MySQL原生主从同步延迟的方案。 Transfer本身是一个在MySQL源码上打的patch,可以用于当Slave,也可以用于当第三方工具,将Master的数据同步发给Slave。 利用多线程实现主从无延迟。

Q: Transfer目前的发布形式?

A: Transfer开发者曾经预计在2012内开源,到现在还未开源,目前的发布形式是可执行的mysqld文件。罗列一下目前发布的版本

目前版本列表:

官方的5.1.48

    MySQL-PS-Transfer.5.5.18 md5:0479bbcb2743a722276a3435af1bbb8e 最后更新时间:2012-12-12

   MySQL-PS-Transfer.5.5.27md5:9a72849115de510fcbe87246e4ed9e11 最后更新时间:2012-12-12

    MySQL-PS-Transfer.5.5.28md5:534611800ed01cec1f9ba278277cb1e7 最后更新时间:2012-12-12

    MySQL-PS-Transfer.5.5.30 md5:95f9646709a55b63496fca60d260db1b 最后更新时间:2013-4-23

Q: Transfer是否会改变主库上的binlog在从库上的执行顺序,导致数据不一致?

A:会改变执行顺序。但Transfer保证对于相同记录的操作都是按顺序的,因此不会导致数据不一致。

Q: 我使用了transfer模式,但是transfer的错误日志为什么一直在输出"trans->inner_events 3",而从库上没有更新?

A: Transfer启动前需要保证Transfer里面要有与slave上相同的表和表结构,请先确认下,若无,则需要从slave把schema都dump 过去。

Q: 我用的是mysql5.1.48版本,我在transfer里面建表的时候会core dump

A: 若你用的是innodb_plugin版本,还需要替换ha_innodb_plugin.so.0.0.0 (lib/mysql/plugin 目录下) 下载地址

 

Q: 需要配置上做什么改变

A:请参考此文 http://dinglin.iteye.com/blog/1670656

Q: 对主从库有什么配置限制

A:有以下限制

     1) 主库的binlog格式必须是row

     2) 主库的表必须有primary key

     3) 从库的 max_allowed_packet建议改为1G。主库的单个事务大小不能超过max_allowed_packet

Q: 我覆盖了mysqld后,Transfer整个实例起不来?

A:先确认一下mysqld是否有可执行权限, 若无,执行 chmod 755 mysqld.

Q: 我用slave模式,能够随时替换回原来的版本吗?

A: 如果要随时替换回原来的版本,可以把增加的参数都加上loose_前缀,这样替换mysqld,重启,start slave,就可以了。

Q: 如何监控transfer是否延迟

A: 在Transfer里面检测是否同步请用 Master_Log_File=Relay_Master_Log_File 且Read_Master_Log_Pos=Exec_Master_Log_Pos

根据测试情况,如果看Seconds_Behind_Master ,结果不准确。

 

参考资料

http://dinglin.iteye.com/blog/1581877  (mysql主从同步mysql transfer介绍)

http://dinglin.iteye.com/blog/1672742(mysql 主从同步加速—FAQ)

http://dinglin.iteye.com/blog/1746185(mysql transfer 2.1发布)

http://dinglin.iteye.com/blog/1187154(一种mysql主从复制加速方案-改进)

http://dinglin.iteye.com/blog/1685947(transfer 迁移注意事项)

http://dinglin.iteye.com/blog/1672146  (mysql transfer 在双主同步架构中的使用)

 

 类似资料: