Files
order_site/docs/数据库SQL约束与运维.md
T
yml2213 6dcdec43f1 chore(deploy): 数据库与各服务增加资源限制和优雅关闭保护
- postgres 增加 mem_limit/cpus/shm_size/stop_grace_period 与 PG
  性能参数(shared_buffers 等,env 可覆盖);backend/web 增加
  内存/CPU 限额与更长的优雅关闭宽限(生产与开发编排同步)
- ubuntu-deploy.sh 增加部署前磁盘空间预检,防止备份或迁移
  中途磁盘写满
- .env.server.example 补充资源变量;文档补充容器资源限制说明
2026-08-30 13:59:19 +08:00

58 lines
3.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 数据库 SQL 约束与运维
## 提交前约束
新增或修改 SQL 必须满足:
1. 列表查询必须有明确的分页、最大数量或日期范围;禁止无界返回历史数据。
2. `GROUP BY``COUNT(DISTINCT)`、窗口函数和跨表聚合必须附带 `EXPLAIN (ANALYZE, BUFFERS)` 结果。
3. 高频接口禁止在公共 `SELECT` 中叠加未必要的 LATERAL、相关子查询或全表聚合。
4. 当前页关联数据必须按当前页 ID 批量查询,不得读取用户全部历史记录再在应用层过滤。
5. 新增索引必须通过数据库 migration 提交,并说明覆盖的查询条件;大表生产索引应评估锁影响。
6. SQL 必须使用参数绑定,禁止把请求参数直接拼接到 SQL 值中。
后端 `npm run check` 会执行 `npm run check:sql`,检查关键性能防线没有被重构移除。该检查不能替代真实数据量下的 `EXPLAIN`
## 生产观测
生产 PostgreSQL 应启用 `pg_stat_statements` 和慢查询日志。Compose 默认通过 `POSTGRES_LOG_MIN_DURATION_STATEMENT_MS`(默认 500ms)配置 PostgreSQL 原生慢查询日志;应用默认将执行超过 `DATABASE_SLOW_QUERY_THRESHOLD_MS`(默认 500ms)的 SQL 记录为慢查询,只记录 SQL 形状、耗时和返回行数,不记录参数值。
常用排查 SQL
```sql
SELECT calls, total_exec_time, mean_exec_time, rows, query
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 30;
SELECT pid, state, wait_event_type, wait_event,
now() - query_start AS duration, query
FROM pg_stat_activity
WHERE datname = current_database() AND state <> 'idle'
ORDER BY query_start;
```
## 容量边界
- `DATABASE_STATEMENT_TIMEOUT_MS` 防止单条 SQL 长时间占用连接。
- `DATABASE_MAX_CONNECTIONS` 按后端实例数总量评估;扩容后端实例时不能简单地每实例增加连接数。
- CPU 限额只能防止数据库拖垮整机,不能替代 SQL 优化。
- 数据量持续增长后,排行榜和历史统计应迁移到汇总表、缓存或只读副本,不应继续依赖在线全量聚合。
## 容器资源限制
Compose 对 postgres 与各服务已配置资源限额,默认值按 2G 内存机器设置,均可在 `.env` 覆盖(见 `.env.server.example``POSTGRES_*` / `BACKEND_MEM_LIMIT` / `WEB_MEM_LIMIT` 等):
| 服务 | 限额 | 说明 |
| --- | --- | --- |
| postgres | `mem_limit` 1g、`cpus` 2、`shm_size` 512mb | `shm_size` 不足会导致并行查询/大排序报错;`stop_grace_period` 60s 保证检查点能完整落盘 |
| backend | `mem_limit` 512m、`cpus` 1 | `stop_grace_period` 30s 保证优雅关闭(HTTP 收尾 + 连接池释放)能跑完 |
| web | `mem_limit` 256m、`cpus` 0.5 | Caddy 静态服务,低占用 |
| dev postgres | 同生产默认 | 仅 postgres 受限;backend/frontend 开发容器不设限,避免 tsx watch / npm install 内存波动被误杀 |
调整原则:
- 内存限额不要低于 RSS 峰值的 1.3 倍,否则会触发 OOM 杀容器(`restart: unless-stopped` 会崩溃循环)。
- 内存类 PG 参数遵循大致比例:`shared_buffers` ≈ 内存的 1/8~1/4`effective_cache_size` ≈ 内存的 1/2~3/4,且两者之和不宜超过可用内存的 80%。
- 修改限额后 `docker compose config` 会以明文展示最终值,可用它核对插值结果;变更仅对重建/重启的容器生效。