See the working PostgreSQL deployment SDL manifest for Akash Network in the comments section.
with the data mounted over /var/lib/postgresql/data
directory.
Make sure to either use
PGDATA=/var/lib/postgresql/data/<some-other-dir>
orrmdir /var/lib/postgresql/data/lost+found
when having/var/lib/postgresql/data
a mountpoint over a device (say Ceph's RBD), due toinitdb
not willing to work with the mountpoints (but can be tricked to by removinglost+found
directory! :-)).
More here https://www.postgresql.org/message-id/flat/21269e094e35a1b32c426408cc0a4408%40nixaid.com#e4510c5b090c2737e68cfdcf8223020a
Example command for K8s:
kubectl -n $ns patch statefulset db --type=json -p='[{"op":"replace", "path":"/spec/template/spec/containers/0/image","value":"postgres:14"},{"op":"replace", "path":"/spec/template/spec/containers/0/command","value":["sleep", "infinity"]}]'
root@db-0:~# gosu postgres sh -c "cd $PGDATA && cat PG_VERSION"
13
It will be used for upgrading from 13 to 14:
sed -i 's/$/ 13/' /etc/apt/sources.list.d/pgdg.list
apt update && apt install -y --no-install-recommends postgresql-13
Export the following environment variables:
export PGBINOLD=/usr/lib/postgresql/13/bin
export PGBINNEW=/usr/lib/postgresql/14/bin
export PGDATAOLD=$PGDATA/../data.old
export PGDATANEW=$PGDATA
$PGDATAOLD
should be a different directory from the$PGDATA
asinitdb
expects the latter to be empty.
WARNING: Make sure the
$PGDATAOLD
has enough disk space before proceeding.
Move the current data to a different directory:
mkdir $PGDATAOLD
chown postgres $PGDATAOLD
chmod 700 $PGDATAOLD
gosu postgres sh -c "cd $PGDATA && mv -vi * .??* $PGDATAOLD"
Initialize PostgreSQL 14 data:
# PostgreSQL 14 defaults to "scram-sha-256" which breaks the authentication
# If you were upgrading from the previous versions:
# - FATAL: password authentication failed for user "postgres"
# Hence, let's preserve the "md5" unless the user was setting a different
# auth method before the postgresql 14.
# "scram-sha-256" is better, but requires you resetting each password:
# https://www.cybertec-postgresql.com/en/from-md5-to-scram-sha-256-in-postgresql/
export POSTGRES_HOST_AUTH_METHOD=${POSTGRES_HOST_AUTH_METHOD:-md5}
timeout 5s /usr/local/bin/docker-entrypoint.sh postgres
Upgrade PostgreSQL 13 to 14:
gosu postgres bash -c "cd /var/lib/postgresql && /usr/lib/postgresql/14/bin/pg_upgrade"
if
pg_upgrade
fails, then try tochmod 700 "$PGDATAOLD" "$PGDATANEW"; chown -R postgres "$PGDATAOLD" "$PGDATANEW"
and repeat the upgrade command again.
Delete old PostgreSQL 13 data:
It is good to ensure you have a backup first in case if the upgrade to 14 fails.
rm -rf $PGDATAOLD
Exit the container:
exit
and with the data mounted over /var/lib/postgresql/data
directory as in the 1st step.
Example command for K8s:
kubectl -n $ns patch statefulset db --type=json -p='[{"op":"replace", "path":"/spec/template/spec/containers/0/image","value":"postgres:14"},{"op":"remove", "path":"/spec/template/spec/containers/0/command"}]'
Working PostgreSQL deployment SDL manifest for Akash Network
TL;DR you have to set
PGDATA=<mountpoint>/<something>
environment variable, where the mountpoint cannot be/var/lib/postgresql
due to 1 & 2.There is also a historical reason for why
PGDATA
cannot be a mountpoint directly - mainly for preventing an issue where postgresql can overwrite the goodpg_control
file if the postgresql was started with the unmountedPGDATA
mountpoint device and had the other DB in that path (when someone eitherinitdb
before mounting the device over thePGDATA
or the postgresql starting script runsinitdb
when findsPGDATA
is empty) and have then stopped the DB with thePGDATA
backing device mounted over back again.IMHO, this is very rare, however, the postgresql devs claim there are horror stories about such cases in the PG community mailing list archives, dating from before they installed the don't-use-a-mount-point defenses in
initdb
.That defense works this simple fail-safe way, where one would be mounting an upper path (i.e.
$PGDATA/../.
) to makeinitdb
fail to initialize andpostgresql
fail to start - both due to a missingPGDATA
unless the upper directory is mounted with thePGDATA
present in it (be it empty or not).