Docker MySQL 自动备份与恢复教程(systemd 定时任务)
Docker MySQL 自动备份与恢复教程systemd 定时任务本文介绍如何为 Docker 中运行的 MySQL 数据库建立自动备份方案使用mysqldump导出数据库自动压缩为.sql.gz每 5 天备份一次自动保留最近 30 天的备份使用systemd timer设置开机自动启用提供完整的数据库恢复流程。本文统一使用MyProject作为示例项目代号。实际使用时只需要替换项目名称、容器名、数据库名、密码和目录即可。1. 需要替换的配置请根据自己的服务器环境修改以下名称示例名称说明MyProject项目名称或项目代号myproject项目名称的小写形式myproject-mysqlMySQL Docker 容器名称myproject-backend后端 Docker 容器名称myproject123456MySQL root 密码/root/MyProject_Backup/mysql备份保存目录/root/backup_myproject_mysql.sh自动备份脚本路径先查看正在运行的 Docker 容器dockerps--formattable {{.Names}}\t{{.Status}}输出示例NAMES STATUS myproject-mysql Up 10 days myproject-backend Up 10 days2. 为什么不要直接复制 MySQL 数据目录MySQL 数据通常挂载在宿主机目录中例如/root/MyProject_Web/data/mysql/不要在 MySQL 正在运行时直接复制这个目录cp-a/root/MyProject_Web/data/mysql /root/mysql_backup因为 MySQL 在运行过程中会持续写入表数据、日志和索引文件。直接复制可能产生不一致的数据副本恢复时可能失败。更可靠的方法是使用mysqldump将数据库导出为 SQL 文件再压缩为.sql.gz这种备份方式可以在 MySQL 正常运行时执行且更容易迁移、检查和恢复。3. 创建独立备份目录建议将备份保存在项目目录之外避免项目目录被误删时连备份一起丢失。mkdir-p/root/MyProject_Backup/mysqlchmod700/root/MyProject_Backup/mysql以后生成的备份文件会保存在/root/MyProject_Backup/mysql/文件名示例myproject_2026-06-26_200000.sql.gz4. 创建 MySQL 自动备份脚本创建脚本文件vi/root/backup_myproject_mysql.sh将下面内容完整粘贴进去#!/usr/bin/env bashset-euopipefail# # MyProject Docker MySQL 自动备份脚本# # Docker 中 MySQL 容器名称CONTAINER_NAMEmyproject-mysql# 要备份的数据库名称DATABASE_NAMEmyproject# MySQL root 密码MYSQL_ROOT_PASSWORDmyproject123456# 备份保存目录BACKUP_DIR/root/MyProject_Backup/mysql# 保留最近多少天的备份# 每 5 天备份一次保留 30 天约等于保留 6 份RETENTION_DAYS30# 创建备份目录mkdir-p${BACKUP_DIR}chmod700${BACKUP_DIR}# 检查 MySQL 容器是否正在运行if!dockerps--format{{.Names}}|grep-qx${CONTAINER_NAME};thenecho[$(date%F %T)] 错误MySQL 容器${CONTAINER_NAME}未运行。2exit1fi# 生成带时间戳的备份文件名TIMESTAMP$(date%F_%H%M%S)BACKUP_FILE${BACKUP_DIR}/${DATABASE_NAME}_${TIMESTAMP}.sql.gzTMP_FILE${BACKUP_FILE}.tmpecho[$(date%F %T)] 开始备份数据库${DATABASE_NAME}# 导出数据库并进行 gzip 压缩# --single-transactionInnoDB 数据库可在不停机状态下进行一致性备份# --quick减少大数据库备份时的内存占用dockerexec\-eMYSQL_PWD${MYSQL_ROOT_PASSWORD}\${CONTAINER_NAME}\mysqldump\-uroot\--single-transaction\--quick\--routines\--events\--triggers\--databases${DATABASE_NAME}\|gzip-c${TMP_FILE}# 检查压缩包是否完整gzip-t${TMP_FILE}# 验证成功后将临时文件改为正式备份文件mv${TMP_FILE}${BACKUP_FILE}echo[$(date%F %T)] 备份成功${BACKUP_FILE}# 删除超过保留期限的旧备份find${BACKUP_DIR}\-typef\-name*.sql.gz\-mtime${RETENTION_DAYS}\-deleteecho[$(date%F %T)] 已清理超过${RETENTION_DAYS}天的旧备份。保存并退出vi按 Esc 输入 :wq 按 Enter为脚本添加执行权限chmod700/root/backup_myproject_mysql.sh检查权限ls-l/root/backup_myproject_mysql.sh正常应看到类似-rwx------ 1 root root ... /root/backup_myproject_mysql.sh其中x表示脚本具有执行权限。5. 手动测试备份先手动运行一次脚本确认配置正确/root/backup_myproject_mysql.sh正常情况下会输出类似[2026-06-26 20:00:00] 开始备份数据库myproject [2026-06-26 20:00:01] 备份成功/root/MyProject_Backup/mysql/myproject_2026-06-26_200000.sql.gz [2026-06-26 20:00:01] 已清理超过 30 天的旧备份。查看备份文件ls-lh/root/MyProject_Backup/mysql/正常会看到myproject_2026-06-26_200000.sql.gz建议先确认手动备份成功再配置自动定时任务。6. 创建 systemd 服务创建service文件cat/etc/systemd/system/myproject-mysql-backup.serviceEOF [Unit] DescriptionMyProject MySQL Backup Afterdocker.service Requiresdocker.service [Service] Typeoneshot ExecStart/root/backup_myproject_mysql.sh EOF查看服务文件cat/etc/systemd/system/myproject-mysql-backup.service正常应显示[Unit] DescriptionMyProject MySQL Backup Afterdocker.service Requiresdocker.service [Service] Typeoneshot ExecStart/root/backup_myproject_mysql.sh7. 创建每 5 天执行一次的 systemd 定时器创建 timer 文件cat/etc/systemd/system/myproject-mysql-backup.timerEOF [Unit] DescriptionRun MyProject MySQL backup every 5 days [Timer] # 定时器启动后每隔 5 天执行一次 OnUnitActiveSec5d # 服务器关机期间错过任务时恢复运行后补做 Persistenttrue [Install] WantedBytimers.target EOF参数说明OnUnitActiveSec5d表示定时器启动后每隔 5 天运行一次备份服务。Persistenttrue表示若服务器在计划执行时关机系统恢复后会补做错过的备份任务。8. 启用定时器并设置开机自动启动执行systemctl daemon-reload systemctlenable--nowmyproject-mysql-backup.timer systemctl restart myproject-mysql-backup.timer检查定时器状态systemctl status myproject-mysql-backup.timer正常会显示类似Loaded: loaded (...; enabled; ...) Active: active (waiting) Trigger: ...其中enabled服务器重启后定时器会自动启动active (waiting)定时器正在等待下一次执行Trigger下一次自动备份的时间。查看下次运行时间systemctl list-timers--all|grepmyproject-mysql-backup检查是否已设置为开机启动systemctl is-enabled myproject-mysql-backup.timer正常应输出enabled9. 测试 systemd 是否能正常调用备份脚本手动触发一次 systemd 备份systemctl start myproject-mysql-backup.service查看日志journalctl-umyproject-mysql-backup.service-n30--no-pager正常会看到类似Starting MyProject MySQL Backup... 开始备份数据库myproject 备份成功/root/MyProject_Backup/mysql/myproject_2026-06-26_200000.sql.gz 已清理超过 30 天的旧备份。 Finished MyProject MySQL Backup.这说明 systemd 可以正常调用备份脚本。10. 常用备份管理命令查看所有备份文件ls-lh/root/MyProject_Backup/mysql/手动立即备份/root/backup_myproject_mysql.sh或systemctl start myproject-mysql-backup.service查看自动备份状态systemctl status myproject-mysql-backup.timer查看下一次备份时间systemctl list-timers--all|grepmyproject-mysql-backup查看备份日志journalctl-umyproject-mysql-backup.service-n50--no-pager停止自动备份systemctl disable--nowmyproject-mysql-backup.timer重新启用自动备份systemctlenable--nowmyproject-mysql-backup.timer11. 如何恢复某一份数据库备份假设需要恢复以下备份/root/MyProject_Backup/mysql/myproject_2026-06-26_200000.sql.gz恢复会将当前数据库替换为历史备份版本。开始前请确认选中的备份文件正确。11.1 先备份当前数据库恢复前先生成一份当前数据库备份/root/backup_myproject_mysql.sh这样即使恢复了错误版本也可以回退到恢复操作前的状态。11.2 停止项目后端容器先查看运行中的容器dockerps假设后端容器名称为myproject-backend停止后端dockerstop myproject-backendmyproject-backend是示例名称请替换为实际后端容器名称。MySQL 容器myproject-mysql不需要停止。11.3 删除当前数据库dockerexec-it\-eMYSQL_PWDmyproject123456\myproject-mysql\mysql-uroot-eDROP DATABASE IF EXISTS myproject;这条命令会删除当前的myproject数据库因此必须确认前一步的备份已成功完成。11.4 导入指定备份gunzip-c/root/MyProject_Backup/mysql/myproject_2026-06-26_200000.sql.gz\|dockerexec-i\-eMYSQL_PWDmyproject123456\myproject-mysql\mysql-uroot导入过程可能没有额外输出只要没有报错一般表示恢复成功。11.5 检查恢复结果查看数据库dockerexec-it\-eMYSQL_PWDmyproject123456\myproject-mysql\mysql-uroot-eSHOW DATABASES;查看恢复后的表dockerexec-it\-eMYSQL_PWDmyproject123456\myproject-mysql\mysql-uroot-eUSE myproject; SHOW TABLES;能够正常显示表名通常说明恢复成功。11.6 启动后端容器dockerstart myproject-backend将myproject-backend替换成实际后端容器名称。12. 完整恢复流程# 1. 备份恢复前的当前数据库/root/backup_myproject_mysql.sh# 2. 查看所有备份文件确认需要恢复哪一份ls-lh/root/MyProject_Backup/mysql/# 3. 停止项目后端容器dockerstop myproject-backend# 4. 删除当前数据库dockerexec-it\-eMYSQL_PWDmyproject123456\myproject-mysql\mysql-uroot-eDROP DATABASE IF EXISTS myproject;# 5. 恢复指定备份gunzip-c/root/MyProject_Backup/mysql/myproject_2026-06-26_200000.sql.gz\|dockerexec-i\-eMYSQL_PWDmyproject123456\myproject-mysql\mysql-uroot# 6. 检查恢复后的数据表dockerexec-it\-eMYSQL_PWDmyproject123456\myproject-mysql\mysql-uroot-eUSE myproject; SHOW TABLES;# 7. 启动项目后端容器dockerstart myproject-backend13. 备份策略总结项目设置MySQL 容器myproject-mysql数据库名称myproject备份目录/root/MyProject_Backup/mysql备份脚本/root/backup_myproject_mysql.sh自动备份频率每 5 天一次备份保留时间30 天预计保留份数约 6 份备份格式.sql.gz自动删除旧备份是开机自动启用定时器是14. 进一步建议本文中的备份文件仍然存放在同一台服务器因此可以防止数据库误删错误更新或错误覆盖项目升级失败项目目录被误删数据库表被错误修改。但它无法防止服务器硬盘损坏整台服务器不可用云服务器被删除勒索软件或严重系统故障。对于重要数据库建议定期将以下目录同步到另一块硬盘、NAS、对象存储或另一台服务器/root/MyProject_Backup/mysql/

