I opened the postgresql logs to see in detail what went wrong at the moment when the query failed (I could track the time from the ansible playbook logs)
less /var/log/postgresql/postgresql-10-main.log.1
and I found this error
2023-07-04 02:37:30.175 CEST [26940] ERROR: Writing to file "base/pgsql_tmp/pgsql_tmp26940.121" failed: No space left on device
I did some research and turns out that when postgres has to run "operations such as sorting more data than can fit in memory", it stores temporary data in the default directory PGDATA/base/pgsql_tmp
So I opened my postgres configuration file to check out where this directory is located (i.e. what is the value of PGDATA
)
less /etc/postgresql/10/main/postgresql.conf
and I found this
#------------------------------------------------------------------------------
# FILE LOCATIONS
#------------------------------------------------------------------------------
# The default values of these variables are driven from the -D command-line
# option or PGDATA environment variable, represented here as ConfigDir.
data_directory = '/var/lib/postgresql/10/main'
So I went to that directory to see what is inside
sudo -i -u postgres
cd /var/lib/postgresql/10/main
ls -al
and there I see the base directory indicated in the error message. So I get inside there to explore it
cd base
ls -al
and I see there is this pgsql_tmp
also indicated in the error message in the postgres log.
So I go inside there and run
postgres@mymachine:~/10/main/base/pgsql_tmp$ df -h --output=avail .
Avail
5.8G
So the amount of free space in postgres temporary data directory is much smaller than in my user's directory.
The csv I am woking on is 1.2 GB large, so still smaller than the available space, but considering that postgres is also used by other processes, I want more free space for postgres temporary data directory.
So what I do is to create a softlink from the postgres temporary data folder to a folder in my user's space (as suggested here).
In another terminal (let's say t2), in my user directory:
cd /home/myuser/
mkdir pgsql_tmp
Then, in the previous terminal (let's say t1):
postgres@mymachine:~/10/main/base$ ln -s /home/myuser/pgsql_tmp
postgres@umymachine:~/10/main/base$ ls -al
total 48
drwx------ 6 postgres postgres 4096 Jul 6 18:02 .
drwx------ 19 postgres postgres 4096 Jul 6 16:22 ..
drwx------ 2 postgres postgres 12288 Jul 6 16:22 1
drwx------ 2 postgres postgres 4096 Oct 9 2020 13014
drwx------ 2 postgres postgres 12288 Jun 29 2022 13015
drwx------ 2 postgres postgres 12288 Jul 6 16:23 16385
lrwxrwxrwx 1 postgres postgres 20 Jul 6 18:02 pgsql_tmp -> /home/myuser/pgsql_tmp
Then back in t2:
chown -R postgres /home/orka/pgsql_tmp
chmod o+x /home/myuser/pgsql_tmp
restarted postgres
sudo service postgresql restart
and then it works.