Skip to the content.

MySQL OneKey Backup

GitHub license GitHub stars

一个面向 Linux 和 Cron 的单文件 MySQL/MariaDB 备份脚本,支持备份校验、过期清理、Hook 和多渠道通知。

生成配置

打开在线配置生成器,通过表单生成命令、环境变量、Crontab、客户端配置文件、每库完成 Hook 示例和 Apprise 配置,也可以直接下载 mysql_backup.sh。配置中心支持浏览器本地保存、JSON 导入导出和命令反解析。保存和导出默认排除密码、Token、Webhook 等敏感字段;需要完整备份时可手动选择包含。所有内容都在浏览器本地处理,不会上传数据。

功能

下载

下载到默认位置 /opt/mysql-backup/mysql_backup.sh

sudo install -d -m 755 /opt/mysql-backup
sudo curl -fL https://raw.githubusercontent.com/funnyzak/mysql-onekey-backup/main/mysql_backup.sh \
  -o /opt/mysql-backup/mysql_backup.sh
sudo chmod 755 /opt/mysql-backup/mysql_backup.sh

如果 GitHub Raw 访问较慢,可把下载地址替换为 jsDelivr CDN 地址。

快速开始

备份根目录必须提前创建,归运行脚本的用户所有,且不能允许组用户或其他用户写入:

install -d -m 700 -o backup -g backup /var/backups/mysql

根目录的上级路径必须归当前用户或 root 所有,也不能允许组用户或其他用户写入。

检查参数和本机依赖。该命令不会连接数据库或发送通知:

bash mysql_backup.sh \
  --target-dir /var/backups/mysql \
  --host 127.0.0.1 \
  --port 3306 \
  --user backup \
  --defaults-extra-file /etc/mysql-backup/client.cnf \
  --database app \
  --check

首次部署时,可以单独检查依赖:

bash mysql_backup.sh --dependency-report

该命令不要求备份目录,也不会连接数据库或发送通知。缺少必要依赖时返回状态码 2,依赖齐全时返回 0

执行备份:

bash mysql_backup.sh \
  --target-dir /var/backups/mysql \
  --host 127.0.0.1 \
  --port 3306 \
  --user backup \
  --defaults-extra-file /etc/mysql-backup/client.cnf \
  --database app \
  --database analytics

不传 --database 时备份全部数据库。默认每个数据库生成一个 SQL 文件,产物模式为 zip。使用 --single-file 时,全部数据库合并到 all_databases.sql,显式指定的数据库合并到 selected_databases.sql

分文件备份会分别启动 mysqldump,各数据库的快照时间可能略有不同。需要跨数据库保持同一备份时间点时,使用 --single-file

运行要求

脚本不会自动安装软件。--dependency-report 会列出缺失项和安装建议,执行安装命令前请先确认。Apprise CLI 的安装方法见官方文档

数据库认证

脚本支持直接密码、MySQL 客户端配置文件和 MySQL Login Path。三种方式只能选一种。生产环境推荐使用权限为 600 的客户端配置文件或 Login Path。

不要通过 MYSQL_BACKUP_DUMP_OPTIONS--dump-option 传递密码。

客户端配置文件

推荐只在配置文件中保存密码:

[client]
password=replace-with-your-password

文件必须存在、可读、不是符号链接,归运行备份的用户所有,且组用户和其他用户没有任何权限。各级父目录必须归当前用户或 root 所有,且不能允许组用户或其他用户写入。

install -d -m 700 -o backup -g backup /etc/mysql-backup
touch /etc/mysql-backup/client.cnf
chown backup:backup /etc/mysql-backup/client.cnf
chmod 600 /etc/mysql-backup/client.cnf

通过 --defaults-extra-fileMYSQL_BACKUP_DEFAULTS_FILE 使用该文件。脚本参数中的 host、port 和 user 会覆盖配置文件中的同名值。

Login Path

使用 mysql_config_editor 创建 Login Path:

mysql_config_editor set \
  --login-path=backup \
  --host=127.0.0.1 \
  --port=3306 \
  --user=backup \
  --password

bash mysql_backup.sh \
  --target-dir /var/backups/mysql \
  --login-path backup \
  --database app

