我正在运行一个 ansible 剧本。运行ansible的机器是localhost。
该剧本在将数据从大 csv (1.2 GB) 加载到 postgres 数据库表(模块community.postgresql.postgresql_copy )的任务期间中断。
中断执行的任务(在本地主机上运行)是:
- name: Load data from CSV into table
community.postgresql.postgresql_copy:
login_host: '{{ db_host }}'
login_user: '{{ db_username }}'
login_password: '{{ db_password }}'
db: '{{ db_database }}'
port: '{{ db_database_port }}'
copy_from: "{{ path }}/my_big_csv_file.csv"
dst: "{{ my_table }}"
options:
format: csv
delimiter: ';'
header: yes
提出的错误是:
msg: Cannot execute SQL 'COPY "my_table" FROM '/path/my_big_csv_file.csv' (format csv, delimiter ';', header True)': ERROR: Could not extend file "base/16385/45444.1": only 4096 bytes of 8192 written in block 165767
HINT: Check free disk space.
CONTEXT: COPY my_table, line 9615264
我做了一些研究,我在这个线程中读到,当磁盘空间不足时会出现此错误。
然而,我已经跑了
df -h --output=avail .
在本地主机上,在源 csv 所在的文件夹中,并84G
作为输出获取。
那么可能是什么问题呢?
您的数据库服务器上的磁盘空间不足,而不是客户端上的磁盘空间不足。你的回答表明你已经明白了这一点。我想知道这是怎么发生的,因为
COPY
只将数据写入表,并且不涉及排序或其他内存密集型操作。但从你的回答来看,诊断是正确的。然而,创建符号链接
pgsql_tmp
并不是正确的解决方案。它会起作用,但一般来说,您不应该手动弄乱数据目录。这是推荐的解决方案:
在具有足够空间的文件系统上的数据库服务器上创建一个目录:
定义表空间:
将配置参数设置
temp_tablespaces
为tmpspace
完成后可以重置参数并删除表空间。
我打开 postgresql 日志来详细查看查询失败时出现的问题(我可以从 ansible playbook 日志中跟踪时间)
我发现这个错误
我做了一些研究,发现当 postgres 必须运行“诸如对超出内存容量的数据进行排序之类的操作”时,它会将临时数据存储在默认目录中
PGDATA/base/pgsql_tmp
所以我打开我的postgres配置文件来查看这个目录所在的位置(即 的值是多少
PGDATA
)我发现了这个
所以我去那个目录看看里面有什么
我在那里看到错误消息中指示的基本目录。所以我进去探索它
我看到
pgsql_tmp
postgres 日志的错误消息中也指出了这一点。所以我进去然后跑
因此,postgres 临时数据目录中的可用空间量比我的用户目录中的可用空间量小得多。
我正在处理的 csv 有 1.2 GB 大,因此仍然小于可用空间,但考虑到 postgres 也被其他进程使用,我希望为 postgres 临时数据目录提供更多可用空间。
所以我要做的就是创建一个从 postgres 临时数据文件夹到我的用户空间中的文件夹的软链接(如此处建议的那样)。
在另一个终端(假设是 t2)中,在我的用户目录中:
然后,在前一个终端(假设是 t1)中:
然后回到 t2:
重新启动 postgres
然后就可以了。