一、概述
主从复制是指将主数据库的DDL和DML操作通过二进制日志传到从库服务器中,然后在从库上对这些日志重新执行(也叫重做),从而是的从库和主库数据保持一致。
MySQL支持一台主库同时向多台从库进行复制,从库同时也可以作为其他服务器的主库,实现链状复制。
优点
MySQL复制的优点主要包含以下三个方面:
1、主库出现问题。可以快速切换到从库提供服务;
2、实现读写分离,降低主库的访问压力;
3、可以在从库中执行备份,以避免备份期间影响主库服务。
二、准备部署工作
两台服务器: 确保有两台安装了 CentOS/Ubuntu/或其他 Linux 系统的服务器,分别用作 Master 和 Slave。
MySQL 5.7 安装: 在两台服务器上都安装 MySQL 5.7 数据库。
网络连通性: 确保 Master 和 Slave 之间网络可达,并且防火墙允许 3306 端口的通信
三、主数据库
安装部署主节点数据库
选择一个服务器作为主数据库部署MySQL主节点服务
创建MySQL数据目录
mkdir -p /data/docker-services/mysql/{data,config}
- data 目录:存储容器持久化数据;
- config 目录: 配置文件目录。
创建 MySQL 自定义配置文件
- 创建自定义 MySQL 配置文件
vim /data/docker-services/mysql/config/mysqld.cnf
生产环境一定要根据使用场景自定义配置文件。(特别是复制设置)
默认安装的 MySQL 使用的 my.cnf 配置文件,适配的业务场景有限,所以自定义 MySQL 配置文件是必然要做的一项配置。
[mysqld]
# 性能设置
lock_wait_timeout = 3600
open_files_limit = 65535
back_log = 1024
max_connections = 2048
max_connect_errors = 1000000
table_open_cache = 1024
table_definition_cache = 1024
thread_stack = 512K
sort_buffer_size = 4M
join_buffer_size = 4M
read_buffer_size = 8M
read_rnd_buffer_size = 4M
bulk_insert_buffer_size = 64M
thread_cache_size = 768
interactive_timeout = 600
wait_timeout = 600
tmp_table_size = 32M
max_heap_table_size = 32M
innodb_open_files = 1024
# TLS 配置
tls_version = TLSv1.2
# 复制设置
server_id = 1
log_bin = mysql-bin
log_bin_index = mysql-bin.index
binlog_format = row
创建 docker-compose 文件
vim /data/docker-services/mysql/docker-compose.yml
version: '3.8'
services:
mysql:
container_name: mysql
image: mysql:5.7.44
restart: always
ulimits:
nofile:
soft: 65536
hard: 65536
environment:
- TZ=Asia/Shanghai
- MYSQL_ROOT_PASSWORD=cy123456!
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/data:/var/lib/mysql
- ${DOCKER_VOLUME_DIRECTORY:-.}/config:/etc/mysql/conf.d/
networks:
- cy-network
ports:
- "3306:3306"
networks:
cy-network:
driver: bridge
版本声明:
version: '3.8'
:声明了 Docker Compose 文件的版本。确保你的 Docker Compose 客户端支持这个版本。
服务定义:
mysql
:定义了一个名为 mysql
的服务。
container_name: mysql
:设置了容器的名称。
image: mysql:5.7.44
:指定了使用的 Docker 镜像。
restart: always
:设置了容器的重启策略。
ulimits
:设置最大的文件打开数,用于提高 MySQL 服务的性能。
environment
:设置了环境变量。
volumes
:挂载了数据卷和配置文件。
networks
:将服务连接到 app-tier
网络。
ports
:将容器的 3306 端口映射到宿主机的 3306 端口。
网络定义:
cy-network:定义了一个名为 cy-network的网络,使用默认的桥接驱动。
创建并启动 MySQL 服务
启动服务
cd /data/docker-services/mysql
docker compose up -d
验证容器状态
查看mysql容器状态
docker compose ps
#或者
docker ps
查看mysql服务实时的日志
docker compose logs -f mysql
#或者
docker logs -f mysql
测试mysql服务可用性
进入容器内测试
docker exec -it mysql /bin/bash
mysql -uroot -p
按提示说明输入密码进入 MySQL 控制台。
出现以下说明成功进入mysql控制台
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 12345
Server version: 5.7.44 MySQL Community Server (GPL)
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
验证 MySQL 配置
验证自定义配置是否生效
mysql> show variables like '%max_conn%';
+--------------------+---------+
| Variable_name | Value |
+--------------------+---------+
| max_connect_errors | 1000000 |
| max_connections | 2048 |
+--------------------+---------+
2 rows in set (0.00 sec)
查询主节点状态
查看当前mysql主节点的状态
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 788 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
四、从数据库
安装部署从节点数据库
选择另外一个服务器作为从数据库部署MySQL从节点服务
创建MySQL数据目录
mkdir -p /data/docker-services/mysql/{data,config}
- data 目录:存储容器持久化数据;
- config 目录: 配置文件目录。
创建 MySQL 自定义配置文件
- 创建自定义 MySQL 配置文件
vim /data/docker-services/mysql/config/mysqld.cnf
生产环境一定要根据使用场景自定义配置文件。(特别是复制设置)
直接复制注数据库的修改
[mysqld]
# 性能设置
lock_wait_timeout = 3600
open_files_limit = 65535
back_log = 1024
max_connections = 2048
max_connect_errors = 1000000
table_open_cache = 1024
table_definition_cache = 1024
thread_stack = 512K
sort_buffer_size = 4M
join_buffer_size = 4M
read_buffer_size = 8M
read_rnd_buffer_size = 4M
bulk_insert_buffer_size = 64M
thread_cache_size = 768
interactive_timeout = 600
wait_timeout = 600
tmp_table_size = 32M
max_heap_table_size = 32M
innodb_open_files = 1024
# TLS 配置
tls_version = TLSv1.2
# 复制设置
server_id = 2
log_bin = mysql-bin
log_bin_index = mysql-bin.index
binlog_format = row
relay-log = mysql-relay-bin
relay-log-index = mysql-relay-bin.index
skip_slave_start = 1
log_slave_updates = 1
read_only = 1
创建 docker-compose 文件
vim /data/docker-services/mysql/docker-compose.yml
version: '3.8'
services:
mysql:
container_name: mysql
image: mysql:5.7.44
restart: always
ulimits:
nofile:
soft: 65536
hard: 65536
environment:
- TZ=Asia/Shanghai
- MYSQL_ROOT_PASSWORD=cy123456!
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/data:/var/lib/mysql
- ${DOCKER_VOLUME_DIRECTORY:-.}/config:/etc/mysql/conf.d/
networks:
- cy-network
ports:
- "3306:3306"
networks:
cy-network:
driver: bridge
版本声明:
version: '3.8'
:声明了 Docker Compose 文件的版本。确保你的 Docker Compose 客户端支持这个版本。
服务定义:
mysql
:定义了一个名为 mysql
的服务。
container_name: mysql
:设置了容器的名称。
image: mysql:5.7.44
:指定了使用的 Docker 镜像。
restart: always
:设置了容器的重启策略。
ulimits
:设置最大的文件打开数,用于提高 MySQL 服务的性能。
environment
:设置了环境变量。
volumes
:挂载了数据卷和配置文件。
networks
:将服务连接到 app-tier
网络。
ports
:将容器的 3306 端口映射到宿主机的 3306 端口。
网络定义:
cy-network:定义了一个名为 cy-network的网络,使用默认的桥接驱动。
创建并启动 MySQL 服务
启动服务
cd /data/docker-services/mysql
docker compose up -d
验证容器状态
查看mysql容器状态
docker compose ps
#或者
docker ps
查看mysql服务实时的日志
docker compose logs -f mysql
#或者
docker logs -f mysql
测试mysql服务可用性
进入容器内测试
docker exec -it mysql /bin/bash
mysql -uroot -p
按提示说明输入密码进入 MySQL 控制台。
出现以下说明成功进入mysql控制台
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 12345
Server version: 5.7.44 MySQL Community Server (GPL)
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
验证 MySQL 配置
验证自定义配置是否生效
mysql> show variables like '%max_conn%';
+--------------------+---------+
| Variable_name | Value |
+--------------------+---------+
| max_connect_errors | 1000000 |
| max_connections | 2048 |
+--------------------+---------+
2 rows in set (0.00 sec)
查询从节点状态
查看当前mysql从节点的状态
mysql> show slave status;
Empty set (0.00 sec)
因为还没有配置主从同步,所以现在的状态是正确的。
五、配置主从同步
创建主从同步
-- 用 root 登录后执行
-- 创建用户
CREATE USER 'repuser'@'192.168.11.%' IDENTIFIED BY 'cy123456!';
-- 赋予权限
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repuser'@'192.168.11.%';
-- 刷新权限
FLUSH PRIVILEGES;
说明:
repuser: 同步用户,实际使用替换成自己想要的;
password: 同步用户密码,实际使用替换成自己想要的;
192.168.11.%: 从节点服务器的 IP,实际使用替换成自己想要的;
额外创建一个新账号 repuser
专门给从库用,这是官方推荐做法。
查询主节点Master 当前状态
在主服务器上执行
docker exec -it mysql /bin/bash
mysql -uroot -p
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 788 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
要记录 mysql-bin.000003 和 788,下面会用到的
配置主从复制
在从服务器上,执行下面的主从同步配置命令
配置主从同步
docker exec -it mysql /bin/bash
mysql -uroot -p
mysql>
CHANGE MASTER TO
MASTER_HOST='192.168.11.81', -- Master 服务器的 IP 地址
MASTER_USER='repuser', -- 在 Master 上创建的复制用户名
MASTER_PASSWORD='cy123456!', -- 复制用户的密码
MASTER_LOG_FILE='mysql-bin.000003', -- 上一步在 Master 上查到的 File 值
MASTER_LOG_POS=788; -- 上一步在 Master 上查到的 Position 值
说明:
MASTER_HOST:主节点 的IP
MASTER_USER:同步用户
MASTER_PASSWORD: 同步用户的密码
MASTER_LOG_FILE: 对应主节点服务器上查询 Master 状态的 File 值
MASTER_LOG_POS :对应主节点服务器上查询 Master 状态的 Position 值
执行结果如下:
# 执行同步语句
mysql> CHANGE MASTER TO
MASTER_HOST='192.168.11.81',
MASTER_USER='repuser',
MASTER_PASSWORD='cy123456!',
MASTER_LOG_FILE='mysql-bin.000003',
MASTER_LOG_POS=788;
Query OK, 0 rows affected, 1 warning (0.03 sec)
开启同步
mysql> START SLAVE;
Query OK, 0 rows affected (0.01 sec)
验证主从同步状态
查看同步状态
mysql> SHOW SLAVE STATUS\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.11.81
Master_User: repuser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000003
Read_Master_Log_Pos: 788
Relay_Log_File: mysql-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 788
Relay_Log_Space: 527
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: c9f31934-010c-11ef-8cd0-2362ac132351
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
ERROR:
No query specified
注意: 以下返回值的内容
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
主数据库创建数据库,从数据库查看是否创建成功
--- 主库执行创建
mysql> create database t_user;
Query OK, 1 row affected (0.01 sec)
--- 从库执行查询
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| t_user |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
--- 从库查看同步后的 slave 状态
mysql> show slave status\G;
重点看:Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
六、总结
本文围绕 Docker 官方 MySQL 镜像,系统梳理了主从架构的完整落地路径:从主、从节点的容器化部署,到复制链路配置与验证,再到自定义配置文件的统一管理,最后通过可用性测试保障业务级稳定。整套方案即开即用、可复现、易扩展,为后续 MySQL 高可用与水平扩展奠定坚实基础。