相关新闻

Kubernetes Pod 驱逐风暴:从 OOM 到节点压力的排障全链路

Kubernetes Pod 驱逐风暴:从 OOM 到节点压力的排障全链路

Kubernetes Pod 驱逐风暴:从 OOM 到节点压力的排障全链路一、凌晨三点的告警洪流:Pod 驱逐如何拖垮整个集群 在 Kubernetes 生产环境中,Pod 驱逐是最令人头疼的故障模式之一。它不像 CrashLoopBackOff 那样有明确的错误日志,而是以…

2026/6/27 2:59:22阅读更多 →
C语言学习笔记 - 64.流程控制18 - 选择结构中的if与switch

C语言学习笔记 - 64.流程控制18 - 选择结构中的if与switch

一、本节学习定位本节内容属于 流程控制 中的选择结构部分。C 语言中的选择结构主要包括两类:if 语句switch 语句在实际入门学习中,if 语句使用频率更高,也是学习流程控制的重点。switch 语句主要用于处理“表达式的值等于某些固定常量”的多…

2026/6/27 2:59:22阅读更多 →
智能合约辅助开发:Web3 DApp 全栈实战——从钱包连接到链上交互的工程化闭环

智能合约辅助开发:Web3 DApp 全栈实战——从钱包连接到链上交互的工程化闭环

