小白都能懂的Mysql主从复制原理

前一篇的Mysql面试仍是很是给力的,很是的干货,有兴趣的能够看一下[],虽然不是我写的,可是内容确实是很是的干货,4万字解决你Mysql面试中存在的问题,好的文章仍是要推荐给你们。node

讲完了单机版的Mysql问题,来讲一说集群,这不写了一篇Mysql主从的搭建,注意片主要讲主从的原理,以及本身实践搭建主从,对于尚未接触主从的程序员,仍是很是友好的,文章内容通俗易懂。mysql

主从复制简介

在实际的上产中,为了解决Mysql的单点故障已经提升MySQL的总体服务性能,通常都会采用主从复制程序员

好比:在复杂的业务系统中,有一句sql执行后致使锁表,而且这条sql的的执行时间有比较长,那么此sql执行的期间致使服务不可用,这样就会严重影响用户的体验度。web

主从复制中分为主服务器(master)从服务器(slave)主服务器负责写,而从服务器负责读,Mysql的主从复制的过程是一个异步的过程面试

这样读写分离的过程可以是总体的服务性能提升,即便写操做时间比较长,也不影响读操做的进行。sql

主从复制的原理

首先放一张Mysql主从复制的原理图,总的来讲Mysql的主从复制原理仍是比较好理解的,原理很是的简单。 Mysql的主从复制中主要有三个线程:master(binlog dump thread)、slave(I/O thread 、SQL thread),Master一条线程和Slave中的两条线程。数据库

master(binlog dump thread)主要负责Master库中有数据更新的时候,会按照binlog格式,将更新的事件类型写入到主库的binlog文件中。centos

而且,Master会建立log dump线程通知Slave主库中存在数据更新,这就是为何主库的binlog日志必定要开启的缘由。服务器

I/O thread线程在Slave中建立,该线程用于请求Master,Master会返回binlog的名称以及当前数据更新的位置、binlog文件位置的副本。并发

而后,将binlog保存在 relay log(中继日志) 中,中继日志也是记录数据更新的信息。

SQL线程也是在Slave中建立的,当Slave检测到中继日志有更新,就会将跟新的内容同步到Slave数据库中,这样就保证了主从的数据的同步。

以上就是主从复制的过程,固然,主从复制的过程有不一样的策略方式进行数据的同步,主要包含如下几种:

  1. 同步策略:Master会等待全部的Slave都回应后才会提交,这个主从的同步的性能会严重的影响。
  2. 半同步策略:Master至少会等待一个Slave回应后提交。
  3. 异步策略:Master不用等待Slave回应就能够提交。
  4. 延迟策略:Slave要落后于Master指定的时间。

对于不一样的业务需求,有不一样的策略方案,可是通常都会采用最终一致性,不会要求强一致性,毕竟强一致性会严重影响性能。

主从搭建

下面咱们就来实操搭建主从,使用的是两台centos7而且安装的是Mysql 8来搭建主从,有一台centos 7而后直接克隆就好了。

安装Mysql 8数据库

(1)首先检查centos 7里面的Mysql安装包和依赖包:

rpm -qa |grep mysql
复制代码

执行后,在我本机上的显示以下: (2)接着能够删除上面的安装包和依赖包:

sudo yum remove mysql*
复制代码

(3)继续检查一下是否存在Mariadb,如果存在直接删除Mariadb

// 检查是否存在Mariadb
rpm -qa |grep mariadb // 删除Mariadb sudo rpm -e --nodeps mariadb-libs-5.5.56-2.el7.x86_64 复制代码

(4)而后,就是删除Mysql的配置文件,可使用下面的命令查找Msqyl配置文件的路径:

sudo find / -name mysql
复制代码

在我本机上的显示的Mysql配置文件的路径以下:

(5)而后,经过下面的命令,将他们逐一删除:

sudo rm -rf /usr/lib64/mysql
...... 复制代码

(6)接着就开始安装Mysql 8了,使用wget命令下载Mysql 8的repo源,而且执行安装:

