一、基本知识
为什么要使用主从同步?若是你的项目只有一个数据库,一旦数据库宕机,导致业务停顿就会产生很大的危害,就会出现单点问题。为了让系统高可用,避免单点问题就可以使用主从方式,采用一主多从的方法,主从之间进行数据同步。
单点问题:系统中出现一点失效,就会让整个系统无法运作部件。单点故障会造成整体故障。
实际举例:负载均衡描述:例如来了10000个请求,其中有1000个写请求,有9000个读请求,将写请求分配到主服务器进行写操作,将其他9000个读请求均衡分布给多个从服务器进行读。
扩展:主从方式另一个目的是进行读写分离,让主服务器数据库进行更新操作即写,查询操作交由从服务器数据库进行!
1.1、什么是主从同步?
主:master
从:slave
解释:一台服务器充当主服务器,一条及以上服务器充当从服务器。主数据库的数据会自动复制到从服务器中(一旦主机有更新操作,从机就能够立马感知,并且从主机上将数据复制下来 )。
针对于多级复制,服务器既可充当主服务器也可充当从服务器。
主从复制的基础就是主服务器对数据进行修改记录二进制文件,从服务器根据主服务器的二进制文件来进行同步更新操作。
好处:帮助备份数据,读写分离。分布式中多主多从。数据库服务器可以互为主从。
1.2、原理分析
过程描述:master服务器会将执行的操作记录到binlog日志中,slave服务器通过配置主服务器的登陆账户,binlog的指定位置之后通过一个I/O线程连接到master服务器,将获取到的binlog日志存储到自己relay log日志中,接着会有一个sql线程去检查relay log日志是否变化,若是变化就进行更新操作,完成同步!
简略步骤:
Master数据库只要发生变化,就会立即记录到Binary log日志文件中。
Slave数据库启动一个I/O thread连接到Master数据库,请求Master变化的二进制文件(binlog)。
Slave I/O线程获取到的二进制日志会保存到自己的relay log日志里。
Slave 有一个SQL线程会定时检查Relay log是否发生变化,若是变化就更新数据。
1.3、MySQL配置主从的特点
1、实现服务器负载均衡:通过在主服务器和从服务器之间切分处理客户查询的负荷,从而得到更好的客户相应时间。一般有两种思路:
第一种思路就是主服务器只会进行更新操作,对于查询操作都会交由从服务器执行(设置多台从服务器),这种是针对于查多改少。
第二种思路就是主服务器上与从服务器切分查询,主服务器不仅要完成更新操作还附带一些查询工作,对于从服务器只用来查询,一旦主服务器比较忙时,部分查询会自动发送到从服务器中,减轻主服务器的负荷。
2、通过复制实现数据的异地备份:主要是用来进行备份数据操作,避免服务器出现损坏等恶意破坏问题。
3、提高数据库系统的可用性:一旦主服务器发生故障,可以让从服务器来充当主服务器继续进行工作,像许多银行系统升级,在升级过程中只能查询不能取钱就是一样的道理。
二、实操
环境背景
虚拟机中两个Centos 7.8系统,数据库版本为5.7.32。
前提准备
一般模拟测试是在虚拟机上使用两个mysql进行主从复制demo试验的。
下面是我准备的主从服务器,分别装有一个mysql:
克隆了一个虚拟机来进行测试!
Navicat也准备就绪:
两个服务器的mysql账号信息如下:shell登陆统一用户名为root,密码是123456
主:192.168.181.129:3306 数据库账号:cl 123456 权限账户(分配给从服务器登陆):repl ro*ot1%23&45 从:192.168.181.131:3306 数据库账号:root 123456
主从同步思路
主服务器需要配置一个二进制日志bin log,启动它。开放一个用户账号给从服务器,该用户有主从同步的权限
从服务器要订阅这个bin log日志(通过主服务器开放的一个账号来去订阅),并且开启relay log日志
1、主从服务器进行配置
主服务器
主服务器配置:/etc/my.cnf中添加即可
#mysql master1 config # [mysqld] # 若是配置文件中有就不带 server-id = 1 # 节点ID,确保唯一,用来区分服务器的编号 # log config log-bin = master-bin #开启mysql的binlog日志功能(就会创建二进制文件) sync_binlog = 1 #控制数据库的binlog刷到磁盘上去 , 0 不控制,性能最好,1每次 事物提交都会刷到日志文件中,性能最差,最安全 binlog_format = mixed #binlog日志格式,mysql默认采用statement,建议使用mixed expire_logs_days = 7 #binlog过期清理时间 max_binlog_size = 100m #binlog每个日志文件大小 binlog_cache_size = 4m #binlog缓存大小 max_binlog_cache_size= 512m #最大binlog缓存大 binlog-ignore-db=mysql #不生成日志文件的数据库,多个忽略数据库可以用逗号拼接,或者 复制 这句话,写多行 auto-increment-offset = 1 # 自增值的偏移量 auto-increment-increment = 1 # 自增值的自增量 slave-skip-errors = all #跳过从库错误
重要的就是3、5行的内容,一个是对服务器进行编号,另一个是开启binlog日志。其他的就是辅助配置,不配置也会有默认值。
重启mysql服务器:systemctl restart mysqld
查看master配置信息(需进入mysql命令行):show master status,获取到binlog文件名称以及偏移量,之后从服务器配置应当按照主服务器来,这样才能找到binlog位置。
从服务器配置
从服务器配置:依旧是在/etc/my.cnf中添加即可
配置信息如下:
# [mysqld] server-id=2 log-bin=mysql-bin relay-log=mysql-relay-bin # 忽略复制的文件,这几个数据库不需要进行同步 replicate-wild-ignore-table=mysql.% replicate-wild-ignore-table=test.% replicate-wild-ignore-table=information_schema.%
对于从重要的就是第2、4行,第一个是服务器编号,第二个是开启relay log日志(中继日志)。
同样配置好之后,重启mysql的服务!
2、主服务器创建用户账号(用于从服务器订阅)
主服务器提供一个用户账号用来进行主从同步的:主要需要规范的就是主机地址以及服务器权限选择复制从
repl -- 用户名 ro*ot1%23&45 -- 密码
账号权限设置为复制从:
若是显示密码弱,可以修改一下密码设置策略再进行修改。
接着我们来尝试在从服务器上进行登陆该账号进行测试:
3、配置从库信息(从服务器数据库)
查看一下主服务器中的master的状态:show master status
获取到其中的两个关键参数,File(文件名)以及position(偏移量)
进入到从服务器中的mysql命令行下进行下面配置:即用于登陆订阅主服务器的账号信息以及binlog文件名、偏移量
mysql> CHANGE MASTER TO MASTER_HOST = '192.168.181.129', MASTER_USER = 'repl', MASTER_PASSWORD = 'ro*ot1%23&45', MASTER_PORT = 3306, MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=663, MASTER_RETRY_COUNT = 60, MASTER_HEARTBEAT_PERIOD = 10000;
注释信息(对配置内容进行说明):
MASTER_HOST = '192.168.181.129', # 目标服务器(即主服务器)的主机地址 MASTER_USER = 'repl', # 登陆主服务器的用户名 MASTER_PASSWORD = 'ro*ot1%23&45', # 登陆主服务器的密码 MASTER_PORT = 3306, # 主服务器开放mysql的端口 # 下面两个是在主服务器中查询到的,使用show master status查询 MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=663, # MASTER_LOG_FILE='mysql-bin.000005',#与主库File 保持一致 # MASTER_LOG_POS=120 , #与主库Position 保持一致 # 额外配置信息 MASTER_RETRY_COUNT = 60, MASTER_HEARTBEAT_PERIOD = 10000;
依旧是在mysql命令行使用命令开启从服务器,并且可以查看一下状态:
start slave; # 开启从服务器(服从) # 关闭从服务器 stop slave show slave status; # 查看从服务器的状态
若是下面两个部分都是yes表示主从同步已经成功开启!
额外说明:若是slave_io_running为no的话最好去看一下Last_IO_Error提示的错误信息。
主从同步效果演示
创建数据库同步:
创建数据库表:
新增表记录:
主从小注意点
1、若是start slave失败了,可以重置一下使用命令reset slave。
2、保持主从同步,需要确定你的主服务器与你的从服务器binlog日志文件名是否相同以及偏移量是否一致。查看主服务器的master信息使用命令show master status。查看从服务器的slave信息使用命令show slave status;若是出现不一致情况,最好就是重新对从服务器数据库重新配置一下,流程:关闭-修改-启动,查看状态是否启动成功!
3、主服务器创建test数据库,从服务器不会进行同步。
问题:show slave status时从服务器的slave_IO_running为no
分析问题
Slave_IO_Running为No,若是主从服务正确开启应该是yes
如何查看错误信息呢?可以看其中的Last_IO_Error信息
错误1:slave failed to initalize relay log info structure
可以去查看一下从服务器中的mysql的日志文件夹:/var/lib/mysql
该图是正确的没有多余的情况,仅作演示。
原因描述:确保中继日志是我们配置的,避免重复的情况,也许是之前配的。
解决方案:将相关的relay-bin文件直接删除,重新配置从服务器。接着重新start slave;,继续查看状态。
若是还是不行,需要你执行reset slave;重置从库。
错误2: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.
问题分析:我们在虚拟机中创建的第二个linux系统实际上是进行克隆的,他们的server uuid是相同的,修改任意一个即可。
解决方案:
查看auto.cnf配置文件中的server-uuid:vim /var/lib/mysql/auto.cnf,可以发现两个服务器的uuid是一致的。
我们自己生成一个uuid,对从服务器的配置文件进行修改即可。
接着重启mysql服务!重新查看状态即可解决。
错误3:MySQL Master command COM_REGISTER_SLAVE failed: Access denied for user
参考文章:MySQL Master command COM_REGISTER_SLAVE failed: Access denied for user
问题描述:
****
解决方案:
查看一下指定账户的权限:show grants for repl@'192.168.181.131'
通过xshell或者navicat来进行修改权限:GRANT REPLICATION SLAVE ON *.* TO repl@'192.168.181.131' identified by 'ro*ot1%23&45';。
刷新权限:FLUSH PRIVILEGES;