创建符号链接会导致无法覆盖目录错误


2

我有一个带postgresql后端的Django应用。PostgreSQL时不时地创建临时文件-如果磁盘空间很关键(就像我这样),这可能是一个致命的杀手。

缓解此问题的一种方法是创建到磁盘空间不是瓶颈的其他存储位置的符号链接。就我而言,postgresql将临时文件存储在/$PGDATA/base/pgsql_tmp。我在安装了一个大SSD /mnt,因此我希望临时文件驻留在那里。以下应注意这一点:

ln -sTf /mnt/pgsql_tmp $PGDATA/base/pgsql_tmp
chown -R postgres /mnt/pgsql_tmp #ensuring user 'postgres' has the right perms
chmod o+x /mnt

在进行生产之前,我决定在本地进行测试。我创建/mnt/pgsql_tmp我的桌面上,然后尝试ln -sTf /home/hassan/Desktop/mnt/pgsql_tmp /home/hassan/Desktop/pgsql_tmp

但这最终给了我ln: ‘/home/hassan/Desktop/pgsql_tmp’: cannot overwrite directory。谁能指出我做错了什么?作为新手,我真的想尽一切办法。


我想你应该考虑的含义Tf旗帜ln,然后我觉得你不应该这样做的。首先,它是不透明的。其次,数据库喜欢控制一切,甚至系统可能不会打开这样的文件,因为open()可以告诉调用将符号链接视为错误。原因是符号链接几乎可以指向任何地方。您的第一选择应该是更改数据库的配置。
运行CMD

那么这样的配置是PostgreSQL的宇宙标准做法:postgresql-archive.org/...
哈桑贝格

感谢您的指导。它显示为“我相信这是公认的惯例”,与“它的标准惯例”有些不同。但可以肯定的是,它至少在某些配置中有效。
运行CMD

Answers:


2

最好的选择是delete ~/pgsql_tmp,然后让ln命令创建它。

首先请注意,LN不会链接两个对象。它会创建一个指向具有特定名称的目标的链接。

ln [OPTION]... [-T] TARGET LINK_NAME

当您使用创建链接时ln,NAME参数应指示一个尚不存在的对象,该对象将作为命令的结果创建。在您的情况下,您已经将其(~/pgsql_tmp)创建为目录。

通常,您可以使用该-f开关来强制删除已经与NAME路径重叠的任何内容,但是在您的情况下,您指定了-T这意味着您想要将链接创建为文件而不是目录。因此,当-f要覆盖NAME处的对象时,它会尝试用文件覆盖目录。

因此,您可以将链接创建为目录并使用-f,也可以删除与NAME重叠的对象,然后创建链接。以后是最好的选择。

#create a test target with a file, but without an object at lnname
~/tmp$ mkdir lntarget
~/tmp$ touch lntarget/contentfile1
~/tmp$ ln -sTf lntarget lnname
~/tmp$ ls ./lnname
contentfile1

我想删除/pgsql_tmp并让ln命令创建它是我缺少的主要成分。告诉我一件事。我的真实情况是将postgresql日志保存在其中/$PGDATA/base/pgsql_tmp,而我希望它们全部驻留在其中/mnt/pgsql_tmp。因此,这是什么,我需要做的:先删除该文件夹pgsql_tmp/$PGDATA/base/。创建一个文件夹,名为/pgsql_tmpmnt,然后运行ln -s /mnt/pgsql_tmp /$PGDATA/base/pgsql_tmp。正确?
哈桑·拜格,

是的,尽管在大多数情况下您可能会将数据从/$PGDATA/base/移到mnt/pgsql_tmp而不是删除。
Frank Thomas

you can either create the link as a directory and use -f我看不到ln用symlink替换目录的方法,除了在运行之前删除目录之外ln。无论如何,“将链接创建为目录”是什么意思?
x-yuri
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.