我在我的 OS X 中使用 homebrew 的 postgres,但是当我重新启动系统时,有时 postgres 在重新启动后无法启动,因此我手动尝试使用 postgres -D /usr/local/var/postgres
启动它,但随后出现错误并显示以下消息:FATAL: could not open directory "pg_tblspc": No such file or directory
。
上次出现这种情况,无法恢复到原来的状态,所以决定卸载整个postgres系统,然后重新安装并创建用户、表、数据集等……太恶心了,但是它经常出现在我的系统上,比如几个月一次。
那么为什么它会经常丢失 pg_tblspc
文件呢?有什么办法可以避免文件丢失吗?
我还没有将我的 homebrew 和 postgres 升级到最新版本(即我一直在使用相同的版本)。此外,我在 postgres 数据库上所做的所有事情都是删除表并每天填充新数据。我没有更改用户,密码等...
编辑(mbannet):我觉得有必要添加这个,因为这个问题在谷歌上是最热门的话题,而且对于许多人来说,症状是不同的。 Homebrewers 可能会遇到此错误消息:
No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
因此,如果您在优胜美地升级后刚刚体验到这一点,那么您现在就可以阅读此线程了。
pg_tblspc
是一个目录。我可以看到这个目录并且这个目录随机消失的唯一方法是文件系统损坏或行为特别糟糕的病毒扫描程序或文件同步工具。
tablespaces
是什么,所以我不认为我把它放在外部存储上。
pg_tblspc
不会在我遇到过的任何系统上消失,我也无法想象它会出现的合理原因。如果没有更多细节,很难说出是什么让您的系统与众不同。
解决了……部分解决。
显然,安装最新版本的 OS X(例如 Yosemite 或 El Capitan)会删除 /usr/local/var/postgres
中的一些目录。
要解决此问题,您只需重新创建丢失的目录:
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
或者,更简洁(感谢 Nate):
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 正在运行,其中一些目录也是空的。也许,作为一些“清理”操作的一部分,优胜美地会删除任何空目录?无论如何,我继续在每个目录中创建了一个“.keep”文件,以防止将来被删除。
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
文件会在您的日志文件中产生一些干扰,但似乎不会对其他任何内容产生负面影响。
Donavan 的答案是正确的,我只是想补充一点,因为我对数据库做了不同的事情(例如 rake db:test
),它会寻找上面没有提到的不同目录,当它们不存在时会窒息'不存在,在我的情况下 pg_logical/mappings
,所以你可能想要设置一个终端运行:
tail -f /usr/local/var/postgres/server.log
并在您进行典型的数据库活动时注意它是否丢失了文件夹。
这有点离题,但在此作为 PostgreSQL Yosemite 恢复过程的一部分值得注意。我遇到了与上面相同的问题,并且我遇到了 PostgreSQL 在后台“看似”运行的问题,所以即使在添加目录之后我也无法重新启动。我尝试使用 pg_ctl stop -m fast
杀死 PostgreSQL 服务器,但没有运气。我还尝试直接使用 kill PID
跟踪该进程,但一旦我这样做,PostgreSQL 进程就会重新出现,并带有不同的 PID。
密钥最终成为 Homebrew 加载的 .plist
文件......对我来说,修复最终是:
launchctl unload /Users/me/Library/LaunchAgents/homebrew.mxcl.postgresql92.plist
之后我就可以正常启动 PostgreSQL。
launchctl unload ${HOME}/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
但基本上这对我来说也是同样的问题,也是同样的解决方案。
缺少的目录需要存在于您的 PostgreSQL 数据目录中。默认数据目录是 /usr/local/var/postgres/
。如果您设置了不同的数据目录,则需要在那里重新创建缺少的目录。如果您修改了启动 PostgreSQL 的 homebrew-recommended .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 应用程序时遇到了这个问题。
而不是 /usr/local/var/postgres 中缺少 pg_tblspc 和其他目录,而是 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 有错误,因此只需仔细阅读命令行输出并根据需要进行调整。
创建丢失的目录当然可以,但我通过重新初始化 postgres db 来修复它,这是避免未来问题的一种更简洁的方法。
注意:此方法将删除现有数据库
$ rm -r /usr/local/var/postgres
$ initdb -D /usr/local/var/postgres
mkdir -p /usr/local/var/postgres/{pg_tblspc,pg_twophase,pg_stat_tmp}/
和touch /usr/local/var/postgres/{pg_tblspc,pg_twophase,pg_stat_tmp}/.keep
could not open temporary-files directory "pg_tblspc/.keep/PG_9.3_201306121/pgsql_tmp": Not a directory
mkdir /usr/local/var/postgres/{pg_tblspc,pg_twophase,pg_stat_tmp,pg_replslot}