智能合约辅助开发:Web3 DApp 全栈实战——从钱包连接到链上交互的工程化闭环一、链上孤岛与开发效率的拉锯战:Web3 应用的工程痛点 Web3 应用的开发流程与传统 Web2 存在本质差异。传统前端调用后端 API,数据存储在中心化数据库,链…

2026/6/27 2:59:22阅读更多 →
零基础怎么做AI数据标注?我的入门实践记录

零基础怎么做AI数据标注?我的入门实践记录

声明:本文为通用技术分析,基于行业公开信息进行逻辑推演,不针对任何特定平台,不构成使用推荐。一、任务建模与分发策略AI数据标注平台的核心是将企业需求的标准数据拆解为标准化单元,分发给标注人员完成。一个标注任务…

2026/6/27 4:24:26阅读更多 →
表压缩新功能 compress for oltp ROW STORE COMPRESS ADVANCED ONLINE

表压缩新功能 compress for oltp ROW STORE COMPRESS ADVANCED ONLINE

ALTER TABLE ... COMPRESS FOR OLTP 对已有分区无效,因仅设置元数据标记而不重写物理块;压缩已有数据须用 MOVE PARTITION ... ROW STORE COMPRESS ADVANCED ONLINE 并重建索引。不能直接用 alter table ... compress for oltp 让已有分区数据变小——它…