Login Path 属于创建它的系统用户,Cron 也必须使用同一个用户运行。显式传入的 host、port 和 user 会覆盖 Login Path 中的值。

直接设置密码

可以通过环境变量设置密码:

export MYSQL_BACKUP_HOST=127.0.0.1
export MYSQL_BACKUP_PORT=3306
export MYSQL_BACKUP_USER=backup
export MYSQL_BACKUP_PASSWORD='replace-with-your-password'

bash mysql_backup.sh \
  --target-dir /var/backups/mysql \
  --database app

也可以使用 --password,但密码会出现在进程参数和 Shell 历史中。环境变量仍可能被同一用户或 root 读取。

密码可包含空格、引号、反斜杠、#;%,在 Shell 中应使用单引号。脚本拒绝包含控制字符的密码。

通知

默认发送成功和失败通知,加入 --notify-start 后也会发送开始通知。通知默认开启脱敏:隐藏数据库地址、端口、用户、Login Path、数据库名和备份路径,失败详情只提示查看本地日志。服务器标签、Run ID、阶段、耗时和备份大小仍会显示。

如需在受信任渠道中查看完整详情,可使用 --no-notify-redact 或设置 MYSQL_BACKUP_NOTIFY_REDACT=false。成功通知会统计本次生成的 SQL 和 ZIP 文件总大小,并以 KBMBGB 等易读单位显示。多个渠道可以同时启用,单个渠道失败不影响备份结果。

HTTP 通知只接受 HTTPS;localhost127.0.0.1[::1] 可以使用 HTTP。命令行中的 Webhook、Token 和 Key 可能出现在进程参数和 Shell 历史中,敏感配置优先使用环境变量或权限为 600 的 Apprise 配置文件。

Bark

export MYSQL_BACKUP_BARK_SERVER=https://api.day.app
export MYSQL_BACKUP_BARK_DEVICE_KEY=replace-with-device-key
export MYSQL_BACKUP_BARK_SOUND=alarm # 可选
export MYSQL_BACKUP_BARK_GROUP=mysql-backup # 可选

MYSQL_BACKUP_BARK_SERVER 也可以指向自建 Bark 服务。

ntfy

export MYSQL_BACKUP_NTFY_SERVER=https://ntfy.sh
export MYSQL_BACKUP_NTFY_TOPIC=mysql-backup
export MYSQL_BACKUP_NTFY_TOKEN=replace-with-access-token # 私有主题才需要

飞书、企业微信和钉钉

export MYSQL_BACKUP_FEISHU_WEBHOOK_URL='https://open.feishu.cn/open-apis/bot/v2/hook/replace-me'
export MYSQL_BACKUP_WECOM_WEBHOOK_URL='https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=replace-me'
export MYSQL_BACKUP_DINGTALK_WEBHOOK_URL='https://oapi.dingtalk.com/robot/send?access_token=replace-me'

钉钉机器人如果启用关键词校验,请加入 MySQL backup,也可以使用 IP 白名单。当前实现不支持钉钉动态签名。

Gotify

export MYSQL_BACKUP_GOTIFY_SERVER=https://gotify.example.com
export MYSQL_BACKUP_GOTIFY_TOKEN=replace-with-app-token
export MYSQL_BACKUP_GOTIFY_PRIORITY=5 # 可选,默认 5

Gotify 优先级范围为 -99999999

Apprise CLI

把 Apprise URL 写入配置文件,例如:

json://example.invalid/replace-with-token

配置文件必须归运行备份的用户所有,权限为 600,不能是符号链接。上级路径需满足客户端配置文件的属主和权限要求。

chown backup:backup /etc/mysql-backup/apprise.conf
chmod 600 /etc/mysql-backup/apprise.conf

export MYSQL_BACKUP_APPRISE_CONFIG=/etc/mysql-backup/apprise.conf
export MYSQL_BACKUP_APPRISE_TAGS='ops,admin' # 可选

Apprise API

调用已保存配置的 Apprise API:

export MYSQL_BACKUP_APPRISE_API_URL=http://127.0.0.1:8000/notify/mysql-backup
export MYSQL_BACKUP_APPRISE_TAGS='ops,admin' # 可选

使用 stateless /notify 时,再提供 Apprise 服务 URL:

