Skip to content

Commit c58f8de

Browse files
committed
docs(pgbackrest): 完善备份配置文档和跨平台调度方案研究
- 添加定时任务MVP实现方式的开放问题,包括PM2模板与systemd/Windows Task Scheduler/launchd模板的选择考虑 - 详细记录PostgreSQL toolkit的设计约束和实现方案: - PM2仅作为调度层,不重写备份逻辑 - bin入口由Manage-BinScripts.ps1生成,不手写shim - 跨平台定时任务采用备份CLI跨平台、调度器按平台适配的模型 - 可选Node.js或Go调度服务实现 - Windows桌面通知需求和实现考虑 - 更新验收标准,包括PM2路线的cron_restart语义说明、 Node/Go调度服务的PM2配置要求、Windows通知后端抽象等 - 新增两个研究文档: - cross-platform-scheduler-options.md:分析原生OS调度器、 PM2、Node调度服务、Go调度服务等跨平台方案的优缺点 - pm2-scheduled-backups-and-bin-packaging.md:研究 PM2调度与工具包打包的关系及可行实现方案 - 添加多种PM2集成方案的对比分析,从纯模板到完整调度服务的演进路径
1 parent 9d5ecb4 commit c58f8de

3 files changed

Lines changed: 273 additions & 0 deletions

File tree

.trellis/tasks/05-14-pgbackrest-config-docs/prd.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
## Open Questions
2929

3030
- 备份仓库应默认存放在执行脚本的当前机器,还是固定存放到某个共享/NAS/服务器路径?
31+
- 定时任务 MVP 是否只实现 PM2 模板,还是同时生成 systemd / Windows Task Scheduler / launchd 模板?
3132

3233
## Requirements (evolving)
3334

@@ -40,6 +41,12 @@
4041
- 文档说明 `pg_dump` 是逻辑快照而非增量备份;需要增量时使用 pgBackRest full/diff/incr 整实例链路。
4142
- 扩展现有 `Postgres-Toolkit.ps1`,至少覆盖 pgBackRest 检查、创建 stanza、全量备份、差异/增量备份、查看状态、过期清理;表级逻辑备份继续由现有 `backup --table` 承担。
4243
- 避免将真实密码提交到仓库;需要提供本地 secret 文件或环境变量方案。
44+
- 若引入 PM2 定时执行,必须明确它是调度层,不重写备份逻辑;最终执行仍调用 `Postgres-Toolkit.ps1 pgbackrest ...`
45+
- `bin/` 入口应由 `Manage-BinScripts.ps1` 生成,不手写提交 shim;PostgreSQL toolkit 使用 `scripts/pwsh/**/tool.psd1` 暴露稳定公开入口。
46+
- 跨平台定时任务采用“备份 CLI 跨平台、调度器按平台适配”的模型,不实现长期运行的 PowerShell 自制 scheduler loop。
47+
- 可选实现一个 Node.js 定时任务服务,由 PM2 管理常驻进程;Node 服务仅负责任务调度、互斥、日志和调用 toolkit,不实现 pgBackRest 参数拼装之外的备份逻辑。
48+
- 可选实现一个 Go 定时任务服务,由 PM2 管理常驻二进制;Go 服务与 Node 服务职责相同,但会引入新的 Go build/test/release 轨道。
49+
- Windows 桌面通知是显式需求:备份开始/成功/失败时应支持发送通知;但本地 toast 仅在运行于当前登录用户会话时可靠,若服务跑在 SYSTEM/非交互会话,应使用 webhook/ntfy/email 等替代通知渠道。
4350

4451
## Acceptance Criteria (evolving)
4552

