文章导读

本文将深入探讨企业级 MySQL 主从复制集群的部署与优化方案,为数据库架构师、DevOps 工程师和系统运维人员提供全面的技术指导。内容涵盖以下核心领域:

  • MySQL 主从复制的底层原理与技术实现
  • 企业级部署架构设计与资源规划
  • 基于 Docker Compose 的容器化部署方案
  • 主从复制的高级配置与性能调优
  • 高可用架构设计与故障自动切换策略
  • 数据库安全加固与权限管理
  • 全维度监控体系建设与告警机制
  • 常见故障诊断与专业解决方案

本文提供的实施方案经过生产环境验证,包含详细的操作步骤、技术参数和最佳实践,可直接应用于企业级应用场景。通过本文的指导,您将能够构建一个高性能、高可用、高安全的 MySQL 主从复制集群,满足企业核心业务的数据库需求。

企业级 Docker Compose 部署 MySQL 主从复制集群

1. 技术架构概览

1.1 主从复制原理

MySQL 主从复制是一种基于二进制日志(binlog)的异步数据同步机制,其核心工作原理涉及以下关键组件和流程:

1.1.1 复制核心组件

  • 二进制日志(Binary Log):主库将所有数据变更以事件(event)形式记录到 binlog 中,作为复制的唯一数据源
  • I/O 线程(IO Thread):从库启动的线程,负责与主库建立 TCP 连接,读取 binlog 事件并写入本地中继日志
  • 中继日志(Relay Log):从库本地存储的日志文件,格式与 binlog 相同,用于缓存从主库获取的变更事件
  • SQL 线程(SQL Thread):从库启动的线程,负责读取中继日志中的事件并在从库上重放,实现数据同步
  • 复制协调器(Coordinator):MySQL 5.6+ 引入,用于管理并行复制的多个工作线程

1.1.2 复制工作流程

  1. binlog 生成:主库执行写操作后,将变更记录到 binlog 中,生成唯一的 binlog 文件名和位置(Position)
  2. binlog 传输:从库 I/O 线程向主库发送复制请求,主库的 Dump 线程读取 binlog 并发送给从库
  3. 中继日志写入:从库 I/O 线程接收 binlog 事件,写入本地中继日志
  4. 事件重放:从库 SQL 线程读取中继日志,解析事件并在从库上执行相同的操作
  5. 复制状态更新:从库定期更新复制状态,记录已处理的 binlog 位置和复制延迟

1.1.3 复制格式

  • 基于语句(STATEMENT):记录 SQL 语句,体积小但可能导致数据不一致
  • 基于行(ROW):记录行级变更,数据一致性高但日志体积较大
  • 混合模式(MIXED):根据语句类型自动选择复制格式

生产环境推荐使用 ROW 格式,确保数据一致性和复制可靠性。

1.2 企业级架构优势

1.2.1 核心业务价值

  • 服务连续性保障:主库故障时可快速切换到从库,实现分钟级故障恢复,满足企业 SLA 要求
  • 线性性能扩展:通过增加从库数量,实现读性能的线性扩展,支撑高并发业务场景
  • 数据安全防护:从库作为实时备份,结合定期全量备份,构建多层次数据安全体系
  • 跨地域灾备:从库可部署在不同数据中心,实现跨地域灾备,应对区域性灾难
  • 零停机维护:通过从库进行版本升级、索引重建等维护操作,实现业务无感知

1.2.2 技术架构优势

  • 架构简单可靠:基于 MySQL 原生复制机制,无需引入复杂第三方组件
  • 部署成本可控:相比分布式数据库,硬件和运维成本显著降低
  • 兼容性广泛:支持所有 MySQL 版本和常见应用场景
  • 运维难度适中:复制配置和监控相对简单,易于掌握和维护

1.3 技术栈与组件选型

组件版本用途配置文件选型理由
MySQL8.0.34 (LTS)主从复制核心conf/master/my.cnf, conf/slave/my.cnf8.0 LTS 版本提供并行复制、GTID、半同步复制等企业级特性,稳定性和性能均优
Docker20.10.24+容器化运行环境-提供隔离性和一致性,简化部署和迁移
Docker Compose1.29.2+多容器编排docker-compose.yml支持服务依赖管理、网络配置和资源限制,适合多实例部署
Nginx1.24.0+负载均衡conf/nginx/nginx.conf轻量级高性能负载均衡器,支持健康检查和会话保持
Prometheus2.45.0+监控系统conf/prometheus/prometheus.yml时序数据库,适合监控指标的采集和存储
Grafana9.5.15+可视化监控conf/grafana/provisioning丰富的仪表盘和告警功能,提供直观的监控视图
MySQL Exporter0.14.0+MySQL 指标采集-专门用于采集 MySQL 实例的详细监控指标

1.4 复制架构模式深度分析

1.4.1 架构模式对比

架构模式适用场景优势劣势推荐指数
一主一从小型应用、开发测试配置简单,资源占用少高可用能力有限⭐⭐⭐
一主多从中大型应用、高并发读场景读性能线性扩展,高可用能力强主库复制压力较大⭐⭐⭐⭐⭐
级联复制大规模部署、跨地域复制减轻主库复制压力,适合长距离复制故障转移复杂度增加⭐⭐⭐⭐
双主复制写入密集场景、无需故障转移双活架构,写入负载分散需解决冲突,配置复杂⭐⭐⭐
环形复制多数据中心场景数据多活,容灾能力强配置复杂,容易出现循环复制⭐⭐

1.4.2 企业级推荐架构

一主多从架构是生产环境的最佳选择,具备以下特点:

  • 主库:负责所有写操作和复制源
  • 从库集群:2-5 个从库,负责读操作和故障备援
  • 负载均衡层:Nginx 或专业数据库代理(如 ProxySQL、MaxScale)
  • 监控告警系统:Prometheus + Grafana + Alertmanager
  • 自动故障转移:Orchestrator 或 MHA

1.4.3 架构演进路径

  1. 基础阶段:一主一从架构,实现基本高可用
  2. 扩展阶段:一主多从架构,提升读性能
  3. 优化阶段:引入负载均衡和监控,完善运维体系
  4. 高级阶段:实现自动故障转移和智能运维

本文将详细介绍企业级一主多从架构的完整部署与优化方案,包括 Docker Compose 配置、性能调优、安全加固和监控运维等核心内容。

2. 企业级部署准备

2.1 硬件资源规划

2.1.1 不同规模部署的资源配置

部署规模CPU内存存储网络适用场景连接数并发查询
小型部署2-4 核4-8GB100-200GB SSD1Gbps开发测试、小型应用< 500< 100
中型部署8-16 核16-32GB500GB-1TB SSD1Gbps+中小型生产环境500-2000100-500
大型部署16-32 核32-64GB1-4TB SSD10Gbps大型生产环境2000-5000500-2000
超大型部署32+ 核64GB+4TB+ NVMe25Gbps+核心业务系统> 5000> 2000

2.1.2 资源规划核心考量因素

CPU 规划

  • 主库:负责所有写操作和复制,建议 CPU 核心数 ≥ 4
  • 从库:负责读操作,建议 CPU 核心数与主库相当或略多
  • 负载均衡器:根据并发连接数,建议 2-4 核

内存规划

  • MySQL 内存 = 系统内存 × 70-80%
  • InnoDB Buffer Pool = MySQL 内存 × 50-70%
  • 从库内存建议比主库多 20-30%,用于缓存更多数据

存储规划

  • 主库:数据量 × 2(预留空间)
  • 从库:与主库相同或略大
  • 备份存储:数据量 × 3(保留多份备份)
  • IOPS 要求:主库 ≥ 1000 IOPS,从库 ≥ 500 IOPS

网络规划

  • 主从复制网络:建议独立网络,带宽 ≥ 1Gbps
  • 应用访问网络:根据并发连接数和数据传输量确定
  • 跨地域复制:考虑网络延迟,建议使用专线或高质量 VPN

2.1.3 云环境资源配置参考

云服务提供商实例类型CPU内存存储类型适用场景
AWSt3.large2 核8GBgp3开发测试
AWSm5.xlarge4 核16GBgp3小型生产
AWSr5.2xlarge8 核64GBio2中型生产
AWSr5.4xlarge16 核128GBio2大型生产
阿里云ecs.c6.large2 核8GBESSD开发测试
阿里云ecs.r6.xlarge4 核32GBESSD小型生产
阿里云ecs.r6.2xlarge8 核64GBESSD中型生产
阿里云ecs.r6.4xlarge16 核128GBESSD大型生产

2.2 软件环境要求

2.2.1 基础软件版本

软件最低版本推荐版本安装方式
Docker20.10.2424.0.7+官方脚本
Docker Compose1.29.22.21.0+官方脚本
Linux 内核4.195.4+系统更新
Python3.63.9+系统包管理器
OpenSSL1.1.13.0+系统包管理器

2.2.2 企业级系统调优

Linux 内核调优(/etc/sysctl.conf)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 编辑系统内核参数
sudo nano /etc/sysctl.conf

# 添加以下配置
# 网络优化
net.core.somaxconn = 65535 # 最大连接数
net.ipv4.tcp_max_syn_backlog = 65535 # 最大半连接数
net.ipv4.tcp_fin_timeout = 30 # FIN 超时时间
net.ipv4.tcp_keepalive_time = 300 # 保活时间
net.ipv4.tcp_keepalive_probes = 5 # 保活探测次数
net.ipv4.tcp_keepalive_intvl = 15 # 保活探测间隔
net.ipv4.tcp_max_tw_buckets = 5000 # 最大 TIME_WAIT 数
net.ipv4.tcp_fastopen = 3 # 启用 TCP Fast Open
net.core.netdev_max_backlog = 65535 # 网络设备缓冲区

# 内存管理
vm.swappiness = 10 # 交换空间使用倾向
vm.max_map_count = 262144 # 最大内存映射数
vm.overcommit_memory = 1 # 内存过度分配策略
vm.overcommit_ratio = 90 # 内存过度分配比例

# 文件系统
fs.file-max = 655350 # 最大文件描述符
fs.aio-max-nr = 1048576 # 最大异步 I/O 数

# 应用配置
sudo sysctl -p

文件描述符调优(/etc/security/limits.conf)

1
2
3
4
5
6
7
8
9
10
11
12
13
# 编辑文件描述符限制
sudo nano /etc/security/limits.conf

# 添加以下配置
* soft nofile 65535
* hard nofile 655350
root soft nofile 65535
root hard nofile 655350

# 编辑 PAM 配置
sudo nano /etc/pam.d/common-session
# 添加以下行
session required pam_limits.so

CPU 调度优化

1
2
3
4
5
# 设置 CPU 性能模式
sudo cpupower frequency-set -g performance

# 禁用 CPU 节能模式
sudo systemctl disable cpufrequtils

2.2.3 文件系统优化

存储类型选择

1
2
3
4
5
6
# 检查存储类型
lsblk -d -o NAME,TYPE,ROTA
# ROTA=0 表示 SSD,ROTA=1 表示 HDD

# 检查 IOPS 性能
sudo fio --name=randread --ioengine=libaio --iodepth=16 --rw=randread --bs=4k --direct=1 --size=1G --numjobs=4 --runtime=60 --group_reporting

挂载选项优化(/etc/fstab)

1
2
3
4
5
# 优化 SSD 挂载选项
UUID=your-disk-uuid /data ext4 defaults,noatime,nodiratime,discard,errors=remount-ro 0 2

# 优化 NVMe 挂载选项
UUID=your-nvme-uuid /data xfs defaults,noatime,nodiratime,discard,logbufs=8 0 2

文件系统参数调优

1
2
3
4
5
6
7
# 优化 ext4 文件系统
sudo tune2fs -o journal_data_writeback /dev/sda1
sudo tune2fs -O ^has_journal /dev/sda1 # 生产环境有备份时可考虑禁用日志

# 优化 XFS 文件系统
sudo xfs_admin -L data /dev/nvme0n1p1
sudo xfs_io -c "setattr -v 128k" /data

