我刚刚通过以下方式重新安装了 postgresbrew install postgres
我跑了initdb /usr/local/var/postgres -E utf8
,但得到了这个:
The files belonging to this database system will be owned by user "atal421".
This user must also own the server process.
The database cluster will be initialized with locale "en_US.UTF-8".
The default text search configuration will be set to "english".
initdb: directory "/usr/local/var/postgres" exists but is not empty
If you want to create a new database system, either remove or empty
the directory "/usr/local/var/postgres" or run initdb
with an argument other than "/usr/local/var/postgres".
因此,我进入了rm -rf
postgres 文件夹并再次运行它:
initdb /usr/local/var/postgres -E utf8
它说一切都好:
Success. You can now start the database server using:
postgres -D /usr/local/var/postgres
因此,我运行了该命令并得到:
postgres -D /usr/local/var/postgres
FATAL: lock file "postmaster.pid" already exists
HINT: Is another postmaster (PID 13731) running in data directory "/usr/local/var/postgres"?
现在,当我查看活动监视器时,我可以看到 6 个 postgress 实例。
我该如何解决?
答案1
公共服务公告:永远不要删除postmaster.pid
。真的。这是导致数据损坏的好方法。
您已经安装了 PostgreSQL,并且删除了数据目录而没有停止正在运行的服务器。因此,您现在有一些孤立的 PostgreSQL 服务器进程正在管理已删除的数据文件,因此它们在文件系统中不再可访问,并且当它们的最后一个打开文件句柄关闭时,它们将被完全删除。pg_ctl
由于您已删除集群数据目录,因此您无法像平常一样关闭服务器,因此您必须简单地终止进程。终止 postmaster(执行不是使用kill -9
,只需普通的 kill 即可),其余的也将关闭。
然后,您将能够根据最新initdb
数据在数据目录中启动一个新服务器。
除非您卸载其他旧版本的 PostgreSQL,否则很可能会遇到冲突。
简而言之:
cat /usr/local/var/postgres/postmaster.pid
记下第一行的数字,即进程号邮政局长的。
验证ps
该 pid 是否是 postgres 邮政局长的 pid。
使用以下命令终止 postmaster 进程,将“PID”替换为您记下的数字。再次,不要使用kill -9
或kill -KILL
,只需使用普通的kill
,即SIGTERM
:
kill PID
如果 pid 不是 postgres postmaster 的 pid,请手动检查kill
任何postgres
可能仍在运行的后端,核实他们不再跑步,只有那时删除postmaster.pid
。 (您还必须验证 不在postmaster.pid
共享存储上,因为服务器可能在其他 VM/主机上运行)。
答案2
另一种可能是你硬关机,postgres 进程死机而没有清理其 pid 文件。我的笔记本电脑电池没电时就会发生这种情况。
此解决方案不是对于生产系统,你应该确保 postgres 守护进程没有运行,但我使用笔记本电脑进行编码,因此并不担心需要重新生成数据库。
因此,如果另一个进程(或者根本没有进程)在该端口上运行,只需删除 pid 文件,例如
rm /usr/local/var/postgres/postmaster.pid
postgres 很快就能正常启动了。
要了解该端口上是否有另一个进程正在运行,您可以执行以下操作
ps wax | grep `head -1 /usr/local/var/postgres/postmaster.pid`
然后运行
tail -f /usr/local/var/postgres/server.log
看看它是否有效。你应该看到
FATAL: lock file "postmaster.pid" already exists
HINT: Is another postmaster (PID 933) running in data directory "/usr/local/var/postgres"?
FATAL: lock file "postmaster.pid" already exists
HINT: Is another postmaster (PID 933) running in data directory "/usr/local/var/postgres"?
LOG: database system was interrupted; last known up at 2014-05-25 09:41:32 PDT
LOG: database system was not properly shut down; automatic recovery in progress
(或者至少这是我完成上述操作后看到的:-))
(实际上,Postgres 难道不应该足够聪明,意识到没有 PID 为 933 的进程,并自行删除虚假的 pid 文件吗?)
答案3
升级到 Yosemite 后,我的 postgres(通过 homebrew 安装)损坏了,我尝试了所有方法但都无济于事。
然后我偶然发现了这篇博文:http://ruckus.tumblr.com/post/100355276496/yosemite-upgrade-breaks-homebrew-installed-postgres
首先,我需要创建在升级过程中显然被消灭的缺失目录(感谢 Apple!)。
$ cd /usr/local/var/postgres
$ mkdir {pg_tblspc,pg_twophase,pg_stat_tmp}
然后只需使用正常的自制启动序列再次启动 postgres:
$ launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
$ launchctl load ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
感谢 Ruckus Notes 帮助我解决了问题。希望它也能帮到您。
答案4
每次启动时,盲目地删除 postmaster.pid 确实是一件非常体面的事情。我的系统就是这样做的。因为你刚刚启动,你知道没有 Postgres 进程在运行,如果你正在从非正常关机中恢复,这个文件会阻止你的恢复。
Postgres 的更好设计是将 postmaster.pid 文件放在 /run 文件系统中,这样可以保证每次重新启动时都会删除它。许多其他服务器也采用这种方式。