目录
- 环境配置
- 容器创建
- 主服务器
- 创建MYSQL容器
- 新增my.cnf文件
- 创建用户并授权
- 从服务器
- 创建MYSQL容器
- 新增my.cnf文件
- 重启MYSQL容器
- 配置主从同步
- 验证主从同步
- 彩蛋
MySQL 主从同步(Master-Slave Replication)是一种常用的解决方案,它允许一个主服务器(Master)将其数据复制到一个或多个从服务器(Slave)。这种架构不仅提高了数据的冗余性,还能通过读取分离来提升应用的性能。
关于MYSQL主从同步的原理以及八股文这篇文章中就暂时不讲述啦,直接上干货,面对许多同学没有大量服务器,又想参与MYSQL集群实战过程中,提升技能,这篇实操技能你值得拥有~
环境配置
正如文章主题,简单明了,docker,会使用基本的docker命令即可,即使不会也没有关系,溪源会带着大家一步一步完成搭建。
- 获取MYSQL镜像:docker命令
docker pull mysql:8.0.36
- 本地服务器创建数据卷
/Users/docker/data/mysql/
对于docker实战而言,少不了,主机目录与容器数据卷映射之类的操作,所以可以将相关数据卷统一目录管理;
- 授权
chmod 777 /Users/docker/data/
授权所有用户读写操作
容器创建
主服务器
创建MYSQL容器
docker run -d -p 3317:3306 --privileged=true \
-v /Users/docker/data/mysql/master/log:/var/log/mysql \
-v /Users/docker/data/mysql/master/data:/var/lib/mysql \
-v /Users/docker/data/mysql/master/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 \
--name mysql_master mysql:8.0.36
- 命令说明:
**docker run**: Docker 命令,用于运行一个新的容器。
**-d:** 以分离模式(detached mode)运行容器。容器将会在后台运行,你不会看到容器的输出。
**-p 3317:3306:** 将主机的端口 3317 映射到容器的端口 3306。MySQL 默认监听 3306 端口,通过这种映射,你可以通过主机的 3317 端口访问 MySQL。
**--privileged=true**:给予容器额外的权限。这通常用于需要访问主机的硬件设备或执行某些受限操作的容器。在大多数情况下,这不是必要的,并且使用时应谨慎。
**-v /Users/docker/data/mysql/master/log:/var/log/mysql**:
将主机目录 /Users/docker/data/mysql/master/log 映射到容器的 /var/log/mysql 目录。这样,MySQL 的日志文件将会保存在主机上,即使容器删除,日志文件也会保留。
**-v /Users/docker/data/mysql/master/data:/var/lib/mysql**:
将主机目录 /Users/docker/data/mysql/master/data 映射到容器的 /var/lib/mysql 目录。MySQL 的数据文件将会保存在主机上,确保数据持久化。
**-v /Users/docker/data/mysql/master/conf:/etc/mysql/conf.d**:
将主机目录 /Users/docker/data/mysql/master/conf 映射到容器的 /etc/mysql/conf.d 目录。可以在该目录中放置 MySQL 配置文件(如 my.cnf),以便自定义 MySQL 配置。
**-e MYSQL_ROOT_PASSWORD=123456**:
设置环境变量 MYSQL_ROOT_PASSWORD,用于初始化 MySQL 的 root 用户密码为 123456。这是在容器首次启动时设置 MySQL root 用户密码的简便方法。
**--name mysql_master** :
指定容器的名称为 mysql_master。这样你可以通过名称而不是容器 ID 来引用这个容器。
**mysql:8.0.36:**
使用 mysql 镜像,并指定版本为 8.0.36。这将从 Docker Hub 拉取指定版本的 MySQL 镜像,并在容器中运行。
新增my.cnf文件
路径:上面新建文件的路径:**/Users/docker/data/mysql/master/conf **
vim my.cnf
[mysqld]
pid-file= /var/run/mysqld/mysqld.pid
socket= /var/run/mysqld/mysqld.sock
datadir= /var/lib/mysql
secure-file-priv= NULL
## 设置server_id,同一局域网中需要唯一
server_id=101
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能
log-bin=binlog
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
## 二进制日志过期清理时间。默认值为0,表示不自动清理。
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
# 设置默认时区
default-time_zone='+8:00'
创建用户并授权
-
进入容器:
docker exec -it mysql_master /bin/bash
-
执行语句创建slave用户以及设置密码
mysql> CREATE USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
-
执行语句授权slave
mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
-
退出容器,输入 exit;
mysql> exit; bash-4.4# exit
-
执行重启主数据库:
docker restart mysql_master;
-
重启完成后,再次进入容器
docker exec -it mysql_master /bin/bash
进入MYSQL命令行 -
查看主库状态
show master status;
特别说明,此处的position特别重要,后面配置从服务器需要用到
从服务器
创建MYSQL容器
docker run -d -p 3318:3306 --privileged=true \
-v /Users/docker/data/mysql/slave01/log:/var/log/mysql \
-v /Users/docker/data/mysql/slave01/data:/var/lib/mysql \
-v /Users/docker/data/mysql/slave01/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 \
--name mysql_slave01 mysql:8.0.36
新增my.cnf文件
[mysqld]
pid-file= /var/run/mysqld/mysqld.pid
socket= /var/run/mysqld/mysqld.sock
datadir= /var/lib/mysql
secure-file-priv= NULL
## 设置server_id,同一局域网中需要唯一
server_id=102
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能,设置二进制日志名,默认binlog
log-bin=binlog
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
## 二进制日志过期清理时间。默认值为0,表示不自动清理。
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
## relay_log配置中继日志
relay_log=mysql-relay-bin
## log_slave_updates表示slave将复制事件写进自己的二进制日志
log_slave_updates=1
## slave设置为只读(具有super权限的用户除外)
read_only=1
# 设置默认时区
default-time_zone='+8:00'
binlog-ignore-db=infomation_schema,配置同步,则主服务器用户会直接同步到从服务器
重启MYSQL容器
命令:docker restart mysql_slave;
配置主从同步
-
进入从服务器
进入容器:docker exec -it mysql_slave01 /bin/bash
登录MYSQL -
执行以下语句,在从数据库配置主从复制
change master to master_host='主库主机ip地址', master_user='2.1在主库创建的账号', master_password='2.1在主库创建的密码', master_port=3307, master_log_file='binlog.000004', master_log_pos=157, master_connect_retry=30;
执行语句:
change master to master_host='XXXXXX', master_user='slave', master_password='123456', master_port=3307, master_log_file='binlog.000004', master_log_pos=157, master_connect_retry=30;
参数说明:
master_host:主数据库的IP地址;
master_port:主数据库的运行端口;
master_user:在主数据库创建的用于同步数据的用户账号;
master_password:在主数据库创建的用于同步数据的用户密码;
master_log_file:指定从数据库要复制数据的日志文件,通过查看主数据的状态,获取File参数;
master_log_pos:指定从数据库从哪个位置开始复制数据,通过查看主数据的状态,获取Position参数;
master_connect_retry:连接失败重试的时间间隔,单位为秒。
-
查看主从同步状态
show slave status \G;
说明:此时Slave_IO_Running与Slave_SQL_Running为 NO状态。 -
开启主从同步
start slave;
说明:Slave_IO_Running与Slave_SQL_Running为 Yes状态
验证主从同步
- 主服务器创建数据库和表
mysql> create database tenant;
Query OK, 1 row affected (0.01 sec)
mysql> use tenant;
Database changed
mysql> CREATE TABLE users (
-> user_id INT AUTO_INCREMENT PRIMARY KEY, -- ID
-> username VARCHAR(50) NOT NULL UNIQUE, -- 50
-> email VARCHAR(100) NOT NULL UNIQUE, -- 100
-> password VARCHAR(255) NOT NULL, -- 255
-> created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, --
-> updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP --
-> );
Query OK, 0 rows affected (0.04 sec)
mysql> show tables;
+------------------+
| Tables_in_tenant |
+------------------+
| users |
+------------------+
1 row in set (0.00 sec)
- 查看从库是否完成同步
彩蛋
哈哈哈,,,此篇彩蛋主要扩展解决问题方案,开启主从同步时,如何取消主从配置说明。溪源在配置主从配置过程IP地址错误,导致从库无法连接,如图:
Error connecting to source 'slave@localhost:3317'. This was attempt 2/86400, with a delay of 30 seconds between attempts. Message: Can't connect to MySQL server on 'localhost:3317' (99)
执行以下命令:
- 停止复制进程:
STOP SLAVE;
- 清除所有复制配置:
RESET SLAVE ALL;
然后按照从库,再重新配置主从同步,但是一定要注意查看一下主库的状态,判断position位置是否变化。