mysql主从复制搭建

MySQL主从同步

1、MySQL主从同步原理

基本原理:

slave会从master读取binlog来进行数据同步

具体步骤:

  • step1:master将数据改变记录到二进制日志(binary log)中。
  • step2: 当slave上执行 start slave 命令之后,slave会创建一个 IO 线程用来连接master,请求master中的binlog。
  • step3:当slave连接master时,master会创建一个 log dump 线程,用于发送 binlog 的内容。在读取 binloge 的内容的操作中,会对主节点上的 binlog 加锁,当读取完成并发送给从服务器后解锁。
  • step4:IO 线程接收主节点 binlog dump 进程发来的更新之后,保存到 中继日志(relay log) 中。
  • step5:slave的SQL线程,读取relay log日志,并解析成具体操作,从而实现主从操作一致,最终数据一致。

2、一主多从配置

用docker模拟多台主机, 虚拟机环境

ip: 10.211.55.100

服务器规划:使用docker方式创建,主从服务器IP一致,端口号不一致

这里只搭建一主一从, 道理都一样

  • 主服务器:容器名mysql-master,端口3307
  • 从服务器:容器名mysql-slave1,端口3308

**注意:**如果此时防火墙是开启的,则先关闭防火墙,并重启docker,否则后续安装的MySQL无法启动

shell 复制代码
#关闭docker
systemctl stop docker
#关闭防火墙
systemctl stop firewalld
#启动docker
systemctl start docker
  • 前置条件

两台 MySQL 都要设置不同的 server-id(复制里它就是身份证) 时间最好同步(NTP),排错会舒服很多 master 必须开启

binlog(复制靠它吃饭)

2.1、准备主服务器

  • step1:在docker中创建并启动MySQL主服务器: 端口3307
shell 复制代码
docker run -d \
-p 3307:3306 \
-v /mysql/master/conf:/etc/mysql/conf.d \
-v /mysql/master/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--name mysql-master \
mysql:8.0.30
  • step2:创建MySQL主服务器配置文件:

默认情况下MySQL的binlog日志是自动开启的,可以通过如下配置定义一些可选配置

shell 复制代码
# 宿主机的路径
vim /mysql/master/conf/my.cnf

配置如下内容

properties 复制代码
[mysqld]
# 服务器唯一id,默认值1
server-id=1

#下面的内容为选择性配置

# 设置日志格式,默认值ROW
#binlog_format=STATEMENT
# 二进制日志名,默认binlog
# log-bin=binlog
# 设置需要复制的数据库,默认复制全部数据库
#binlog-do-db=mytestdb1
#binlog-do-db=mytestdb2
# 设置不需要复制的数据库
#binlog-ignore-db=mysql
#binlog-ignore-db=information_schema
#binlog-ignore-db=performance_schema
#binlog-ignore-db=sys

重启MySQL容器

shell 复制代码
docker restart mysql-master

binlog格式说明:

  • binlog_format=STATEMENT:日志记录的是主机数据库的写指令,性能高,但是now()之类的函数以及获取系统参数的操作会出现主从数据不同步的问题。
  • binlog_format=ROW(默认):日志记录的是主机数据库的写后的数据,批量操作时性能较差,解决now()或者 user()或者 @@hostname 等操作在主从机器上不一致的问题。
  • binlog_format=MIXED:是以上两种level的混合使用,有函数用ROW,没函数用STATEMENT

binlog-ignore-db和binlog-do-db的优先级问题:

  • step3:使用命令行登录MySQL主服务器:
sql 复制代码
-- 进入容器:env LANG=C.UTF-8 避免容器中显示中文乱码
docker exec -it mysql-master env LANG=C.UTF-8 /bin/bash
-- 进入容器内的mysql命令行
mysql -uroot -p
-- 修改默认密码校验方式
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
-- 刷新权限,可以不用重启服务器
FLUSH PRIVILEGES;

如果不修改默认密码校验方式, 连接的时候需要加上(开发/内网常用)jdbc:mysql://host:3306/db?allowPublicKeyRetrieval=true&useSSL=false
'root'@'%'

解释: 让root 用户可以任意ip 访问, 根据具体需求写, 方便测试这里写任意ip,也就是%

  • step4:主机中创建slave用户:
  • 专用于复制的账号最少只需要 REPLICATION SLAVE 权限
sql 复制代码
-- 创建slave用户, 这个用户可以给多个从机用.
CREATE USER 'slave'@'%';
-- 设置密码
ALTER USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
-- 授予复制权限
GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%';
-- 刷新权限
FLUSH PRIVILEGES;
  • step5:主机中查询master状态:

执行完此步骤后不要再操作主服务器MYSQL,防止主服务器状态值变化

sql 复制代码
SHOW MASTER STATUS;

记下FilePosition的值。执行完此步骤后不要再操作主服务器MYSQL,防止主服务器状态值变化。

binlog.000003 1500

2.2、准备从服务器1

  • step1:在docker中创建并启动MySQL从服务器: 端口3308
