我在我的OS X中使用自制的postgres,但当我重新启动系统时,有时postgres在重新启动后不会启动,所以我手动尝试用postgres -D /usr/local/var/postgres启动它,但随后出现以下错误消息:FATAL: could not open directory "pg_tblspc":没有这样的文件或目录。

上次出现这种情况时,我无法恢复到原来的状态,所以我决定卸载整个postgres系统,然后重新安装,并创建用户、表、数据集等等……这是如此恶心,但它经常发生在我的系统,比如几个月一次。

那么为什么它经常丢失pg_tblspc文件呢?我能做些什么来避免文件丢失吗?

我还没有把我的自制和postgres升级到最新版本(也就是说,我一直在使用同一个版本)。此外,我在postgres数据库上所做的所有事情就是每天删除表并填充新数据。我还没有更改用户、密码等。

编辑(mbannert): 我觉得有必要添加这个,因为这个线程是谷歌上这个问题的顶部,而且对于许多症状是不同的。自制啤酒可能会遇到以下错误信息:

No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/tmp/.s.PGSQL.5432"?

所以,如果你在优胜美地升级后经历了这个,你现在可以阅读这篇文章了。


解决了…在某种程度上。

显然,安装最新版本的OS X(例如Yosemite或El Capitan)会删除/usr/local/var/ postgresql中的一些目录。

要解决这个问题,你只需重新创建丢失的目录:

mkdir -p /usr/local/var/postgres/pg_commit_ts
mkdir -p /usr/local/var/postgres/pg_dynshmem
mkdir -p /usr/local/var/postgres/pg_logical/mappings
mkdir -p /usr/local/var/postgres/pg_logical/snapshots
mkdir -p /usr/local/var/postgres/pg_replslot
mkdir -p /usr/local/var/postgres/pg_serial
mkdir -p /usr/local/var/postgres/pg_snapshots
mkdir -p /usr/local/var/postgres/pg_stat
mkdir -p /usr/local/var/postgres/pg_stat_tmp
mkdir -p /usr/local/var/postgres/pg_tblspc
mkdir -p /usr/local/var/postgres/pg_twophase

或者,更简洁地说(感谢内特):

mkdir -p /usr/local/var/postgres/{{pg_commit_ts,pg_dynshmem,pg_replslot,pg_serial,pg_snapshots,pg_stat,pg_stat_tmp,pg_tblspc,pg_twophase},pg_logical/{mappings,snapshots}}

重新运行pg_ctl start -D /usr/local/var/postgres现在可以正常启动服务器,至少对我来说,没有任何数据丢失。

更新

在我的系统上,即使在Postgres运行时,其中一些目录也是空的。也许,作为某些“清理”操作的一部分,优胜美地国家公园删除了任何空目录?在任何情况下,我都创建了一个'。将文件保存在每个目录中,以防止将来删除。

touch /usr/local/var/postgres/{{pg_commit_ts,pg_dynshmem,pg_replslot,pg_serial,pg_snapshots,pg_stat,pg_stat_tmp,pg_tblspc,pg_twophase},pg_logical/{mappings,snapshots}}/.keep

注意:在这些目录中创建.keep文件会在日志文件中产生一些噪音,但似乎不会对其他任何东西产生负面影响。


创建丢失的目录当然有效,但我通过重新初始化postgres db来修复它,这是一个更干净的方法,以避免未来的问题。

注意:这种方法将删除现有的数据库

$ rm -r /usr/local/var/postgres
$ initdb -D /usr/local/var/postgres

这有点离题,但值得注意的是,作为约塞米蒂复原过程的一部分。我遇到了和上面一样的问题,而且PostgreSQL“似乎”在后台运行,所以即使添加了目录,我也无法重新启动。我尝试使用pg_ctl stop -m fast来杀死PostgreSQL服务器,但没有运气。我也尝试过直接杀死PID的进程,但只要我这样做,一个PostgreSQL进程重新出现了一个不同的PID。

密钥最终是一个。plist文件,Homebrew已经加载…我的解决方案是:

launchctl unload /Users/me/Library/LaunchAgents/homebrew.mxcl.postgresql92.plist

之后我就可以正常启动PostgreSQL了。


Donavan的答案是正确的,我只是想添加,因为我做了不同的事情与数据库(例如rake db:test),它去寻找不同的目录,没有提到上面,并会阻塞时,他们不存在,在我的情况下pg_logical/mappings,所以你可能想要设置一个终端运行:

tail -f /usr/local/var/postgres/server.log

在进行典型的数据库活动时,请注意是否有丢失的文件夹。


缺失的目录需要出现在PostgreSQL数据目录中。默认数据目录为/usr/local/var/postgres/。如果设置了不同的数据目录,则需要在那里重新创建丢失的目录。如果你修改了homebrew推荐的启动PostgreSQL的.plist文件,你可以在那里找到数据目录:

cat ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist

(这是你启动postgres的-D选项:)

  <key>ProgramArguments</key>
  <array>
    <string>/usr/local/bin/postgres</string>
    <string>-D</string>
    <string>/usr/local/pgsql/data</string>

在上面的例子中,你会在/usr/local/pgsql/data中创建缺失的目录,如下所示:

cd /usr/local/pgsql/data
mkdir {pg_tblspc,pg_twophase,pg_stat,pg_stat_tmp,pg_replslot,pg_snapshots,pg_logical}
mkdir pg_logical/{snapshots,mappings}

我在一个dockerized Rails应用程序中遇到了这个问题。

而不是pg_tblspc和其他目录在/usr/local/var/postgres中缺失,他们在myRailsApp/tmp/db中缺失。

你会想要使用Donovan的解决方案的类似版本,你只需要改变你的Rails应用程序的正确路径…

mkdir /myRailsApp/tmp/db/{pg_tblspc,pg_twophase,pg_stat,pg_stat_tmp,pg_replslot,pg_snapshots}/

此外,您还需要添加一个.keep文件,以确保git不会忽略空目录。

touch /myRailsApp/tmp/db/{pg_tblspc,pg_twophase,pg_stat,pg_stat_tmp,pg_replslot,pg_snapshots}/.keep

我注意到其中一个目录中有一个.keep错误,所以只需仔细阅读命令行输出并根据需要进行调整。