9月26日,开发者社区推出一款名为 safe-not-safe 的开源 PostgreSQL 迁移安全性检查器,它把 libpg_query 17 编译为 WebAssembly,在用户的浏览器 Web Worker 里完成全部解析,DDL 内容不会上传到任何后端 API,也没有日志、没有账号系统、没有 telemetry。开发者可以打开浏览器访问 safenotsafe.dev,将 ALTER TABLE、CREATE INDEX CONCURRENTLY 等迁移语句粘贴进去,也可以通过命令行 npx safe-not-safe check migration.sql 在本地 CI 中调用同一套解析逻辑。
该工具的解析引擎直接来自 PostgreSQL 官方解析器 libpg_query 17,被业界广泛认为是与服务器端语法最接近的实现。WebAssembly 模块在用户首次访问时下载并在浏览器 Worker 里编译,整个过程不需要任何后端服务。当用户在编辑框里输入一段迁移脚本,工具会立刻报告每条 DDL 的语义风险,并按目标表行数划分为三档:小于 5 万行、5 万到 500 万行、超过 500 万行,分别给出不同等级的锁等待提示。
DDL 模式解析:抓住锁升级与长时间阻塞的早期信号
safe-not-safe 默认开启的规则覆盖了最常见的几类高风险模式。举例来说,对 users 表 ADD COLUMN status text DEFAULT 'active' 这类轻量 DDL,工具会标注在表行数较大时的潜在阻塞;而对 orders 表 ADD CONSTRAINT ... FOREIGN KEY ... NOT VALID 加上随后的 VALIDATE CONSTRAINT 组合,它会识别出“先加约束再校验”这一在大型表上避免长时间排他锁的标准做法;如果检测到不带 CONCURRENTLY 关键字的 CREATE INDEX,它会提示在生产环境上直接加索引会阻塞写入。
在 Hacker News 讨论中,资深 PostgreSQL 用户补充了实战里最容易翻车的点。一位运维工程师写道:真正让人受伤的往往不是 DDL 本身,而是锁排队;ADD COLUMN 虽然在元数据层面是瞬时的,但一旦它前面有长读请求,每一条排在后面的查询都会被一起卡住。这位工程师在生产环境里救回系统最有效的组合是设置 lock_timeout 加上重试,而不是任何花哨的迁移工具。另一位评论者建议把 safe-not-safe 接进 CI,在合并前就拦住高风险模式。
面向 vibe coding 时代的数据库安全护栏
工具的命名是一个两层冷笑话:safe 是 SQL 迁移安全检查,not safe 是数据库圈内对 hot dog 是否算三明治这类无限辩题的经典戏仿。项目方在页面底部写道:PostgreSQL 16 解析、无遥测、GitHub 仓库公开、你的 SQL 永远不会离开浏览器,没有 API route、没有日志、没有账号。页面也写明,项目名是数据库圈内对热狗之争的一次戏仿。开发者拿到一份 risky.sql 或 safe.sql 示例脚本后,可以直接对照修改自己的迁移文件。
在 vibe coding 趋势下,越来越多 AI 生成的迁移脚本被直接应用到生产数据库,而 LLM 并不总能正确选择 CONCURRENTLY、NOT VALID 等避免长时间锁的关键字。safe-not-safe 这类零安装、零凭证的纯前端工具填补了一个空白:不需要数据库调用本身,也能在合并前把最具破坏性的模式拦在门外。它支持 PostgreSQL 16,未来计划兼容更新的版本,并扩展更多 DDL 模式以及 lock_timeout 自动建议。