96 lines
3.1 KiB
Bash
96 lines
3.1 KiB
Bash
|
|
#!/bin/bash
|
||
|
|
|
||
|
|
set -o errexit
|
||
|
|
set -o nounset
|
||
|
|
|
||
|
|
# This script will upgrade Postgres to the "current" version of Postgres, if needed.
|
||
|
|
|
||
|
|
# Assumptions:
|
||
|
|
# 1. Postgres is currently not running. The caller of this script ensures that _no_ version of Postgres server is currently running.
|
||
|
|
# 2. The newest version of Postgres we want to use, is already installed.
|
||
|
|
# 3. Postgres is installed via apt package manager only.
|
||
|
|
|
||
|
|
# Contract:
|
||
|
|
# 1. Don't install old version of Postgres, if it's already installed.
|
||
|
|
# 2. Use absolute paths to all Postgres executables, don't rely on any of them to be coming from "\$PATH".
|
||
|
|
# 3. Be idempotent across versions.
|
||
|
|
# 4. When we can't proceed due to any exceptional scenarios, communicate clearly.
|
||
|
|
# 5. Mark old/stale/deprecated data with a date, so it can be deleted with confidence later.
|
||
|
|
|
||
|
|
# Check if any Postgres server is running
|
||
|
|
if pgrep -x "postgres" > /dev/null; then
|
||
|
|
echo "Error: A Postgres server is currently running. Please stop it before proceeding with the upgrade."
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
postgres_path=/usr/lib/postgresql
|
||
|
|
|
||
|
|
pg_data_dir=/appsmith-stacks/data/postgres/main
|
||
|
|
|
||
|
|
old_version=""
|
||
|
|
if [[ -f "$pg_data_dir/PG_VERSION" ]]; then
|
||
|
|
old_version="$(cat "$pg_data_dir/PG_VERSION")"
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [[ -z "$old_version" ]]; then
|
||
|
|
tlog "No existing Postgres data found, not upgrading anything." >&2
|
||
|
|
exit
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [[ -f "$pg_data_dir/postmaster.pid" ]]; then
|
||
|
|
tlog "Previous Postgres was not shutdown cleanly. Please start and stop Postgres $old_version properly with 'supervisorctl' only." >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
top_available_version="$(postgres --version | grep -o '[[:digit:]]\+' | head -1)"
|
||
|
|
|
||
|
|
declare -a to_uninstall
|
||
|
|
to_uninstall=()
|
||
|
|
|
||
|
|
# 13 to 14
|
||
|
|
if [[ "$old_version" == 13 && "$top_available_version" > "$old_version" ]]; then
|
||
|
|
if [[ ! -e "$postgres_path/$old_version" ]]; then
|
||
|
|
apt-get update
|
||
|
|
apt-get install --yes "postgresql-$old_version"
|
||
|
|
to_uninstall+=("postgresql-$old_version")
|
||
|
|
fi
|
||
|
|
|
||
|
|
new_version="$((old_version + 1))"
|
||
|
|
new_data_dir="$pg_data_dir-$new_version"
|
||
|
|
|
||
|
|
# `pg_upgrade` writes log to current folder. So change to a temp folder first.
|
||
|
|
rm -rf "$TMP/pg_upgrade" "$new_data_dir"
|
||
|
|
mkdir -p "$TMP/pg_upgrade" "$new_data_dir"
|
||
|
|
chown -R postgres "$TMP/pg_upgrade" "$new_data_dir"
|
||
|
|
cd "$TMP/pg_upgrade"
|
||
|
|
|
||
|
|
# Required by the temporary Postgres server started by `pg_upgrade`.
|
||
|
|
chown postgres /etc/ssl/private/ssl-cert-snakeoil.key
|
||
|
|
chmod 0600 /etc/ssl/private/ssl-cert-snakeoil.key
|
||
|
|
|
||
|
|
su postgres --command "
|
||
|
|
set -o errexit
|
||
|
|
set -o xtrace
|
||
|
|
'$postgres_path/$new_version/bin/initdb' --pgdata='$new_data_dir'
|
||
|
|
'$postgres_path/$new_version/bin/pg_upgrade' \
|
||
|
|
--old-datadir='$pg_data_dir' \
|
||
|
|
--new-datadir='$new_data_dir' \
|
||
|
|
--old-bindir='$postgres_path/$old_version/bin' \
|
||
|
|
--new-bindir='$postgres_path/$new_version/bin'
|
||
|
|
"
|
||
|
|
|
||
|
|
date -u '+%FT%T.%3NZ' > "$pg_data_dir/deprecated-on.txt"
|
||
|
|
mv -v "$pg_data_dir" "$pg_data_dir-$old_version"
|
||
|
|
mv -v "$new_data_dir" "$pg_data_dir"
|
||
|
|
|
||
|
|
# Dangerous generated script that deletes the now updated data folder.
|
||
|
|
rm -fv "$TMP/pg_upgrade/delete_old_cluster.sh"
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [[ -n "${#to_uninstall[@]}" ]]; then
|
||
|
|
apt-get purge "${to_uninstall[@]}"
|
||
|
|
apt-get clean
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo "== Fin =="
|