跳转到主要内容

58P01 — undefined_file

PostgreSQL SQLSTATE 58P01 的源码核验与诊断参考。

58P01

速览

58P01 表示所需文件或目录找不到。固定表空间路径会把 chmodENOENT 与其他权限/文件系统失败分开;只有服务器正在恢复时才加入重启前创建目录的提示。

字段
SQLSTATE 58P01
条件名 undefined_file
状态 有效
已知存在于 7.4
锁定快照 9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3
ERRCODE_UNDEFINED_FILE
别名

含义

utility.c 在进入 CreateTableSpace 前调用 PreventInTransactionBlock(isTopLevel, "CREATE TABLESPACE"),因此该命令必须在顶层执行,无需再手工回滚一个显式事务块。create_tablespace_directories() 在该命令之后以及表空间 WAL 重放中调用。目标不是原地目录时,如果 chmod(location, ...) 返回 ENOENT,源码以 SQLSTATE 58P01 报告 directory "%s" does not exist;仅在 InRecovery 为真时加入 Create this directory for the tablespace before restarting the server.。其他 chmod 失败通过 errcode_for_file_access() 报告动态主消息 could not set permissions on directory "%s": %m;原地创建失败也使用 could not create directory "%s": %m,其代码由 errno 选择。

因此此码不只属于表空间启动。实际操作和 %m 详细信息才能判断缺失的是表空间、关系文件、配置文件还是其他文件消费者。

消息

  • ERROR,SQLSTATE 58P01directory "%s" does not exist
    • 恢复时的条件提示:Create this directory for the tablespace before restarting the server.
  • ERROR,使用 errcode_for_file_access()could not set permissions on directory "%s": %m
  • ERROR,使用 errcode_for_file_access()could not create directory "%s": %m(原地目录分支)。

后两种模板不保证都是 58P01errcode_for_file_access() 会根据保存的 errno 选择 SQLSTATE。

诊断

记录完整主消息、%m 详细信息、阶段、路径、数据库/表空间身份,以及调用者是 SQL 执行还是 WAL 重放。确认目标卷挂载在精确路径,再检查所有者、权限、符号链接目标和表空间版本目录;卷未挂载与目录被删除需要不同处理。

处理

按部署和备份流程恢复预期挂载或目录,不要在未知表空间位置覆盖创建空路径。CREATE TABLESPACEPreventInTransactionBlock 保护,必须在显式事务之外运行;该命令本身无需再手工回滚一个显式事务块。若其他文件消费者在显式事务内报告客户端 ERROR,继续前先 ROLLBACK 或回到已建立的保存点。若消息来自 WAL 恢复,则没有可恢复的客户端事务:恢复路径并按服务器重启/恢复流程处理;确认所有者、权限和目录内容后再重试。

版本

锁定目录从 7.4 记录此条件;固定源码覆盖 PostgreSQL 18.6。本条为源码核验,没有诱发表空间故障。

58P0258P0358030

来源

src/backend/commands/tablespace.c#L347-L359

src/backend/commands/tablespace.c#L565-L625

src/backend/commands/tablespace.c#L1515-L1525

src/backend/tcop/utility.c#L713-L717

结构化证据记录保存条件提示、动态 errno 路径和源码/运行边界。