shell 复制代码
docker run -d \
-p 3308:3306 \
-v /mysql/slave1/conf:/etc/mysql/conf.d \
-v /mysql/slave1/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--name mysql-slave1 \
mysql:8.0.30
  • step2:创建MySQL从服务器配置文件:
shell 复制代码
vim /mysql/slave1/conf/my.cnf

配置如下内容:

properties 复制代码
[mysqld]
# 服务器唯一id,每台服务器的id必须不同,如果配置其他从机,注意修改id
server-id=2

#下面内容不用动
# 中继日志名,默认xxxxxxxxxxxx-relay-bin
#relay-log=relay-bin

重启MySQL容器

shell 复制代码
docker restart mysql-slave1
  • step3:使用命令行登录MySQL从服务器:
sql 复制代码
-- 进入容器:
docker exec -it mysql-slave1 env LANG=C.UTF-8 /bin/bash
-- 进入容器内的mysql命令行
mysql -uroot -p
-- 修改默认密码校验方式
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
-- 刷新权限
FLUSH PRIVILEGES;
  • step4:在从机上配置主从关系:

从机上执行以下SQL操作 , 注意下面的语句块是一条命令

sql 复制代码
CHANGE MASTER TO MASTER_HOST='10.211.55.100',

#用的是master给分配的用户 slave
MASTER_USER='slave',MASTER_PASSWORD='123456', MASTER_PORT=3307,

# 对应file和 position 的值,前面在master中获取的 file: binlog.000003     position:1500
MASTER_LOG_FILE='binlog.000003',MASTER_LOG_POS=1500; 
bash 复制代码
CHANGE MASTER TO MASTER_HOST='10.211.55.100',\
MASTER_USER='slave',MASTER_PASSWORD='123456', MASTER_PORT=3307,\
MASTER_LOG_FILE='binlog.000003',MASTER_LOG_POS=1500; 

2.3、启动主从同步

分别在从机上启动从机的复制功能,执行SQL:

sql 复制代码
START SLAVE;
-- 查看状态(不需要分号)
#\G 表示列显示,方便查看
SHOW SLAVE STATUS\G      

**两个关键进程:**下面两个参数都是Yes,则说明主从配置成功!

2.4、测试主从同步

在主机中执行以下SQL,在从机中查看数据库、表和数据是否已经被同步

sql 复制代码
CREATE DATABASE db_user;
USE db_user;
CREATE TABLE t_user (
 id BIGINT AUTO_INCREMENT,
 uname VARCHAR(30),
 PRIMARY KEY (id)
);
INSERT INTO t_user(uname) VALUES('chen');

# @@hostname 是系统变量:表示当前 MySQL 服务器所在机器的主机名(hostname)。
INSERT INTO t_user(uname) VALUES(@@hostname);

2.5、常见问题

问题1

启动主从同步后,常见错误是Slave_IO_Running: No 或者 Connecting 的情况,此时查看下方的 Last_IO_ERROR错误日志,根据日志中显示的错误信息在网上搜索解决方案即可

典型的错误例如: Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Client requested master to start replication from position > file size'

解决方案:

sql 复制代码
-- 在从机停止slave
-- 在从机上执行。功能说明:停止I/O 线程和SQL线程的操作。
stop slave; 

-- 在从机上执行。功能说明:用于删除SLAVE数据库的relaylog日志文件,并重新启用新的relaylog文件。
reset slave;

-- 在主机上执行。功能说明:删除所有的binlog日志文件,并将日志索引文件清空,重新开始所有新的日志文件。
-- 用于第一次进行搭建主从库时,进行主库binlog初始化工作;
reset master;

-- 还原主服务器之前的操作

-- 在主机查看mater状态
SHOW MASTER STATUS;
-- 在主机刷新日志
FLUSH LOGS;
-- 再次在主机查看mater状态(会发现File和Position发生了变化)
SHOW MASTER STATUS;
-- 修改从机连接主机的SQL,并重新连接即可
相关推荐
Fleshy数模6 小时前
CentOS7 安装配置 MySQL5.7 完整教程(本地虚拟机学习版)
linux·mysql·centos
az44yao7 小时前
mysql 创建事件 每天17点执行一个存储过程
mysql
秦老师Q8 小时前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
橘子139 小时前
MySQL用户管理(十三)
数据库·mysql
Dxy12393102169 小时前
MySQL如何加唯一索引
android·数据库·mysql
我真的是大笨蛋9 小时前
深度解析InnoDB如何保障Buffer与磁盘数据一致性
java·数据库·sql·mysql·性能优化
怣509 小时前
MySQL数据检索入门:从零开始学SELECT查询
数据库·mysql
人道领域10 小时前
javaWeb从入门到进阶(SpringBoot事务管理及AOP)
java·数据库·mysql
千寻技术帮11 小时前
10404_基于Web的校园网络安全防御系统
网络·mysql·安全·web安全·springboot
spencer_tseng12 小时前
MySQL table backup
mysql