跳到内容

数据库备份

受众:管理员 / 运维 / 二开开发者 摘要:后台可控的 MySQL / PostgreSQL 数据库备份能力。默认关闭,支持手动触发、定时触发、Queue 即时执行、Scheduler 定时托底、备份后校验、信封加密、密钥版本轮换、本地或远端副本、健康快照、告警通知、保留策略、文件下载、手动复验和删除。

数据库备份模块位于 spring-open-core-database-backup。它面向开发库、测试库和生产库的运维兜底:管理员可以在后台开启或关闭备份能力,设置备份目录、备份保留策略,校验备份文件,并下载已完成且可信的备份文件。

安全默认值

所有备份开关默认关闭:

开关默认说明
总开关关闭关闭时不允许手动或定时备份
手动备份关闭关闭时后台“立即备份”按钮不可用
定时备份关闭关闭时不会注册定时任务
压缩开启成功备份后默认生成 .sql.gz
备份后自动校验开启功能开启后,每次备份落地都会重新计算 SHA-256 并读取文件内容
加密关闭开启后生成 .enc 文件,密钥只从服务端配置读取
副本关闭开启后把最终备份文件复制到副本路径,可使用本地或 Storage starter disk
通知关闭可分别开启成功 / 失败通知
健康告警关闭手动健康检查发现异常时,可通过通知通道发送告警

这样可以避免安装后立即占用服务器硬盘。生产环境开启前,应确认磁盘容量、备份目录权限、数据库账号权限和下载权限。

支持范围

数据库工具说明
MySQLmysqldumpspring.datasource.url、用户名和密码构造受控命令
PostgreSQLpg_dump支持 postgres / postgresql 类型

H2 / SQLite 等本地轻量数据库不走本模块。lite 模式如需保护数据,建议直接备份 storage/database/storage/ 目录。

后台入口

菜单入口:运维监控 / 数据库备份

后台 API 前缀:

text
/api/v1/admin/database-backups

主要接口:

方法路径说明
GET/config查看备份配置
PUT/config保存备份配置
GET/health查看备份工具和存储路径状态
POST/health/check手动运行健康检查并保存快照
GET/keys查看备份加密密钥版本
POST/keys/rotate新增 / 轮换备份加密密钥版本
POST/keys/{id}/test测试密钥版本是否能保护和解开数据密钥
POST/trigger手动触发一次备份
GET/分页查询备份记录
GET/{id}查看备份记录详情
POST/{id}/verify手动复验备份文件
POST/{id}/rekey使用当前活跃密钥版本重新保护历史备份的数据密钥
GET/{id}/download下载成功备份文件
DELETE/{id}/artifact删除备份文件并标记记录
POST/cleanup按保留策略清理旧备份

存储目录

默认路径:

text
storage/backup/database/{databaseType}

{databaseType} 会在运行时替换为 mysqlpostgres。例如:

text
storage/backup/database/mysql
storage/backup/database/postgres

路径必须是项目工作目录下的相对路径,不能使用绝对路径,也不能包含 ..。模块会把文件写入:

text
${user.dir}/<storagePath>

生产建议把 storage/ 挂载到独立数据盘或持久化卷,并纳入服务器容量监控。

校验、信封加密和副本

备份文件落地后的处理顺序:

text
mysqldump / pg_dump
  -> 可选 gzip
  -> 可选 AES-GCM 信封加密
  -> 写入主备份路径
  -> 计算最终文件 SHA-256
  -> 备份后校验
  -> 可选复制副本
  -> 可选发送通知
  • 校验:校验最终文件 SHA-256,并按文件类型读取内容;.sql.gz 会解压读取,.enc 会先解密再读取。校验失败的记录会标记为失败,不作为可靠备份下载。
  • 加密:开启后每个备份都会生成一个随机数据密钥(DEK),备份文件用 DEK 做 AES-GCM 加密;DEK 再由密钥版本(KEK)保护后写入记录。数据库只保存受保护的数据密钥和密钥版本元数据,不保存真实密钥材料。
properties
spring.open.database-backup.encryption-master-keys.default.v1=<base64-or-text-key>
# 兼容旧配置,也可继续使用 keyId 或兜底密钥
spring.open.database-backup.encryption-keys.default=<base64-or-text-key>
spring.open.database-backup.encryption-key=<base64-or-text-key>

这里的密钥只用于保护数据库备份文件的数据密钥,不是数据库账号密码、登录令牌、支付密钥、Web3 私钥或第三方 Provider 密钥。密钥建议使用 16 / 24 / 32 字节 AES key 的 Base64 编码;非标准长度文本会自动派生 SHA-256 key。不要把密钥写入前端、文档截图或数据库。

