主题
备份与恢复
程序自身不做任何备份。 需要你方自己安排,至少做到:每日备份、保留多份、备份放在另一块盘或另一台机器上。
备份什么
| 内容 | 位置 | 必须备份 |
|---|---|---|
| 业务数据(SQLite) | data/apexpm.db | ✅ |
| 附件 | data/uploads/ | ✅ |
| 在线文档(本地存储模式) | data/documents/ | ✅ |
| 授权与状态 | data/license.lic、data/license_state.json | ✅ |
| 配置 | config.yaml | ✅ |
| 外部数据库 | 由数据库自身备份 | 使用外部数据库时 ✅ |
最简单的做法:备份整个 data/ 目录 + config.yaml。
SQLite 不停服备份
服务运行时直接复制 apexpm.db,可能复制到写了一半的状态。停服备份最稳妥;不能停服时用 sqlite3 的在线备份命令(见下文)。
Linux / macOS
每日 2 点备份并保留 14 天,crontab -e 中加入:
bash
0 2 * * * cd /opt/apexpm && sqlite3 data/apexpm.db ".backup /backup/apexpm-db-$(date +\%Y\%m\%d).db" && tar czf /backup/apexpm-$(date +\%Y\%m\%d).tar.gz --exclude=data/apexpm.db data config.yaml && find /backup -name 'apexpm-*' -mtime +14 -deletesqlite3 .backup可以在服务运行时得到一致的数据库副本(需安装sqlite3:apt install sqlite3/yum install sqlite)。- crontab 里的
%必须写成\%。 /backup应是另一块盘的挂载点,或定期同步到其他机器(rsync)。
外部数据库:
bash
pg_dump -Fc -h 127.0.0.1 -U apexpm apexpm > /backup/apexpm-pg-$(date +%Y%m%d).dump
mysqldump --single-transaction -h 127.0.0.1 -u apexpm -p apexpm > /backup/apexpm-mysql-$(date +%Y%m%d).sqlWindows
用「任务计划程序」每日执行下面的 PowerShell 脚本(保存为 C:\apexpm\backup.ps1):
powershell
$ts = Get-Date -Format "yyyyMMdd"
$dest = "D:\backup"
New-Item -ItemType Directory -Force $dest | Out-Null
C:\apexpm\apexpm-service.exe stop
Compress-Archive -Path C:\apexpm\data, C:\apexpm\config.yaml -DestinationPath "$dest\apexpm-$ts.zip" -Force
C:\apexpm\apexpm-service.exe start
Get-ChildItem $dest -Filter "apexpm-*.zip" | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-14) } | Remove-Item注册计划任务(管理员 PowerShell):
powershell
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File C:\apexpm\backup.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At 2am
Register-ScheduledTask -TaskName "ApexPM Backup" -Action $action -Trigger $trigger -User "SYSTEM" -RunLevel Highest恢复
- 停止服务
- 把当前
data/改名留存(不要直接删除) - 把备份解压到部署目录,恢复
data/与config.yaml;单独备份的数据库文件复制回data/apexpm.db - 检查文件属主(Linux:
chown -R apexpm:apexpm data) - 启动服务并验证
定期做恢复演练。 没有恢复过的备份不算备份。
常见错误
| 现象 | 原因 | 处理 |
|---|---|---|
| cron 任务没有执行 | crontab 里 % 没转义,或 sqlite3 不在 cron 的 PATH 里 | 写成 \%;命令写绝对路径(which sqlite3) |
database is locked | 备份时有写入且未用 .backup | 改用 sqlite3 .backup 或停服备份 |
恢复后启动报 permission denied | 文件属主变成了 root | chown -R apexpm:apexpm data |
恢复后 IP 未授权 | 恢复到了另一台服务器 | 授权按 IP 签发,见更换服务器 |
| Windows 计划任务显示成功但没有备份文件 | 执行策略拦截了脚本 | 确认参数里带了 -ExecutionPolicy Bypass |