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

3.3 KiB
Raw Blame History

数据库 SQL 约束与运维

提交前约束

新增或修改 SQL 必须满足:

  1. 列表查询必须有明确的分页、最大数量或日期范围;禁止无界返回历史数据。
  2. GROUP BYCOUNT(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

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.examplePOSTGRES_* / 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/81/4effective_cache_size ≈ 内存的 1/23/4,且两者之和不宜超过可用内存的 80%。
  • 修改限额后 docker compose config 会以明文展示最终值,可用它核对插值结果;变更仅对重建/重启的容器生效。