MkSaaS 本地启动时连不上数据库 / 从连接串和迁移命令两头查

文章导读
MkSaaS 本地启动报数据库连接失败时,报错文案经常只有一个笼统的 "connect ECONNREFUSED" 或者一句堆栈,容易让人第一反应去改连接串。更稳的做法是先按启动日志把失败点收窄到三个阶段:读配置、建连接、跑迁移。这三类问题的修法完全不同,先分阶段再动手,能少改很多不该改的地方。
📋 目录
  1. A 在启动日志里找到连接失败的第一条错误行
  2. B 核对连接配置的四个值来自哪里
  3. C 用一条独立命令验证数据库本身可达
  4. D 检查迁移是否已执行到当前版本
  5. E 改完配置重启并确认错误消失
A A

MkSaaS 本地启动报数据库连接失败时,报错文案经常只有一个笼统的 "connect ECONNREFUSED" 或者一句堆栈,容易让人第一反应去改连接串。更稳的做法是先按启动日志把失败点收窄到三个阶段:读配置、建连接、跑迁移。这三类问题的修法完全不同,先分阶段再动手,能少改很多不该改的地方。

先看启动日志里第一条数据库相关错误出现在哪一步:如果卡在读配置,去查配置文件位置和环境变量覆盖;如果卡在建连接,用一条独立命令验证主机端口和服务本身是否可达;如果是迁移之后才报表不存在,那是迁移没跑到当前版本。连接串、服务状态、迁移版本要分开验证,不要用改一处配置的方式同时猜三个问题。边界是:本页只覆盖本地开发环境,容器、远程库和托管数据库的网络差异需要结合具体环境确认。

在启动日志里找到连接失败的第一条错误行

启动日志通常按顺序打印「加载配置 → 连接数据库 → 执行迁移 → 启动服务」。往上翻,找第一条带数据库关键字的错误,而不是最后一条。区分方法可以先按下面三类信号看:

  • 读配置阶段的错误:常见提示是环境变量未定义、配置项为 undefined、解析连接串失败。这类错误发生得最早,通常在建连接之前,堆栈里不会出现数据库驱动。
  • 建连接阶段的错误:会带主机、端口、认证或超时信息,例如 connection refused、ETIMEDOUT、password authentication failed、no pg_hba.conf entry。到这一步说明配置已经读到了,问题在网络或服务侧。
  • 迁移阶段的错误:连接已经成功,报的是 relation / table does not exist、migration not found、relation already exists。这类不是连不上,而是连上了但库的状态不对。

把日志贴到提问区或发给同事前,先脱敏:主机名、端口、用户名可以保留结构但替换成占位值,密码和连接串里的口令部分一定要打码,内部域名和库名如果不方便公开也一并替换。脱敏后要保证错误类型、错误码和层级结构不被改动,否则别人没法判断。

核对连接配置的四个值来自哪里

四个值指主机、端口、库名、认证信息。重点不是「值对不对」,而是「程序实际读到的是哪一份」。先确认配置文件位置:常见是项目根目录的 .env、.env.local,或 config/ 目录下的环境配置文件,也可能是 docker-compose 里的 environment 段。把项目里所有可能提供同一变量的文件列出来,再确认启动脚本加载的是哪一个。

优先级方面,多数 Node 项目用 dotenv 一类库加载 .env,默认行为是不覆盖已存在的进程环境变量,也就是说 shell 里 export 的值会压过文件里的值。所以可能出现「文件改了但没生效」的情况。可以先做一次不打印密码的读取自检:

MkSaaS 本地启动时连不上数据库 / 从连接串和迁移命令两头查
# 只确认变量存在和来源,不输出密码
node -e "const u=new URL(process.env.DATABASE_URL||'');console.log({host:u.hostname,port:u.port,db:u.pathname})"

# 查看 .env 中的键名,并把口令部分打码
grep -n "DATABASE_URL" .env | sed -E 's#(://[^:]+:)[^@]+@#\1***@#'

如果脚本不是 Node 写的,把上面的命令换成对应运行时的读环境变量方式即可,判断标准一致:主机、端口、库名打印出来是否符合预期。这一步只验证「读到什么」,不解决「连不连得上」。

用一条独立命令验证数据库本身可达

这一步要把网络或服务问题和框架问题分开。绕过 MkSaaS 本身,直接用系统工具或客户端连一次。先测端口通不通:

nc -vz 127.0.0.1 5432

把地址和端口换成实际值。预期输出是 succeeded 或 open,失败时通常直接给 refused 或超时。再用数据库客户端做一次带认证的查询:

MkSaaS 本地启动时连不上数据库 / 从连接串和迁移命令两头查
psql "postgresql://user@127.0.0.1:5432/dbname" -c 'select 1;'

其他数据库换成 mysql、redis-cli、mongosh 等对应命令;如果本机没装客户端,用一个短脚本骨架也可以:建立连接、执行一条最小查询、打印结果、关闭连接。失败时的提示类型可以这样判读:connection refused 一般是服务没起或端口写错;timeout 多为地址不通、容器网络或防火墙;password authentication failed / access denied 是认证信息问题;database "xxx" does not exist 是库名问题。这一步通过而 MkSaaS 仍连不上,说明问题在配置读取或应用层参数,不在数据库本身。

检查迁移是否已执行到当前版本

表不存在引发的报错,容易被当成连接失败继续往上查,其实连接早就通了。先看迁移状态,命令名各项目不同,常见形式是项目自带的脚本,例如:

npm run db:migrate:status
# 或使用具体迁移工具的等价命令,如 prisma migrate status、knex migrate:list 等

输出里要关注两点:已应用的迁移条数,以及是否存在 pending 或 failed 的记录。如果有未应用项,执行迁移命令,同样是项目脚本或迁移工具命令,注意本地库的迁移命令不要带生产参数:

npm run db:migrate

执行完再确认目标表真的存在,而不是只看命令退出码。可以用客户端的元数据查询确认:

MkSaaS 本地启动时连不上数据库 / 从连接串和迁移命令两头查
psql "postgresql://user@127.0.0.1:5432/dbname" -c '\dt'
psql "postgresql://user@127.0.0.1:5432/dbname" -c "select to_regclass('public.users');"

表名按项目实际替换。如果迁移报 failed,先解决失败的那一条再重跑,不要直接强行标记为已应用,否则后续 schema 会不一致。

改完配置重启并确认错误消失

改完配置或迁移后,先停掉旧进程再启动,避免旧进程占着端口继续报同样的错:

# 按项目实际脚本替换
npm run dev

成功启动时,日志里应依次出现配置加载完成、数据库连接成功、迁移检查通过、服务监听端口这几类行,原先是第一条数据库错误的位置不再出现报错。判断标准不是「这次起来了」,而是连续重启两次都能稳定到服务监听,并且中间没有随机出现的连接重试日志。如果只在第一次成功、第二次失败,多半是迁移或本地数据状态问题;如果每次都在同一位置失败,回到日志的第一条错误行重新分阶段排查。