MySQL实战 主从同步(原理+实战)

举报
长路 发表于 2022/11/23 00:16:01 2022/11/23
【摘要】 文章目录前言一、基本知识1.1、什么是主从同步?1.2、原理分析1.3、MySQL配置主从的特点二、实操环境背景前提准备主从同步思路1、主从服务器进行配置2、主服务器创建用户账号(用于从服务器订阅)3、配置从库信息(从服务器数据库)主从同步效果演示主从小注意点问题:show slave status时从服务器的slave_IO_running为no分析问题错误1:slave failed to i

@[toc]

前言

本篇博客是MySQL的学习笔记,若文章中出现相关问题,请指出!

所有博客文件目录索引:博客目录索引(持续更新)

一、基本知识

为什么要使用主从同步?若是你的项目只有一个数据库,一旦数据库宕机,导致业务停顿就会产生很大的危害,就会出现单点问题。为了让系统高可用,避免单点问题就可以使用主从方式,采用一主多从的方法,主从之间进行数据同步。

  • 单点问题:系统中出现一点失效,就会让整个系统无法运作部件。单点故障会造成整体故障。
  • 实际举例:负载均衡描述:例如来了10000个请求,其中有1000个写请求,有9000个读请求,将写请求分配到主服务器进行写操作,将其他9000个读请求均衡分布给多个从服务器进行读。

扩展:主从方式另一个目的是进行读写分离,让主服务器数据库进行更新操作即写,查询操作交由从服务器数据库进行!



1.1、什么是主从同步?

主:master

从:slave

解释:一台服务器充当主服务器,一条及以上服务器充当从服务器。主数据库的数据会自动复制到从服务器中(一旦主机有更新操作,从机就能够立马感知,并且从主机上将数据复制下来 )。

针对于多级复制,服务器既可充当主服务器也可充当从服务器。

主从复制的基础就是主服务器对数据进行修改记录二进制文件,从服务器根据主服务器的二进制文件来进行同步更新操作。

好处:帮助备份数据,读写分离。分布式中多主多从。数据库服务器可以互为主从。



1.2、原理分析

image-20210507141318227

过程描述:master服务器会将执行的操作记录到binlog日志中,slave服务器通过配置主服务器的登陆账户,binlog的指定位置之后通过一个I/O线程连接到master服务器,将获取到的binlog日志存储到自己relay log日志中,接着会有一个sql线程去检查relay log日志是否变化,若是变化就进行更新操作,完成同步!

简略步骤

  1. Master数据库只要发生变化,就会立即记录到Binary log日志文件中。
  2. Slave数据库启动一个I/O thread连接到Master数据库,请求Master变化的二进制文件(binlog)。
  3. Slave I/O线程获取到的二进制日志会保存到自己的relay log日志里。
  4. Slave 有一个SQL线程会定时检查Relay log是否发生变化,若是变化就更新数据。


1.3、MySQL配置主从的特点

1、实现服务器负载均衡:通过在主服务器和从服务器之间切分处理客户查询的负荷,从而得到更好的客户相应时间。一般有两种思路:

  • 第一种思路就是主服务器只会进行更新操作,对于查询操作都会交由从服务器执行(设置多台从服务器),这种是针对于查多改少。
  • 第二种思路就是主服务器上与从服务器切分查询,主服务器不仅要完成更新操作还附带一些查询工作,对于从服务器只用来查询,一旦主服务器比较忙时,部分查询会自动发送到从服务器中,减轻主服务器的负荷。

2、通过复制实现数据的异地备份:主要是用来进行备份数据操作,避免服务器出现损坏等恶意破坏问题。

3、提高数据库系统的可用性:一旦主服务器发生故障,可以让从服务器来充当主服务器继续进行工作,像许多银行系统升级,在升级过程中只能查询不能取钱就是一样的道理。



二、实操

环境背景

虚拟机中两个Centos 7.8系统,数据库版本为5.7.32



前提准备

一般模拟测试是在虚拟机上使用两个mysql进行主从复制demo试验的。

下面是我准备的主从服务器,分别装有一个mysql:

image-20210506211111373

  • 克隆了一个虚拟机来进行测试!

Navicat也准备就绪:

image-20210506211210307

两个服务器的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、主服务器创建用户账号(用于从服务器订阅)

主服务器提供一个用户账号用来进行主从同步的:主要需要规范的就是主机地址以及服务器权限选择复制从

image-20210507091017412

repl  -- 用户名
ro*ot1%23&45  -- 密码

账号权限设置为复制从:

image-20210507091048623

若是显示密码弱,可以修改一下密码设置策略再进行修改。

接着我们来尝试在从服务器上进行登陆该账号进行测试:

image-20210507092018496



3、配置从库信息(从服务器数据库)

查看一下主服务器中的master的状态:show master status

image-20210507092605415

  • 获取到其中的两个关键参数,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; 
  • image-20210507093448328

注释信息(对配置内容进行说明):

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表示主从同步已经成功开启!

image-20210507103213842

额外说明:若是slave_io_running为no的话最好去看一下Last_IO_Error提示的错误信息。



主从同步效果演示

创建数据库同步

GIF

创建数据库表

GIF

新增表记录

GIF


主从小注意点

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

image-20210507094020020

如何查看错误信息呢?可以看其中的Last_IO_Error信息

image-20210507094431311



错误1:slave failed to initalize relay log info structure

image-20210507094505415

可以去查看一下从服务器中的mysql的日志文件夹:/var/lib/mysql

image-20210507095123711

  • 该图是正确的没有多余的情况,仅作演示。

原因描述:确保中继日志是我们配置的,避免重复的情况,也许是之前配的。

解决方案:将相关的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是相同的,修改任意一个即可。

image-20210507094020020

解决方案

查看auto.cnf配置文件中的server-uuid:vim /var/lib/mysql/auto.cnf,可以发现两个服务器的uuid是一致的。

image-20210507101125322

我们自己生成一个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

问题描述

image-20210507103115748****

解决方案

查看一下指定账户的权限:show grants for repl@'192.168.181.131'

image-20210507102548500

通过xshell或者navicat来进行修改权限:GRANT REPLICATION SLAVE ON *.* TO repl@'192.168.181.131' identified by 'ro*ot1%23&45';

刷新权限:FLUSH PRIVILEGES;

image-20210507102911307

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。