【Linux】MySQL主从复制

概念

为什么需要主从复制?

  1. 在业务复杂的系统中,有这么一个情景,有一句sql语句需要锁表,导致暂时不能使用读的服务,那么就很影响运行中的业务,使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了锁表的情景,通过读从库也可以保证业务的正常运行。
  2. 做数据的热备,主库宕机后能够及时替换主库,保证业务可用性。
  3. 架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O 访问的频率,提高单个机器的I/O性能。

主从复制的原理

主数据库:

MySQL主从复制是一个异步的复制过程,主库发送更新事件到从库,从库读取更新记录,并执行更新记录,使得从库的内容与主库保持一致。

binlog:主库中保存所有更新事件日志的二进制文件。binlog是数据库服务启动的一刻起,保存数据库所有变更记录(数据库结构和内容)的文件。

从数据库:

在从库中,当复制开始时,从库就会创建从库I/O线程和从库的SQL线程进行复制处理。 从库I/O线程:当START SLAVE语句在从库开始执行之后,从库创建一个I/O线程,该线程连接到主库并请求主库发送binlog里面的更新记录到从库上。 从库I/O线程读取主库的binlog输出线程发送的更新并拷 贝这些更新到本地文件,其中包括relay log文件。

主从复制执行流程

  1. 主库db的更新事件(update、insert、delete)被写到binlog
  2. 从库启动并发起连接,连接到主库
  3. 主库创建一个binlog dump thread,把binlog的内容发送到从库
  4. 从库启动之后,创建一个I/O线程,读取主库传过来的binlog内容并写 入到relay log
  5. 从库启动之后,创建一个SQL线程,从relay log里面读取内容,从 Exec_Master_Log_Pos位置开始执行读取到的更新事件,将更新内容写 入到slave的db

阿里云:(二十四)全解MySQL之主从篇:死磕主从复制中数据同步原理与优化-阿里云开发者社区

①客户端将写入数据的需求交给主节点,主节点先向自身写入数据。

②数据写入完成后,紧接着会再去记录一份Bin-log二进制日志。

③配置主从架构后,主节点上会创建一条专门监听Bin-log日志的log dump线程。

④当log dump线程监听到日志发生变更时,会通知从节点来拉取数据。

⑤从节点会有专门的I/O线程用于等待主节点的通知,当收到通知时会去请求一定范围的数据。

⑥当从节点在主节点上请求到一定数据后,接着会将得到的数据写入到relay-log中继日志。

⑦从节点上也会有专门负责监听relay-log变更的SQL线程,当日志出现变更时会开始工作。

⑧中继日志出现变更后,接着会从中读取日志记录,然后解析日志并将数据写入到自身磁盘中。

主从复制的集群搭建

搭建

主服务器3306

** 1.创建环境目录:**

bash 复制代码
cd /usr/local/ 
mkdir mysql 
cd mysql mkdir 
master-data 

2.主mysql容器运行:

docker run --name mysql-master --privileged=true -v /usr/local/mysql/master-data:/var/lib/mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d daocloud.io/library/mysql:8.0.16 --characterset-server=utf8 --server-id=1 --lower_case_table_names=1

参数:

  • --privileged指定了当前容器是否真正的具有root权限
  • -p表示宿主机上的某个端口映射到docker容器内的某个端口
  • -d参数指定了当前容器是在后台运行
  • --server-id 设置服务器的编号,主从复制的每一个服务的编号都不能相同
perl 复制代码
docker run --name  mysql-master  --privileged=true  -v /usr/local/mysql/master-data:/var/lib/mysql   -p 3306:3306  -e  MYSQL_ROOT_PASSWORD=root  -d  de764ad211de  --character-set-server=utf8mb4 --server-id=1 --lower_case_table_names=1

**3.配置mysql权限账户: **

bash 复制代码
docker exec -it mysql-master /bin/bash 

**4.登录主服务器 **

bash 复制代码
mysql: mysql -uroot -p 

5.修改密码和设置从服务器登录用户:

进入容器,更改配置:

perl 复制代码
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';

CREATE USER 'slave_one'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'slave_one'@'%';

CREATE USER 'slave_two'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'slave_two'@'%';

flush privileges;

**6. 查看主mysql的master节点的binlog状态: **

从数据库1:3307

** 1.创建环境目录: **

perl 复制代码
cd /usr/local/mysql mkdir slave_one-data  

2.主mysql运行

