本周在搭建集群的时候,特意将数据库也建立一个集群为以后方便扩容,故此处带大家了解一下MySQL的主从配置

主从复制介绍

原理

主从复制是指一台服务器充当主数据库服务器,另一台或多台服务器充当从数据库服务器,主服务器中的数据自动复制到从服务器之中。对于多级复制,数据库服务器即可充当主机,也可充当从机。MySQL主从复制的基础是主服务器对数据库修改记录二进制日志,从服务器通过主服务器的二进制日志自动执行更新。

工作原理

主从复制工作原理.png

如图所示,主服务器上面的任何修改都会保存在二进制日志Binary log里面,从服务器上面启动一个I/O thread(实际上就是一个主服务器的客户端进程),连接到主服务器上面请求读取二进制日志,然后把读取到的二进制日志写到本地的一个Realy log里面。从服务器上面开启一个SQL thread定时检查Realy log,如果发现有更改立即把更改的内容在本机上面执行一遍。

如果一主多从的话,这时主库既要负责写又要负责为几个从库提供二进制日志。此时可以稍做调整,将二进制日志只给某一从,这一从再开启二进制日志并将自己的二进制日志再发给其它从。或者是干脆这个从不记录只负责将二进制日志转发给其它从,这样架构起来性能可能要好得多,而且数据之间的延时应该也稍微要好一些。

复制过程

1、Slave上面的IO进程连接上Master,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容。

2、Master接收到来自Slave的IO进程的请求后,负责复制的IO进程会根据请求信息读取日志指定位置之后的日志信息,返回给Slave的IO进程。返回信息中除了日志所包含的信息之外,还包括本次返回的信息已经到Master端的bin-log文件的名称以及bin-log的位置。

3、Slave的IO进程接收到信息后,将接收到的日志内容依次添加到Slave端的relay-log文件的最末端,并将读取到的Master端的 bin-log的文件名和位置记录到master-info文件中,以便在下一次读取的时候能够清楚的告诉Master从何处开始读取日志。

4、Slave的SQL进程检测到relay-log中新增加了内容后,会马上解析relay-log的内容成为在Master端真实执行时候的那些可执行的内容,并在自身执行。

下面是博主配置主从的服务器列表:

节点系统环境IPMySQL主从关系
node3CentOS 7LNMP192.168.17.130
node4CentOS 7LNMP192.168.17.150主+从

主从配置

注:在主从配置之前需要确保两台MySQL需要同步的库状态一致。

主:

配置文件默认在/etc/my.cnf下。

在配置文件中新增配置:

[mysqld]
# 同一局域网内注意要唯一
server-id=1
# 开启二进制日志功能,名称可以随便取(关键)
log-bin=mysql-bin
# 二进制数据自动删除/过期天数设置,默认值为0,表示不自动删除
expire_logs_days = 7

补充:若需要选择性的复制某些数据库,可在下方根据自己的需求选择性的加参数设置:
binlog-do-db= 需要复制的数据库名,如果复制多个数据库,重复设置这个选项即可
binlog-ignore-db= 不需要复制的数据库名,如果不需要复制多个数据库,重复设置这个选项即可

此处并不推荐使用这两个设置需要同步与不同步的库,原因是binlog-do-db和binlog-ignore-db它们将语句写入了二进制日志. 意味着你不能使用二进制日志从备份恢复指定时间的数据;且过滤操作带来的负载都在主数据库服务器上,加重主数据库服务器负载。安全的操作则是在slave上配置过滤,来决定是否同步库或表。

修改配置后需要重启才能生效:

service mysql restart

重启之后进入MySQL:

mysql -uroot -p

在master数据库创建数据同步用户,授予用户slave REPLICATION SLAVE权限和REPLICATION CLIENT权限,用于在主从库之间同步数据。

CREATE USER 'slave'@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';

语句中的%代表所有服务器都可以使用这个用户,如果想指定特定的IP,将%改成IP即可。密码password请自定义

查看主MySQL的状态:

show master status;

主MySQL状态.png

记录下FilePosition的值,并且不进行其他操作以免引起Position的变化。

从:

在从my.cnf配置中新增:

[mysqld]
# 设置server_id,注意要唯一
server-id=2