@@ -50,6 +57,11 @@
5057
- [ ] 表级备份示例能指定 schema/table,并默认指向 `lobechat`
5158
- [ ] README 明确说明 pg_dump 无通用增量备份,避免用户误以为单表可通过 pg_dump 做增量。
5259
- [ ] 文档包含首次初始化、执行备份、查看备份、恢复注意事项的步骤。
60+
- [ ] 若选择 PM2 路线,文档或脚本必须解释 `cron_restart` 对一次性备份任务的语义,并避免成功退出后被 PM2 自动循环重启。
61+
- [ ] 若选择 Node scheduler 服务,必须限制 PM2 为 fork/单实例运行,任务执行需要 no-overlap 或等价互斥,失败退出码需进入日志并影响健康判断。
62+
- [ ] 若选择 Go scheduler 服务,必须提供 go module、构建命令、测试命令、PM2 `interpreter: none` 配置,以及 Windows 通知后端抽象。
63+
- [ ] Windows 通知后端至少能区分 `backup_started``backup_succeeded``backup_failed` 三类事件,并允许在非 Windows 或无交互桌面环境下禁用或降级为日志/webhook。
64+
- [ ] 若调整 `bin/` 打包,`Manage-BinScripts.ps1` 测试覆盖 toolkit 入口只暴露公开脚本、不暴露内部模块。
5365

5466
## Definition of Done
5567

@@ -68,6 +80,8 @@
6880
## Research References
6981

7082
- [`research/pgbackrest-backup-practices.md`](research/pgbackrest-backup-practices.md) — pgBackRest 适合整实例物理备份,表级备份应使用 `pg_dump -t`
83+
- [`research/pm2-scheduled-backups-and-bin-packaging.md`](research/pm2-scheduled-backups-and-bin-packaging.md) — PM2 可做 cron restart,但应作为调度层;`bin/` 应由 `Manage-BinScripts.ps1` 生成 shim,toolkit bundle 仍走现有构建脚本。
84+
- [`research/cross-platform-scheduler-options.md`](research/cross-platform-scheduler-options.md) — 推荐保留跨平台备份 CLI,通过 PM2/systemd/Windows Task Scheduler/launchd 做薄调度适配。
7185

7286
## Research Notes
7387

@@ -91,6 +105,63 @@
91105
- Pros: 复用已有工具,新增脚本少。
92106
- Cons: 不能完全满足“提供维护脚本”的直觉预期,Linux/macmini 上使用 PowerShell 可能不如 Bash 直接。
93107