export MYSQL_BACKUP_APPRISE_API_URL=http://127.0.0.1:8000/notify
export MYSQL_BACKUP_APPRISE_URLS='bark://device-key ntfy://ntfy.sh/mysql-backup'

--check 只检查通知配置、URL、文件权限和依赖,不发送测试消息。

产物目录

每次成功备份对应一个独立目录:

/var/backups/mysql/
├── .staging/
└── runs/
    └── dbback_20260729T120000Z_12345/
        ├── .mysql-onekey-backup-run
        ├── backup.zip
        ├── manifest.txt
        └── SHA256SUMS

manifest.txt 记录脚本版本、运行 ID、数据库连接来源、数据库列表、产物模式和耗时,不包含密码。

常用选项

查看完整帮助:

bash mysql_backup.sh --help

所有备份配置都支持环境变量和命令行选项。标量使用命令行值覆盖环境变量;列表出现对应命令行选项后,会整体替换环境变量列表。--dependency-report 是独立检查命令,没有对应的环境变量。选项和值之间使用空格,不支持 --option=value 写法。

环境变量 命令行选项 说明
MYSQL_BACKUP_TARGET_DIR --target-dir DIR 已存在的备份根目录,必填
MYSQL_BACKUP_HOST --host HOST 数据库地址,默认 127.0.0.1
MYSQL_BACKUP_PORT --port PORT 数据库端口,默认 3306
MYSQL_BACKUP_USER --user USER 数据库用户,默认 root
MYSQL_BACKUP_PASSWORD --password PASSWORD 数据库密码;与客户端配置文件、Login Path 三选一
MYSQL_BACKUP_DATABASES --database NAME,可重复;--all-databases 清空环境列表 环境变量每行一个数据库;空值表示全部数据库
MYSQL_BACKUP_DEFAULTS_FILE --defaults-extra-file FILE MySQL 客户端配置文件,权限设为 600
MYSQL_BACKUP_LOGIN_PATH --login-path NAME MySQL Login Path;与直接密码、客户端配置文件三选一
MYSQL_BACKUP_DUMP_OPTIONS --dump-option OPTION,可重复;--default-dump-options 清空环境追加项 环境变量每行一个白名单参数
MYSQL_BACKUP_SEPARATE_FILES --separate-files / --single-file 文件粒度,默认分别导出;适用于指定数据库和全部数据库
MYSQL_BACKUP_OUTPUT_MODE --output-mode MODE zipsqlboth,默认 zip
MYSQL_BACKUP_EXPIRE_HOURS --expire-hours HOURS 保留小时数,默认 43200 不清理
MYSQL_BACKUP_BEFORE_HOOK --before-hook FILE 前置 Hook
MYSQL_BACKUP_BEFORE_HOOK_COMMAND --before-hook-command CMD 前置自定义命令;与脚本二选一
MYSQL_BACKUP_AFTER_DATABASE_HOOK --after-database-hook FILE 每个数据库分别导出成功后执行的 Hook
MYSQL_BACKUP_AFTER_DATABASE_HOOK_COMMAND --after-database-hook-command CMD 每个数据库分别导出成功后执行的自定义命令;与脚本二选一
MYSQL_BACKUP_AFTER_HOOK --after-hook FILE 后置 Hook
MYSQL_BACKUP_AFTER_HOOK_COMMAND --after-hook-command CMD 发布和清理完成后执行的自定义命令;与脚本二选一
MYSQL_BACKUP_SERVER_NAME --server-name NAME 通知中的服务器名
MYSQL_BACKUP_CHECK --check / --no-check 只检查配置,默认 false
MYSQL_BACKUP_NOTIFY_START --notify-start / --no-notify-start 是否发送开始通知,默认 false
MYSQL_BACKUP_NOTIFY_REDACT --notify-redact / --no-notify-redact 是否隐藏通知中的连接、数据库和路径详情,默认 true
MYSQL_BACKUP_NOTIFY_TIMEOUT --notify-timeout SECONDS 通知超时,范围 1300,默认 10
MYSQL_BACKUP_APPRISE_CONFIG --apprise-config FILE Apprise CLI 配置文件
MYSQL_BACKUP_APPRISE_API_URL --apprise-api-url URL Apprise API 的 /notify/notify/{key} 地址
MYSQL_BACKUP_APPRISE_URLS --apprise-urls URLS Stateless Apprise 服务 URL
MYSQL_BACKUP_APPRISE_TAGS --apprise-tags TAGS Apprise 标签表达式
MYSQL_BACKUP_BARK_SERVER --bark-server URL Bark 服务地址
MYSQL_BACKUP_BARK_DEVICE_KEY --bark-device-key KEY Bark 设备 Key
MYSQL_BACKUP_BARK_SOUND --bark-sound SOUND Bark 提示音,可选
MYSQL_BACKUP_BARK_GROUP --bark-group GROUP Bark 通知分组,可选
MYSQL_BACKUP_NTFY_SERVER --ntfy-server URL ntfy 服务地址
MYSQL_BACKUP_NTFY_TOPIC --ntfy-topic TOPIC ntfy 主题
MYSQL_BACKUP_NTFY_TOKEN --ntfy-token TOKEN ntfy Access Token,可选
MYSQL_BACKUP_FEISHU_WEBHOOK_URL --feishu-webhook-url URL 飞书机器人 Webhook
MYSQL_BACKUP_WECOM_WEBHOOK_URL --wecom-webhook-url URL 企业微信机器人 Webhook
MYSQL_BACKUP_DINGTALK_WEBHOOK_URL --dingtalk-webhook-url URL 钉钉机器人 Webhook
MYSQL_BACKUP_GOTIFY_SERVER --gotify-server URL Gotify 服务地址
MYSQL_BACKUP_GOTIFY_TOKEN --gotify-token TOKEN Gotify 应用 Token
MYSQL_BACKUP_GOTIFY_PRIORITY --gotify-priority NUMBER Gotify 优先级,范围 -99999999,默认 5

