MySQL容器化部署与自动备份实战
前言
在中小型 Web 项目或个人开发者应用的后端架构中,关系型数据库 MySQL 依然是最核心的基础组件之一。相比直接在华为云弹性云服务器(ECS)宿主机上通过二进制包或 APT 源安装 MySQL,采用 Docker Compose 容器化编排 不仅能快速锁定数据库版本、隔离依赖环境,还能通过数据卷挂载实现配置与持久化数据的解耦。
与此同时,“数据无价”,任何生产或测试环境都必须具备完善的容灾备份机制。本文将完整演示在华为云 Ubuntu 22.04 实例上,使用 Docker Compose 部署优化后的 MySQL 8.0 实例,并编写 Shell 脚本配合 Crontab 实现每日自动化压缩热备份与过期备份清理。
一、 环境准备与目录规划
在开始部署前,我们在宿主机的数据盘或 /opt 目录下规划清晰的目录结构,分别用于存放编排文件、自定义配置、持久化数据以及备份归档文件:
# 创建 MySQL 容器化工作目录与子目录
sudo mkdir -p /opt/mysql8/{conf,data,logs,backup}
# 进入工作主目录
cd /opt/mysql8
各目录职责说明:
conf/:存放自定义的my.cnf配置文件(字符集、连接数与内存缓冲池调优)。data/:挂载容器内/var/lib/mysql,确保容器销毁或重建时数据不丢失。logs/:存放慢查询日志与错误日志。backup/:存放每日定时导出的.sql.gz压缩备份文件。
二、 编写 MySQL 8.0 调优配置文件
为了避免中文乱码问题,并让 MySQL 更好地适应 2核4G 或 1核2G 等不同规格的华为云 ECS 实例,我们先在 /opt/mysql8/conf/my.cnf 中写入标准化配置:
sudo tee /opt/mysql8/conf/my.cnf << 'EOF'
[mysqld]
# 基础设置与默认字符集
user = mysql
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
default-time-zone = '+08:00'
# 禁用域名反向解析,加快客户端连接速度
skip-name-resolve
# 连接数与超时控制
max_connections = 500
wait_timeout = 600
interactive_timeout = 600
# InnoDB 缓冲池调优(可根据服务器实际内存大小调整,2G内存建议设为 512M)
innodb_buffer_pool_size = 512M
innodb_log_file_size = 128M
innodb_flush_log_at_trx_commit = 1
# 开启慢查询日志,记录超过 2 秒的 SQL 语句
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 2
[client]
default-character-set = utf8mb4
EOF
三、 使用 Docker Compose 启动 MySQL 8.0
1. 编写 docker-compose.yml 文件
出于安全考虑,如果不涉及跨公网远程直连,建议将端口仅绑定在宿主机本地回环地址 127.0.0.1:3306(或者通过华为云安全组严格限制仅允许特定内网/办公网 IP 访问 3306 端口):
sudo tee /opt/mysql8/docker-compose.yml << 'EOF'
version: '3.8'
services:
mysql:
image: mysql:8.0
container_name: mysql8-server
restart: always
ports:
- "127.0.0.1:3306:3306"
environment:
MYSQL_ROOT_PASSWORD: "StrongPassword_2026!"
MYSQL_DATABASE: "app_prod_db"
TZ: "Asia/Shanghai"
volumes:
- ./conf/my.cnf:/etc/mysql/conf.d/my.cnf:ro
- ./data:/var/lib/mysql
- ./logs:/var/log/mysql
command:
- --default-authentication-plugin=mysql_native_password
EOF
2. 启动容器并验证状态
赋予日志目录合适的权限后,一键拉起服务:
sudo chmod -R 777 /opt/mysql8/logs
sudo docker-compose up -d
# 查看容器运行状态与初始化日志
sudo docker ps | grep mysql8-server
sudo docker logs --tail 50 mysql8-server
当日志中出现 ready for connections. Version: '8.0.x' 时,说明数据库已成功初始化并正常对外提供服务。
四、 编写自动化热备份与历史归档清理脚本
为了防止人工误删表或硬件意外造成数据丢失,我们利用 docker exec 结合 mysqldump 的 --single-transaction 参数实现不锁表的在线热备份,并使用 gzip 实时压缩以节省华为云云硬盘空间。
1. 创建备份脚本 mysql_backup.sh
sudo tee /opt/mysql8/mysql_backup.sh << 'EOF'
#!/bin/bash
# 配置参数
CONTAINER_NAME="mysql8-server"
DB_USER="root"
DB_PASS="StrongPassword_2026!"
DB_NAME="app_prod_db"
BACKUP_DIR="/opt/mysql8/backup"
DATE_STR=$(date +"%Y%m%d_%H%M%S")
RETENTION_DAYS=14
# 确保备份目录存在
mkdir -p ${BACKUP_DIR}
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 开始备份数据库: ${DB_NAME}" >> ${BACKUP_DIR}/backup.log
# 执行在线热备份并直接通过 gzip 高比率压缩
docker exec ${CONTAINER_NAME} mysqldump -u${DB_USER} -p"${DB_PASS}" \
--single-transaction \
--routines \
--triggers \
--events \
${DB_NAME} 2>/dev/null | gzip > ${BACKUP_DIR}/${DB_NAME}_${DATE_STR}.sql.gz
# 检查备份文件是否成功生成且非空
if [ -s "${BACKUP_DIR}/${DB_NAME}_${DATE_STR}.sql.gz" ]; then
FILE_SIZE=$(du -sh "${BACKUP_DIR}/${DB_NAME}_${DATE_STR}.sql.gz" | awk '{print $1}')
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 备份成功: ${DB_NAME}_${DATE_STR}.sql.gz (大小: ${FILE_SIZE})" >> ${BACKUP_DIR}/backup.log
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [错误] 备份失败,请检查容器状态或密码配置!" >> ${BACKUP_DIR}/backup.log
rm -f "${BACKUP_DIR}/${DB_NAME}_${DATE_STR}.sql.gz"
exit 1
fi
# 自动清理超过 14 天的历史旧备份,释放磁盘空间
find ${BACKUP_DIR} -name "${DB_NAME}_*.sql.gz" -type f -mtime +${RETENTION_DAYS} -delete
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 已清理超过 ${RETENTION_DAYS} 天的过期备份。" >> ${BACKUP_DIR}/backup.log
EOF
# 赋予脚本执行权限并设置仅 root 可读(保护脚本内的密码信息)
sudo chmod 700 /opt/mysql8/mysql_backup.sh
2. 手动测试备份与恢复命令
先手动运行一次脚本,验证备份产物是否正常生成:
sudo /opt/mysql8/mysql_backup.sh
ls -lh /opt/mysql8/backup/
日后若需要从某次压缩备份中恢复数据,只需执行以下流式解压导入命令即可:
gunzip < /opt/mysql8/backup/app_prod_db_xxxxxxx.sql.gz | docker exec -i mysql8-server mysql -uroot -p"StrongPassword_2026!" app_prod_db
3. 配置 Crontab 每日凌晨定时执行
将脚本加入系统计划任务,设置在每天业务低峰期(凌晨 02:30)自动执行备份:
(sudo crontab -l 2>/dev/null; echo "30 2 * * * /opt/mysql8/mysql_backup.sh") | sudo crontab -
总结
通过 Docker Compose 编排与自定义 my.cnf 挂载,我们在华为云 ECS 上实现了 MySQL 8.0 的标准化快速交付;而结合 --single-transaction 热备与 find 定时轮转清理脚本,则在零额外成本的前提下构建起了可靠的数据安全防线。对于重要生产数据,后续还可以进一步结合华为云对象存储服务(OBS)命令行工具,将本地生成的 .sql.gz 备份同步上传至异地云存储桶中,实现更高等级的灾备保护。
- 点赞
- 收藏
- 关注作者
评论(0)