Files
order_site/docs/数据库SQL约束与运维.md
T
yml2213 737c957bb3 chore(deploy): 资源默认值适配 4 核 8G 共用服务器
- postgres mem_limit 1.5g/shared_buffers 384MB/effective_cache_size
  4GB/work_mem 16MB/maintenance_work_mem 256MB
- backend mem_limit 768m、cpus 1.5;web 保持不变
- 生产与开发编排、env 模板、运维文档同步更新
2026-08-30 14:07:39 +08:00

58 lines
3.4 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 与各服务已配置资源限额,默认值按 4 核 8G 且与其他服务共用的服务器设置,均可在 `.env` 覆盖(见 `.env.server.example``POSTGRES_*` / `BACKEND_MEM_LIMIT` / `WEB_MEM_LIMIT` 等):
| 服务 | 限额 | 说明 |
| --- | --- | --- |
| postgres | `mem_limit` 1.5g、`cpus` 2、`shm_size` 512mb | `shm_size` 不足会导致并行查询/大排序报错;`stop_grace_period` 60s 保证检查点能完整落盘;`effective_cache_size` 只是规划器提示,不实际占用内存 |
| backend | `mem_limit` 768m、`cpus` 1.5 | `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` 会以明文展示最终值,可用它核对插值结果;变更仅对重建/重启的容器生效。