2.3 企业级目录结构

2.3.1 标准目录结构设计

创建符合企业级规范的目录结构,确保权限安全和可维护性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 创建主目录结构
mkdir -p mysql-master-slave/{
data/{master,slave1,slave2,prometheus,grafana},
conf/{master,slave,nginx,prometheus,grafana,orchestrator},
scripts/{backup,monitor,maintenance,ha},
logs/{master,slave1,slave2,nginx,prometheus,grafana},
ssl,
backup,
temp
}

# 进入部署目录
cd mysql-master-slave

# 设置权限
chmod -R 755 data/ # 数据目录
chmod -R 700 ssl/ # SSL 证书目录(严格权限)
chmod -R 755 scripts/ # 脚本目录
chmod +x scripts/**/*.sh # 执行权限
chmod -R 644 conf/ # 配置文件目录
chmod -R 755 logs/ # 日志目录
chmod -R 750 backup/ # 备份目录
chmod -R 755 temp/ # 临时目录

# 设置 Docker 卷权限
sudo chown -R 999:999 data/master/ # MySQL 用户(999)
sudo chown -R 999:999 data/slave1/
sudo chown -R 999:999 data/slave2/
sudo chown -R 65534:65534 data/prometheus/ # nobody 用户
sudo chown -R 472:472 data/grafana/ # Grafana 用户

2.3.2 目录结构说明

