我在我的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"? |
所以,如果你在约塞米蒂升级后刚刚经历过这一点,你现在可以阅读这篇文章了。
- EEP,真的,真的不应该!当你说"最新版本"时,请显示准确的版本号。另外,您是否在外部存储上放置了表空间?PostgreSQL数据目录在哪里?
- 另外,pg_tblspc是一个目录。我能看到这个目录和这个目录随机消失的唯一方法是文件系统损坏,或者是一个特别糟糕的病毒扫描程序或文件同步工具。
- 我没有任何病毒扫描程序。我不知道tablespaces是什么,所以我不认为我把它放在了外部存储器上。
- 嗯,我能告诉你的就是出了严重的问题。pg_tblspc不仅消失在我所遇到的任何系统上,我也无法想象它会是一个理智的理由。如果没有更多的细节,很难说是什么让你的系统与众不同。
- 我在Postgres上所做的是1)选择一个数据库,2)删除数据库上的所有数据,3)将新数据填充到数据库,4)将其推送到Heroku。这个程序每天都要进行。你认为把它推到Heroku数据库是相关的吗?
- "选择一个数据库","删除数据库上的整个数据"。细节?
- 啊,对不起,那是错的。我在我的mysql系统上完成了以上所有的步骤,然后使用py-mysql2pgsql(github.com/philiposutham/py-mysql2pgsql)将mysql数据库复制到相应的postgres数据库中。
- 好吧,这似乎不太可能是相关的,它只是使用PostgreSQL的客户端库或生成一个SQL脚本。你必须直接处理数据目录来创建你遇到的问题。
- 那么操作系统升级是否相关?我现在使用约塞米蒂β,但我不确定它以前是什么时候发生的。每当新的测试版可用时,我都会更新它(我想总共是6到7次)。
- 测试版操作系统?是的,那可能是这个问题的候选人。也许你应该和苹果一起提这个,你可能发现了一个虫子。同样,如果没有详细的调查和实际再现问题的能力,几乎不可能说出来。
- 你能为这个@gardecolo找到解决方案吗?升级到约塞米蒂后,我也遇到了同样的问题。
- @多诺万,没有。我已经卸载并重新安装了它。我不认为我应该这样做,但我必须尽快恢复它,因为我用它做我的生意…
- @Craigringer不知道苹果公司的测试版,但Yosemite的发布版仍然存在这个问题。恩芬,过来解决了问题。
- 在进一步研究这个问题之后,我写了一篇关于这个和另一个问题的博客文章。总的来说,我简直无法相信苹果是如何处理这一问题的。blog.2ndquadrant.com/…
- 有没有人设法找出OSX中的什么在做这个?这是疯狂的行为。
- 我在$home下有一个自定义安装路径,有一天我想我会清理所有空目录,这在下一次Postgressql重新启动时发生。空目录终究不是无用的。
解决了的。。。部分地。
显然,安装最新版本的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文件会在日志文件中产生一些噪声,但不会对其他任何内容产生负面影响。
- 是否仍丢失/usr/local/var/postgres中的其他文件/目录,如pg_clog、pg_stat、pg_subtrans、base等?
- 我没有,没有,我只是错过了那三个
- 在我的例子中,剩下的所有文件都是postmaster.opts和server.log。但谢谢你提供的信息。
- 可能是因为拆卸和重新安装了Postgres?
- 重新安装Postgres后,一切看起来都很好。所以我认为这是由于约塞米蒂β的安装。
- 我同意。在我的例子中,只有这三个目录,但由于我不知道为什么要删除任何目录,所以完全有可能删除其他目录。
- 我也有同样的问题,这个问题解决了。在现有(和工作)上安装通用候选(14A379A)10.9.5。Yosemite安装程序必须已删除这些空目录。
- 用BREW重新安装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
- 这修复了安装Yosemite 10.10版本后的postg。
- 谢谢!在约塞米蒂和Postgres9.3.2的最新版本上为我工作
- 谢谢!升级到约塞米蒂后也出现了同样的问题。BREW升级Postgres没有帮助。
- 您可能不需要创建所有三个目录(我只需要创建两个)。启动Postgres时,运行pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start -w以获得更好的输出。然后执行tail -5 /usr/local/var/postgres/server.log以查看启动时的错误。错误将指示缺少哪些目录。
- 那些.keep文件实际上在服务器日志中给我带来了一些麻烦:could not open temporary-files directory"pg_tblspc/.keep/PG_9.3_201306121/pgsql_tmp": Not a directory。
- @是的,我也得到了这些日志条目,但它们不会给我带来麻烦。如果他们打扰您,您可以删除.keep文件,因为这不是严格必要的。它们只是防止目录被意外删除(因为它们不是空的)。
- 我还缺少pg_快照和pg_stat目录。
- @如果日志很烦人,请尝试对.keep文件进行chown,并对其进行chmod,以便Postgres运行的用户看不到这些文件(注意,这可能是不可能的)
- 谢谢你……我今天早上刚升级到约塞米蒂,就在那时,PostgreSQL停止工作,因为显然苹果只需要使用非操作系统的基本软件包。我厌倦了每次OS X升级都是如此糟糕。
- 如果你在约塞米蒂安装程序(command-l)运行的时候一直在看它的话!!)你会看到它疯狂地移动/usr/local中的所有内容-不知道为什么,但我敢打赌空目录会丢失。多方便啊!
- 在我的例子中.keep文件应该是目录,所以我只执行了这个:mkdir -p /usr/local/var/postgres/{pg_tblspc,pg_twophase,pg_stat_tmp}/.keep。
- 要启动Postgres,我需要运行pg_ctl start -D /usr/local/var/postgres/*。
- 我还必须创建一个额外的目录"pg-replslot"。但它工作得很好。谢谢!
- 与@lucas的瓶装Postgres 9.4.0体验相同。我不得不去埃多克斯〔14〕。
- 遇到了这种情况,但必须运行以下命令才能获取server.log而不出现警告或错误:mkdir -p /usr/local/var/postgres/{pg_tblspc,pg_twophase,pg_stat_tmp,pg_replslot,pg_stat,pg_logical/snapshots,pg_logical/mappings,pg_snapshots}/。这是针对BREW PostgreSQL 9.4.1的
- 当系统重新启动时,如何让Postgres自动启动?似乎每次我在实现了你的解决方案后重新启动我的电脑,我都需要再次运行pg-ctl-start-d/usr/local/var/postgres来让一切正常运行,在升级到约塞米蒂之前我不需要这样做。
- 在ElCapitan上安装了最新版本的Postgres9.4.5_2之后,也必须这样做。您的解决方案仍然适用。作品。
- 我不得不添加/usr/local/var/postgres/pg_logical/snapshots和/usr/local/var/postgres/pg_logical/mappings来启动服务器。(yosimite,BREW安装homebrew/versions/postgresql94)
Donavan的回答是现场的,我只是想补充一点,因为我对数据库做了不同的事情(例如,rake db:test),它寻找了不同的目录,这些目录在上面没有提到过,在我的例子中,pg_logical/mappings会在不存在时阻塞,因此您可能需要设置一个运行的终端:
1
| tail -f /usr/LOCAL/var/postgres/server.log |
在浏览典型的数据库活动时,请注意丢失的文件夹。
- 需要添加mkdir-p/usr/local/var/postgres/pg_logical/快照,映射
这有点离题,但作为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了。
- 我的plist的命名略有不同:launchctl unload ${HOME}/Library/LaunchAgents/homebrew.mxcl.postgresql.plist,但基本上这对我来说也是同样的问题,也是同样的解决方案。
丢失的目录需要存在于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 |
- 显然,删除现有数据库并不是一个小的例外。这有点像说"我找不到/var/tmp,所以我重新安装了操作系统"。
- 哦,伙计,这比我能想到的任何东西都"干净"了:)只是希望Interwebz的一些随机复制粘贴程序不要在不看的情况下直接将其拍摄到控制台上:)
- 很抱歉投了反对票,Greg,但我建议修改您的解决方案,使其明确表示,这种方法只应在开发中使用,或者如果用户有能力擦除他们的数据库。
- 为什么这次被否决了这么多?在dev服务器上,这是正确的方法。