108+
### PM2 / bin packaging follow-up
109+
110+
**Approach D: PM2 仅作为配置模板**
111+
112+
- How it works: 在 `config/database/backup/pgBackRest/` 增加 PM2 ecosystem 示例,定时触发现有 `Postgres-Toolkit.ps1 pgbackrest --action backup --type ...`
113+
- Pros: 改动轻,符合“配置目录只放模板和 README”的约束。
114+
- Cons: 用户需要自己执行 `pm2 start``pm2 save``pm2 startup`,脚本级可测试性弱。
115+
116+
**Approach E: PM2 wrapper + ecosystem 模板**
117+
118+
- How it works: 参考 `config/network/rathole/start.ps1` 写一个 PM2 管理包装,只管理 start/stop/logs/status/save/config/dry-run,不实现备份。
119+
- Pros: 操作体验最好,和仓库已有 rathole PM2 风格一致。
120+
- Cons: 在 `config/database/backup/pgBackRest/` 增加脚本会触碰当前 PostgreSQL spec 的边界,需要把它定义为“调度胶水”而非备份维护脚本。
121+
122+
**Approach F: Toolkit scheduler 子命令 + bin manifest(推荐进一步评估)**
123+
124+
- How it works: 在 `scripts/pwsh/devops/postgresql` 增加 scheduler/pm2 命令生成能力;`config/database/backup/pgBackRest/` 只保留模板;通过 `Build-PostgresToolkit.ps1` 生成单文件 bundle,并用 `tool.psd1``Manage-BinScripts.ps1``bin/` 暴露公开入口。
125+
- Pros: 最符合现有 toolkit、测试、bundle 与 bin shim 机制。
126+
- Cons: 实现量最大,需要更新 `Manage-BinScripts` 或测试确认 Postgres toolkit 目录工具不会暴露内部脚本。
127+
128+
**Approach G: Node.js scheduler 服务 + PM2 管理**
129+
130+
- How it works: 在 Node 脚本体系里实现一个 `pgbackrest-scheduler` 常驻服务,读取 `pgBackRest` 目录里的 scheduler 配置,按 cron/interval 调用 `Postgres-Toolkit.ps1 pgbackrest ...`;PM2 只负责守护这个 Node 进程。
131+
- Pros: 跨平台体验比 systemd/Task Scheduler/launchd 统一;比 PM2 `cron_restart` 更适合表达一次性备份任务、互斥、重试和日志。
132+
- Cons: 新增一个长期维护的 Node 组件;需要明确停机期间 missed run 是否补跑、多机器是否允许同时调度、PM2 cluster 禁用等边界。
133+
134+
**Approach H: Go scheduler 服务 + PM2 管理**
135+
136+
- How it works: 新增 Go 模块,编译为 `pgbackrest-scheduler` 单二进制;PM2 用 `interpreter: none` 管理该二进制;Go 服务读取配置、按计划调用 `Postgres-Toolkit.ps1 pgbackrest ...`,并在开始/成功/失败时触发通知。
137+
- Pros: 分发体验最好,运行时依赖少,内存占用低;Go 的 `gocron``os/exec`、信号处理适合常驻调度服务。
138+
- Cons: 仓库目前没有 Go 服务先例,会增加 Go toolchain、构建产物、测试和发布规范;Windows toast 仍受当前登录用户会话/AppID 限制。
139+
140+
### Notification follow-up
141+
142+
**Option 1: Windows toast local notification**
143+
144+
- Use when: scheduler runs on the Windows desktop session where the user wants to see backup notifications.
145+
- Risk: if PM2 is running as SYSTEM/background service, toast may not appear.
146+
147+
**Option 2: PowerShell BurntToast bridge**
148+
149+
- Use when: we want minimal implementation and can rely on the existing Windows PowerShell module setup.
150+
- Risk: PowerShell module availability and user-session constraints.
151+
152+
**Option 3: Webhook/ntfy/email notification**
153+
154+
- Use when: backup runs on macmini/Linux/NAS but notification should arrive on Windows or phone.
155+
- Risk: requires external endpoint/token but is more reliable than desktop toast for unattended machines.
156+
157+
## Decision (ADR-lite)
158+
159+
**Context**: PostgreSQL toolkit 已经是模块化源码加单文件 bundle 的结构;`Manage-BinScripts.ps1` 已支持 `tool.psd1` 暴露目录型工具入口并隐藏内部脚本。
160+
161+
**Decision**: 使用 `tool.psd1` 作为 PostgreSQL toolkit 进入 `bin/` 的公开入口机制。定时任务不做 PowerShell 自制 scheduler loop;可选方向是在 PM2 下运行 Node/Go scheduler 服务,或让 toolkit 生成/记录 PM2/systemd/Windows Task Scheduler/launchd 等调度器适配。
162+
163+
**Consequences**: `bin/` 不手写 shim;PM2 可作为 MVP 的跨平台-ish 路线。若采用 Node scheduler 服务,需要按 `node-script` 包规范补 TypeScript/Vitest 质量检查;若采用 Go scheduler 服务,需要新增 Go 模块和构建测试规范。两者都必须保持备份执行入口仍为 Postgres Toolkit,并把通知设计成可替换后端。
164+
94165
## Technical Notes
95166

