当前位置:首页 » 数据库存储

relay fetch解决MySQL主从复制延迟

2013-11-10 13:56 本站整理 浏览(41)

Mysql复制单线程的本质意味着从服务器效率的降低,即使从服务器有很多磁盘、cpu、和内存,也很容易落后于主服务器,因为从服务器的单线程只能有效的使用一个cpu和磁盘。

从服务器上的锁定也是一个问题,运行在从服务器上的另外的查询也会加锁并阻塞复制线程。复制是单线程,复制线程(sql_thread)除了等待也不能做别的事情。

为了解决这个问题,业界开发了一些补丁解决这类问题,一个思路是由复制单线程改进为多线程。另外一种是在从服务器上通过并行IO把数据预先提取到内存中,这里我们着重介绍第二种。

这个主意的想法是通过程序,让他比从服务器的sql线程稍微提前一点在中继日志中读取到查询语句,并将其作为select语句来执行,这导致服务器把一些数据从磁盘读取到内存,因此当从服务器的sql线程从中继日志中执行命令的时候,它就不需要等待从磁盘读取数据。Select并行处理从服务器必须串行处理的I/O。

程序应该在sql线程前多久执行这个是要确定的问题。提前太多,提取到缓存到的数据会被清空。可以尝试几秒钟,或者中继日志中相同的字节数

IO密集型从服务器利用这个方案将取得明显效果。

广泛分布的单行update命令和delete命令操作,数据预热效果明显,大批量的insert命令可能不会有太大明显提高。

基本原理 在备库sql线程执行更新之前,预先将相应的数据加载到内存中,并不能提高sql_thread线程执行sql的能力,也不能加快io_thread线程读取日志的速度。

限制

1 目前仅支持主库binlog ROW模式

2 表需要有主键或唯一索引

3 忽略test和mysql数据库

4 如果数据库中存在类似tbname_1、tbname_2这样命名的多个表,但其表模式却不相同时,请加上-t选项,例如:tb_1 tb_2 tb_3这样命名的三个表,默认情况下,被认为是同样模式的表,这个特点是淘宝为了适应他们自己的数据库环境

5 默认最多支持10000个用户表,如果学员支持更多表,可以通过修改宏MAX_TABLE_NUM来进行调整。

使用方法运行: ./relayfetch -h来获取选项

主要选项包括:

-d debug

-D 后台运行

-p 密码

-u 用户名,请以root用户运行

-P mysqld端口号

-s 整数,单位为M,当read线程超过sql线程position这么多字节数时,会等待sql线程,默认为1M

-S mysql sock文件路径

-n worker线程数目。默认为5

-a 当seconds_behind_master大于这个值时,会唤醒relayfetch,默认为1s

-t 当使用该选项时,表明不使用分表规则(例如,表name_1 和表name_2会被视为同一类表)

我们可以通过端口号来运行

./relayfetch-uroot -t -P3306

或者通过sock来运行

./relayfetch-S /u01/mysql/run/mysql.sock -uroot

与该工具类似的还有Maatkit的mk-slave-prefetch,功能类似