MySQL部署主从复制

MySQL部署主从复制

基本原理

从库会基于初始设定的binlog日志和其位置点与指定的主库交互,每次执行完后更新位置点,下此取数据将基于此位置点进行新一次的交互;从库具体实现细节:在从库上启动了slave以后,会有两个主要的线程:I/O线程SQL线程,前者主要负责与主机上的dump线程交互,将数据取回放到relay-log里面(relay-bin.000001格式与binlog一致,都是二进制),然后SQL线程会在一定的时间(具体时间取决于slavemaster-delay设定值)内到relay-log里面读取数据,并执行这些更改到本机的库。 注: 很多属于个人理解,如有理解错误得地方,还请评论指正,谢谢您!🙂

结构图

mysql_master_slave_copy20190728100415

相关文件的作用

通常情况下,预编译包形式安装的MySQL数据目录位于/usr/local/mysql/data内,下面列出了与主从相关的文件的作用

文件名作用备注
$hostname-relay-bin.000001记录从master侧拉取的数据I/O线程会将拉取数据回来将数据写到这个文件,做了延时同步,可以使用该文件进行数据恢复,可能会存在多个
$hostname-relay-bin.index记录relay-log的分页文件列表masterbinlog一样,relay-log也会产生分页
master.info记录master的当前位置点和基本配置信息change master to后产生,slave会定期更新其内部记录的master侧的当前binlog位置点
relay-log.info包含记录了slave上次执行的位置点如果未设置延时复制策略,则该值与master.info内的位置点保持一致(异步的,可能会有一定差异,但最终会一致),如果设定了了延时,则在master_delay延时结束之前,该值会保持最后一次执行操作的位置点,该位置点会在SQL线程执行完所有更改任务后被更新,注: 延时参数也在内记录

配置master

开启主从复制必须为master指定一个server_id并为master开启binlog日志功能,除此之外还需要添加一个用于slave连接master的账户,用以执行复制操作。

master侧my.cnf

[mysqld]
server_id=5
#尽量确保master侧的id唯一
log_bin=mysql_bin
#binlog名称随意
skip_name_resolv
#跳过反向解析
#其他参数根据业务具体进行优化

添加replication账户,执行以下SQL语句:

grant replication slave on *.* to 'repl'@'%' identified by '123';
#根据具体情况设定主机域和密码

重启master服务。在配置slave侧之前需要先对主库进行一次全量备份,并将该备份推到slave侧后导入数据,如下代码:

#执行mysqldump进行全备并打点,该点将用于slave侧的初始设定
#不锁表
mysqldump -A -R --triggers --master-data=2 --single-transaction > /tmp/full.sql
#将full.sql推送到slave侧
scp /tmp/full.sql [slave_ip]:/opt/full.sql

配置slave

从机侧不需要执行太多的配置,仅需配置下server_id和配置master参数。

slave侧my.cnf

[mysqld]
server_id=7
skip_name_resolv
#id可以任意,即便是多个slave一样的id也无所谓,但不能和master一样

添加master信息到slave侧

在进行配置之前需要打开full.sql脚本,检查里面的位置点和binlog名称,记录该参数,稍后将使用该参数。

#执行以下SQL语句
#必须确保slave侧的库完全为初始环境
#导入推送过来的全量备份恢复到slave的库中
source /opt/full.sql
#查看当前的
#在slave添加master信息
change master to
master_host='master_ip',
master_user='repl',
master_password='123',
#如果更改了端口则指定端口号,默认不指定即3306
master_port=3306,
master_log_file=mysql_bin.xxxxxxx,     #根据full.sql里面的当前binlog名称,也就是master当前使用的binlog名
master_log_pos=205,			#根据获取到的位置点来填写
#开启延时执行的话需要指定下面的值,单位秒,我做的是延时复制200秒
#也就是主库执行完操作后,从库延时200秒后执行主库所执行的操作
master_delay=200;

配置好后,启动slave,执行start slave;启动I/O线程和SQL线程。

#启动线程
start slave;
#查看slave状态
show slave status;
#重置master参数执行如下语句:
#先停止slave
stop slave;
#然后重置
reset slave;

测试

测试主从是否成功,仅需在master侧进行一些建库或建表或插入操作,观察slave侧有无相同的数据过来,如果你设定了master_delay的值,则根据该值的大小进行延时,在延时之前是无法看到master侧的更改的,只有在延时过后,master执行的操作才会被应用到slave

扩展:主从复制的排错思路

主从复制工作正常的情况下,在slave侧的I/O线程和SQL线程会处于yes状态,如下图:

sql_slave_status20190723112424

这两个线程任意一个为No都会影响主从复制的正常工作。

I/O线程起不来或停止的排查思路

  1. 检查master
    • 网络畅通性
    • 端口开放性
    • 授权用户存在且在slave侧可登陆
  2. 检查slave
    • 检查用户名密码正确性
    • 手动登陆测试
    • 跳过DNS反向解析skip_name_resolv

在解决了问题后,可进行跳过错误:set global sql_slave_skip_counter=1;,然后尝试启动I/O线程。

SQL线程起不来的排查思路

主从两侧数据肯定存在差异,必须保持一致;否侧错误有可能还会出现。该错误跳过意义不大。

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×