96167
- Context7 查询库:`/websites/pgbackrest_configuration`
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# Cross-Platform Scheduler Options
2+
3+
## Question
4+
5+
For PostgreSQL / pgBackRest backup jobs, what are the viable cross-platform scheduling approaches?
6+
7+
## Sources
8+
9+
- systemd timers: https://www.freedesktop.org/software/systemd/man/systemd.timer.html
10+
- Windows scheduled tasks: https://learn.microsoft.com/en-us/powershell/module/scheduledtasks/register-scheduledtask
11+
- macOS launchd timed jobs: https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/ScheduledJobs.html
12+
- PM2 restart strategies: https://pm2.keymetrics.io/docs/usage/restart-strategies/
13+
- PM2 startup persistence: https://pm2.keymetrics.io/docs/usage/startup/
14+
- Windows app notifications: https://learn.microsoft.com/en-us/windows/apps/develop/notifications/app-notifications/app-notifications-quickstart
15+
- Go scheduler library: https://pkg.go.dev/github.com/go-co-op/gocron/v2
16+
- Go Windows toast library: https://pkg.go.dev/github.com/go-toast/go-toast
17+
- Go cross-platform notification library: https://github.com/gen2brain/beeep
18+
- Local systemd-service-manager docs: `scripts/bash/systemd-service-manager/README.md`
19+
- Local PM2 pattern: `config/network/rathole/start.ps1`
20+
21+
## Options
22+
23+
### Option A: Native OS Scheduler Adapters
24+
25+
Generate or document scheduler targets per OS:
26+
27+
- Linux: systemd timer, preferably through this repo's `systemd-service-manager` when available.
28+
- Windows: Task Scheduler via `Register-ScheduledTask`.
29+
- macOS: launchd plist with `StartCalendarInterval`.
30+
31+
Pros: Best reliability, native logs/lifecycle, reboot behavior, permissions, and service account support.
32+
Cons: More templates and validation paths; no single file works unchanged on all OSes.
33+
34+
### Option B: PM2 as a Cross-Platform Scheduler Layer
35+
36+
Use PM2 ecosystem files with `cron_restart` to trigger the backup app at scheduled times.
37+
38+
Pros: Similar commands across Windows/macOS/Linux when Node + PM2 are installed; repo already has PM2 patterns.
39+
Cons: PM2's cron model is restart-oriented, so one-shot backups need careful `autorestart` / exit-code settings.
40+
41+
### Option C: Plain cron
42+
43+
Use crontab on Unix-like systems.
44+
45+
Pros: Simple, common, very low ceremony.
46+
Cons: Not Windows-native; weaker logs/status; less explicit environment and missed-run behavior than systemd timers.
47+
48+
### Option D: Container / Platform Scheduler
49+
50+
Use Kubernetes CronJob, CI schedule with self-hosted runner, NAS scheduler, or another orchestration platform.
51+
52+
Pros: Good when the deployment platform already exists.
53+
Cons: Overkill for a local macmini/Tailscale backup setup; ties backups to a specific platform.
54+
55+
### Option E: Long-Running PowerShell Scheduler Loop
56+
57+
Run a persistent `pwsh` process that sleeps and invokes the toolkit on schedule.
58+
59+
Pros: The script itself can be cross-platform.
60+
Cons: Recreates a supervisor poorly; still needs PM2/systemd/Task Scheduler/launchd to keep it alive. Not recommended for backup reliability.
61+
62+
### Option F: Node Scheduler Service Managed by PM2
63+
64+
Run a small long-lived Node service under PM2. The Node service owns schedule parsing, non-overlap, logging, and child-process execution of `Postgres-Toolkit.ps1 pgbackrest ...`; PM2 owns process supervision and reboot persistence.
65+
66+
Potential implementation shape:
67+
68+
- Source: `scripts/node/src/postgres-scheduler/**` or a dedicated `scripts/node/src/pgbackrest-scheduler/**`.
69+
- Config: committed example under `config/database/backup/pgBackRest/`, real `.local` ignored.
70+
- PM2 app: one fork-mode instance, no cluster mode.
71+
- Scheduler library: `node-cron` is enough for MVP because it supports timezone and no-overlap scheduling options.
72+
- Execution: use `node:child_process` to spawn `pwsh -NoProfile -File <Postgres-Toolkit.ps1> pgbackrest ...`.
73+
74+
Pros: One operational model across Windows/macOS/Linux when Node + PM2 are available; better logs and retry behavior than PM2 `cron_restart` alone; avoids OS-specific unit/plist/task templates for the MVP.
75+
76+
Cons: It is a real service that must be tested and maintained; missed-run semantics after downtime must be defined; single-instance enforcement matters if PM2 cluster mode or multiple machines run the same schedule.
77+
78+
Windows notification note: Node can use a notification library or call a PowerShell notification helper after each backup, but Windows toast reliability still depends on running in the interactive user's session with a stable app identity. If PM2 is installed as a background service under `SYSTEM`, desktop notifications may not appear for the logged-in user.
79+
80+
### Option G: Go Scheduler Service Managed by PM2
81+
82+
Build a small Go service binary and let PM2 manage it with `interpreter: none`. The Go service owns schedule parsing, non-overlap, command execution, and notification dispatch; PM2 still owns process supervision and restart.
83+
84+
Potential implementation shape:
85+
86+
- Source: a new Go module under `projects/clis/pgbackrest-scheduler` or a similar project path.
87+
- Scheduler library: `github.com/go-co-op/gocron/v2`, which supports scheduler location/timezone, concurrency limiting, monitors, and locking-related extension points.
88+
- Windows notifications:
89+
- `github.com/go-toast/go-toast` for Windows-specific toast notifications. It exposes `AppID`, `Title`, `Message`, icon/audio/action fields, then invokes PowerShell to display the toast.
90+
- `github.com/gen2brain/beeep` for a simpler cross-platform notification abstraction.
91+
- Execution: use `os/exec` to run `pwsh -NoProfile -File <Postgres-Toolkit.ps1> pgbackrest ...`.
92+
93+
Pros: Best runtime distribution story; one compiled binary, low memory, no Node runtime for the service itself; Go scheduling and process execution are a natural fit.
94+
95+
Cons: This repo currently has no Go module/service precedent, so it introduces a new build/test/release lane. Windows toast constraints remain the same as Node: the process must run where the logged-in user can receive desktop notifications.
96+
97+
## Windows Notification Design Notes
98+
99+
Windows desktop toast is not just a language choice. Key constraints:
100+
101+
- The scheduler must run in the interactive user's context if the goal is a local desktop toast.
102+
- A stable app identity/AppID is important for notification grouping and reliability.
103+
- Running as a Windows service or under `SYSTEM` is good for unattended operation but bad for per-user desktop notifications.
104+
- If the backup actually runs on macmini/Linux and the user wants a Windows desktop toast, the scheduler/notification bridge needs to run on the Windows machine or send a remote notification through another channel such as ntfy, email, webhook, Telegram, or Teams.
105+
106+
This means the project should separate notification delivery from backup execution. A scheduler can emit:
107+
108+
- local desktop notification,
109+
- log-only notification,
110+
- webhook notification,
111+
- email or ntfy notification,
112+
- disabled notification.
113+
114+
## Recommendation
115+
116+
Use a cross-platform backup CLI plus scheduler adapters:
117+
118+
1. Keep `Postgres-Toolkit.ps1 pgbackrest ...` as the only backup execution path.
119+
2. Expose the toolkit through `tool.psd1` and `Manage-BinScripts.ps1`.
120+
3. For MVP, either support PM2 ecosystem templates directly, or build a Node/Go scheduler service managed by PM2 if richer logs/retry/non-overlap/notification behavior is required.
121+
4. Document native alternatives for Linux, Windows, and macOS; avoid pretending that one scheduler is equally native everywhere.
122+
123+
Future toolkit command shape could be:
124+
125+
```powershell
126+
Postgres-Toolkit.ps1 schedule render --target pm2 --type incr --schedule '0 3 * * *'
127+
Postgres-Toolkit.ps1 schedule render --target systemd --type incr --schedule '0 3 * * *'
128+
Postgres-Toolkit.ps1 schedule render --target windows-task --type incr --schedule daily
129+
Postgres-Toolkit.ps1 schedule render --target launchd --type incr --schedule daily
130+
```
131+
132+
If choosing the Node service route, the MVP command shape can stay simpler:
133+
134+
```bash
135+
pm2 start config/database/backup/pgBackRest/pgbackrest-scheduler.pm2.config.cjs
136+
pm2 logs pgbackrest-scheduler
137+
pm2 save
138+
```

0 commit comments

Comments
 (0)