2026/6/27 4:24:26阅读更多 →
用 responses-proxy 将 agnes-20-flash 接入原生 Codex:让免费 LLM 也能跑起来

用 responses-proxy 将 agnes-20-flash 接入原生 Codex:让免费 LLM 也能跑起来

最近在折腾原生 Codex 的模型接入时,遇到了一个比较典型的问题: 当前 Codex 主要支持 wire_api "responses" 模式,而很多第三方 OpenAI 兼容服务只提供 /v1/chat/completions 接口,无法直接接入。 其中,agn…

2026/6/27 4:24:26阅读更多 →
网络安全可以考什么证书?

网络安全可以考什么证书?

随着网络安全行业持续升温,越来越多人想进入这个领域。网络安全可以考什么证书?今天这篇文章一次性把国内外的重点网络安全证书讲清楚,帮你找到最适合自己的考证路线。一、为什么网络安全证书如此重要?网络安全行业拥有专业认证&a…

2026/6/27 4:24:26阅读更多 →
OpenClaw:自托管开源 AI 智能体网关,重新定义你的专属 AI 工作流

OpenClaw:自托管开源 AI 智能体网关,重新定义你的专属 AI 工作流

一、项目起源与核心定位OpenClaw 是 2025 年末诞生、2026 年正式定名的开源 AI 智能体网关项目,开发主体为 Peter Steinberger 团队,代码托管于 GitHub,采用宽松 MIT 开源协议,曾先后以 ClawdBot、Moltbot 为名迭代,最…

