文章导读 本文将深入探讨企业级 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 复制工作流程 binlog 生成 :主库执行写操作后,将变更记录到 binlog 中,生成唯一的 binlog 文件名和位置(Position)binlog 传输 :从库 I/O 线程向主库发送复制请求,主库的 Dump 线程读取 binlog 并发送给从库中继日志写入 :从库 I/O 线程接收 binlog 事件,写入本地中继日志事件重放 :从库 SQL 线程读取中继日志,解析事件并在从库上执行相同的操作复制状态更新 :从库定期更新复制状态,记录已处理的 binlog 位置和复制延迟1.1.3 复制格式 基于语句(STATEMENT) :记录 SQL 语句,体积小但可能导致数据不一致基于行(ROW) :记录行级变更,数据一致性高但日志体积较大混合模式(MIXED) :根据语句类型自动选择复制格式生产环境推荐使用 ROW 格式 ,确保数据一致性和复制可靠性。
1.2 企业级架构优势 1.2.1 核心业务价值 服务连续性保障 :主库故障时可快速切换到从库,实现分钟级故障恢复,满足企业 SLA 要求线性性能扩展 :通过增加从库数量,实现读性能的线性扩展,支撑高并发业务场景数据安全防护 :从库作为实时备份,结合定期全量备份,构建多层次数据安全体系跨地域灾备 :从库可部署在不同数据中心,实现跨地域灾备,应对区域性灾难零停机维护 :通过从库进行版本升级、索引重建等维护操作,实现业务无感知1.2.2 技术架构优势 架构简单可靠 :基于 MySQL 原生复制机制,无需引入复杂第三方组件部署成本可控 :相比分布式数据库,硬件和运维成本显著降低兼容性广泛 :支持所有 MySQL 版本和常见应用场景运维难度适中 :复制配置和监控相对简单,易于掌握和维护1.3 技术栈与组件选型 组件 版本 用途 配置文件 选型理由 MySQL 8.0.34 (LTS) 主从复制核心 conf/master/my.cnf, conf/slave/my.cnf8.0 LTS 版本提供并行复制、GTID、半同步复制等企业级特性,稳定性和性能均优 Docker 20.10.24+ 容器化运行环境 - 提供隔离性和一致性,简化部署和迁移 Docker Compose 1.29.2+ 多容器编排 docker-compose.yml支持服务依赖管理、网络配置和资源限制,适合多实例部署 Nginx 1.24.0+ 负载均衡 conf/nginx/nginx.conf轻量级高性能负载均衡器,支持健康检查和会话保持 Prometheus 2.45.0+ 监控系统 conf/prometheus/prometheus.yml时序数据库,适合监控指标的采集和存储 Grafana 9.5.15+ 可视化监控 conf/grafana/provisioning丰富的仪表盘和告警功能,提供直观的监控视图 MySQL Exporter 0.14.0+ MySQL 指标采集 - 专门用于采集 MySQL 实例的详细监控指标
1.4 复制架构模式深度分析 1.4.1 架构模式对比 架构模式 适用场景 优势 劣势 推荐指数 一主一从 小型应用、开发测试 配置简单,资源占用少 高可用能力有限 ⭐⭐⭐ 一主多从 中大型应用、高并发读场景 读性能线性扩展,高可用能力强 主库复制压力较大 ⭐⭐⭐⭐⭐ 级联复制 大规模部署、跨地域复制 减轻主库复制压力,适合长距离复制 故障转移复杂度增加 ⭐⭐⭐⭐ 双主复制 写入密集场景、无需故障转移 双活架构,写入负载分散 需解决冲突,配置复杂 ⭐⭐⭐ 环形复制 多数据中心场景 数据多活,容灾能力强 配置复杂,容易出现循环复制 ⭐⭐
1.4.2 企业级推荐架构 一主多从架构 是生产环境的最佳选择,具备以下特点:
主库 :负责所有写操作和复制源从库集群 :2-5 个从库,负责读操作和故障备援负载均衡层 :Nginx 或专业数据库代理(如 ProxySQL、MaxScale)监控告警系统 :Prometheus + Grafana + Alertmanager自动故障转移 :Orchestrator 或 MHA1.4.3 架构演进路径 基础阶段 :一主一从架构,实现基本高可用扩展阶段 :一主多从架构,提升读性能优化阶段 :引入负载均衡和监控,完善运维体系高级阶段 :实现自动故障转移和智能运维本文将详细介绍企业级一主多从架构的完整部署与优化方案,包括 Docker Compose 配置、性能调优、安全加固和监控运维等核心内容。
2. 企业级部署准备 2.1 硬件资源规划 2.1.1 不同规模部署的资源配置 部署规模 CPU 内存 存储 网络 适用场景 连接数 并发查询 小型部署 2-4 核 4-8GB 100-200GB SSD 1Gbps 开发测试、小型应用 < 500 < 100 中型部署 8-16 核 16-32GB 500GB-1TB SSD 1Gbps+ 中小型生产环境 500-2000 100-500 大型部署 16-32 核 32-64GB 1-4TB SSD 10Gbps 大型生产环境 2000-5000 500-2000 超大型部署 32+ 核 64GB+ 4TB+ NVMe 25Gbps+ 核心业务系统 > 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 内存 存储类型 适用场景 AWS t3.large 2 核 8GB gp3 开发测试 AWS m5.xlarge 4 核 16GB gp3 小型生产 AWS r5.2xlarge 8 核 64GB io2 中型生产 AWS r5.4xlarge 16 核 128GB io2 大型生产 阿里云 ecs.c6.large 2 核 8GB ESSD 开发测试 阿里云 ecs.r6.xlarge 4 核 32GB ESSD 小型生产 阿里云 ecs.r6.2xlarge 8 核 64GB ESSD 中型生产 阿里云 ecs.r6.4xlarge 16 核 128GB ESSD 大型生产
2.2 软件环境要求 2.2.1 基础软件版本 软件 最低版本 推荐版本 安装方式 Docker 20.10.24 24.0.7+ 官方脚本 Docker Compose 1.29.2 2.21.0+ 官方脚本 Linux 内核 4.19 5.4+ 系统更新 Python 3.6 3.9+ 系统包管理器 OpenSSL 1.1.1 3.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.confnet.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.tcp_max_tw_buckets = 5000 net.ipv4.tcp_fastopen = 3 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 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 sudo nano /etc/pam.d/common-sessionsession required pam_limits.so
CPU 调度优化 :
1 2 3 4 5 sudo cpupower frequency-set -g performancesudo systemctl disable cpufrequtils
2.2.3 文件系统优化 存储类型选择 :
1 2 3 4 5 6 lsblk -d -o NAME,TYPE,ROTA 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 UUID=your-disk-uuid /data ext4 defaults,noatime,nodiratime,discard,errors=remount-ro 0 2 UUID=your-nvme-uuid /data xfs defaults,noatime,nodiratime,discard,logbufs=8 0 2
文件系统参数调优 :
1 2 3 4 5 6 7 sudo tune2fs -o journal_data_writeback /dev/sda1sudo tune2fs -O ^has_journal /dev/sda1 sudo xfs_admin -L data /dev/nvme0n1p1sudo 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-slavechmod -R 755 data/ chmod -R 700 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/ sudo chown -R 999:999 data/master/ sudo chown -R 999:999 data/slave1/sudo chown -R 999:999 data/slave2/sudo chown -R 65534:65534 data/prometheus/ sudo chown -R 472:472 data/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 init cat > .gitignore << 'EOF' data/ logs/ backup/ temp/ ssl/ .env .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 port = 3306 bind-address = 0.0 .0.0 socket = /var/run/mysqld/mysqld.sock pid-file = /var/run/mysqld/mysqld.pid log-bin = mysql-bin binlog-format = ROW binlog-row-image = FULL max-binlog-size = 100 M expire-logs-days = 7 sync-binlog = 100 binlog-checksum = CRC32 binlog-rows-query-log-events = ON log-slave-updates = 1 enforce-gtid-consistency = 1 gtid-mode = ON binlog-ignore-db = mysql,information_schema,performance_schema,sys replicate-wild-ignore-table = mysql.% max_connections = 2000 max_connect_errors = 10000 max_allowed_packet = 64 M wait_timeout = 3600 interactive_timeout = 3600 thread_cache_size = 128 table_open_cache = 2048 innodb_buffer_pool_size = 2 G innodb_buffer_pool_instances = 4 innodb_log_buffer_size = 64 M innodb_sort_buffer_size = 1 M join_buffer_size = 2 M read_buffer_size = 1 M read_rnd_buffer_size = 4 M innodb_log_file_size = 512 M innodb_log_files_in_group = 2 innodb_flush_log_at_trx_commit = 2 innodb_flush_method = O_DIRECT innodb_io_capacity = 2000 innodb_io_capacity_max = 4000 innodb_lru_scan_depth = 1024 innodb_page_cleaners = 4 innodb_purge_threads = 4 innodb_thread_concurrency = 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 userstat = 1 plugin-load = "rpl_semi_sync_master=semisync_master.so" rpl_semi_sync_master_enabled = 1 rpl_semi_sync_master_timeout = 10000 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" lower_case_table_names = 0 max_heap_table_size = 64 M tmp_table_size = 64 M query_cache_type = 0 query_cache_size = 0
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 port = 3306 bind-address = 0.0 .0.0 socket = /var/run/mysqld/mysqld.sock pid-file = /var/run/mysqld/mysqld.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 = 100 M relay-log-space-limit = 4 G 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 slave_preserve_commit_order = 1 slave_transaction_retries = 10 slave-checkpoint-period = 300 slave-checkpoint-group = 512 max_connections = 2500 max_connect_errors = 10000 max_allowed_packet = 64 M wait_timeout = 3600 interactive_timeout = 3600 thread_cache_size = 128 thread_pool_size = 8 innodb_buffer_pool_size = 3 G innodb_buffer_pool_instances = 4 innodb_log_buffer_size = 64 M innodb_sort_buffer_size = 1 M join_buffer_size = 2 M read_buffer_size = 2 M read_rnd_buffer_size = 4 M innodb_log_file_size = 512 M innodb_log_files_in_group = 2 innodb_flush_log_at_trx_commit = 2 innodb_flush_method = O_DIRECT innodb_io_capacity = 2000 innodb_io_capacity_max = 4000 innodb_lru_scan_depth = 1024 innodb_page_cleaners = 4 innodb_purge_threads = 4 innodb_thread_concurrency = 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 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" lower_case_table_names = 0 max_heap_table_size = 64 M tmp_table_size = 64 M query_cache_type = 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 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-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-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-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: 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: 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: 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; } 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: - 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' - 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' - 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' - 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-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
4. 企业级部署步骤 4.1 部署前验证 环境检查
1 2 3 4 5 6 7 8 9 10 11 12 docker --version docker compose version free -h df -hping -c 4 mysql.com
配置文件验证
1 2 3 4 5 6 7 8 9 ls -lacat .env ls -la conf/master/ls -la conf/slave/
生成 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.pemchmod 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 docker-compose exec mysql-master bash
登录 MySQL :
1 mysql -u root -p${MYSQL_ROOT_PASSWORD}
创建监控用户 :
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;
查看主库状态 :
记录 File 和 Position 的值,后续配置从库时需要使用。
验证二进制日志配置 :
1 2 3 4 5 SHOW VARIABLES LIKE '%binlog%' ;SHOW VARIABLES LIKE 'server_id' ;
4.4 从库初始化配置 4.4.1 配置从库 1 进入从库 1 容器 :
1 docker-compose exec mysql-slave1 bash
登录 MySQL :
1 mysql -u root -p${MYSQL_ROOT_PASSWORD}
配置主从复制 :
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;
查看从库状态 :
检查 Slave_IO_Running 和 Slave_SQL_Running 是否均为 Yes。
4.4.2 配置从库 2 按照相同步骤配置从库 2,确保使用相同的主库日志文件和位置。
4.5 验证主从复制 测试数据同步 :
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 );
在从库验证数据 :
1 2 3 4 5 6 7 USE ${MYSQL_DATABASE}; SELECT * FROM test_table;USE ${MYSQL_DATABASE}; SELECT * FROM test_table;
验证复制延迟 :
4.6 负载均衡配置 验证 Nginx 配置 :
1 docker-compose exec nginx nginx -t
测试负载均衡 :
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 监控服务配置 访问 Prometheus :
访问 Grafana :
5. 企业级主从复制测试 5.1 基础功能测试 5.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; "
在从库 1 验证数据 :
1 2 3 4 docker-compose exec mysql-slave1 mysql -u root -p${MYSQL_ROOT_PASSWORD} -e " USE ${MYSQL_DATABASE} ; SELECT * FROM users; "
在从库 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 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。
验证从库状态 :
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 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; "
在从库验证同步 :
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 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; "
恢复主库 :
1 2 3 4 5 6 7 8 9 10 docker-compose start mysql-master sleep 30docker-compose exec mysql-slave1 mysql -u root -p${MYSQL_ROOT_PASSWORD} -e " SHOW SLAVE STATUS\G; "
5.2.3 负载均衡测试 测试 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
验证负载均衡效果 :
1 2 docker-compose logs nginx | grep -E 'upstream_addr|upstream_response_time'
5.3 性能测试 5.3.1 读性能测试 使用 sysbench 测试从库读性能 :
1 2 3 4 5 6 7 8 sudo apt-get install sysbench -ysysbench 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
测试负载均衡后的读性能 :
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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 cat > monitor_replication.sh << 'EOF' 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
在主库执行大量写操作 :
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(); "
观察复制延迟变化 : 查看监控脚本输出,观察 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 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 networks: - mysql-network
配置步骤 :
在主库上启用 log-slave-updates 将从库 3 的主库设置为 mysql-slave1 确保从库 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 ; 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 ;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 ; SET GLOBAL slave_preserve_commit_order = 1 ; SET GLOBAL slave_parallel_workers = 8 ; 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' ;
在 my.cnf 中持久化配置 :
1 2 3 4 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 ; 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_row_image = MINIMAL sync_binlog = 1 slave_parallel_workers = 8 slave_compressed_protocol = 1 max_allowed_packet = 64 M
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 = 4 G innodb_log_buffer_size = 64 M innodb_io_capacity = 2000 innodb_flush_method = O_DIRECT
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-ca = /etc/mysql/ssl/ca-cert.pemssl-cert = /etc/mysql/ssl/server-cert.pemssl-key = /etc/mysql/ssl/server-key.pemssl-ca = /etc/mysql/ssl/ca-cert.pemssl-cert = /etc/mysql/ssl/client-cert.pemssl-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_Running 或 Slave_SQL_Running 为 No。
解决方案 :
详细诊断 :
1 2 3 4 5 SHOW SLAVE STATUS\G;docker- compose logs mysql- slave1 | grep - i error
常见错误及专业解决方案 :
错误 1062 :主键冲突
1 2 3 4 5 6 7 8 9 10 SET GLOBAL sql_slave_skip_counter = 1 ;START SLAVE;STOP SLAVE; 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 2 3 4 5 6 7 8 SHOW SLAVE STATUS\G;docker- compose exec mysql- slave1 top docker- compose exec mysql- master mysql - u root - p${MYSQL_ROOT_PASSWORD} - e "SHOW GLOBAL STATUS LIKE 'Binlog%';"
优化措施 :
启用并行复制 :1 2 SET GLOBAL slave_parallel_workers = 8 ;SET GLOBAL slave_parallel_type = 'LOGICAL_CLOCK' ;
调整从库配置 :1 2 3 innodb_buffer_pool_size = 4 Ginnodb_log_buffer_size = 64 Minnodb_io_capacity = 2000
网络优化 :启用压缩传输1 SET GLOBAL slave_compressed_protocol = 1 ;
7.2 存储与性能问题 7.2.1 主库 binlog 过大 问题 :主库的 binlog 文件过大,占用磁盘空间。
解决方案 :
配置优化 :
1 2 3 4 expire-logs-days = 7 max-binlog-size = 100 Mbinlog-row-image = MINIMAL
安全清理 :
1 2 3 4 5 6 7 8 SHOW MASTER STATUS;PURGE BINARY LOGS TO 'mysql-bin.000005' ; PURGE BINARY LOGS BEFORE '2026-02-01 00:00:00' ;
监控与告警 :
7.2.2 从库 IO 性能瓶颈 问题 :从库 IO 性能不足,导致复制延迟。
解决方案 :
存储优化 :
MySQL 配置优化 :
1 2 3 4 innodb_flush_method = O_DIRECTinnodb_io_capacity = 4000 innodb_io_capacity_max = 8000 innodb_lru_scan_depth = 1024
监控 IO 性能 :
1 docker-compose exec mysql-slave1 iostat -x 1
7.3 高可用与故障转移 7.3.1 主库故障切换 问题 :主库故障,需要将从库提升为主库。
解决方案 :
手动故障转移 :
1 2 3 4 5 6 7 8 9 10 11 12 13 STOP SLAVE; SHOW SLAVE STATUS\G;RESET MASTER; SET GLOBAL read_only = 0 ;SET GLOBAL super_read_only = 0 ;
其他从库重新指向 :
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;
应用配置更新 :
7.3.2 自动故障转移方案 推荐方案 :使用 Orchestrator 实现自动故障转移
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
配置示例 :
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" ] }
优势 :
自动检测主库故障 智能选择最佳从库提升 自动更新其他从库指向 支持手动和自动故障转移 7.4 安全与权限问题 7.4.1 复制用户权限不足 问题 :复制用户权限不足,导致复制失败。
解决方案 :
检查权限 :
1 SHOW GRANTS FOR '${MYSQL_REPL_USER}' @'%' ;
修复权限 :
1 2 GRANT REPLICATION SLAVE, REPLICATION CLIENT ON * .* TO '${MYSQL_REPL_USER}' @'%' ;FLUSH PRIVILEGES;
7.4.2 SSL 复制配置错误 问题 :SSL 复制配置错误,导致连接失败。
解决方案 :
检查 SSL 配置 :
1 2 3 4 5 SHOW GLOBAL VARIABLES LIKE '%ssl%' ;SHOW GLOBAL VARIABLES LIKE '%ssl%' ;
验证证书 :
1 docker-compose exec mysql-master openssl verify -CAfile /etc/mysql/ssl/ca-cert.pem /etc/mysql/ssl/server-cert.pem
重新配置 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 方案 :
部署 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
Grafana 仪表盘 :
导入 MySQL 官方仪表盘(ID: 7362) 自定义复制监控仪表盘 设置关键指标告警 告警配置 :
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 find /backup/full -mtime +7 -type d -exec rm -rf {} \;
备份验证 :
定期测试备份恢复 验证备份文件完整性 监控备份执行状态 8.2.2 性能优化维护 定期维护任务 :
表优化 :
1 2 3 4 5 6 7 8 OPTIMIZE TABLE dbname.tablename; ANALYZE TABLE dbname.tablename; CHECK TABLE dbname.tablename;
索引优化 :
定期分析慢查询日志 使用 EXPLAIN 分析查询计划 添加或调整索引结构 配置调优 :
根据工作负载调整参数 监控配置有效性 定期review配置文件 8.2.3 安全维护 定期安全检查 :
权限审计 :
1 2 3 4 5 SELECT user , host, plugin FROM mysql.user;SHOW GRANTS FOR 'username' @'host' ;
密码策略 :
SSL 证书维护 :
定期更新 SSL 证书 验证证书链完整性 监控证书过期时间 漏洞扫描 :
使用 MySQLTuner 进行安全扫描 定期检查 CVE 漏洞 及时应用安全补丁 8.3 企业级升级与迁移 8.3.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/
升级执行 :
1 2 3 4 5 6 7 8 9 10 11 docker-compose down docker-compose up -d docker-compose exec mysql-master mysql_upgrade -u root -p${MYSQL_ROOT_PASSWORD}
验证升级 :
8.3.2 数据迁移方案 方案选择 :
逻辑备份迁移 :使用 mysqldump 或 mydumper物理备份迁移 :使用 XtraBackup主从复制迁移 :使用 GTID 复制第三方工具 :使用 Oracle Data Pump 或第三方迁移工具主从复制迁移步骤 :
在新服务器部署从库 配置主从复制 等待数据同步完成 执行故障转移 验证应用连接 大数据库迁移优化 :
使用并行备份工具 启用压缩传输 优化网络带宽 分批次迁移数据 8.4 灾难恢复计划 8.4.1 灾难恢复策略 RTO/RPO 定义 :
RTO (恢复时间目标):最大可接受的服务中断时间RPO (恢复点目标):最大可接受的数据丢失量灾难恢复级别 :
Level 0 :无备份,手动恢复Level 1 :本地备份,手动恢复Level 2 :本地备份,自动恢复Level 3 :异地备份,手动恢复Level 4 :异地备份,自动恢复Level 5 :多活架构,自动故障转移8.4.2 恢复演练 定期演练计划 :
每季度执行一次完整恢复演练 每月执行一次增量恢复演练 每次配置变更后执行测试恢复 演练步骤 :
准备演练环境 执行恢复操作 验证恢复结果 记录演练时间 更新恢复计划 演练指标 :
恢复时间:实际 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] binlog-format = ROWmax-binlog-size = 100 Mexpire-logs-days = 7 sync-binlog = 100 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_buffer_pool_size = 8 Ginnodb_buffer_pool_instances = 8 innodb_log_buffer_size = 64 Msort_buffer_size = 2 Mjoin_buffer_size = 2 Mread_rnd_buffer_size = 1 Mread_buffer_size = 1 M
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 = 1 Ginnodb_log_files_in_group = 2 innodb_flush_log_at_trx_commit = 2 innodb_flush_method = O_DIRECTinnodb_file_per_table = 1 innodb_file_format = Barracudainnodb_large_prefix = 1 innodb_io_capacity = 2000 innodb_io_capacity_max = 4000 innodb_thread_concurrency = 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 = 64 Mmax_heap_table_size = 64 Mtmpdir = /tmp
慢查询日志 :
1 2 3 4 5 6 [mysqld] slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow-query.loglong_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_CLOCKslave-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 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 = 12 Goptimizer_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 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 vm.swappiness = 10 vm.overcommit_memory = 1 vm.max_map_count = 262144
IO 调度优化 :
1 2 3 4 5 echo deadline > /sys/block/sda/queue/schedulerecho 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 sudo apt-get install sysbenchsysbench 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 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 SET profiling = 1 ;SELECT * FROM large_table WHERE id > 1000000 ;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-ca = /etc/mysql/ssl/ca-cert.pemssl-cert = /etc/mysql/ssl/server-cert.pemssl-key = /etc/mysql/ssl/server-key.pemrequire_secure_transport = 1 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 sslcd sslopenssl 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 *.pemchmod 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.sovalidate_password_policy = STRONGvalidate_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 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.loglog_error = /var/log/mysql/error.loglog-bin = mysql-binslow_query_log = 1 slow_query_log_file = /var/log/mysql/slow-query.loglong_query_time = 1
MySQL Enterprise Audit (企业版):
1 2 3 4 5 6 [mysqld] plugin-load = audit_log.soaudit_log_format = JSONaudit_log_policy = ALLaudit_log_file = /var/log/mysql/audit.log
10.4.2 日志轮转 日志轮转配置 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 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 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-compose pull docker-compose down docker-compose up -d 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、主从复制、高可用、部署教程、读写分离、故障切换、数据备份、性能优化、安全配置