wget https://repo.mysql.com//mysql80-community-release-el7-3.noarch.rpm
sudo yum -y install mysql80-community-release-el7-3.noarch.rpm 复制代码

安装完后会在/etc/yum.repos.d/目录下生成下面的两个文件,说明安装成功了:

mysql-community.repo
mysql-community-source.repo 复制代码

(7)安装完Mysql8后,接着来更新一下yum源,而且查看yum仓库中的Mysql:

// 更新yum源
yum clean all yum makecache // 查看yum仓库中的Mysql yum list | grep mysql 复制代码

(8)能够查看到仓库中存在mysql-community-server.x86_64,直接安装就好了:

sudo yum -y install mysql-community-server
复制代码

(9)接着启动Mysql,并检查Mysql的状态:

// 启动Mysql
systemctl start mysqld.service // 检查Mysql的状态 systemctl status mysqld 复制代码

确保查看Mysql的状态是active(running),表示正在运行,而且配置一下Mysql开机启动:

systemctl enable mysqld
复制代码

(10)由于Mysql是新安装的,因此要修改一下初始密码,先查看一下初始密码:

grep "password" /var/log/mysqld.log
复制代码

你可能找出来有多个,多是你以前安装卸载后的文件没有删干净,这里你就直接看时间,时间对应你如今的时间,就是你的初始密码: (11)而后使用初始密码,登录数据库,而且修改密码:

mysql -uroot -p
ALTER USER 'root'@'localhost' IDENTIFIED BY 'LDCldc@123095; 复制代码

(12)此时在建立一个能够用于给两一台centos链接的用户,默认的root用户只有本机才能链接:

// 建立链接用户
create user 'test'@'%' identified by 'LDCldc-2020'; // 而且把防火墙给关了,或者配置一下3306端口 systemctl stop firewalld.service; // 设置防火墙开机自动关闭 systemctl disable firewalld.service; 复制代码

(13)测试:到这里就Mysql的安装教程就就讲完了,能够测试一下,两台centos是否能够ping通:

ping 192.168.163.156
复制代码

我这里的两台机是能够互通的,Master:192.168.163.156,Slave:192.168.163.155,而且Slave使用下面的命令能够登录到Master的Mysql:

mysql -u[user] -p[密码] -h[远程主机ip]
复制代码

确保了这两项测试成功后,就能够进行下面的主从搭建了。

配置主库

(14)我这里使用的使用两台centos 7的vmware的ip分别是192.168.163.155(Slave)192.168.163.156(Master)做为测试,首先在192.168.163.156(Master)中建立一个测试库test:

// 建立测试库
create database test default character set utf8mb4 collate utf8mb4_general_ci; // 而且受权 grant all privileges on test.* to 'test'@'%'; 复制代码

(15)而后编辑Master中的my.cnf文件,此文件位于/etc/my.cnf,执行下面的sql,并添加下面的信息:

sudo vi /etc/my.cnf
 ==========如下是配置文件中的信息============= # 配置编码为utf8 character_set_server=utf8mb4 init_connect='SET NAMES utf8mb4'  # 配置要给Slave同步的数据库 binlog-do-db=test # 不用给Slave同步的数据库,通常是Mysql自带的数据库就不用给Slave同步了 binlog-ignore-db=mysql binlog-ignore-db=information_schema binlog-ignore-db=performance_schema binlog-ignore-db=sys # 自动清理30天前的log文件 expire_logs_days=30 # 启用二进制日志 log-bin=mysql-bin # Master的id,这个要惟一,惟一是值,在主从中惟一 server-id=3 复制代码

(16)配置完后重启Mysql服务,并查看Mysql的log_bin日志是否启动成功:

systemctl restart mysqld
# 查看log_bin日志是否启动成功 show variables like '%log_bin%'; 复制代码

(17)接着查看Master的状态:

show master status;
复制代码

这两个数据FilePosition要记住,后面配置Slave的时候要使用到这两个数据。