perl 复制代码
docker run --name mysql-slave_one --privileged=true -v /usr/local/mysql/slave_onedata:/var/lib/mysql -p 3307:3306 --link mysql-master:master -e MYSQL_ROOT_PASSWORD=root -
d daocloud.io/library/mysql:8.0.16 --character-set-server=utf8 --server-id=2 --
lower_case_table_names=1

** 3.配置mysql权限账户:**

perl 复制代码
docker exec -it mysql-slave_one /bin/bash  

** 4.登录主服务器**

perl 复制代码
mysql: mysql -uroot -p  

5.修改密码登录用户

perl 复制代码
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';
flush privileges;

**6.切换当前服务的状态,使其能够连接上master服务器,并且复制其数据 **

perl 复制代码
change master to master_host='master', master_user='slave_one', master_password='123456', master_port=3306, master_log_file='binlog.000002', master_log_pos=1920, master_connect_retry=30;

7.启动日志同步

perl 复制代码
start slave;

8.查看状态

perl 复制代码
show slave status\G;

测试:

perl 复制代码
create database test;

use test;

create table Student(Sid int primary key, Sname varchar(10), birthday datetime, Ssex varchar(10), classid int);
insert into Student values('1' , '赵雷' , '1990-01-01' , '男', '1');
insert into Student values('2' , '钱电' , '1990-12-21' , '男', '2');
insert into Student values('3' , '孙风' , '1990-05-20' , '男', '1');
insert into Student values('4' , '李云' , '1990-08-06' , '男', '2');
insert into Student values('5' , '周梅' , '1991-12-01' , '女', '1');
insert into Student values('6' , '吴兰' , '1992-03-01' , '女', '2');
insert into Student values('7' , '郑竹' , '1989-07-01' , '女', '1');
insert into Student values('8' , '王菊' , '1990-01-20' , '女', '2');

主服务器:

从服务器:

**9. 其他多个从服务器搭建步骤相同; **

请按照第一个从服务器步骤进行搭建。 (3)使用docker运行java应用: docker run --name javatest -v /root/jardir:/use/jar -v /mnt:/mnt -d daocloud.io/library/java:8u91-jdk java -jar /use/jar/fetch_douban.jar (4)使用Navicat查询效果

从数据库2:3308

perl 复制代码
docker run --name mysql-slave_two --privileged=true -v /usr/local/mysql/slave_two-data:/var/lib/mysql -p 3308:3306 --link mysql-master:master  -e MYSQL_ROOT_PASSWORD=root   -d de764ad211de  --character-set-server=utf8mb4 --server-id=3   --lower_case_table_names=1
perl 复制代码
change master to master_host='master', master_user='slave_two', master_password='123456', master_port=3306, master_log_file='binlog.000002', master_log_pos=1920, master_connect_retry=30;

搭建成功:

测试:

同步成功;

perl 复制代码
docker run --name mysql-slave_two --privileged=true -v /usr/local/mysql/slave_two-data:/var/lib/mysql -p 3308:3306 --link mysql-master:master  -e MYSQL_ROOT_PASSWORD=root   -d de764ad211de  --character-set-server=utf8mb4 --server-id=3   --lower_case_table_names=1

docker exec -it mysql-slave_two /bin/bash


ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';
flush privileges;


change master to master_host='master', master_user='slave_two', master_password='123456', master_port=3306, master_log_file='binlog.000002', master_log_pos=1920, master_connect_retry=30;

start slave;
相关推荐
知初~3 小时前
出行项目案例
hive·hadoop·redis·sql·mysql·spark·database
子非衣5 小时前
MySQL修改JSON格式数据示例
android·mysql·json
钊兵6 小时前
数据库驱动免费下载(Oracle、Mysql、达梦、Postgresql)
数据库·mysql·postgresql·oracle·达梦·驱动
lllsure7 小时前
Linux 实用指令
linux·物联网
隔壁老王1567 小时前
mysql实时同步到es
数据库·mysql·elasticsearch
努力的小T8 小时前
使用 Docker 部署 Apache Spark 集群教程
linux·运维·服务器·docker·容器·spark·云计算
Nerd Nirvana8 小时前
OpenSSL crt & key (生成一套用于TLS双向认证的证书密钥)
linux·ssl·shell·认证·加密·tls·oepnssl
letisgo59 小时前
记录一次部署PC端网址全过程
linux·阿里云·服务器运维
猫猫的小茶馆9 小时前
【网络编程】UDP协议
linux·服务器·网络·网络协议·ubuntu·udp