授予权限的Postgresql COPY命令被拒绝错误

授予权限的Postgresql COPY命令被拒绝错误,postgresql,copy,permission-denied,Postgresql,Copy,Permission Denied,我正在尝试将文件复制到PostgreSQL中的表中。表所有者是postgres,文件所有者是postgres 该文件位于/tmp中 我仍然收到错误消息: 无法打开文件“/tmp/file”进行读取:权限被拒绝 我不明白我做错了什么,因为我找到的所有帖子都说,如果我在/tmp中有文件,并且所有者是postgres,那么COPY命令应该可以工作 猜测:您正在使用Fedora、Red Hat Enterprise Linux、CentOS、Scientific Linux或其他默认启用的发行版之一 在

我正在尝试将文件
复制到PostgreSQL中的表中。表所有者是
postgres
,文件所有者是
postgres

该文件位于
/tmp

我仍然收到错误消息:

无法打开文件“/tmp/file”进行读取:权限被拒绝


我不明白我做错了什么,因为我找到的所有帖子都说,如果我在
/tmp
中有文件,并且所有者是
postgres
,那么
COPY
命令应该可以工作

猜测:您正在使用Fedora、Red Hat Enterprise Linux、CentOS、Scientific Linux或其他默认启用的发行版之一

在您的特定操作系统/版本上,PostgreSQL的SELinux策略不允许服务器读取PostgreSQL数据目录之外的文件,或者该文件是由目标策略所覆盖的服务创建的,因此它有一个不允许PostgreSQL读取的标签

您可以通过以root用户身份运行来确认这是否是问题:

setenforce 0
然后重新测试。运行:

setenforce 1
在测试后重新启用SELinux。不是永久的;SELinux将在重新启动时自动重新启用。永久禁用SELinux通常不是解决此类问题的好方法;如果您确认问题是SELinux,则可以进一步探讨


由于您没有指定您正在使用的操作系统或版本、PostgreSQL版本、您正在运行的确切命令、文件上的
ls-al
、表上的
\d+
等等,因此很难给出更多细节,也很难知道这是否只是猜测。尝试更新您的答案以包含所有这些内容,并在文件中添加一个
ls--lcontext

COPY
使用文件名指示PostgreSQL server直接读取或写入文件。PostgreSQL用户(服务器运行时的用户ID)必须可以访问该文件,并且必须从服务器的角度指定名称。(来源:)

因此,运行postgresql server的unix用户(即不是您的用户!)应该可以读取(或写入)该文件。当然,您可以尝试运行
sudo-u postgres head/tmp/test.csv
(假设允许您使用
sudo
,并且假设数据库用户是postgres)

如果失败,可能是与SELinux有关的问题(如Craig Ringer所述)。在Red Hat/Fedora/CentOS、Scientific Linux、Debian和其他公司使用的最常见的SELinux策略(“目标”参考策略)下。。。postgresql server进程受到限制:它只能读取/写入少数文件类型

由于donaudit规则,拒绝可能未记录在auditd的日志文件(
/var/log/audit/audit.log
)中。因此,通常的SELinux快速测试适用,例如:通过运行
getenforce停止SELinux限制任何进程;setengorce 0;获取强制执行,然后测试postgresql的复制。然后通过运行setenforce 1重新激活SELinux(此命令修改运行状态,而不是配置文件,因此SELinux将在重新启动后处于活动状态(强制)

解决此问题的正确方法是更改要加载的文件的SELinux上下文。快速破解方法是运行:

chcon -t postgresql_tmp_t /tmp/a.csv
但是,如果重新标记文件系统或创建新文件,则此文件标签将无法保留。您需要使用SELinux文件上下文映射创建目录:

which semanage || yum install policycoreutils-python
semanage fcontext -a -t postgresql_tmp_t '/srv/psql_copydir(/.*)?'
mkdir /srv/psql_copydir
chmod 750 /srv/psql_copydir
chgrp postgres /srv/psql_copydir
restorecon -Rv /srv/psql_copydir
ls -Zd /srv/psql_copydir
在该目录中创建的任何文件都应该自动具有适当的文件上下文,以便postgresql server能够读/写它


(要检查postgres运行的SELinux上下文,请运行
ps xaZ | grep“postmaste[r]“| grep-o”[a-z|]*\t”
,它应该打印
postgresql\u t
。要列出
postgresql\u t
可以写入的上下文类型,请使用
sesesearch-s postgresql\u t-A | grep::文件。*write'
。命令
sesesearch
属于
setools控制台
RPM包).

请添加您使用的语法和对文件的权限。是的,编辑您的答案以提及:PostgreSQL版本、您如何安装Pg、操作系统和版本、文件权限(
ls-l文件名
ls--lcontext文件名
)、表权限(
\d+tablename
psql
中),以及您运行的命令的确切文本+错误消息将非常有用。@user1439690太好了,现在您知道它是SELinux。
setenforce
是一种临时措施。正确的修复方法是设置文件的SELinux上下文。请参阅