vlambda博客
学习文章列表

MYSQL主从同步搭建

背景

我们知道,为了保障数据库的高可用,往往需要搭建mysql主备、主从等架构。其中主从可以保证数据库实时同步数据到从库,这样即使我们主库宕机,也可以通过主从切换为从主,来保证我们业务正常访问。所以,趁着有闲置的服务器,研究了下主从结构并搭建了一下。一般主从会搭配读写分离来弄,主库写,从库读。

一、主从原理

Mysql主从主要涉及到三个线程,一个运行在主节点(binlog dump thread)和两个运行在从节点(I/O thread,SQL thread)。图示如下

主节点 binlog dump线程

  1. 该线程运行在主节点上,有多少个从节点连接到主节点,就会创建多少个该线程。

  2. 当对数据库进行insert、update、delete等DML操作时,如果主库开启了binlog日志,会生成binlog文件。

  3. binlog dump线程会将binlog发生变更的内容通知到从节点的I/O 线程。

从节点I/O线程

 负责连接主库的binlog dump线程,并读取最新更改的内容,在本地目录生成一份relay log日志

从节点SQL线程

 负责读取本地生成的relay log日志文件,并将变更的内容同步到从库中。

所以,当我们的relay log日志很大,SQL线程来不及全部读完变更的内容并同步到从库中时,就会造成主从延迟。

二、主从搭建

现在开始进入我们的主题—主从搭建。这里省去mysql的安装等流程,并演示简单的一主一从。我的mysql环境是部署在centos7.6,mysql版本是5.7.17

主节点配置

--修改mysql的配置
[root@VM-0-9-centos mysql]# vim /etc/my.cnf

这里贴出我的配置

[mysqld]
sql_mode=NO_ZERO_IN_DATE,NO_ZERO_DATE,STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,NO_AUTO_CREATE_USER,ERROR_FOR_DIVISION_BY_ZERO
max_allowed_packet = 1073741824

#主库和从库这里的server_id要配置不一样,随意即可
server_id=101
#开启binlog日志,否则不能实时同步
log_bin=mysql-bin
#有statement、row和mix三种模式,选择row吧
binlog_format=ROW

#binlog保存路径
log-bin=/usr/local/mysql/logs/mysql-bin.log
#binlog保存天数
expire-logs-days=5
max-binlog-size=300M
#设置字符编码utf8mb4,防止特殊字符不能保存
character-set-server=utf8mb4
#设置排序规则
collation-server = utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'
skip-character-set-client-handshake = true
#设置mysql的数据保存路径
datadir=/data/mysql

#配置需要同步的数据库,我这里是shy_dep
binlog-do-db=shy_dep

[mysql]
default-character-set = utf8mb4

其中,主要设置:

server_id、log_bin、binlog_format、binlog-do-db几个关键的配置,其他根据自己需求来。

设置完成后,重启mysql

[root@VM-0-9-centos mysql]# service mysql restart

通过navicat客户端查看mysql是否开启binlog日志

show VARIABLES like 'log%'

MYSQL主从同步搭建

--查看主库状态
show master status;

MYSQL主从同步搭建

这里要记下File和Position的值,后面从库连接的时候需要用到。

从节点配置

从库不需要开启binlog日志。

--修改mysql的配置
vim /etc/my.cnf

贴上我的配置

[mysqld]
sql_mode=NO_ZERO_IN_DATE,NO_ZERO_DATE,STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,NO_AUTO_CREATE_USER,ERROR_FOR_DIVISION_BY_ZERO
max_allowed_packet = 1073741824

#设置下server_id即可,注意不要和主库一样,以便区分
server_id=102

然后重启从库mysql

接着在navicat客户端连接从库并执行命令,用于和主库的binlog dump线程连接

#注意master_log_file和master_log_pos为从上面执行show master status查看到的值
CHANGE MASTER TO master_host = '192.168.13.16',
MASTER_PORT = 3306,
master_user = 'root',
master_password = 'root',
master_log_file = 'mysql-bin.000001',
master_log_pos = 230863;
#开启从库同步线程
start SLAVE;
#查看从库同步状态
show slave status;

当从库中看到上面两个Yes,表示主从搭建成功。

这时候,当你在主库对表进行增删改操作,变更的记录都会实时同步到从库。

三、遇到的问题

  • 在执行 show slave status 查看从库同步状态时,发现Slave_IO_Runnning为No,而Slave_SQL_Running为Yes.

      查看mysql错误日志,发现报错:[ERROR] Slave I/O for channel '': , Error_code: 1593

原因:由于我的从库虚拟机是从主库的虚拟机镜像过来的,导致从库mysql中配置的data目录下的auto.cnf配置文件中server-uuid是一样的,从而导致这个问题

解决:可以通过navicat主库和从库分别执行

show variables like '%server_uuid%'

如果两者一样,则修改主库或者从库的server-uuid不同即可。

#auto.cnf在mysql配置的data目录下
[root@VM_0_6_centos mysql]# vim auto.cnf
[auto]
server-uuid=27e1dddd-c3sd36-11edf98e9-525df0059e18

当修改好以后,重启mysql数据库,再重新在从库执行以下命令

stop SLAVE;

CHANGE MASTER TO master_host = '192.168.13.16',
MASTER_PORT = 3306,
master_user = 'root',
master_password = 'root',
master_log_file = 'mysql-bin.000001',
master_log_pos = 230863;

start SLAVE;

show slave status;

当看到从库的I/O线程和SQL线程都为Yes,表明成功。

另外要注意的是,主从的server_id也要不一样,可以通过下面命令查看。

show variables like '%server_id%';
  • 主从数据同步问题

发现当数据库不存在或者表不存在,貌似不能进行同步。需要在第一次全量同步完成后,主库才能增量更新同步到从库中。

总结

好了~,以上就是我搭建一主一从遇到的一些坑,以及自己的一些拙见。主从切换,主备,一主多从,多主多从,读写分离,请听下回分解。