目录
在实际的生产中,为了解决Mysql的单点故障已经提高MySQL的整体服务性能,一般都会采用「主从复制」。
比如:在复杂的业务系统中,有一句sql执行后导致锁表,并且这条sql的的执行时间有比较长,那么此sql执行的期间导致服务不可用,这样就会严重影响用户的体验度。
主从复制中分为「主服务器(master)「和」从服务器(slave)」,「主服务器负责写,而从服务器负责读」,Mysql的主从复制的过程是一个「异步的过程」。
这样读写分离的过程能够是整体的服务性能提高,即使写操作时间比较长,也不影响读操作的进行。
Mysql的主从复制中主要有三个线程:
master(binlog dump thread)、slave(I/O thread 、SQL thread)
,Master一条线程和Slave中的两条线程
master(binlog dump thread)
主要负责Master库中有数据更新的时候,会按照binlog
格式,将更新的事件类型写入到主库的binlog
文件中。并且,Master会创建
log dump
线程通知Slave主库中存在数据更新,这就是为什么主库的binlog日志一定要开启的原因。
I/O thread
线程在Slave中创建,该线程用于请求Master,Master会返回binlog的名称以及当前数据更新的位置、binlog文件位置的副本。然后,将
binlog
保存在 「relay log(中继日志)」 中,中继日志也是记录数据更新的信息。SQL线程也是在Slave中创建的,当Slave检测到中继日志有更新,就会将更新的内容同步到Slave数据库中,这样就保证了主从的数据的同步
从复制的过程有不同的策略方式进行数据的同步,主要包含以下几种:
「同步策略」:Master会等待所有的Slave都回应后才会提交,这个主从的同步的性能会严重 的影响。
「半同步策略」:Master至少会等待一个Slave回应后提交。
「异步策略」:Master不用等待Slave回应就可以提交。
「延迟策略」:Slave要落后于Master指定的时间。
需要一个mysql服务
docker pull mysql/mysql-server:5.7
mkdir -p /home/data/mysql/master/{conf,data}
mkdir -p /home/data/mysql/slave/{conf,data}
确保了上面已有之后
就可以进行主从搭建了
我这里使用的事centos7 vmware的ip分别是
192.168.232.155(Slave)
和192.168.232.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'@'%';
然后编辑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
配置完后重启Mysql服务,并查看Mysql的log_bin日志
是否启动成功:
systemctl restart mysqld
# 查看log_bin日志是否启动成功
show variables like '%log_bin%';
接着查看Master的状态:
show master status;
这两个数据File
和Position
要记住,后面配置Slave的时候要使用到这两个数据
最后登陆Master的数据库,并创建一个用户用于同步数据:
create user 'kbin'@'%' IDENTIFIED BY 'LDCldc-2020';
grant file on *.* to 'kbin'@'%';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* to 'kbin'@'%';
到这里Master的配置就配置完了,后面就进行Slave的配置。
在Slave中同样要创建test数据库,并且授权给kbin用户:
# 创建同步数据的test数据库
create database test default character set utf8mb4 collate utf8mb4_general_ci;
# 授权
grant all privileges on test.* to 'kbin'@'%';
接着编辑Slave中my.cnf文件,同样是在/etc/my.cnf路径下,加入如下配置:
# 配置从服务器的ID,唯一的
server-id=4
#加上以下参数可以避免更新不及时,SLAVE 重启后导致的主从复制出错。
read_only = 1
master_info_repository=TABLE
relay_log_info_repository=TABLE
并且重启Slave中的Mysql服务:
systemctl restart mysqld
在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='LDCldc-2020',master_log_file='mysql-bin.000001',master_log_pos=1513;
最后查看Slave的状态:
show slave status\G
当看到Slave_IO_Running
和Slave_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_Running
和Slave_SQL_Running
显示都是yes了
最后就是测试了,测试使用的是之前创建的test库,Master是用来写的,在Master的test库中随机创建一个表,你会发现Slave也会有这个表,插入数据也一样,都会被同步到Slave中
Mysql主从有什么优点?为什么要选择主从?
?高性能方面:
主从复制通过水平扩展的方式,解决了原来单点故障的问题,并且原来的并发都集中到了一台Mysql服务器中,现在将单点负载分散到了多台机器上,实现读写分离,不会因为写操作过长锁表而导致读服务不能进行的问题,提高了服务器的整体性能
?可靠性方面:
主从在对外提供服务的时候,若是主库挂了,会有通过主从切换,选择其中的一台Slave作为Master;若是Slave挂了,还有其它的Slave提供读服务,提高了系统的可靠性和稳定性