在 Centos 7 上移动 datadir 后 PostgreSQL 无法启动

在 Centos 7 上移动 datadir 后 PostgreSQL 无法启动

我在 Centos 7 上安装了 PostgreSQL 9.3。安装后,我可以启动系统服务并登录 psql。我想将 PGDATA 文件夹移动到另一个分区,因此我尝试了几种方法来更改 DATADIR。

我将/var/lib/pgsql/data文件夹复制到/postgresdata/data,然后创建了一个符号链接:

systemctl stop postgresql
cp -rp /var/lib/pgsql/data /postgresdata/data
mv /var/lib/pgsql/data /var/lib/pgsql/data.old
ln -s /postgresdata/data /var/lib/pgsql/data
systemctl start postgresql

该文件夹/postgresdata/设置为 700 且所有者为 postgres。

这会导致以下错误:

postgresql.service 的作业失败,因为控制进程退出并显示错误代码。有关详细信息,请参阅“systemctl status postgresql.service”和“journalctl -xe”。

我也尝试了另外两种方法,但都出现了同样的错误:

方法 1:更改 postgresql.conf

data_directory = '/postgresdata/data'

方法2:更改系统服务设置:

vim /usr/lib/systemd/system/postgresql.service

然后改变:

# Environment=PGDATA=/var/lib/pgsql/data
Environment=PGDATA=/postgresdata/data

两者都会导致相同的错误。

当我跑步时journalctl -xe我得到了这个:

-- Unit postgresql.service has begun starting up.
apr 25 15:08:03 srv001 pg_ctl[15517]: FATAL:  could not open file "/postgresdata/data/PG_VERSION": Permission denied
apr 25 15:08:04 srv001 systemd[1]: postgresql.service: control process exited, code=exited status=1
apr 25 15:08:04 srv001 pg_ctl[15517]: pg_ctl: could not start server
apr 25 15:08:04 srv001 pg_ctl[15517]: Examine the log output.
apr 25 15:08:04 srv001 systemd[1]: Failed to start PostgreSQL database server.
-- Subject: Unit postgresql.service has failed
-- Defined-By: systemd
-- Unit postgresql.service has failed.

/postgresdata/data/PG_VERSION我看来,权利没有问题。它们似乎与原版完全相同。

如何在 Centos 7 上移动 PostgreSQL 的数据文件夹?

答案1

最简单的做法是安装新磁盘,/var/lib/pgsql这样可以省去很多麻烦。这样你就不必担心更改 SELinux 策略或任何类似的事情。


如果你坚持将 PostgreSQL 的数据目录放在意想不到的位置,可以通过为新目录结构设置与现有目录结构相同的新文件上下文来使 SELinux 正常工作。例如:

semanage fcontext --add --equal /var/lib/pgsql /postgresdata

这会导致 下的安全上下文/postgresdata被应用,就像它们在 下一样/var/lib/pgsql。然后,您可以使用 修复任何现有文件的上下文restorecon

restorecon -rv /postgresdata

要意识到人们不是了解你为什么这么做。包括将来查看此服务器的任何管理员,包括你自己。无需因为使用新磁盘而使用非标准目录。只需将新存储挂载在 即可/var/lib/pgsql

答案2

提到的 PG_VERSION 文件的权限应该与此类似:(使用用户和组 postgres)

-rw------- 1 postgres postgres

并且还不要忘记不仅允许访问 /postgresdata/ 还要允许访问 /postgresdata/data !

也许尝试使用带有 -R (递归选项) 的 chown。

另一个问题可能是“其他分区”,如果您使用不同的文件系统(例如 NTFS)在多启动系统之间移动数据,您将遇到此类权限问题,尤其是因为 NTFS 不支持可执行权限位。当然,其他非 UNIX FS(例如 fat 等)也是如此。

最好的方法是使用 rsync 的存档选项“-a 或 --archive”复制整个文件夹,以尝试保持原始权限和符号链接等相同。当然,前提是它在目标文件系统上是可能的......

答案3

文件和目录需要进行相应的标记。您可以使用 查看当前标签ls -Z

可以使用 来确定 PostgreSQL 所需的文件上下文semanage fcontext --list | grep ^/var/lib/pgsql

您需要调整策略以正确标记文件。因此,您必须semanage fcontext -a -t <type> <path-pattern>针对上述命令输出中列出的每个模式进行设置。

完成后,您只需调用即可restorecon -Rv /postgresdata让 SElinux 根据您刚刚创建的更新的文件上下文模式重新标记文件。

完成后你的 PostgreSQL 实例应该重新启动。

答案4

我最终来到这个页面是因为我遇到了类似的情况。我感谢@Andreas Rogge 在上一篇文章中提供的解决方案。

事实上,我所要做的就是restorecon -Rv /var/lib/pgsql/data让 SElinux 根据更新的文件上下文模式重新标记文件。ls -Z我发现它们不正确。我保留了一个原始数据文件夹,以便进行比较。

我移动了 postgres 数据目录。实际上,我将它复制到了另一个临时文件夹,因为我需要将当前文件系统从 ext2 迁移到 xfs。(数据目录是单独挂载的文件系统)因此,我使用 tar 复制到临时文件系统,tar 通常会保留所有文件特征,但显然不会保留 selinux 标签。我将文件系统初始化为 xfs,并将整个数据目录通过 tar 复制回这个重新挂载的位置。但随后 postgres 无法启动,尽管 /var/lib/pgsql/data 可用且已填充,journalctl -xe 输出显示错误"/var/lib/pgsql/data" is missing or empty。借助 Andreas 提供的知识,我可以检查ls -Z标签是否正确。需要从以下位置恢复:

unconfined_u:object_r:unlabeled_t:s0unconfined_u:object_r:postgresql_db_t:s0

解决restorecon -Rv /var/lib/pgsql/data了!

因此,如果有人在谷歌搜索“移动数据文件夹后 postgres 无法启动,并且 journalctl -xe 输出中缺少错误“/var/lib/pgsql/data”或为空”后最终来到这里,我希望这可以帮助他们利用这些知识快速恢复。

相关内容