# 开启二进制日志功能,以备Slave作为其它Slave的Master时使用(按需添加,添加后该节点将主从并存)
log-bin=mysql-slave-bin

# relay_log配置中继日志
relay_log=mysql-relay-bin

#作为从库时生效,中继日志relay_log可以自我修复
relay_log_recovery=1

#设置为只读(正常不需添加,若配置读写分离且从库只负责读的话可按需添加)
#read_only=1

补充:从库不复制部分库,根据需求可按需设置
replicate-do-db= 设定需要复制的数据库
replicate-ignore-db= 设定需要忽略的复制数据库
replicate-do-table= 设定需要复制的表
replicate-ignore-table= 设定需要忽略的复制表
replicate-wild-do-table=replication-do-table功能一样,但是可以使用通配符
replicate-wild-ignore-table=replication-ignore-table功能一样,但是可以加通配符

修改配置后需要重启才能生效:

service mysql restart

重启之后进入MySQL:

mysql -u root -p

# 配置主从复制项
change master to master_host='192.168.17.130', master_user='slave', master_password='password', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos=433, master_connect_retry=30;

参数说明:
master_host:Master的地址
master_port:Master的端口号
master_user:用于数据同步的用户
master_password:用于同步的用户的密码
master_log_file:指定 Slave 从哪个日志文件开始复制数据,即在上面提到的 File 字段的值
master_log_pos:从哪个 Position 开始读,即在上面提到的 Position 字段的值
master_connect_retry:如果连接失败,重试的时间间隔,单位是秒,默认是60秒

在从MySQL中查看主从同步状态:

show slave status \G;

查看主从同步状态.png

此时的Slave_IO_RunningSlave_SQL_Running都是No,因为我们还没有开启主从复制过程。

开启主从复制:

start slave;

再次查看同步状态:

show slave status \G;

再次查看主从状态.png

Slave_IO_RunningSlave_SQL_Running都是Yes说明主从复制已经开启。

遇到的问题

1、开启后Slave_IO_Running报No,查看日志发现错误如下:

[ERROR] Slave I/O: Fatal error: The slave I/O thread stops because master and slave have equal MySQL > server UUIDs; these UUIDs must be different for replication to work. Error_code: 1593

这是因为MySQL 5.6的复制引入了UUID的概念,各个复制结构中的server_uuid得保证不一样,但是直接复制数据库的data文件夹后server_uuid是相同的,可使用如下命令查看:

show variables like '%server_uuid%';

这时候我们找到data文件夹下的auto.cnf文件,修改里面的UUID值(改动一个数值即可),保证各个数据库的UUID不一样,然后再重启数据库

若不知道该文件位置,可使用以下命令查找该文件位置:

find / -name auto.cnf

2、创建主从关系时copy了同样的my.cnf文件,报错,如下:

Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids;

错误原因和server_uuid类似,server_id也得保证不一样才行,找到my.cnf配置文件中的server_id,修改从库的server_id保证和复制结构中的其他数据库不一样,再重启数据库即可

3、Slave_IO_Running报Connecting,可能有下面几种原因,请逐一排查解决:

  • 网络不通,检查IP端口
  • 密码不对,检查用于同步的用户名和密码
  • Pos不对,检查Master的Position
  • MySQL 8特有的密码规则问题引起,可将密码规则修改为:mysql_native_password,如下:
ALTER USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY 'password';

4、主从复制出现的1008错误,如下:

1008错误.png

其发生的原因可以是你在从数据库上将一个数据库删除了,你又在主数据库上将该数据库删除了,导致文件同步过来时,从数据库由于提前删除了该库,导致执行命令时找不到该库,命令执行失败,同步中断;又或是主库上建立了名为11的数据库,然后立马就删除了,导致从库并没有同步完成,然后再去执行log-bin文件中删除的操作时,找不到11的数据库,导致了同步中断。

其解决办法就是将log-bin文件的执行指针下移一个位置,命令如下:

mysql> stop slave;

#将binglog指针下移一个位置,若移动多位指针,可调后面的数值
mysql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;

mysql> start slave;
End

本文标题:MySQL主从复制

本文链接:https://www.isisy.com/1007.html

除非另有说明,本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

声明:转载请注明文章来源。

如果觉得我的文章对你有用,请随意赞赏