关于macos:安装最新版OS X(Yosemite或El Capitan)后缺少`pg_tblspc`

`pg_tblspc` missing after installation of latest version of OS X (Yosemite or El Capitan)

我在我的OS X中使用自制的Postgres,但是当我重新启动系统时,有时候Postgres在重新启动后不会启动,所以我手动尝试用postgres -D /usr/local/var/postgres启动它,但随后出现了以下错误消息:FATAL: could not open directory"pg_tblspc": No such file or directory

上次发生时,我无法将其恢复到原始状态,所以我决定卸载整个Postgres系统,然后重新安装,并创建用户、表、数据集等。这太恶心了,但它经常发生在我的系统上,比如说几个月一次。

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

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

编辑(mbannert):我觉得有必要加上这个,因为这个线程是谷歌在这个问题上最受欢迎的,而且对于许多人来说,症状是不同的。家庭酿酒商可能会遇到此错误消息:

1
2
3
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/postgres中的一些目录。

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

1
2
3
4
5
6
mkdir /usr/LOCAL/var/postgres/pg_tblspc
mkdir /usr/LOCAL/var/postgres/pg_twophase
mkdir /usr/LOCAL/var/postgres/pg_stat
mkdir /usr/LOCAL/var/postgres/pg_stat_tmp
mkdir /usr/LOCAL/var/postgres/pg_replslot
mkdir /usr/LOCAL/var/postgres/pg_snapshots

或者更简而言之(感谢内特):

1
mkdir /usr/LOCAL/var/postgres/{pg_tblspc,pg_twophase,pg_stat,pg_stat_tmp,pg_replslot,pg_snapshots}/

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

更新

在我的系统中,有些目录甚至在Postgres运行时也是空的。也许,作为某些"清理"操作的一部分,Yosemite会删除任何空目录?无论如何,我继续在每个目录中创建了一个".keep"文件,以防止将来删除。

1
touch /usr/LOCAL/var/postgres/{pg_tblspc,pg_twophase,pg_stat,pg_stat_tmp,pg_replslot,pg_snapshots}/.keep

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


Donavan的回答是现场的,我只是想补充一点,因为我对数据库做了不同的事情(例如,rake db:test),它寻找了不同的目录,这些目录在上面没有提到过,在我的例子中,pg_logical/mappings会在不存在时阻塞,因此您可能需要设置一个运行的终端:

1
tail -f /usr/LOCAL/var/postgres/server.log

在浏览典型的数据库活动时,请注意丢失的文件夹。


这有点离题,但作为PostgreSQL Yosemite恢复过程的一部分,这里值得注意。我有和上面一样的问题,我有一个问题,PostgreSQL"似乎"在后台运行,所以即使添加了目录,我也无法重新启动。我试着用pg_ctl stop -m fast来杀死PostgreSQL服务器,但没有运气。我还尝试直接使用kill PID来完成这个过程,但当我完成后,一个postgresql过程用不同的PID重新出现。

密钥最终是一个自制加载的.plist文件…我的解决办法是:

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

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


丢失的目录需要存在于PostgreSQL数据目录中。默认的数据目录是/usr/local/var/postgres/。如果设置了不同的数据目录,则需要在其中重新创建丢失的目录。如果修改了启动PostgreSQL的自制推荐.plist文件,可以在其中找到数据目录:

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

(这是你从Postgres开始的-D选项:)

1
2
3
4
5
  <key>ProgramArguments</key>
 
    <string>/usr/LOCAL/bin/postgres</string>
    <string>-D</string>
    <string>/usr/LOCAL/pgsql/data</string>

在上面的示例中,您将在/usr/local/pgsql/data中创建丢失的目录,如下所示:

1
2
3
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}

创建丢失的目录当然可以,但是我通过重新初始化postgres-db来修复它,这是一种避免将来出现问题的更清洁的方法。

注意:此方法将删除现有数据库

1
2
$ rm -r /usr/LOCAL/var/postgres
$ initdb -D /usr/LOCAL/var/postgres