目录用途权限要求存储类型
data/master主库数据文件755 (mysql:mysql)SSD/NVMe
data/slave*从库数据文件755 (mysql:mysql)SSD/NVMe
data/prometheusPrometheus 数据755 (nobody:nobody)SSD
data/grafanaGrafana 数据755 (grafana:grafana)SSD
conf/*各服务配置文件644 (root:root)任何
scripts/*自动化脚本755 (root:root)任何
logs/*各服务日志755 (root:root)任何
sslSSL 证书700 (root:root)任何
backup备份文件750 (root:root)大容量存储
temp临时文件755 (root:root)任何

2.3.3 企业级配置文件管理

配置文件版本控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 初始化 Git 仓库
git init

# 创建 .gitignore 文件
cat > .gitignore << 'EOF'
# 数据目录
data/

# 日志目录
logs/

# 备份目录
backup/

# 临时目录
temp/

# SSL 证书
ssl/

# 环境变量文件
.env

# IDE 配置
.idea/
.vscode/
EOF

# 提交初始配置
git add .
git commit -m "Initial commit: MySQL master-slave cluster configuration"

配置文件模板管理

1
2
3
4
5
6
7
8
# 创建配置模板目录
mkdir -p templates/

# 复制配置文件作为模板
cp -r conf/ templates/

# 替换敏感信息为变量
sed -i 's/YourStrongPassword/{{MYSQL_ROOT_PASSWORD}}/g' templates/master/my.cnf

2.4 企业级配置文件

2.4.1 主库配置(conf/master/my.cnf)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
[mysqld]
# 基础配置
server-id = 1 # 唯一服务器 ID
port = 3306 # 监听端口
bind-address = 0.0.0.0 # 绑定地址(容器环境推荐)
socket = /var/run/mysqld/mysqld.sock # Socket 文件路径
pid-file = /var/run/mysqld/mysqld.pid # PID 文件路径

# 二进制日志配置(核心复制组件)
log-bin = mysql-bin # 二进制日志文件名前缀
binlog-format = ROW # 复制格式(生产环境推荐)
binlog-row-image = FULL # 行镜像模式(确保数据一致性)
max-binlog-size = 100M # 单个 binlog 文件最大大小
expire-logs-days = 7 # binlog 保留天数
sync-binlog = 100 # 每 100 个事务同步一次 binlog
binlog-checksum = CRC32 # binlog 校验和
binlog-rows-query-log-events = ON # 记录原始 SQL 语句

# 复制配置
log-slave-updates = 1 # 从库更新也记录到 binlog(级联复制需要)
enforce-gtid-consistency = 1 # 强制 GTID 一致性
gtid-mode = ON # 启用 GTID 复制
binlog-ignore-db = mysql,information_schema,performance_schema,sys # 忽略复制的数据库
replicate-wild-ignore-table = mysql.% # 忽略 mysql 库下所有表

# 连接与线程配置
max_connections = 2000 # 最大连接数
max_connect_errors = 10000 # 最大连接错误数
max_allowed_packet = 64M # 最大数据包大小
wait_timeout = 3600 # 非交互连接超时
interactive_timeout = 3600 # 交互连接超时
thread_cache_size = 128 # 线程缓存大小
table_open_cache = 2048 # 表打开缓存

# 内存配置
innodb_buffer_pool_size = 2G # InnoDB 缓冲池大小(推荐内存的 50-70%)
innodb_buffer_pool_instances = 4 # 缓冲池实例数(与 CPU 核心数匹配)
innodb_log_buffer_size = 64M # InnoDB 日志缓冲区大小
innodb_sort_buffer_size = 1M # InnoDB 排序缓冲区大小
join_buffer_size = 2M # 连接缓冲区大小
read_buffer_size = 1M # 读缓冲区大小
read_rnd_buffer_size = 4M # 随机读缓冲区大小

# InnoDB 核心配置
innodb_log_file_size = 512M # InnoDB 日志文件大小
innodb_log_files_in_group = 2 # 日志文件组数量
innodb_flush_log_at_trx_commit = 2 # 日志刷新策略(2 性能优先)
innodb_flush_method = O_DIRECT # IO 刷新方法(直接 IO)
innodb_io_capacity = 2000 # IO 容量(根据存储设备调整)
innodb_io_capacity_max = 4000 # 最大 IO 容量
innodb_lru_scan_depth = 1024 # LRU 扫描深度
innodb_page_cleaners = 4 # 页清理线程数
innodb_purge_threads = 4 # purge 线程数
innodb_thread_concurrency = 0 # 并发线程数(0 表示不限制)

# 存储配置
innodb_file_per_table = 1 # 每张表独立表空间
innodb_file_format = Barracuda # 文件格式
innodb_file_format_max = Barracuda # 最大文件格式
innodb_stats_on_metadata = 0 # 关闭元数据统计(提升性能)
innodb_autoinc_lock_mode = 2 # 自增锁模式(提升并发)

# 字符集配置
character-set-server = utf8mb4 # 服务器字符集
collation-server = utf8mb4_unicode_ci # 服务器校对规则
init-connect = 'SET NAMES utf8mb4' # 初始化连接字符集

# 安全配置
symbolic-links = 0 # 禁用符号链接
skip-name-resolve = 1 # 跳过主机名解析(提升性能)
skip-symbolic-links = 1 # 禁用符号链接
local-infile = 0 # 禁用本地文件导入
secure-file-priv = /tmp # 限制文件操作目录

# 监控配置
performance_schema = ON # 启用性能模式
performance_schema_max_thread_instances = 2000 # 最大线程实例数
innodb_monitor_enable = all # 启用所有 InnoDB 监控
userstat = 1 # 启用用户统计

# 半同步复制配置
plugin-load = "rpl_semi_sync_master=semisync_master.so"
rpl_semi_sync_master_enabled = 1 # 启用半同步复制
rpl_semi_sync_master_timeout = 10000 # 超时时间(10秒)
rpl_semi_sync_master_wait_no_slave = 1 # 无从库时仍等待
rpl_semi_sync_master_wait_point = 'AFTER_SYNC' # 等待点(推荐)

# 其他优化配置
sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION" # SQL 模式
lower_case_table_names = 0 # 表名大小写敏感(Linux 推荐)
max_heap_table_size = 64M # 临时表最大大小
tmp_table_size = 64M # 临时表大小
query_cache_type = 0 # 禁用查询缓存(8.0+ 已废弃)
query_cache_size = 0 # 查询缓存大小

# 审计配置(可选)
# plugin-load = "audit_log=audit_log.so"
# audit_log_policy = ALL
# audit_log_format = JSON
# audit_log_file = /var/log/mysql/audit.log

2.4.2 从库配置(conf/slave/my.cnf)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
[mysqld]
# 基础配置
server-id = 2 # 唯一服务器 ID(每个从库必须不同)
port = 3306 # 监听端口
bind-address = 0.0.0.0 # 绑定地址(容器环境推荐)
socket = /var/run/mysqld/mysqld.sock # Socket 文件路径
pid-file = /var/run/mysqld/mysqld.pid # PID 文件路径

# 中继日志配置(从库核心组件)
relay-log = mysql-relay-bin # 中继日志文件名前缀
relay-log-index = mysql-relay-bin.index # 中继日志索引文件
relay-log-info-file = relay-log.info # 中继日志信息文件
relay-log-recovery = 1 # 中继日志自动恢复
max-relay-log-size = 100M # 单个中继日志最大大小
relay-log-space-limit = 4G # 中继日志空间限制

# 复制配置
read-only = 1 # 启用只读模式
super-read-only = 1 # 超级用户也只读
skip-slave-start = 0 # 自动启动复制
slave-net-timeout = 60 # 网络超时时间(秒)
slave-skip-errors = "" # 不跳过任何错误(生产环境推荐)

# 并行复制配置(提升从库性能核心)
slave-parallel-type = LOGICAL_CLOCK # 并行复制类型(基于逻辑时钟)
slave-parallel-workers = 8 # 并行工作线程数(根据 CPU 核心数调整)
slave_preserve_commit_order = 1 # 保持提交顺序
slave_transaction_retries = 10 # 事务重试次数
slave-checkpoint-period = 300 # 从库检查点周期
slave-checkpoint-group = 512 # 从库检查点组大小

# 复制延迟配置(可选,用于灾备)
# MASTER_DELAY = 3600 # 从库延迟主库 1 小时

# 连接与线程配置
max_connections = 2500 # 最大连接数(从库可适当增大)
max_connect_errors = 10000 # 最大连接错误数
max_allowed_packet = 64M # 最大数据包大小
wait_timeout = 3600 # 非交互连接超时
interactive_timeout = 3600 # 交互连接超时
thread_cache_size = 128 # 线程缓存大小
thread_pool_size = 8 # 线程池大小(MySQL 5.6+)

# 内存配置(从库可适当增大)
innodb_buffer_pool_size = 3G # InnoDB 缓冲池大小(比主库大 20-30%)
innodb_buffer_pool_instances = 4 # 缓冲池实例数(与 CPU 核心数匹配)
innodb_log_buffer_size = 64M # InnoDB 日志缓冲区大小
innodb_sort_buffer_size = 1M # InnoDB 排序缓冲区大小
join_buffer_size = 2M # 连接缓冲区大小
read_buffer_size = 2M # 读缓冲区大小
read_rnd_buffer_size = 4M # 随机读缓冲区大小

# InnoDB 核心配置
innodb_log_file_size = 512M # InnoDB 日志文件大小
innodb_log_files_in_group = 2 # 日志文件组数量
innodb_flush_log_at_trx_commit = 2 # 日志刷新策略(2 性能优先)
innodb_flush_method = O_DIRECT # IO 刷新方法(直接 IO)
innodb_io_capacity = 2000 # IO 容量(根据存储设备调整)
innodb_io_capacity_max = 4000 # 最大 IO 容量
innodb_lru_scan_depth = 1024 # LRU 扫描深度
innodb_page_cleaners = 4 # 页清理线程数
innodb_purge_threads = 4 # purge 线程数
innodb_thread_concurrency = 0 # 并发线程数(0 表示不限制)

# 存储配置
innodb_file_per_table = 1 # 每张表独立表空间
innodb_file_format = Barracuda # 文件格式
innodb_file_format_max = Barracuda # 最大文件格式
innodb_stats_on_metadata = 0 # 关闭元数据统计(提升性能)
innodb_autoinc_lock_mode = 2 # 自增锁模式(提升并发)

# 字符集配置
character-set-server = utf8mb4 # 服务器字符集
collation-server = utf8mb4_unicode_ci # 服务器校对规则
init-connect = 'SET NAMES utf8mb4' # 初始化连接字符集

# 安全配置
symbolic-links = 0 # 禁用符号链接
skip-name-resolve = 1 # 跳过主机名解析(提升性能)
skip-symbolic-links = 1 # 禁用符号链接
local-infile = 0 # 禁用本地文件导入
secure-file-priv = /tmp # 限制文件操作目录

# 监控配置
performance_schema = ON # 启用性能模式
performance_schema_max_thread_instances = 2500 # 最大线程实例数
innodb_monitor_enable = all # 启用所有 InnoDB 监控
userstat = 1 # 启用用户统计

# 半同步复制配置
plugin-load = "rpl_semi_sync_slave=semisync_slave.so"
rpl_semi_sync_slave_enabled = 1 # 启用半同步复制

# 其他优化配置
sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION" # SQL 模式
lower_case_table_names = 0 # 表名大小写敏感(Linux 推荐)
max_heap_table_size = 64M # 临时表最大大小
tmp_table_size = 64M # 临时表大小
query_cache_type = 0 # 禁用查询缓存(8.0+ 已废弃)
query_cache_size = 0 # 查询缓存大小

# 从库读取优化
innodb_adaptive_hash_index = 1 # 自适应哈希索引
innodb_adaptive_flushing = 1 # 自适应刷新
innodb_old_blocks_time = 1000 # 旧块时间(毫秒)

2.4.3 环境变量配置(.env)

创建企业级 .env 文件,集中管理所有敏感信息和配置参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# ==========================================
# MySQL 核心配置
# ==========================================

# 根用户配置
MYSQL_ROOT_PASSWORD=YourStrongRootPassword2024! # 强密码要求:至少 12 位,包含大小写字母、数字和特殊字符

# 复制用户配置(用于主从复制)
MYSQL_REPL_USER=repl # 复制用户名
MYSQL_REPL_PASSWORD=YourStrongReplPassword2024! # 复制用户密码

# 监控用户配置
MYSQL_EXPORTER_USER=exporter # 监控用户名
MYSQL_EXPORTER_PASSWORD=YourStrongExporterPassword2024! # 监控用户密码

# 应用用户配置
MYSQL_APP_USER=app_user # 应用用户名
MYSQL_APP_PASSWORD=YourStrongAppPassword2024! # 应用用户密码

# 初始化配置
MYSQL_DATABASE=business_db # 初始化数据库名
MYSQL_CHARSET=utf8mb4 # 数据库字符集
MYSQL_COLLATION=utf8mb4_unicode_ci # 数据库校对规则

# ==========================================
# 服务器资源配置
# ==========================================

# 主机资源信息
HOST_MEMORY=16G # 主机内存总量
HOST_CPU_CORES=8 # 主机 CPU 核心数

# 容器资源限制
CONTAINER_MASTER_MEMORY=8G # 主库容器内存限制
CONTAINER_MASTER_CPU=4 # 主库容器 CPU 限制
CONTAINER_SLAVE_MEMORY=10G # 从库容器内存限制(比主库大)
CONTAINER_SLAVE_CPU=4 # 从库容器 CPU 限制

# ==========================================
# 备份配置
# ==========================================

# 备份策略
BACKUP_RETENTION_DAYS=7 # 备份保留天数
BACKUP_DIR=/backup # 备份目录
BACKUP_CRON_SCHEDULE=0 2 * * * # 备份执行计划(每天凌晨 2 点)
BACKUP_COMPRESSION=ON # 启用备份压缩
BACKUP_ENCRYPTION=ON # 启用备份加密
BACKUP_ENCRYPTION_KEY=YourStrongEncryptionKey2024! # 备份加密密钥

# ==========================================
# 监控配置
# ==========================================

# Prometheus 配置
PROMETHEUS_PORT=9090 # Prometheus 端口
PROMETHEUS_RETENTION=15d # 监控数据保留天数

# Grafana 配置
GRAFANA_PORT=3000 # Grafana 端口
GRAFANA_ADMIN_USER=admin # Grafana 管理员用户名
GRAFANA_ADMIN_PASSWORD=YourStrongGrafanaPassword2024! # Grafana 管理员密码
GRAFANA_DASHBOARD_ID=7362 # MySQL 监控仪表盘 ID

# Alertmanager 配置
ALERTMANAGER_PORT=9093 # Alertmanager 端口

# ==========================================
# 网络配置
# ==========================================

# 网络子网
NETWORK_SUBNET=172.20.0.0/16 # Docker 网络子网
NETWORK_GATEWAY=172.20.0.1 # Docker 网络网关

# 端口映射
MASTER_PORT=3306 # 主库映射端口
SLAVE1_PORT=3307 # 从库 1 映射端口
SLAVE2_PORT=3308 # 从库 2 映射端口
NGINX_PORT=3309 # Nginx 负载均衡映射端口

# ==========================================
# 高可用配置
# ==========================================

# Orchestrator 配置
ORCHESTRATOR_PORT=3001 # Orchestrator 端口
ORCHESTRATOR_USER=orchestrator # Orchestrator 用户名
ORCHESTRATOR_PASSWORD=YourStrongOrchestratorPassword2024! # Orchestrator 密码

# 故障转移配置
FAILOVER_AUTO=1 # 启用自动故障转移
FAILOVER_CHECK_INTERVAL=5 # 故障检测间隔(秒)
FAILOVER_RECOVERY_INTERVAL=10 # 故障恢复间隔(秒)

# ==========================================
# 安全配置
# ==========================================

# SSL 配置
SSL_ENABLED=1 # 启用 SSL
SSL_CERT_PATH=/etc/mysql/ssl # SSL 证书路径

# 密码策略
PASSWORD_VALIDATION_PLUGIN=ON # 启用密码验证插件
PASSWORD_VALIDATION_LENGTH=12 # 密码最小长度
PASSWORD_VALIDATION_COMPLEXITY=STRONG # 密码复杂度要求

3. 企业级 Docker Compose 配置

创建企业级 docker-compose.yml 文件,支持一主多从架构并集成监控、高可用等企业级特性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
version: '3.8'

# 扩展配置
x-mysql-common:
&mysql-common
image: mysql:8.0.34 # MySQL 8.0 LTS 版本
restart: always
environment:
- TZ=Asia/Shanghai
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_USER=${MYSQL_REPL_USER}
- MYSQL_PASSWORD=${MYSQL_REPL_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
volumes:
- ./ssl:/etc/mysql/ssl
security_opt:
- no-new-privileges:true
networks:
- mysql-network

x-mysql-healthcheck:
&mysql-healthcheck
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s

services:
# ==========================================
# MySQL 主库服务
# ==========================================
mysql-master:
<<: *mysql-common
container_name: mysql-master
ports:
- "${MASTER_PORT}:3306"
volumes:
- ./data/master:/var/lib/mysql
- ./conf/master/my.cnf:/etc/mysql/conf.d/my.cnf
- ./logs/master:/var/log/mysql
- ./ssl:/etc/mysql/ssl
environment:
<<: *mysql-common.environment
- MYSQL_INITDB_SKIP_TZINFO=1
resources:
limits:
cpus: '${CONTAINER_MASTER_CPU}'
memory: '${CONTAINER_MASTER_MEMORY}'
reservations:
cpus: '${CONTAINER_MASTER_CPU}'
memory: '${CONTAINER_MASTER_MEMORY}'
<<: *mysql-healthcheck
depends_on:
- mysql-exporter-master

# ==========================================
# MySQL 从库服务
# ==========================================
mysql-slave1:
<<: *mysql-common
container_name: mysql-slave1
ports:
- "${SLAVE1_PORT}:3306"
volumes:
- ./data/slave1:/var/lib/mysql
- ./conf/slave/my.cnf:/etc/mysql/conf.d/my.cnf
- ./logs/slave1:/var/log/mysql
- ./ssl:/etc/mysql/ssl
resources:
limits:
cpus: '${CONTAINER_SLAVE_CPU}'
memory: '${CONTAINER_SLAVE_MEMORY}'
reservations:
cpus: '${CONTAINER_SLAVE_CPU}'
memory: '${CONTAINER_SLAVE_MEMORY}'
<<: *mysql-healthcheck
depends_on:
- mysql-master
- mysql-exporter-slave1

mysql-slave2:
<<: *mysql-common
container_name: mysql-slave2
ports:
- "${SLAVE2_PORT}:3306"
volumes:
- ./data/slave2:/var/lib/mysql
- ./conf/slave/my.cnf:/etc/mysql/conf.d/my.cnf
- ./logs/slave2:/var/log/mysql
- ./ssl:/etc/mysql/ssl
resources:
limits:
cpus: '${CONTAINER_SLAVE_CPU}'
memory: '${CONTAINER_SLAVE_MEMORY}'
reservations:
cpus: '${CONTAINER_SLAVE_CPU}'
memory: '${CONTAINER_SLAVE_MEMORY}'
<<: *mysql-healthcheck
depends_on:
- mysql-master
- mysql-exporter-slave2

# ==========================================
# MySQL Exporter 监控服务
# ==========================================
mysql-exporter-master:
image: prom/mysqld-exporter:v0.14.0
container_name: mysql-exporter-master
ports:
- "9104:9104"
environment:
- DATA_SOURCE_NAME=${MYSQL_EXPORTER_USER}:${MYSQL_EXPORTER_PASSWORD}@(mysql-master:3306)/
restart: always
depends_on:
- mysql-master
networks:
- mysql-network

mysql-exporter-slave1:
image: prom/mysqld-exporter:v0.14.0
container_name: mysql-exporter-slave1
ports:
- "9105:9104"
environment:
- DATA_SOURCE_NAME=${MYSQL_EXPORTER_USER}:${MYSQL_EXPORTER_PASSWORD}@(mysql-slave1:3306)/
restart: always
depends_on:
- mysql-slave1
networks:
- mysql-network

mysql-exporter-slave2:
image: prom/mysqld-exporter:v0.14.0
container_name: mysql-exporter-slave2
ports:
- "9106:9104"
environment:
- DATA_SOURCE_NAME=${MYSQL_EXPORTER_USER}:${MYSQL_EXPORTER_PASSWORD}@(mysql-slave2:3306)/
restart: always
depends_on:
- mysql-slave2
networks:
- mysql-network

# Nginx 负载均衡服务(可选)
nginx:
image: nginx:1.24-alpine
container_name: mysql-lb
ports:
- "3309:3309"
volumes:
- ./conf/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./logs/nginx:/var/log/nginx
restart: always
depends_on:
- mysql-slave1
- mysql-slave2
healthcheck:
test: ["CMD", "nginx", "-t"]
interval: 30s
timeout: 10s
retries: 3
networks:
- mysql-network

# Prometheus 监控服务
prometheus:
image: prom/prometheus:v2.45.0
container_name: prometheus
volumes:
- ./conf/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- ./data/prometheus:/prometheus
ports:
- "${PROMETHEUS_PORT}:9090"
restart: always
depends_on:
- mysql-master
- mysql-slave1
- mysql-slave2
networks:
- mysql-network

# Grafana 可视化服务
grafana:
image: grafana/grafana:9.5.15
container_name: grafana
volumes:
- ./data/grafana:/var/lib/grafana
- ./conf/grafana/provisioning:/etc/grafana/provisioning
- ./conf/grafana/dashboards:/var/lib/grafana/dashboards
ports:
- "${GRAFANA_PORT}:3000"
restart: always
environment:
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD}
- GF_USERS_ALLOW_SIGN_UP=false
- GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource
depends_on:
- prometheus
networks:
- mysql-network

# 网络配置
networks:
mysql-network:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
driver_opts:
com.docker.network.bridge.name: "mysql-br"
com.docker.network.bridge.enable_icc: "true"
com.docker.network.bridge.enable_ip_masquerade: "true"

3.1 Nginx 负载均衡配置

创建 conf/nginx/nginx.conf 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# 用户配置
user nginx;
worker_processes auto;
pid /var/run/nginx.pid;

events {
worker_connections 4096;
multi_accept on;
use epoll;
}

http {
# 基本配置
include /etc/nginx/mime.types;
default_type application/octet-stream;

# 日志配置
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'"$upstream_addr" "$upstream_status" "$upstream_response_time"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;

# 性能优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 100;

# 上游服务器配置
upstream mysql_read {
least_conn;
server mysql-slave1:3306 max_fails=3 fail_timeout=30s weight=1;
server mysql-slave2:3306 max_fails=3 fail_timeout=30s weight=1;
}

# 主服务器配置
server {
listen 3309;
server_name localhost;

# 健康检查
location /health {
stub_status on;
access_log off;
allow 127.0.0.1;
allow 172.20.0.0/16;
deny all;
}

# MySQL 读请求负载均衡
location / {
proxy_pass http://mysql_read;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Connection "";

# 超时配置
proxy_connect_timeout 10s;
proxy_send_timeout 10s;
proxy_read_timeout 30s;
}
}
}

3.2 Prometheus 监控配置

创建 conf/prometheus/prometheus.yml 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
global:
scrape_interval: 15s
evaluation_interval: 15s
external_labels:
monitor: 'mysql-cluster'

# 告警管理
alerting:
alertmanagers:
- static_configs:
- targets: []

# 告警规则
rule_files:
- /etc/prometheus/rules.yml

# 抓取配置
scrape_configs:
# MySQL 主库监控
- job_name: 'mysql-master'
static_configs:
- targets: ['mysql-master:9104']
metrics_path: '/metrics'
relabel_configs:
- source_labels: [__address__]
regex: '(.*):9104'
target_label: instance
replacement: '$1'

# MySQL 从库 1 监控
- job_name: 'mysql-slave1'
static_configs:
- targets: ['mysql-slave1:9104']
metrics_path: '/metrics'
relabel_configs:
- source_labels: [__address__]
regex: '(.*):9104'
target_label: instance
replacement: '$1'

# MySQL 从库 2 监控
- job_name: 'mysql-slave2'
static_configs:
- targets: ['mysql-slave2:9104']
metrics_path: '/metrics'
relabel_configs:
- source_labels: [__address__]
regex: '(.*):9104'
target_label: instance
replacement: '$1'

# Nginx 监控
- job_name: 'nginx'
static_configs:
- targets: ['nginx:3309']
metrics_path: '/health'
relabel_configs:
- source_labels: [__address__]
regex: '(.*):3309'
target_label: instance
replacement: '$1'

3.3 MySQL Exporter 配置

为了监控 MySQL 实例,需要在每个 MySQL 容器中部署 MySQL Exporter。可以通过修改 Docker Compose 配置,添加 MySQL Exporter 服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# MySQL Exporter for master
mysql-exporter-master:
image: prom/mysqld-exporter:v0.14.0
container_name: mysql-exporter-master
ports:
- "9104:9104"
environment:
- DATA_SOURCE_NAME=exporter:exporter-password@(mysql-master:3306)/
restart: always
depends_on:
- mysql-master
networks:
- mysql-network

# 类似配置 mysql-exporter-slave1 和 mysql-exporter-slave2

4. 企业级部署步骤

4.1 部署前验证

  1. 环境检查

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # 检查 Docker 版本
    docker --version

    # 检查 Docker Compose 版本
    docker compose version

    # 检查系统资源
    free -h
    df -h

    # 检查网络连接
    ping -c 4 mysql.com
  2. 配置文件验证

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 检查目录结构
    ls -la

    # 检查环境变量文件
    cat .env

    # 检查配置文件
    ls -la conf/master/
    ls -la conf/slave/
  3. 生成 SSL 证书(可选)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 生成自签名证书
    openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
    -keyout ssl/server-key.pem \
    -out ssl/server-cert.pem \
    -subj "/C=CN/ST=Beijing/L=Beijing/O=Company/OU=IT/CN=mysql-cluster"

    # 设置权限
    chmod 600 ssl/server-key.pem
    chmod 644 ssl/server-cert.pem

4.2 启动服务

1
2
3
4
5
6
7
8
# 启动所有服务
docker-compose up -d

# 检查服务状态
docker-compose ps

# 查看启动日志
docker-compose logs -f --tail=100

4.3 主库初始化配置

  1. 进入主库容器

    1
    docker-compose exec mysql-master bash
  2. 登录 MySQL

    1
    mysql -u root -p${MYSQL_ROOT_PASSWORD}
  3. 创建监控用户

    1
    2
    3
    4
    5
    6
    7
    8
    -- 创建监控用户
    CREATE USER 'exporter'@'%' IDENTIFIED BY 'exporter-password';

    -- 授予监控权限
    GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'%';

    -- 刷新权限
    FLUSH PRIVILEGES;
  4. 查看主库状态

    1
    2
    -- 查看主库状态
    SHOW MASTER STATUS\G;

    记录 FilePosition 的值,后续配置从库时需要使用。

  5. 验证二进制日志配置

    1
    2
    3
    4
    5
    -- 查看二进制日志配置
    SHOW VARIABLES LIKE '%binlog%';

    -- 查看服务器 ID
    SHOW VARIABLES LIKE 'server_id';

4.4 从库初始化配置

4.4.1 配置从库 1

  1. 进入从库 1 容器

    1
    docker-compose exec mysql-slave1 bash
  2. 登录 MySQL

    1
    mysql -u root -p${MYSQL_ROOT_PASSWORD}
  3. 配置主从复制

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    -- 停止从库复制
    STOP SLAVE;

    -- 重置从库状态
    RESET SLAVE ALL;

    -- 配置主库信息
    CHANGE MASTER TO
    MASTER_HOST='mysql-master',
    MASTER_USER='${MYSQL_REPL_USER}',
    MASTER_PASSWORD='${MYSQL_REPL_PASSWORD}',
    MASTER_PORT=3306,
    MASTER_LOG_FILE='mysql-bin.000001', -- 从主库状态中获取
    MASTER_LOG_POS=156, -- 从主库状态中获取
    MASTER_CONNECT_RETRY=30,
    MASTER_HEARTBEAT_PERIOD=10000,
    MASTER_RETRY_COUNT=86400;

    -- 启动从库复制
    START SLAVE;
  4. 查看从库状态

    1
    SHOW SLAVE STATUS\G;

    检查 Slave_IO_RunningSlave_SQL_Running 是否均为 Yes

4.4.2 配置从库 2

按照相同步骤配置从库 2,确保使用相同的主库日志文件和位置。

4.5 验证主从复制

  1. 测试数据同步

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    -- 在主库创建测试数据
    USE ${MYSQL_DATABASE};

    CREATE TABLE IF NOT EXISTS test_table (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    value INT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );

    INSERT INTO test_table (name, value) VALUES
    ('test1', 100),
    ('test2', 200),
    ('test3', 300);
  2. 在从库验证数据

    1
    2
    3
    4
    5
    6
    7
    -- 在从库 1 验证
    USE ${MYSQL_DATABASE};
    SELECT * FROM test_table;

    -- 在从库 2 验证
    USE ${MYSQL_DATABASE};
    SELECT * FROM test_table;
  3. 验证复制延迟

    1
    2
    3
    -- 在从库查看复制延迟
    SHOW SLAVE STATUS\G;
    -- 查看 Seconds_Behind_Master 值

4.6 负载均衡配置

  1. 验证 Nginx 配置

    1
    docker-compose exec nginx nginx -t
  2. 测试负载均衡

    1
    2
    3
    4
    5
    6
    # 测试连接
    mysql -h localhost -P 3309 -u root -p${MYSQL_ROOT_PASSWORD}

    # 执行查询
    USE ${MYSQL_DATABASE};
    SELECT * FROM test_table;

4.7 监控服务配置

  1. 访问 Prometheus

  2. 访问 Grafana

    • 打开浏览器:http://localhost:3000
    • 登录:admin / ${GRAFANA_ADMIN_PASSWORD}
    • 导入 MySQL 监控仪表盘(ID: 7362)

5. 企业级主从复制测试

5.1 基础功能测试

5.1.1 数据同步测试

  1. 在主库创建测试数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    docker-compose exec mysql-master mysql -u root -p${MYSQL_ROOT_PASSWORD} -e "
    USE ${MYSQL_DATABASE};
    CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL UNIQUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );
    INSERT INTO users (name, email) VALUES
    ('张三', 'zhangsan@example.com'),
    ('李四', 'lisi@example.com'),
    ('王五', 'wangwu@example.com');
    SELECT * FROM users;
    "
  2. 在从库 1 验证数据

    1
    2
    3
    4
    docker-compose exec mysql-slave1 mysql -u root -p${MYSQL_ROOT_PASSWORD} -e "
    USE ${MYSQL_DATABASE};
    SELECT * FROM users;
    "
  3. 在从库 2 验证数据

    1
    2
    3
    4
    docker-compose exec mysql-slave2 mysql -u root -p${MYSQL_ROOT_PASSWORD} -e "
    USE ${MYSQL_DATABASE};
    SELECT * FROM users;
    "

5.1.2 只读模式测试

  1. 在从库尝试写操作

    1
    2
    3
    4
    docker-compose exec mysql-slave1 mysql -u root -p${MYSQL_ROOT_PASSWORD} -e "
    USE ${MYSQL_DATABASE};
    INSERT INTO users (name, email) VALUES ('赵六', 'zhaoliu@example.com');
    "

    预期结果:收到错误提示,因为从库配置了 read-only = 1

  2. 验证从库状态

    1
    2
    3
    docker-compose exec mysql-slave1 mysql -u root -p${MYSQL_ROOT_PASSWORD} -e "
    SHOW VARIABLES LIKE 'read_only';
    "

5.2 高级功能测试

5.2.1 大事务测试

  1. 在主库执行大事务

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    docker-compose exec mysql-master mysql -u root -p${MYSQL_ROOT_PASSWORD} -e "
    USE ${MYSQL_DATABASE};
    -- 创建测试表
    CREATE TABLE IF NOT EXISTS large_table (
    id INT AUTO_INCREMENT PRIMARY KEY,
    data VARCHAR(1000) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );
    -- 插入大量数据
    DELIMITER //
    CREATE PROCEDURE insert_large_data()
    BEGIN
    DECLARE i INT DEFAULT 0;
    WHILE i < 1000 DO
    INSERT INTO large_table (data) VALUES (CONCAT('test data ', i));
    SET i = i + 1;
    END WHILE;
    END //
    DELIMITER ;
    -- 执行存储过程
    CALL insert_large_data();
    -- 查看结果
    SELECT COUNT(*) FROM large_table;
    "
  2. 在从库验证同步

    1
    2
    3
    4
    docker-compose exec mysql-slave1 mysql -u root -p${MYSQL_ROOT_PASSWORD} -e "
    USE ${MYSQL_DATABASE};
    SELECT COUNT(*) FROM large_table;
    "

5.2.2 故障恢复测试

  1. 模拟主库故障

    1
    2
    3
    4
    5
    6
    7
    # 停止主库
    docker-compose stop mysql-master

    # 检查从库状态
    docker-compose exec mysql-slave1 mysql -u root -p${MYSQL_ROOT_PASSWORD} -e "
    SHOW SLAVE STATUS\G;
    "
  2. 恢复主库

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 启动主库
    docker-compose start mysql-master

    # 等待主库启动
    sleep 30

    # 检查从库状态
    docker-compose exec mysql-slave1 mysql -u root -p${MYSQL_ROOT_PASSWORD} -e "
    SHOW SLAVE STATUS\G;
    "

5.2.3 负载均衡测试

  1. 测试 Nginx 负载均衡

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 执行多次查询,验证负载均衡
    for i in {1..10}; do
    echo "Query $i:"
    mysql -h localhost -P 3309 -u root -p${MYSQL_ROOT_PASSWORD} -e "
    USE ${MYSQL_DATABASE};
    SELECT @@server_id, NOW();
    "
    sleep 1
    done
  2. 验证负载均衡效果

    1
    2
    # 查看 Nginx 访问日志
    docker-compose logs nginx | grep -E 'upstream_addr|upstream_response_time'

5.3 性能测试

5.3.1 读性能测试

  1. 使用 sysbench 测试从库读性能

    1
    2
    3
    4
    5
    6
    7
    8
    # 安装 sysbench
    sudo apt-get install sysbench -y

    # 准备测试数据
    sysbench oltp_read_only --table-size=100000 --mysql-host=localhost --mysql-port=3307 --mysql-user=root --mysql-password=${MYSQL_ROOT_PASSWORD} --mysql-db=${MYSQL_DATABASE} prepare

    # 执行测试
    sysbench oltp_read_only --table-size=100000 --mysql-host=localhost --mysql-port=3307 --mysql-user=root --mysql-password=${MYSQL_ROOT_PASSWORD} --mysql-db=${MYSQL_DATABASE} --threads=16 --time=60 run
  2. 测试负载均衡后的读性能

    1
    sysbench oltp_read_only --table-size=100000 --mysql-host=localhost --mysql-port=3309 --mysql-user=root --mysql-password=${MYSQL_ROOT_PASSWORD} --mysql-db=${MYSQL_DATABASE} --threads=32 --time=60 run

5.3.2 复制延迟测试

  1. 监控复制延迟

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    # 创建监控脚本
    cat > monitor_replication.sh << 'EOF'
    #!/bin/bash

    while true; do
    echo "$(date '+%Y-%m-%d %H:%M:%S')"
    docker-compose exec mysql-slave1 mysql -u root -p${MYSQL_ROOT_PASSWORD} -e "
    SHOW SLAVE STATUS\G;
    " | grep -E 'Seconds_Behind_Master|Slave_IO_Running|Slave_SQL_Running'
    echo "---"
    sleep 5
    done
    EOF

    # 执行监控
    chmod +x monitor_replication.sh
    ./monitor_replication.sh
  2. 在主库执行大量写操作

    1
    2
    3
    4
    5
    6
    7
    docker-compose exec mysql-master mysql -u root -p${MYSQL_ROOT_PASSWORD} -e "
    USE ${MYSQL_DATABASE};
    -- 插入更多数据
    CALL insert_large_data();
    CALL insert_large_data();
    CALL insert_large_data();
    "
  3. 观察复制延迟变化
    查看监控脚本输出,观察 Seconds_Behind_Master 值的变化。

6. 企业级高级配置

6.1 多从库架构设计

6.1.1 级联复制架构

对于大规模部署,可以采用级联复制架构,减少主库的复制压力:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 在 docker-compose.yml 中添加级联从库
mysql-slave3:
image: mysql:8.0.34
container_name: mysql-slave3
ports:
- "3310:3306"
volumes:
- ./data/slave3:/var/lib/mysql
- ./conf/slave/my.cnf:/etc/mysql/conf.d/my.cnf
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_USER=${MYSQL_REPL_USER}
- MYSQL_PASSWORD=${MYSQL_REPL_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
restart: always
depends_on:
- mysql-slave1 # 从从库 1 复制
networks:
- mysql-network

配置步骤

  1. 在主库上启用 log-slave-updates
  2. 将从库 3 的主库设置为 mysql-slave1
  3. 确保从库 1 配置了 server-id 且唯一

6.1.2 地理分布式复制

对于跨地域部署,可以配置地理分布式复制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 远程从库配置示例
mysql-remote-slave:
image: mysql:8.0.34
container_name: mysql-remote-slave
ports:
- "3306:3306"
volumes:
- ./data/remote:/var/lib/mysql
- ./conf/slave/my.cnf:/etc/mysql/conf.d/my.cnf
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_USER=${MYSQL_REPL_USER}
- MYSQL_PASSWORD=${MYSQL_REPL_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
restart: always
networks:
- external-network

networks:
external-network:
external: true
name: public-network

优化建议

  • 使用 MASTER_HEARTBEAT_PERIOD 保持连接
  • 调整 MASTER_CONNECT_RETRY 适应网络波动
  • 考虑使用 GTID 简化故障转移

6.2 半同步复制优化

6.2.1 半同步复制配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- 在主库上配置
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
SET GLOBAL rpl_semi_sync_master_enabled = 1;
SET GLOBAL rpl_semi_sync_master_timeout = 10000; -- 10秒
SET GLOBAL rpl_semi_sync_master_wait_no_slave = 1; -- 无从库时仍等待
SET GLOBAL rpl_semi_sync_master_wait_point = 'AFTER_SYNC'; -- 推荐设置

-- 在从库上配置
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
SET GLOBAL rpl_semi_sync_slave_enabled = 1;

-- 重启从库 IO 线程
STOP SLAVE IO_THREAD;
START SLAVE IO_THREAD;

6.2.2 半同步复制监控

1
2
3
4
5
6
7
8
-- 主库状态监控
SHOW GLOBAL STATUS LIKE 'Rpl_semi_sync_master%';

-- 从库状态监控
SHOW GLOBAL STATUS LIKE 'Rpl_semi_sync_slave%';

-- 半同步复制配置
SHOW GLOBAL VARIABLES LIKE 'rpl_semi_sync%';

关键指标

  • Rpl_semi_sync_master_clients:活跃的半同步从库数量
  • Rpl_semi_sync_master_yes_tx:成功的半同步事务数
  • Rpl_semi_sync_master_no_tx:降级为异步的事务数

6.3 并行复制优化

6.3.1 并行复制配置

1
2
3
4
5
6
7
8
9
10
-- 在从库上配置
SET GLOBAL slave_parallel_type = 'LOGICAL_CLOCK';
SET GLOBAL slave_parallel_workers = 8; -- 根据 CPU 核心数调整
SET GLOBAL slave_preserve_commit_order = 1; -- 保持提交顺序
SET GLOBAL slave_parallel_workers = 8; -- 根据 CPU 核心数调整
SET GLOBAL slave_compressed_protocol = 1; -- 启用压缩传输

-- 重启从库
STOP SLAVE;
START SLAVE;

6.3.2 并行复制调优

根据工作负载调整

  • OLTP 工作负载:slave_parallel_workers = CPU核心数
  • OLAP 工作负载:slave_parallel_workers = CPU核心数/2
  • 混合工作负载:slave_parallel_workers = CPU核心数*0.75

监控指标

1
2
SHOW GLOBAL STATUS LIKE 'Slave_parallel%';
SHOW GLOBAL STATUS LIKE 'Slave_%';

6.4 GTID 复制配置

6.4.1 GTID 配置

1
2
3
4
5
-- 在主库和从库上都配置
SET GLOBAL enforce_gtid_consistency = 1;
SET GLOBAL gtid_mode = 'ON';

-- 重启 MySQL 服务

在 my.cnf 中持久化配置

1
2
3
4
# GTID 配置
enforce-gtid-consistency = 1
gtid-mode = ON
log-slave-updates = 1

6.4.2 使用 GTID 配置复制

1
2
3
4
5
6
7
8
9
10
11
12
-- 在从库上配置
STOP SLAVE;
RESET SLAVE ALL;

CHANGE MASTER TO
MASTER_HOST='mysql-master',
MASTER_USER='${MYSQL_REPL_USER}',
MASTER_PASSWORD='${MYSQL_REPL_PASSWORD}',
MASTER_PORT=3306,
MASTER_AUTO_POSITION=1; -- 使用 GTID 自动定位

START SLAVE;

GTID 优势

  • 简化主从切换
  • 避免复制位置错误
  • 支持多源复制

6.5 复制过滤配置

6.5.1 数据库级过滤

1
2
3
4
5
6
7
8
9
10
-- 在从库上配置
STOP SLAVE;

-- 只复制特定数据库
CHANGE REPLICATION FILTER REPLICATE_DO_DB = (db1, db2);

-- 或忽略特定数据库
CHANGE REPLICATION FILTER REPLICATE_IGNORE_DB = (mysql, information_schema);

START SLAVE;

6.5.2 表级过滤

1
2
3
4
5
6
7
8
9
10
-- 在从库上配置
STOP SLAVE;

-- 只复制特定表
CHANGE REPLICATION FILTER REPLICATE_DO_TABLE = (db1.table1, db2.table2);

-- 或忽略特定表
CHANGE REPLICATION FILTER REPLICATE_IGNORE_TABLE = (db1.log_table);

START SLAVE;

注意事项

  • 复制过滤会增加从库的计算开销
  • 可能导致主从数据不一致
  • 建议使用 binlog 过滤替代从库过滤

6.6 性能调优建议

6.6.1 主库性能调优

1
2
3
4
5
6
7
8
9
10
# binlog 优化
binlog_row_image = MINIMAL # 减少 binlog 大小
sync_binlog = 1 # 安全性优先,性能敏感场景可设为 100

# 复制优化
slave_parallel_workers = 8 # 并行复制线程数
slave_compressed_protocol = 1 # 启用压缩

# 网络优化
max_allowed_packet = 64M # 增大数据包大小

6.6.2 从库性能调优

1
2
3
4
5
6
7
8
9
10
11
12
# 从库专用优化
skip_slave_start = 0 # 自动启动复制
slave_net_timeout = 60 # 网络超时时间
slave_exec_mode = STRICT # 严格模式

# 内存优化
innodb_buffer_pool_size = 4G # 根据内存调整
innodb_log_buffer_size = 64M # 增大日志缓冲区

# IO 优化
innodb_io_capacity = 2000 # 根据存储设备调整
innodb_flush_method = O_DIRECT # 直接 IO

6.7 安全加固配置

6.7.1 复制用户安全

1
2
3
4
-- 创建受限的复制用户
CREATE USER 'repl'@'172.20.0.%' IDENTIFIED BY '${MYSQL_REPL_PASSWORD}';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'172.20.0.%';
FLUSH PRIVILEGES;

6.7.2 SSL 复制配置

1
2
3
4
5
6
7
8
9
# 主库 SSL 配置
ssl-ca = /etc/mysql/ssl/ca-cert.pem
ssl-cert = /etc/mysql/ssl/server-cert.pem
ssl-key = /etc/mysql/ssl/server-key.pem

# 从库 SSL 配置
ssl-ca = /etc/mysql/ssl/ca-cert.pem
ssl-cert = /etc/mysql/ssl/client-cert.pem
ssl-key = /etc/mysql/ssl/client-key.pem

配置 SSL 复制

1
2
3
4
5
6
7
8
CHANGE MASTER TO
MASTER_HOST='mysql-master',
MASTER_USER='repl',
MASTER_PASSWORD='${MYSQL_REPL_PASSWORD}',
MASTER_SSL=1,
MASTER_SSL_CA='/etc/mysql/ssl/ca-cert.pem',
MASTER_SSL_CERT='/etc/mysql/ssl/client-cert.pem',
MASTER_SSL_KEY='/etc/mysql/ssl/client-key.pem';

7. 企业级常见问题与解决方案

7.1 复制故障诊断与修复

7.1.1 从库复制失败

问题Slave_IO_RunningSlave_SQL_RunningNo

解决方案

  1. 详细诊断

    1
    2
    3
    4
    5
    -- 查看完整错误信息
    SHOW SLAVE STATUS\G;

    -- 查看从库错误日志
    docker-compose logs mysql-slave1 | grep -i error
  2. 常见错误及专业解决方案

    • 错误 1062:主键冲突

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      -- 方法 1:跳过错误(临时解决方案)
      SET GLOBAL sql_slave_skip_counter = 1;
      START SLAVE;

      -- 方法 2:修复数据不一致(推荐)
      -- 1. 停止从库
      STOP SLAVE;
      -- 2. 手动修复冲突数据
      -- 3. 重新启动复制
      START SLAVE;
    • 错误 1032:找不到记录

      1
      2
      3
      4
      5
      -- 查看具体错误
      SHOW SLAVE STATUS\G;
      -- 根据错误信息手动修复数据
      -- 然后重启复制
      START SLAVE;
    • 错误 2003:主库连接失败

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      -- 检查网络连接
      docker-compose exec mysql-slave1 ping mysql-master

      -- 检查主库状态
      docker-compose exec mysql-master mysql -u root -p${MYSQL_ROOT_PASSWORD} -e "SELECT @@server_id;"

      -- 重新配置复制
      CHANGE MASTER TO
      MASTER_HOST='mysql-master',
      MASTER_USER='${MYSQL_REPL_USER}',
      MASTER_PASSWORD='${MYSQL_REPL_PASSWORD}',
      MASTER_PORT=3306,
      MASTER_AUTO_POSITION=1;
      START SLAVE;

7.1.2 复制延迟问题

问题Seconds_Behind_Master 值持续增加。

解决方案

  1. 分析延迟原因

    1
    2
    3
    4
    5
    6
    7
    8
    -- 查看复制状态
    SHOW SLAVE STATUS\G;

    -- 查看从库负载
    docker-compose exec mysql-slave1 top

    -- 查看主库 binlog 生成速率
    docker-compose exec mysql-master mysql -u root -p${MYSQL_ROOT_PASSWORD} -e "SHOW GLOBAL STATUS LIKE 'Binlog%';"
  2. 优化措施

    • 启用并行复制
      1
      2
      SET GLOBAL slave_parallel_workers = 8;
      SET GLOBAL slave_parallel_type = 'LOGICAL_CLOCK';
    • 调整从库配置
      1
      2
      3
      innodb_buffer_pool_size = 4G
      innodb_log_buffer_size = 64M
      innodb_io_capacity = 2000
    • 网络优化:启用压缩传输
      1
      SET GLOBAL slave_compressed_protocol = 1;

7.2 存储与性能问题

7.2.1 主库 binlog 过大

问题:主库的 binlog 文件过大,占用磁盘空间。

解决方案

  1. 配置优化

    1
    2
    3
    4
    # binlog 配置优化
    expire-logs-days = 7
    max-binlog-size = 100M
    binlog-row-image = MINIMAL
  2. 安全清理

    1
    2
    3
    4
    5
    6
    7
    8
    -- 查看当前使用的 binlog 文件
    SHOW MASTER STATUS;

    -- 清理指定文件之前的 binlog
    PURGE BINARY LOGS TO 'mysql-bin.000005';

    -- 清理指定时间之前的 binlog
    PURGE BINARY LOGS BEFORE '2026-02-01 00:00:00';
  3. 监控与告警

    • 设置 binlog 目录空间监控
    • 配置自动清理脚本

7.2.2 从库 IO 性能瓶颈

问题:从库 IO 性能不足,导致复制延迟。

解决方案

  1. 存储优化

    • 使用 SSD 存储
    • 调整 IO 调度器
  2. MySQL 配置优化

    1
    2
    3
    4
    innodb_flush_method = O_DIRECT
    innodb_io_capacity = 4000
    innodb_io_capacity_max = 8000
    innodb_lru_scan_depth = 1024
  3. 监控 IO 性能

    1
    docker-compose exec mysql-slave1 iostat -x 1

7.3 高可用与故障转移

7.3.1 主库故障切换

问题:主库故障,需要将从库提升为主库。

解决方案

  1. 手动故障转移

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    -- 在从库上执行
    -- 1. 停止复制
    STOP SLAVE;

    -- 2. 检查复制状态,确保数据同步
    SHOW SLAVE STATUS\G;

    -- 3. 将从库提升为主库
    RESET MASTER;

    -- 4. 开启写操作
    SET GLOBAL read_only = 0;
    SET GLOBAL super_read_only = 0;
  2. 其他从库重新指向

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    -- 在其他从库上执行
    STOP SLAVE;
    RESET SLAVE ALL;

    CHANGE MASTER TO
    MASTER_HOST='mysql-slave1',
    MASTER_USER='${MYSQL_REPL_USER}',
    MASTER_PASSWORD='${MYSQL_REPL_PASSWORD}',
    MASTER_PORT=3306,
    MASTER_AUTO_POSITION=1;

    START SLAVE;
  3. 应用配置更新

    • 修改应用数据库连接字符串
    • 重启应用服务

7.3.2 自动故障转移方案

推荐方案:使用 Orchestrator 实现自动故障转移

  1. Orchestrator 部署

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    orchestrator:
    image: openark/orchestrator:latest
    container_name: orchestrator
    ports:
    - "3000:3000"
    environment:
    - ORCHESTRATOR_PASSWORD=your-password
    volumes:
    - ./conf/orchestrator.conf.json:/etc/orchestrator.conf.json
    restart: always
    networks:
    - mysql-network
  2. 配置示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    {
    "MySQLTopologyCredentialsConfig": {
    "User": "orchestrator",
    "Password": "orchestrator-password"
    },
    "FailureDetectionPeriodSeconds": 5,
    "RecoveryPeriodSeconds": 10,
    "PostFailoverProcesses": ["/path/to/post-failover-script.sh"]
    }
  3. 优势

    • 自动检测主库故障
    • 智能选择最佳从库提升
    • 自动更新其他从库指向
    • 支持手动和自动故障转移

7.4 安全与权限问题

7.4.1 复制用户权限不足

问题:复制用户权限不足,导致复制失败。

解决方案

  1. 检查权限

    1
    SHOW GRANTS FOR '${MYSQL_REPL_USER}'@'%';
  2. 修复权限

    1
    2
    GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO '${MYSQL_REPL_USER}'@'%';
    FLUSH PRIVILEGES;

7.4.2 SSL 复制配置错误

问题:SSL 复制配置错误,导致连接失败。

解决方案

  1. 检查 SSL 配置

    1
    2
    3
    4
    5
    -- 主库
    SHOW GLOBAL VARIABLES LIKE '%ssl%';

    -- 从库
    SHOW GLOBAL VARIABLES LIKE '%ssl%';
  2. 验证证书

    1
    docker-compose exec mysql-master openssl verify -CAfile /etc/mysql/ssl/ca-cert.pem /etc/mysql/ssl/server-cert.pem
  3. 重新配置 SSL 复制

    1
    2
    3
    4
    5
    6
    7
    8
    9
    CHANGE MASTER TO
    MASTER_HOST='mysql-master',
    MASTER_USER='${MYSQL_REPL_USER}',
    MASTER_PASSWORD='${MYSQL_REPL_PASSWORD}',
    MASTER_SSL=1,
    MASTER_SSL_CA='/etc/mysql/ssl/ca-cert.pem',
    MASTER_SSL_CERT='/etc/mysql/ssl/client-cert.pem',
    MASTER_SSL_KEY='/etc/mysql/ssl/client-key.pem',
    MASTER_AUTO_POSITION=1;

8. 企业级监控与维护

8.1 全面监控方案

8.1.1 核心监控指标

复制状态监控

  • Slave_IO_Running:IO 线程状态
  • Slave_SQL_Running:SQL 线程状态
  • Seconds_Behind_Master:复制延迟
  • Last_Error:复制错误信息
  • Master_Log_File/Read_Master_Log_Pos:主库日志位置
  • Relay_Master_Log_File/Exec_Master_Log_Pos:从库执行位置

性能监控

  • QPS/TPS:查询和事务每秒
  • 连接数:活跃连接和最大连接
  • 缓冲池利用率:InnoDB 缓冲池使用情况
  • IO 性能:磁盘读写延迟和吞吐量
  • 网络流量:主从复制网络带宽

资源监控

  • CPU 使用率:系统和 MySQL 进程
  • 内存使用率:系统和 MySQL 内存
  • 磁盘使用率:数据目录和 binlog 目录
  • 磁盘 IOPS:随机和顺序 IO 性能

8.1.2 监控工具集成

Prometheus + Grafana 方案

  1. 部署 MySQL Exporter

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    mysql-exporter:
    image: prom/mysqld-exporter:v0.14.0
    container_name: mysql-exporter
    ports:
    - "9104:9104"
    environment:
    - DATA_SOURCE_NAME=exporter:exporter-password@(mysql-master:3306)/
    restart: always
    networks:
    - mysql-network
  2. Grafana 仪表盘

    • 导入 MySQL 官方仪表盘(ID: 7362)
    • 自定义复制监控仪表盘
    • 设置关键指标告警
  3. 告警配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    groups:
    - name: mysql-replication
    rules:
    - alert: MySQLReplicationLag
    expr: mysql_slave_lag_seconds > 30
    for: 5m
    labels:
    severity: warning
    annotations:
    summary: "MySQL 复制延迟"
    description: "从库 {{ $labels.instance }} 复制延迟超过 30 秒"

    - alert: MySQLReplicationStopped
    expr: mysql_slave_status_slave_io_running == 0 or mysql_slave_status_slave_sql_running == 0
    for: 1m
    labels:
    severity: critical
    annotations:
    summary: "MySQL 复制停止"
    description: "从库 {{ $labels.instance }} 复制线程停止"

企业级监控方案

  • Datadog:全面的数据库监控和分析
  • New Relic:应用性能和数据库监控
  • MySQL Enterprise Monitor:官方企业级监控工具
  • Percona Monitoring and Management (PMM):开源 MySQL 监控平台

8.2 企业级维护策略

8.2.1 自动化备份策略

备份类型

  • 全量备份:使用 XtraBackup 每天执行
  • 增量备份:每 6 小时执行一次
  • binlog 备份:实时备份 binlog 文件

备份脚本示例

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash

# 全量备份脚本
BACKUP_DIR="/backup/full/$(date +%Y%m%d)"
mkdir -p $BACKUP_DIR

docker-compose exec mysql-master xtrabackup --backup --target-dir=$BACKUP_DIR --user=root --password=${MYSQL_ROOT_PASSWORD}

# 备份验证
xtrabackup --prepare --target-dir=$BACKUP_DIR

# 清理 7 天前的备份
find /backup/full -mtime +7 -type d -exec rm -rf {} \;

备份验证

  • 定期测试备份恢复
  • 验证备份文件完整性
  • 监控备份执行状态

8.2.2 性能优化维护

定期维护任务

  1. 表优化

    1
    2
    3
    4
    5
    6
    7
    8
    -- 优化表结构
    OPTIMIZE TABLE dbname.tablename;

    -- 分析表统计信息
    ANALYZE TABLE dbname.tablename;

    -- 检查表完整性
    CHECK TABLE dbname.tablename;
  2. 索引优化

    • 定期分析慢查询日志
    • 使用 EXPLAIN 分析查询计划
    • 添加或调整索引结构
  3. 配置调优

    • 根据工作负载调整参数
    • 监控配置有效性
    • 定期review配置文件

8.2.3 安全维护

定期安全检查

  1. 权限审计

    1
    2
    3
    4
    5
    -- 查看用户权限
    SELECT user, host, plugin FROM mysql.user;

    -- 查看角色权限
    SHOW GRANTS FOR 'username'@'host';
  2. 密码策略

    • 定期更新密码
    • 启用密码复杂度要求
    • 使用密码过期策略
  3. SSL 证书维护

    • 定期更新 SSL 证书
    • 验证证书链完整性
    • 监控证书过期时间
  4. 漏洞扫描

    • 使用 MySQLTuner 进行安全扫描
    • 定期检查 CVE 漏洞
    • 及时应用安全补丁

8.3 企业级升级与迁移

8.3.1 版本升级策略

升级前准备

  1. 风险评估

    • 检查版本兼容性
    • 评估应用影响
    • 制定回滚计划
  2. 环境准备

    • 创建测试环境
    • 验证升级流程
    • 准备备份方案

升级步骤

  1. 备份数据

    1
    2
    3
    4
    5
    # 全量备份
    docker-compose exec mysql-master mysqldump --all-databases --routines --triggers --single-transaction > full_backup.sql

    # 备份配置文件
    docker cp mysql-master:/etc/mysql/conf.d/my.cnf ./backup/
  2. 升级执行

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 停止服务
    docker-compose down

    # 修改 docker-compose.yml 中的镜像版本
    # image: mysql:8.0.34 -> image: mysql:8.0.36

    # 启动服务
    docker-compose up -d

    # 运行升级检查
    docker-compose exec mysql-master mysql_upgrade -u root -p${MYSQL_ROOT_PASSWORD}
  3. 验证升级

    • 检查服务状态
    • 验证复制状态
    • 测试应用功能
    • 监控性能指标

8.3.2 数据迁移方案

方案选择

  • 逻辑备份迁移:使用 mysqldump 或 mydumper
  • 物理备份迁移:使用 XtraBackup
  • 主从复制迁移:使用 GTID 复制
  • 第三方工具:使用 Oracle Data Pump 或第三方迁移工具

主从复制迁移步骤

  1. 在新服务器部署从库
  2. 配置主从复制
  3. 等待数据同步完成
  4. 执行故障转移
  5. 验证应用连接

大数据库迁移优化

  • 使用并行备份工具
  • 启用压缩传输
  • 优化网络带宽
  • 分批次迁移数据

8.4 灾难恢复计划

8.4.1 灾难恢复策略

RTO/RPO 定义

  • RTO(恢复时间目标):最大可接受的服务中断时间
  • RPO(恢复点目标):最大可接受的数据丢失量

灾难恢复级别

  • Level 0:无备份,手动恢复
  • Level 1:本地备份,手动恢复
  • Level 2:本地备份,自动恢复
  • Level 3:异地备份,手动恢复
  • Level 4:异地备份,自动恢复
  • Level 5:多活架构,自动故障转移

8.4.2 恢复演练

定期演练计划

  • 每季度执行一次完整恢复演练
  • 每月执行一次增量恢复演练
  • 每次配置变更后执行测试恢复

演练步骤

  1. 准备演练环境
  2. 执行恢复操作
  3. 验证恢复结果
  4. 记录演练时间
  5. 更新恢复计划

演练指标

  • 恢复时间:实际 RTO vs 目标 RTO
  • 数据完整性:恢复后数据一致性
  • 服务可用性:恢复后服务功能
  • 文档准确性:恢复文档的有效性

8.5 最佳实践总结

监控最佳实践

  • 建立多层监控体系
  • 设置合理的告警阈值
  • 实现自动化告警处理
  • 定期review监控数据

维护最佳实践

  • 制定详细的维护计划
  • 执行自动化维护任务
  • 记录所有维护操作
  • 持续优化维护流程

安全最佳实践

  • 遵循最小权限原则
  • 定期进行安全审计
  • 及时应用安全补丁
  • 建立安全事件响应机制

性能最佳实践

  • 定期进行性能基准测试
  • 持续优化数据库结构
  • 监控并调整配置参数
  • 预测并规划资源需求

通过实施这套企业级监控与维护方案,可以确保 MySQL 主从复制集群的高可用性、高性能和安全性,为业务系统提供稳定可靠的数据服务。

9. 企业级性能优化

9.1 主库性能优化

9.1.1 核心参数调优

二进制日志优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[mysqld]
# 生产环境推荐使用 ROW 格式
binlog-format = ROW

# 二进制日志大小限制
max-binlog-size = 100M

# 二进制日志过期时间
expire-logs-days = 7

# 安全同步级别
sync-binlog = 100

# 减少 binlog 大小
binlog-row-image = MINIMAL

连接管理优化

1
2
3
4
5
6
7
8
9
10
11
12
13
[mysqld]
# 最大连接数
max_connections = 2000

# 连接错误限制
max_connect_errors = 10000

# 连接超时时间
wait_timeout = 3600
interactive_timeout = 3600

# 连接池优化
back_log = 100

内存配置优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[mysqld]
# InnoDB 缓冲池大小(推荐内存的 50-70%)
innodb_buffer_pool_size = 8G

# 缓冲池实例数(推荐与 CPU 核心数匹配)
innodb_buffer_pool_instances = 8

# 日志缓冲区大小
innodb_log_buffer_size = 64M

# 排序缓冲区大小
sort_buffer_size = 2M

# 连接缓冲区大小
join_buffer_size = 2M

# 随机读写缓冲区大小
read_rnd_buffer_size = 1M

# 顺序读缓冲区大小
read_buffer_size = 1M

9.1.2 存储引擎优化

InnoDB 优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[mysqld]
# 事务日志大小
innodb_log_file_size = 1G
innodb_log_files_in_group = 2

# 事务提交方式(1:最安全,2:性能更好)
innodb_flush_log_at_trx_commit = 2

# IO 操作方式
innodb_flush_method = O_DIRECT

# 存储配置
innodb_file_per_table = 1
innodb_file_format = Barracuda
innodb_large_prefix = 1

# IO 能力设置(根据存储设备调整)
innodb_io_capacity = 2000
innodb_io_capacity_max = 4000

# 并发控制
innodb_thread_concurrency = 0 # 0 表示自动
innodb_commit_concurrency = 0

# 自适应哈希索引
innodb_adaptive_hash_index = 1

9.1.3 查询优化

查询缓存(谨慎使用)

1
2
3
4
[mysqld]
# 查询缓存大小(推荐关闭)
query_cache_size = 0
query_cache_type = 0

临时表优化

1
2
3
4
5
6
7
[mysqld]
# 临时表最大大小
tmp_table_size = 64M
max_heap_table_size = 64M

# 临时文件目录
tmpdir = /tmp

慢查询日志

1
2
3
4
5
6
[mysqld]
# 启用慢查询日志
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow-query.log
long_query_time = 1
log_queries_not_using_indexes = 1

9.2 从库性能优化

9.2.1 复制性能优化

并行复制调优

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[mysqld]
# 并行复制类型
slave-parallel-type = LOGICAL_CLOCK

# 并行复制线程数(根据 CPU 核心数调整)
slave-parallel-workers = 8

# 保持提交顺序
slave_preserve_commit_order = 1

# 并行应用事务
sync_master_info = 1000
sync_relay_log = 1000
sync_relay_log_info = 1000

复制链路优化

1
2
3
4
5
6
7
8
9
10
11
12
13
[mysqld]
# 网络超时设置
slave_net_timeout = 60

# 复制重试次数
master_connect_retry = 10

# 压缩传输
slave_compressed_protocol = 1

# 从库只读
read_only = 1
super_read_only = 1

延迟复制配置

1
2
3
4
5
-- 设置从库延迟 1 小时(用于灾难恢复)
CHANGE MASTER TO MASTER_DELAY = 3600;

-- 查看延迟状态
SHOW SLAVE STATUS\G;

9.2.2 从库专用优化

查询性能优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[mysqld]
# 从库缓冲池优化
innodb_buffer_pool_size = 12G

# 查询优化器设置
optimizer_switch = 'index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on'

# 统计信息更新
innodb_stats_on_metadata = 0

# 表定义缓存
table_definition_cache = 4096

# 表缓存
table_open_cache = 4096

只读优化

1
2
3
4
5
6
7
8
[mysqld]
# 禁用写相关功能
skip-slave-start = 0
skip-innodb_doublewrite = 0

# 优化只读查询
innodb_read_io_threads = 16
innodb_write_io_threads = 4

9.3 系统级优化

9.3.1 Linux 内核优化

网络优化

1
2
3
4
5
6
7
8
9
# 编辑 /etc/sysctl.conf
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.ip_local_port_range = 1024 65535
net.core.netdev_max_backlog = 65535

内存管理优化

1
2
3
4
# 编辑 /etc/sysctl.conf
vm.swappiness = 10
vm.overcommit_memory = 1
vm.max_map_count = 262144

IO 调度优化

1
2
3
4
5
# 设置 SSD 磁盘调度器
echo deadline > /sys/block/sda/queue/scheduler

# 或使用 none 调度器(推荐 SSD)
echo none > /sys/block/sda/queue/scheduler

9.3.2 文件系统优化

XFS 文件系统

1
2
# 挂载选项优化
/dev/sda1 /data xfs defaults,noatime,nodiratime,allocsize=64m 0 0

EXT4 文件系统

1
2
# 挂载选项优化
/dev/sda1 /data ext4 defaults,noatime,nodiratime,discard 0 0

9.4 性能监控与调优

9.4.1 性能基准测试

使用 sysbench 进行基准测试

1
2
3
4
5
6
7
8
9
10
11
# 安装 sysbench
sudo apt-get install sysbench

# 准备测试数据
sysbench oltp_read_write --table-size=1000000 --mysql-host=localhost --mysql-port=3306 --mysql-user=root --mysql-password=${MYSQL_ROOT_PASSWORD} --mysql-db=${MYSQL_DATABASE} prepare

# 执行测试
sysbench oltp_read_write --table-size=1000000 --mysql-host=localhost --mysql-port=3306 --mysql-user=root --mysql-password=${MYSQL_ROOT_PASSWORD} --mysql-db=${MYSQL_DATABASE} --threads=16 --time=60 run

# 清理测试数据
sysbench oltp_read_write --mysql-host=localhost --mysql-port=3306 --mysql-user=root --mysql-password=${MYSQL_ROOT_PASSWORD} --mysql-db=${MYSQL_DATABASE} cleanup

9.4.2 性能分析工具

使用 Performance Schema

1
2
3
4
5
6
7
8
-- 启用 Performance Schema
SET GLOBAL performance_schema = 1;

-- 查看等待事件
SELECT * FROM performance_schema.events_waits_current WHERE event_name LIKE '%wait%' LIMIT 10;

-- 查看语句性能
SELECT * FROM performance_schema.events_statements_history_long ORDER BY timer_wait DESC LIMIT 10;

使用 MySQL Profiler

1
2
3
4
5
6
7
8
9
-- 启用 Profiler
SET profiling = 1;

-- 执行查询
SELECT * FROM large_table WHERE id > 1000000;

-- 查看 Profiler 结果
SHOW PROFILES;
SHOW PROFILE FOR QUERY 1;

9.5 最佳实践总结

配置调优最佳实践

  • 根据硬件资源调整配置参数
  • 分阶段测试配置变更
  • 监控配置变更效果
  • 定期review配置参数

查询优化最佳实践

  • 为所有查询添加适当索引
  • 避免使用 SELECT *
  • 合理使用 JOIN 语句
  • 避免在 WHERE 子句中使用函数
  • 限制结果集大小

架构优化最佳实践

  • 实施读写分离
  • 使用连接池管理连接
  • 考虑使用分片架构
  • 合理设计表结构
  • 定期进行数据归档

监控与调优最佳实践

  • 建立性能基准
  • 实施持续监控
  • 自动告警性能异常
  • 定期进行性能分析
  • 持续优化系统性能

通过综合实施这些企业级性能优化策略,可以显著提升 MySQL 主从复制集群的性能和稳定性,满足高并发业务场景的需求。

10. 企业级安全配置

10.1 网络安全加固

10.1.1 网络隔离

Docker 网络配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
networks:
mysql-network:
driver: bridge
internal: true # 内部网络,禁止外部访问
ipam:
config:
- subnet: 172.20.0.0/16
driver_opts:
com.docker.network.bridge.name: "mysql-br"
com.docker.network.bridge.enable_icc: "true"
com.docker.network.bridge.enable_ip_masquerade: "true"

# 管理网络(可选)
management-network:
driver: bridge
internal: false
ipam:
config:
- subnet: 172.21.0.0/16

端口暴露控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 主库只暴露给管理网络
mysql-master:
ports:
- "127.0.0.1:3306:3306" # 只允许本地访问
networks:
- mysql-network
- management-network

# 从库不暴露端口
mysql-slave1:
networks:
- mysql-network

# 监控服务暴露端口
prometheus:
ports:
- "9090:9090"
networks:
- management-network

10.1.2 防火墙配置

Linux 防火墙规则

1
2
3
4
5
6
7
8
9
10
11
# 允许本地访问
iptables -A INPUT -s 127.0.0.1 -p tcp --dport 3306 -j ACCEPT

# 允许管理网络访问
iptables -A INPUT -s 172.21.0.0/16 -p tcp --dport 3306 -j ACCEPT

# 拒绝其他所有访问
iptables -A INPUT -p tcp --dport 3306 -j DROP

# 保存规则
iptables-save > /etc/iptables/rules.v4

Windows 防火墙规则

1
2
3
4
5
6
7
8
# 允许本地访问
New-NetFirewallRule -DisplayName "MySQL Local Access" -Direction Inbound -Protocol TCP -LocalPort 3306 -Action Allow -LocalAddress 127.0.0.1

# 允许管理网络访问
New-NetFirewallRule -DisplayName "MySQL Management Access" -Direction Inbound -Protocol TCP -LocalPort 3306 -Action Allow -LocalAddress 172.21.0.0/16

# 拒绝其他所有访问
New-NetFirewallRule -DisplayName "MySQL Deny All" -Direction Inbound -Protocol TCP -LocalPort 3306 -Action Block

10.2 数据安全

10.2.1 SSL/TLS 加密

SSL 证书配置

1
2
3
4
5
6
7
8
9
10
11
[mysqld]
# SSL 配置
ssl-ca = /etc/mysql/ssl/ca-cert.pem
ssl-cert = /etc/mysql/ssl/server-cert.pem
ssl-key = /etc/mysql/ssl/server-key.pem

# 强制使用 SSL
require_secure_transport = 1

# SSL 密码套件
ssl_cipher = 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384'

生成 SSL 证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 创建证书目录
mkdir -p ssl
cd ssl

# 生成 CA 证书
openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 3650 -key ca-key.pem -out ca-cert.pem -subj "/C=CN/ST=Beijing/L=Beijing/O=Company/OU=IT/CN=mysql-ca"

# 生成服务器证书
openssl req -newkey rsa:2048 -days 3650 -nodes -keyout server-key.pem -out server-req.pem -subj "/C=CN/ST=Beijing/L=Beijing/O=Company/OU=IT/CN=mysql-server"
openssl rsa -in server-key.pem -out server-key.pem
openssl x509 -req -in server-req.pem -days 3650 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem

# 生成客户端证书
openssl req -newkey rsa:2048 -days 3650 -nodes -keyout client-key.pem -out client-req.pem -subj "/C=CN/ST=Beijing/L=Beijing/O=Company/OU=IT/CN=mysql-client"
openssl rsa -in client-key.pem -out client-key.pem
openssl x509 -req -in client-req.pem -days 3650 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 02 -out client-cert.pem

# 验证证书
openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem

# 设置权限
chmod 600 *.pem
chmod 644 ca-cert.pem

10.2.2 密码安全管理

密码策略

1
2
3
4
5
6
7
8
9
10
11
12
13
[mysqld]
# 密码验证插件
plugin-load-add = validate_password.so
validate_password_policy = STRONG
validate_password_length = 12
validate_password_number_count = 1
validate_password_special_char_count = 1
validate_password_mixed_case_count = 1

# 密码过期策略
default_password_lifetime = 90
password_history = 10
password_reuse_interval = 365

环境变量管理

1
2
3
4
5
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_REPL_USER=${MYSQL_REPL_USER}
- MYSQL_REPL_PASSWORD=${MYSQL_REPL_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}

密码轮换

1
2
3
4
5
6
7
8
9
10
-- 修改 root 用户密码
ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewStrongPassword2024!';

-- 修改复制用户密码
ALTER USER 'repl'@'172.20.0.%' IDENTIFIED BY 'NewReplPassword2024!';

-- 在从库中更新密码
STOP SLAVE;
CHANGE MASTER TO MASTER_PASSWORD='NewReplPassword2024!';
START SLAVE;

10.3 权限管理

10.3.1 最小权限原则

复制用户权限

1
2
3
4
-- 创建复制用户(最小权限)
CREATE USER 'repl'@'172.20.0.%' IDENTIFIED BY '${MYSQL_REPL_PASSWORD}';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl'@'172.20.0.%';
FLUSH PRIVILEGES;

监控用户权限

1
2
3
4
-- 创建监控用户
CREATE USER 'exporter'@'172.20.0.%' IDENTIFIED BY 'exporter-password';
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'172.20.0.%';
FLUSH PRIVILEGES;

应用用户权限

1
2
3
4
-- 创建应用用户(按数据库授权)
CREATE USER 'app_user'@'172.20.0.%' IDENTIFIED BY 'app-password';
GRANT SELECT, INSERT, UPDATE, DELETE ON app_db.* TO 'app_user'@'172.20.0.%';
FLUSH PRIVILEGES;

10.3.2 权限审计

定期权限检查

1
2
3
4
5
6
7
8
-- 查看所有用户
SELECT user, host, plugin FROM mysql.user;

-- 查看用户权限
SELECT user, host, db, table_name, grant_priv, super_priv FROM mysql.db;

-- 查看角色权限
SHOW GRANTS FOR 'repl'@'172.20.0.%';

移除不必要权限

1
2
3
4
5
6
7
8
9
10
11
12
-- 撤销多余权限
REVOKE ALL PRIVILEGES ON *.* FROM 'test'@'%';
DROP USER 'test'@'%';

-- 移除匿名用户
DELETE FROM mysql.user WHERE User='';

-- 移除测试数据库
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%';

FLUSH PRIVILEGES;

10.4 审计与日志

10.4.1 审计日志

启用审计日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[mysqld]
# 启用通用查询日志(生产环境谨慎使用)
general_log = 0
general_log_file = /var/log/mysql/general.log

# 启用错误日志
log_error = /var/log/mysql/error.log

# 启用二进制日志
log-bin = mysql-bin

# 启用慢查询日志
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow-query.log
long_query_time = 1

MySQL Enterprise Audit(企业版):

1
2
3
4
5
6
[mysqld]
# 加载审计插件
plugin-load = audit_log.so
audit_log_format = JSON
audit_log_policy = ALL
audit_log_file = /var/log/mysql/audit.log

10.4.2 日志轮转

日志轮转配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 创建 logrotate 配置
cat > /etc/logrotate.d/mysql << 'EOF'
/var/log/mysql/*.log {
daily
rotate 7
compress
delaycompress
missingok
create 640 mysql mysql
postrotate
docker-compose exec mysql-master mysqladmin flush-logs
endscript
}
EOF

10.5 漏洞防护

10.5.1 定期安全扫描

使用 MySQLTuner

1
2
3
4
5
6
# 下载 MySQLTuner
wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl
chmod +x mysqltuner.pl

# 运行安全扫描
./mysqltuner.pl --host=localhost --user=root --pass=${MYSQL_ROOT_PASSWORD}

使用 OpenVAS

  • 部署 OpenVAS 漏洞扫描器
  • 定期扫描 MySQL 服务器
  • 及时修复发现的漏洞

10.5.2 安全补丁管理

定期更新

1
2
3
4
5
6
7
8
# 更新 Docker 镜像
docker-compose pull

docker-compose down
docker-compose up -d

# 运行 mysql_upgrade
docker-compose exec mysql-master mysql_upgrade -u root -p${MYSQL_ROOT_PASSWORD}

CVE 监控

  • 订阅 MySQL 安全公告
  • 使用漏洞管理工具监控 CVE
  • 建立安全补丁评估流程

10.6 最佳实践总结

网络安全最佳实践

  • 实施网络隔离
  • 限制端口暴露
  • 配置防火墙规则
  • 使用 VPN 进行远程访问

数据安全最佳实践

  • 启用 SSL/TLS 加密
  • 实施强密码策略
  • 定期轮换密码
  • 使用环境变量管理敏感信息

权限管理最佳实践

  • 遵循最小权限原则
  • 定期审计权限
  • 移除不必要的用户和权限
  • 使用角色管理权限

审计与监控最佳实践

  • 启用适当的日志
  • 配置日志轮转
  • 监控日志异常
  • 建立安全事件响应机制

漏洞防护最佳实践

  • 定期进行安全扫描
  • 及时应用安全补丁
  • 监控 CVE 漏洞
  • 建立漏洞修复流程

通过实施这套企业级安全配置,可以显著提高 MySQL 主从复制集群的安全性,保护数据资产免受攻击和泄露。

11. 企业级架构总结

通过 Docker Compose 部署企业级 MySQL 主从复制集群,我们实现了以下核心价值:

11.1 架构优势

高可用性

  • 主从架构提供故障转移能力
  • 当主库故障时,可快速将从库提升为主库
  • 实现服务连续性,减少业务中断时间

性能扩展

  • 读写分离架构分散数据库负载
  • 多从库配置支持水平扩展读性能
  • 并行复制技术提升从库同步效率
  • 负载均衡分发读请求,提高系统吞吐量

数据安全

  • 实时数据同步提供数据冗余
  • 从库可作为灾难恢复备份
  • SSL/TLS 加密保护数据传输
  • 多级别权限控制保障数据访问安全

可维护性

  • Docker 容器化简化部署和管理
  • 标准化配置文件提高一致性
  • 自动化监控和告警减少人工干预
  • 滚动升级支持无停机维护

11.2 技术实现

核心组件

  • MySQL 8.0 LTS 版本
  • Docker Compose 容器编排
  • Nginx 负载均衡
  • Prometheus + Grafana 监控
  • SSL/TLS 安全传输

关键特性

  • GTID 复制确保数据一致性
  • 半同步复制提高数据可靠性
  • 并行复制提升同步性能
  • 延迟复制提供时间点恢复能力
  • 级联复制支持大规模部署

企业级配置

  • 资源限制和健康检查
  • 详细的日志和审计
  • 自动化备份和恢复
  • 安全加固和漏洞防护
  • 性能调优和监控

11.3 应用场景

高并发 Web 应用

  • 适用于电商、社交、金融等流量密集型应用
  • 读写分离架构支持海量并发请求
  • 多从库配置满足高读负载需求

数据 analytics 场景

  • 从库可用于数据分析和报表生成
  • 避免分析查询影响主库性能
  • 支持实时数据仓库构建

灾备和迁移

  • 跨地域复制提供灾难恢复能力
  • 主从架构简化数据库迁移过程
  • 零停机迁移方案减少业务影响

混合云部署

  • 支持本地和云环境混合部署
  • 跨云复制实现多云架构
  • 灵活应对业务扩展需求

11.4 最佳实践

架构设计

  • 根据业务需求选择合适的复制拓扑
  • 合理规划从库数量和分布
  • 考虑网络延迟和带宽限制
  • 设计故障转移和恢复流程

配置管理

  • 使用版本控制管理配置文件
  • 标准化环境变量和配置模板
  • 定期 review 和优化配置参数
  • 建立配置变更审核流程

运维管理

  • 实施自动化监控和告警
  • 定期进行备份和恢复演练
  • 建立性能基准和优化流程
  • 制定详细的运维手册和应急预案

安全管理

  • 定期进行安全扫描和漏洞评估
  • 及时应用安全补丁和更新
  • 实施最小权限原则和访问控制
  • 建立安全事件响应机制

11.5 未来展望

技术演进

  • 探索 MySQL Group Replication 实现多主架构
  • 研究 MySQL InnoDB Cluster 简化集群管理
  • 考虑使用 MySQL Router 实现透明的读写分离
  • 评估云原生数据库服务的可行性

性能优化

  • 持续优化数据库查询和索引
  • 探索数据库分片技术支持更大规模数据
  • 研究内存数据库和缓存技术
  • 实施智能查询路由和负载均衡

运维自动化

  • 构建完整的 CI/CD 流程
  • 实现自动化的故障检测和恢复
  • 开发智能运维工具和平台
  • 应用机器学习预测性能问题

通过本方案部署的 MySQL 主从复制集群,不仅满足了企业级应用的高可用性和性能需求,也为未来的技术演进和业务扩展奠定了坚实基础。在实际应用中,应根据具体业务场景和技术需求,灵活调整架构设计和配置参数,持续优化和改进,以实现最佳的系统性能和可靠性。

12. 参考资料

相关推荐

关键词总结

本文详细介绍了 Docker Compose 部署主从结构 MySQL 的完整流程,包括主从复制原理、环境准备、配置文件设置、部署步骤、测试验证、故障切换等内容。通过本文的指导,您可以快速搭建一个稳定、高效的 MySQL 主从集群,实现数据的高可用性和读写分离。

主要关键词:Docker Compose、MySQL、主从复制、高可用、部署教程、读写分离、故障切换、数据备份、性能优化、安全配置