--dump-option 只接受白名单内的参数,例如 --routines--events--hex-blob--no-data--ignore-table=库.表--where=条件

Hook

Hook 脚本必须是普通可执行文件,不能是符号链接。文件需归运行备份的用户所有,且不能允许组用户或其他用户写入。上级路径必须归当前用户或 root 所有,且不能允许组用户或其他用户写入。每个阶段也可以改用 --before-hook-command--after-database-hook-command--after-hook-command 直接填写 Bash 命令;同一阶段的脚本和命令只能配置一个。

自定义命令通过 bash -c 执行,命令可以读取下列 BACKUP_* 上下文变量。命令内容中的密码、Token 等敏感值不会默认保存到配置中心的本地配置。

所有 Hook 都可以读取:

BACKUP_PUBLISHED_DIR 在发布完成前为空。

每库完成 Hook 还可以读取:

每库完成 Hook 支持指定数据库和全部数据库的分文件模式,不支持 --single-file。它接收压缩前的暂存 SQL,应把文件当作只读输入,并把处理结果写到暂存目录之外。

前置 Hook 失败时不会执行备份;每库完成 Hook 失败时会终止任务且不发布本次产物;后置 Hook 失败时产物已经发布,但任务仍会返回失败并发送失败通知。

完整的每库完成 Hook 示例可通过在线配置生成器生成和下载。

Cron

每天 03:00 使用客户端配置文件备份,并通过 Apprise 发送通知:

0 3 * * * /usr/bin/bash /opt/mysql-backup/mysql_backup.sh --target-dir /var/backups/mysql --defaults-extra-file /etc/mysql-backup/client.cnf --database app --apprise-config /etc/mysql-backup/apprise.conf --apprise-tags ops >> /var/log/mysql-backup.log 2>&1

每条 Cron 任务应在自己的命令中携带完整参数,避免多个备份任务共享环境变量后相互覆盖。Cron 会在 Shell 之前处理命令中的 %,参数里的每个 % 都要写成 \%。敏感值建议放在权限为 600 的 MySQL 或 Apprise 配置文件中,并使用独立的低权限账号运行任务。

开发与测试

bash -n mysql_backup.sh scripts/test_mysql_backup.sh
bash scripts/test_mysql_backup.sh
node scripts/test_config_html.js
shellcheck mysql_backup.sh scripts/test_mysql_backup.sh

测试使用命令替身模拟 MySQL、任务锁、curl 和 Apprise,不需要真实数据库或通知地址。

License

MIT License © 2023 funnyzak