(18)最后登录Master的数据库,并建立一个用户用于同步数据:

create user 'backup'@'%' IDENTIFIED BY 'Purepgmr-2020';
grant file on *.* to 'backup'@'%'; GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* to 'backup'@'%'; 复制代码

到这里Master的配置就配置完了,后面就进行Slave的配置。

配置从库

(19)在Slave中一样要建立test数据库,而且受权给test用户:

# 建立同步数据的test数据库
create database test default character set utf8mb4 collate utf8mb4_general_ci; # 受权 grant all privileges on test.* to 'test'@'%'; 复制代码

(20)接着编辑Slave中my.cnf文件,一样是在/etc/my.cnf路径下,加入以下配置:

# 配置从服务器的ID,惟一的
server-id=4 #加上如下参数能够避免更新不及时,SLAVE 重启后致使的主从复制出错。 read_only = 1 master_info_repository=TABLE relay_log_info_repository=TABLE 复制代码

(21)而且重启Slave中的Mysql服务:

systemctl restart mysqld
复制代码

(22)在Slave中添加Master的信息:

# master_host是Master的ip,master_log_file和master_log_pos就是配置以前查看Master状态时显示的File和Position信息
change master to master_host='192.168.163.156',master_port=3306,master_user='backup',master_password='Purepgmr-2020',master_log_file='mysql-bin.000001',master_log_pos=1513; 复制代码

(23)最后查看Slave的状态:

show slave status\G
复制代码

当看到Slave_IO_RunningSlave_SQL_Running都是yes的时候,这表示主从配置成功。

Slave_IO_Running也就是Slave中的IO线程用于请求Master,Slave_SQL_Running时sql线程将中继日志中更新日志同步到Slave数据库中。

到那时,有时候Slave_IO_Running会为no,而Slave_SQL_Running为yes,这时候须要检查一下缘由,由于我本身初次搭建的时候,也是出现这个问题。

首先看重启一下Slave的MySQL服务:systemctl restart mysqld,而后执行:

stop slave;
start slave; 复制代码

这样就可以使Slave_IO_RunningSlave_SQL_Running显示都是yes了。

(24)最后就是测试了,测试使用的是以前建立的test库,Master是用来写的,在Master的test库中随机建立一个表,你会发现Slave也会有这个表,插入数据也同样,都会被同步到Slave中。

主从面试

Mysql主从有什么优势?为何要选择主从?

  1. 高性能方面:主从复制经过水平扩展的方式,解决了原来单点故障的问题,而且原来的并发都集中到了一台Mysql服务器中,如今将单点负载分散到了多台机器上,实现读写分离,不会由于写操做过长锁表而致使读服务不能进行的问题,提升了服务器的总体性能。
  2. 可靠性方面:主从在对外提供服务的时候,如果主库挂了,会有经过主从切换,选择其中的一台Slave做为Master;如果Slave挂了,还有其它的Slave提供读服务,提升了系统的可靠性和稳定性。

如果主从复制,达到了写性能的瓶颈,你是怎么解决的呢?

主从模式对于写少读多的场景确实很是大的优点,可是总会写操做达到瓶颈的时候,致使性能提不上去。

这时候能够在设计上进行解决采用分库分表的形式,对于业务数据比较大的数据库能够采用分表,使得数据表的存储的数据量达到一个合理的状态。

也能够采用分库,按照业务进行划分,这样对于单点的写,就会分红多点的写,性能方面也就会大大提升。

主从复制的过程有数据延迟怎么办?致使Slave被读取到的数据并非最新数据。

主从复制有不一样的复制策略,对于不一样的场景的适应性也不一样,对于数据的实时性要求很高,要求强一致性,能够采用同步复制策略,可是这样就会性能就会大打折扣。

如果主从复制采用异步复制,要求数据最终一致性,性能方面也会好不少。只能说,对于数据延迟的解决方案没有最好的方案,就看你的业务场景中哪一种方案使比较适合的。

相关文章
相关标签/搜索