MYSQL主从同步搭建
背景
我们知道,为了保障数据库的高可用,往往需要搭建mysql主备、主从等架构。其中主从可以保证数据库实时同步数据到从库,这样即使我们主库宕机,也可以通过主从切换为从主,来保证我们业务正常访问。所以,趁着有闲置的服务器,研究了下主从结构并搭建了一下。一般主从会搭配读写分离来弄,主库写,从库读。
一、主从原理
Mysql主从主要涉及到三个线程,一个运行在主节点(binlog dump thread)和两个运行在从节点(I/O thread,SQL thread)。图示如下
主节点 binlog dump线程
该线程运行在主节点上,有多少个从节点连接到主节点,就会创建多少个该线程。
当对数据库进行insert、update、delete等DML操作时,如果主库开启了binlog日志,会生成binlog文件。
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%'
--查看主库状态
show master status;
这里要记下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%';
主从数据同步问题
发现当数据库不存在或者表不存在,貌似不能进行同步。需要在第一次全量同步完成后,主库才能增量更新同步到从库中。
总结
好了~,以上就是我搭建一主一从遇到的一些坑,以及自己的一些拙见。主从切换,主备,一主多从,多主多从,读写分离,请听下回分解。