2026/6/27 4:24:26阅读更多 →
本地商户的获客指南,高德地图商户通到底能不能帮助本地商家获客当下本地实体行业竞争日趋激烈,餐饮、酒店、休闲娱乐、生活服务、汽修美容等各类线下商户,早已告别“坐等上门”的传统经营模式。多数中小本地商

本地商户的获客指南,高德地图商户通到底能不能帮助本地商家获客当下本地实体行业竞争日趋激烈,餐饮、酒店、休闲娱乐、生活服务、汽修美容等各类线下商户,早已告别“坐等上门”的传统经营模式。多数中小本地商

当下本地实体行业竞争日趋激烈,餐饮、酒店、休闲娱乐、生活服务、汽修美容等各类线下商户,早已告别“坐等上门”的传统经营模式。多数中小本地商户普遍面临两大核心难题:一是线下门店流量固定,自然到店客量增长乏力;二…

2026/6/27 4:19:26阅读更多 →
【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体 一文搞定到底什么是智能体【人工智能】一文搞定到底什么是智能体一. LM,WorkFlow,Agent分别有什么么不同二. Agent的思考过程是怎样的三. Agent的五个核心部分1)LLM2)Prompt3)Me…

2026/6/26 11:03:22阅读更多 →
嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

1. 嵌入式GUI控件:从原理到实战的深度解析在嵌入式系统开发中,图形用户界面(GUI)的设计与实现往往是项目从“能用”到“好用”的关键一跃。不同于资源充沛的PC或移动平台,嵌入式设备的GUI需要在有限的CPU性能、内存空间…

2026/6/26 4:15:25阅读更多 →
Google AI Studio 300美元额度的真相与实战指南

Google AI Studio 300美元额度的真相与实战指南

1. 这300美金不是“送钱”,而是Google埋下的第一道技术门槛 你看到标题里那个醒目的“$300美金”时,第一反应可能是:又一个免费额度?领完就完事?我亲手试过——这300美金根本不是红包,而是一张入场券&…

2026/6/26 9:29:01阅读更多 →
10分钟AI语音克隆与实时变声:Retrieval-based-Voice-Conversion-WebUI完整指南

10分钟AI语音克隆与实时变声:Retrieval-based-Voice-Conversion-WebUI完整指南

10分钟AI语音克隆与实时变声&#xff1a;Retrieval-based-Voice-Conversion-WebUI完整指南 【免费下载链接】Retrieval-based-Voice-Conversion-WebUI Easily train a good VC model with voice data < 10 mins! 项目地址: https://gitcode.com/GitHub_Trending/re/Retrie…

2026/6/27 0:04:03阅读更多 →
Layerdivider:3分钟AI智能分层,彻底告别手动抠图时代

Layerdivider:3分钟AI智能分层,彻底告别手动抠图时代

Layerdivider&#xff1a;3分钟AI智能分层&#xff0c;彻底告别手动抠图时代 【免费下载链接】layerdivider A tool to divide a single illustration into a layered structure. 项目地址: https://gitcode.com/gh_mirrors/la/layerdivider 还在为复杂的图像分层工作烦…

2026/6/27 0:04:03阅读更多 →
Tomcat中X-Frame-Options配置实战:防御点击劫持的四种方法与最佳实践

Tomcat中X-Frame-Options配置实战:防御点击劫持的四种方法与最佳实践

1. 项目概述&#xff1a;为什么X-Frame-Options是Web安全的“防盗门”&#xff1f;最近在排查一个老项目的安全审计报告时&#xff0c;又被提到了“点击劫持”风险&#xff0c;矛头直指缺失的X-Frame-Options响应头。这已经不是第一次了&#xff0c;很多开发团队&#xff0c;尤…

2026/6/27 0:04:03阅读更多 →