Postgres: Unable to save psql history

Created on 9 Jul 2018  路  1Comment  路  Source: docker-library/postgres

Using 10.4 (but this also occurs with 10.3):

In an attempt to save psql history between sessions, I'm mounting a .psqlrc volume at /root/.psqlrc which contains only these lines:

\x auto
\set HISTFILE ~/.psql_history

I'm also mounting a .psql_history volume at ~/root/.psql_history, but after entering some queries in psql and exiting, I receive the following error:

could not save history to file "/root/.psql_history": Unknown error -1

question

Most helpful comment

Dug out old strace to figure out what was going on here, and the reason this is happening is that psql writes to a temporary file before then moving that temporary file on top of the old history file: (which is why this fails -- a bind mount of a file only bind mounts the inode, so a rename like this won't ever work)

( lots of boring strace output )
close(3)                                = 0
rt_sigaction(SIGPIPE, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7fec6d2f80c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
stat("/root/.psql_history", {st_mode=S_IFREG|0777, st_size=3, ...}) = 0
readlink("/root/.psql_history", 0x7ffdcdc3ea40, 4096) = -1 EINVAL (Invalid argument)
getpid()                                = 301
open("/root/.psql_history-00301.tmp", O_WRONLY|O_CREAT|O_TRUNC, 0600) = 3
write(3, "hi\n\\q\n", 6)                = 6
close(3)                                = 0
readlink("/root/.psql_history", 0x7ffdcdc3ea40, 4096) = -1 EINVAL (Invalid argument)
rename("/root/.psql_history-00301.tmp", "/root/.psql_history") = -1 EBUSY (Device or resource busy)
unlink("/root/.psql_history-00301.tmp") = 0
open("/usr/share/locale/en_US.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, "could not save history to file \""..., 71could not save history to file "/root/.psql_history": Unknown error -1
) = 71
exit_group(0)                           = ?
+++ exited with 0 +++

What I'd recommend doing instead is bind-mounting an entire directory that includes your history file, and using the PSQL_HISTORY environment variable to set the desired location appropriately. You shouldn't even need your .psqlrc since it should write a history file by default. :+1:

>All comments

Dug out old strace to figure out what was going on here, and the reason this is happening is that psql writes to a temporary file before then moving that temporary file on top of the old history file: (which is why this fails -- a bind mount of a file only bind mounts the inode, so a rename like this won't ever work)

( lots of boring strace output )
close(3)                                = 0
rt_sigaction(SIGPIPE, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7fec6d2f80c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
stat("/root/.psql_history", {st_mode=S_IFREG|0777, st_size=3, ...}) = 0
readlink("/root/.psql_history", 0x7ffdcdc3ea40, 4096) = -1 EINVAL (Invalid argument)
getpid()                                = 301
open("/root/.psql_history-00301.tmp", O_WRONLY|O_CREAT|O_TRUNC, 0600) = 3
write(3, "hi\n\\q\n", 6)                = 6
close(3)                                = 0
readlink("/root/.psql_history", 0x7ffdcdc3ea40, 4096) = -1 EINVAL (Invalid argument)
rename("/root/.psql_history-00301.tmp", "/root/.psql_history") = -1 EBUSY (Device or resource busy)
unlink("/root/.psql_history-00301.tmp") = 0
open("/usr/share/locale/en_US.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, "could not save history to file \""..., 71could not save history to file "/root/.psql_history": Unknown error -1
) = 71
exit_group(0)                           = ?
+++ exited with 0 +++

What I'd recommend doing instead is bind-mounting an entire directory that includes your history file, and using the PSQL_HISTORY environment variable to set the desired location appropriately. You shouldn't even need your .psqlrc since it should write a history file by default. :+1:

Was this page helpful?
0 / 5 - 0 ratings