密钥版本表 database_backup_key_version 只保存 keyIdkeyVersion、状态、Provider、算法和测试结果。轮换时可把旧版本改为 decrypt_only,新备份使用新版本;历史备份仍可解密。需要把历史记录切到新 KEK 时,使用后台“重新保护”操作,它只重包受保护的数据密钥,不重写整份备份文件。

  • 副本:默认副本路径为:
text
storage/backup/database-replica/{databaseType}

副本复制失败不会删除主备份文件,但记录会标记 replica_status=failed,并可触发失败通知。副本可以继续写本地路径,也可以写入 Storage starter 已配置的 disk,例如 minios3ossnas

properties
# 后台 replicaStorageDisk 填写 minio / s3 / oss / nas 等已注册 disk
spring.open.storage.disks.minio.provider=minio
spring.open.storage.disks.minio.bucket=spring-open-backup

主备份文件仍先写入本地受控路径,用于校验、下载和保留策略;副本是异地 / 远端冗余,不替代主文件状态。

健康检查和告警

后台健康看板会展示:

  • 备份总开关、手动 / 定时开关。
  • 当前数据库类型、备份工具和工具可用性。
  • 主备份路径和副本路径。
  • 最近成功 / 最近失败时间。
  • 连续失败次数。
  • 最近校验状态和副本状态。
  • 主路径 / 本地副本路径磁盘剩余空间。
  • 当前活跃密钥版本和密钥测试状态。

手动点击“健康检查”会保存 database_backup_health_snapshot 快照。健康状态规则:

状态触发条件
healthy已启用、工具可用、最近成功未超时、连续失败未超过阈值、磁盘空间充足
warning尚无成功备份、最近成功超出阈值、磁盘剩余低于预警阈值
critical工具不可用、连续失败达到阈值、磁盘剩余低于严重阈值或最小字节阈值
unknown备份总开关关闭

健康阈值可在后台配置:最近成功最大间隔、连续失败阈值、磁盘预警百分比、磁盘严重百分比和最小剩余空间字节数。开启“健康异常通知”后,手动健康检查发现 warningcritical 会通过配置的通知通道发送告警。

执行模型

手动和定时触发都先创建 database_backup_record 记录,再投递 Queue:

text
Admin / Scheduler
  -> database_backup_record(pending)
  -> Queue job database-backup.execute
  -> mysqldump / pg_dump
  -> storage/backup/database/<type>/<file>.sql.gz[.enc]
  -> verify / replica / notify
  -> database_backup_record(success / failed)
  • Queue 负责即时执行,避免管理员点击后必须等待调度轮询。
  • Scheduler 只负责按 Cron 触发定时备份。
  • 保留策略在每次成功备份后执行,并可通过后台手动触发。

保留策略

配置项:

配置默认说明
保留天数7删除完成时间早于阈值的成功备份
最大文件数10只保留最新成功备份
最大总大小5 GiB超过总大小后从旧到新删除成功备份

删除文件会同步删除主文件和副本文件,并把记录标记为 deleted。失败记录不会自动删除,便于排查工具、权限和磁盘问题。

权限

权限码说明
database-backup:view查看配置、健康检查和备份记录
database-backup:config修改备份配置
database-backup:trigger手动触发备份和清理
database-backup:verify手动复验备份文件
database-backup:health:check手动运行健康检查并保存快照
database-backup:key:manage轮换 / 测试密钥版本,重新保护历史备份数据密钥
database-backup:download下载备份文件
database-backup:delete删除备份文件

默认 super-admin 拥有全部权限,admin 仅拥有查看菜单和查看权限。

生产建议

  1. 使用权限最小的数据库只读备份账号。
  2. 确认服务器安装 mysqldumppg_dump,且应用进程可执行。
  3. 备份目录放在持久化磁盘,不和临时目录混用。
  4. 根据业务数据量设置合理的保留天数、最大文件数和最大总大小。
  5. 不把备份文件放入公开静态目录。
  6. 下载权限只给可信运维角色。
  7. 开启加密时,把密钥放到安全配置、KMS 或 Secret 管理系统,按 keyId.keyVersion 保留历史密钥版本,定期轮换并测试。
  8. 开启副本时优先使用独立挂载盘、NAS、MinIO、S3、OSS 等远端 disk;不要和主备份目录放在同一个易满分区。
  9. 开启健康告警,并根据业务 RPO 设置“最近成功最大间隔”和“连续失败阈值”。
  10. 定期把备份文件同步到外部安全存储,并在隔离库做恢复演练;不要在生产库自动还原备份文件。

验证命令

bash
./mvnw -pl spring-open-core/spring-open-core-database-backup -am test -DskipITs -DskipFrontend -Dsurefire.failIfNoSpecifiedTests=false
pnpm -C views/admin typecheck
./.ai/scripts/check i18n
./.ai/scripts/check modules
git diff --check

Released under the Apache License 2.0.