MySQL 主从同步 ,即一个 MySQL 服务都是 Master,另一个MySQL服务的 Slave。

一、准备

服务器

MySQL 服务器 IP 地址
master 192.168.1.201
slave 192.168.1.202

注:操作过程中注意两边数据的一致!!!

二、具体操作

1、master 配置

修改my.cnf文件

vim /evc/my.cnf

配置如下属性

[mysqld]  
  
# 服务器唯一标识  
  
server-id=1  
  
# 二进制日志文件名  
  
log-bin=mysql-bin  
  
# 需要备份的数据库,多个数据库用 , 分隔  
  
binlog-do-db=piumnl  
  
# 需要复制的数据库,多个数据库用 , 分隔  
  
replicate-do-db=piumnl  
  
# 中继日志文件名  
  
relay_log=mysqld-relay-bin  
  
# 互为主从需要加入这一行  
  
log-slave-updates=ON  
  
# 禁用符号链接,防止安全风险,可不加  
  
symbolic-links=0  
  
# 可不加  
  
# resolve - [Warning] Slave SQL: If a crash  
# happens this configuration does not guarantee that the relay log info will be  
# consistent, Error_code: 0  
  
master-info-repository=table  
  
relay-log-info-repository=table  
  
relay-log-recovery=1  
  
  
# 可不加  
  
# 禁用 dns 解析,会使授权时使用的域名无效  
  
skip-host-cache  
  
skip-name-resolve  
  
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

2、slave 配置

修改my.cnf文件

vim /evc/my.cnf

配置如下属性

# 不再解释各个配置项  
[mysqld]  
server-id=2  
log-bin=mysql-bin  
    
binlog-do-db=piumnl  
replicate-do-db=piumnl  
relay_log=mysql-relay-bin  
log-slave-updates=ON  
symbolic-links=0  
    
# resolve - [Warning] Slave SQL: If a crash happens this configuration does not  
# guarantee that the relay log info will be consistent, Error_code: 0  
    
master-info-repository=table  
relay-log-info-repository=table  
relay-log-recovery=1  
    
skip-host-cache  
skip-name-resolve  
    
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

3、创建同步用户

slave创建同步用户:

create user 'rep'@'%' identified by 'rep';    # 创建一个账户  
  
grant replication slave on *.* to 'rep'@'%';  # 授予该账户对任意数据库任意表的主从同步权限

grant all on *.* to 'rep'@'%';  #给新创建的用户赋予操作数据库的权限
备注:

Linux 下 MySQL 对 root@% 关闭了 grant_priv 权限

此处备份用户帐号和密码可不一致,此处为了简化操作使用一样的帐号和密码

注:如果想做双向同步则每个MySQL服务器都要创建用户

4、重启服务器

service mysql restart

5、开启同步

查看 master 状态

show master status\G;
或
show master status;

注意:此处需要关注 File 和 Position 值

操作slave

stop slave; 

change master to master_host='master_hostname', master_user='rep_username', master_password='rep_password', master_log_file='mysql-log.000003', master_log_pos=154,get_master_public_key=master_server-id;  

start slave;
master_hostname:master的IP地址
rep_username:刚刚注册新用户的用户名
rep_password:刚刚注册新用户的密码
master_log_file:就是第一步操作的 File 值  
master_log_pos:就是第一步操作的 Position 值  
master_server-id:master的my.cnf文件中的server-id

注:如果MySQL服务器的版本为8,则在加入最后一个属性即可

6、查看结果

show slave status\G;

查看最重要的两项,两个都必须为 Yes ,有一个为 No 都要去查看错误日志文件,看看什么地方存在问题

Slave_IO_Running: Yes  
 Slave_SQL_Running: Yes

注:如果要做成双向同步则上述操作在两个MySQL服务器中都要进行

7、测试

在 master中插入数据,并在slave使用新注册的用户查看是否及时出现预期的数据

三、常见错误及解决方法

1、如果操作弄乱了 master 与 slave 的日志,可使用如下操作进行重置。

reset master; # 重置 master 的配置,包括二进制日志  

reset slave; # 重置 slave 的配置

2、出现Slave_IO_Running:No问题

原因

两台主从数据库的uuid相同了(没猜错的话,各位应该是直接克隆了linux服务器,然后配置主从数据库,一通操作,到最后启动从数据库,发现的这个问题吧)。

网络问题

my.cnf配置问题

权限问题

(1)UUID解决

使用一下命令查询UUID所在文件的位置

find / -iname "auto.cnf"

删除该文件

rm 要删除的文件名

重启MySQL服务

service mysql restart

(2)网络问题解决

虚拟机下的Linux系统选用的网络适配器是选择的nat共享主机ip的,也就是说主机与从机其实是不在同一个局域网中的,所以自然无法连接上。

选择桥接模式,这个模式就是会拥有一个同一局域网下的ip地址,重新进入之后,在进行测试

网络问题还有一种可能是没有关闭防火墙,其他主机无法连接MySQL服务器,这是采用以下命令去关闭防火墙即可。

systemctl stop firewald.service //关闭防火墙
systemctl disable firewald.service //永久关闭防火墙
systemctl list-unit-files |grep fire  //查看防火墙状态

(3)my.cnf文件配置问题解决

参考具体操作中的master配置和slave配置,修改自己的配置问题

(4)权限问题解决

创建的新用户replication slave和file权限是必须要赋予的,如果仅仅是自己使用或测试可以赋予all权限

3、出现Slave_IO_Running: Connecting问题

原因及解决方法与Slave_IO_Running:No问题基本相同

还有之中可能即为:由于每次数据库重启后都会导致master status发生变化,所以需要根据当前的master status来修改从数据库中的SQL同步语句

4、出现Slave_SQL_Running: No问题

原因

程序在slave上进行了写操作

slave机器重起后,事务回滚造成的.

事务回滚的解决方法

mysql> stop slave ;
mysql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;//将这个全局变量赋值为1
mysql> start slave ;