9 changed files with 217 additions and 6 deletions
@ -1,2 +1,8 @@ |
|||||
PARENT_DIR := .. |
PARENT_DIR := .. |
||||
include $(PARENT_DIR)/Makefile |
include $(PARENT_DIR)/Makefile |
||||
|
|
||||
|
.PHONY: test |
||||
|
|
||||
|
test: uninstall clean install |
||||
|
@echo "Running Nginx tests..." |
||||
|
curl -sSfL -I http://localhost/ |
||||
|
|||||
@ -1,2 +1,39 @@ |
|||||
PARENT_DIR := .. |
PARENT_DIR := .. |
||||
include $(PARENT_DIR)/Makefile |
include $(PARENT_DIR)/Makefile |
||||
|
|
||||
|
.PHONY: test test-set-pgmajor |
||||
|
|
||||
|
PG_MAJOR_START ?= 14 |
||||
|
PG_MAJOR_LAST ?= 18 |
||||
|
test-set-pgmajor: |
||||
|
sed -i 's/^PG_MAJOR=.*/PG_MAJOR=$(PG_MAJOR_START)/' config/config.env |
||||
|
|
||||
|
test: uninstall clean test-set-pgmajor install |
||||
|
@echo "Running PostgreSQL integration tests..."; \
|
||||
|
set -Eeuo pipefail; \
|
||||
|
sleep 2; \
|
||||
|
echo "Creating a test database and a witness table..."; \
|
||||
|
podman exec postgresql-server su postgres -c "createdb test"; \
|
||||
|
podman exec postgresql-server su postgres -c "psql -U postgres -d test -c \"CREATE TABLE witness (id SERIAL PRIMARY KEY, version VARCHAR); INSERT INTO witness (version) SELECT version();\""; \
|
||||
|
podman exec postgresql-server su postgres -c "psql -U postgres -d test -c \"SELECT * FROM witness;\""; \
|
||||
|
for (( ver=$(PG_MAJOR_START); ver<$(PG_MAJOR_LAST); ver++ )); do \
|
||||
|
echo "Running a backup..."; \
|
||||
|
nextver=$$(($$ver + 1)); \
|
||||
|
systemctl start postgresql-backup.service; \
|
||||
|
systemctl stop postgresql.target; \
|
||||
|
sleep 1; \
|
||||
|
rm -rf /var/lib/quadlets/postgresql/{$$ver,$$nextver,data,latest,.initialized}; \
|
||||
|
echo "Restoring the backup to PostgreSQL $$ver..."; \
|
||||
|
systemctl start postgresql.target; \
|
||||
|
sleep 2; \
|
||||
|
podman exec postgresql-server su postgres -c "psql -U postgres -d test -c \"SELECT * FROM witness;\""; \
|
||||
|
echo "Testing upgrade from PostgreSQL $$ver to $$nextver..."; \
|
||||
|
systemctl stop postgresql.target; \
|
||||
|
sed -i "s/^PG_MAJOR=.*/PG_MAJOR=$$nextver/" /etc/quadlets/postgresql/config.env; \
|
||||
|
systemctl start postgresql.target; \
|
||||
|
sleep 2; \
|
||||
|
echo "Inserting line into the witness table..."; \
|
||||
|
podman exec postgresql-server su postgres -c "psql -U postgres -d test -c \"INSERT INTO witness (version) SELECT version();\""; \
|
||||
|
done; \
|
||||
|
podman exec postgresql-server su postgres -c "psql -U postgres -d test -c \"SELECT * FROM witness;\""; \
|
||||
|
echo "PostgreSQL upgrade tests completed." |
||||
|
|||||
@ -0,0 +1,149 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
set -Eeuo pipefail |
||||
|
|
||||
|
# Find the latest PostgreSQL data directory |
||||
|
SOURCE_PGDATA="" |
||||
|
last_version="" |
||||
|
for version_file in /var/lib/postgresql/*/docker/PG_VERSION; do |
||||
|
if [ -f "$version_file" ]; then |
||||
|
version_dir=$(dirname "$version_file") |
||||
|
version_major=$(cat "$version_file") |
||||
|
if [ -z "$last_version" ] || [ "$version_major" -gt "$last_version" ]; then |
||||
|
last_version="$version_major" |
||||
|
SOURCE_PGDATA="$version_dir" |
||||
|
fi |
||||
|
fi |
||||
|
done |
||||
|
if [ -z "$SOURCE_PGDATA" ] || [ ! -d "$SOURCE_PGDATA" ]; then |
||||
|
echo "No PostgreSQL data directory found." |
||||
|
exit 1 |
||||
|
fi |
||||
|
echo "Using PostgreSQL data directory: $SOURCE_PGDATA" |
||||
|
|
||||
|
# Upgrade destination |
||||
|
TARGET_MAJOR_VERSION=${PGTARGET%%.*} |
||||
|
TARGET_PATH="/usr/local/bin/" |
||||
|
TARGET_PGDATA="/var/lib/postgresql/${TARGET_MAJOR_VERSION}/docker" |
||||
|
|
||||
|
# Upgrade source |
||||
|
SOURCE_MAJOR_VERSION=$(cat "${SOURCE_PGDATA}/PG_VERSION") |
||||
|
SOURCE_PATH="/usr/local-pg${SOURCE_MAJOR_VERSION}/bin" |
||||
|
|
||||
|
# Reuse functions from the official entrypoint script |
||||
|
source /usr/local/bin/postgres-docker-entrypoint.sh |
||||
|
|
||||
|
# Because they may have been over by the sourced script, reset all flags |
||||
|
set -Eeuo pipefail |
||||
|
|
||||
|
# if first arg looks like a flag, assume we want to run postgres server |
||||
|
if [ "$#" -eq 0 ] || [ "${1:0:1}" = '-' ]; then |
||||
|
set -- postgres "$@" |
||||
|
fi |
||||
|
|
||||
|
# Setup environment variables |
||||
|
docker_setup_env |
||||
|
|
||||
|
## |
||||
|
## Sanity checks |
||||
|
## |
||||
|
|
||||
|
# No need to upgrade if same major version |
||||
|
if [ "${SOURCE_MAJOR_VERSION}" == "${TARGET_MAJOR_VERSION}" ]; then |
||||
|
echo "PostgreSQL data files version matches target version. No upgrade required." |
||||
|
exit 0 |
||||
|
fi |
||||
|
# No automatic upgrade support for PostgreSQL versions less than 14 |
||||
|
if [ "${SOURCE_MAJOR_VERSION}" -lt 14 ]; then |
||||
|
echo "PosgreSQL <14 is no longer supported for automatic upgrade. Please perform a manual upgrade." |
||||
|
exit 1 |
||||
|
fi |
||||
|
# No downgrade support |
||||
|
if [ "${SOURCE_MAJOR_VERSION}" -gt "${TARGET_MAJOR_VERSION}" ]; then |
||||
|
echo "Downgrades are not supported. Aborting." |
||||
|
exit 1 |
||||
|
fi |
||||
|
# Check for concurrent upgrade processes |
||||
|
if [ -f "${SOURCE_PGDATA}/upgrade_in_progress.lock" ]; then |
||||
|
echo "Another upgrade process seems to be running (upgrade_in_progress.lock file found). Aborting." |
||||
|
exit 2 |
||||
|
fi |
||||
|
|
||||
|
# On PG v18, we have to check that data checksums, be it positive or negative, is set on the initdb args |
||||
|
# even when the user already provided initdb args, because otherwise Postgres v18 assumes you want checksums |
||||
|
# we now do this on every version to avoid one more conditional |
||||
|
# it also adds support for people who used Postgres with checksums before v18 |
||||
|
if [[ -z "${POSTGRES_INITDB_ARGS:-}" || "${POSTGRES_INITDB_ARGS:-}" != *"data-checksums"* ]]; then |
||||
|
DATA_CHECKSUMS_ENABLED=$(echo 'SHOW DATA_CHECKSUMS' | "${SOURCE_PATH}/postgres" --single "${@:2}" -D "${SOURCE_PGDATA}" "${POSTGRES_DB}" | grep 'data_checksums = "' | cut -d '"' -f 2) |
||||
|
|
||||
|
if [ "$DATA_CHECKSUMS_ENABLED" == "on" ]; then |
||||
|
DATA_CHECKSUMS_PARAMETER="--data-checksums" |
||||
|
elif [ "$TARGET_MAJOR_VERSION" -eq 18 ]; then |
||||
|
# Postgres v18 enables data checksums by default and is the only version with this opt-out parameter |
||||
|
DATA_CHECKSUMS_PARAMETER="--no-data-checksums" |
||||
|
fi |
||||
|
POSTGRES_INITDB_ARGS="${POSTGRES_INITDB_ARGS:-} ${DATA_CHECKSUMS_PARAMETER:-}" |
||||
|
fi |
||||
|
|
||||
|
# Flags the data directory as being in the middle of an upgrade |
||||
|
mkdir -p "${TARGET_PGDATA}" |
||||
|
touch "${SOURCE_PGDATA}/upgrade_in_progress.lock" |
||||
|
|
||||
|
# Now PGDATA points to the target data directory |
||||
|
export PGDATA="${TARGET_PGDATA}" |
||||
|
|
||||
|
# Initialize target data directory |
||||
|
docker_verify_minimum_env |
||||
|
docker_init_database_dir |
||||
|
|
||||
|
# Change into the PostgreSQL database directory, to avoid a pg_upgrade error about write permissions |
||||
|
cd "${PGDATA}" |
||||
|
|
||||
|
# Perform the upgrade |
||||
|
echo "Upgrading PostgreSQL from version ${SOURCE_MAJOR_VERSION} to ${TARGET_MAJOR_VERSION}..." |
||||
|
"${TARGET_PATH}/pg_upgrade" --username="${POSTGRES_USER}" --link \ |
||||
|
--old-datadir "${SOURCE_PGDATA}" --new-datadir "${TARGET_PGDATA}" \ |
||||
|
--old-bindir "${SOURCE_PATH}" --new-bindir "${TARGET_PATH}" \ |
||||
|
--socketdir="/var/run/postgresql" \ |
||||
|
--old-options "${run_options[*]}" --new-options "${run_options[*]}" |
||||
|
|
||||
|
# Re-use the pg_hba.conf and pg_ident.conf from the old data directory |
||||
|
cp -f "${SOURCE_PGDATA}/pg_hba.conf" "${SOURCE_PGDATA}/pg_ident.conf" "${TARGET_PGDATA}" |
||||
|
|
||||
|
# Set PGPASSWORD in case password authentication is used |
||||
|
if [ -z "${PGPASSWORD:-}" ] && [ -n "${POSTGRES_PASSWORD:-}" ]; then |
||||
|
export PGPASSWORD="${POSTGRES_PASSWORD}" |
||||
|
fi |
||||
|
|
||||
|
# Start a temporary PostgreSQL server |
||||
|
docker_temp_server_start "$@" |
||||
|
|
||||
|
if [ -n "${POSTGRES_UPDATE_SCRIPT:-}" ] && [ -f "${POSTGRES_UPDATE_SCRIPT}" ]; then |
||||
|
echo "Running update script: ${POSTGRES_UPDATE_SCRIPT}" |
||||
|
psql --username="${POSTGRES_USER}" -f "${POSTGRES_UPDATE_SCRIPT}" |
||||
|
fi |
||||
|
|
||||
|
echo "Updating query planner stats" |
||||
|
declare -a database_list=( $(echo 'SELECT datname FROM pg_catalog.pg_database WHERE datistemplate IS FALSE' | psql --username="${POSTGRES_USER}" -1t --csv "${POSTGRES_DB}") ) |
||||
|
for database in "${database_list[@]}"; do |
||||
|
echo "VACUUM (ANALYZE, VERBOSE, INDEX_CLEANUP FALSE)" | psql --username="${POSTGRES_USER}" -t --csv "${database}" |
||||
|
done |
||||
|
|
||||
|
if [[ "${PGAUTO_REINDEX:-}" != "no" ]]; then |
||||
|
echo "Reindexing the databases" |
||||
|
|
||||
|
if [[ "$TARGET_MAJOR_VERSION" -le 15 ]]; then |
||||
|
reindexdb --all --username="${POSTGRES_USER}" |
||||
|
else |
||||
|
reindexdb --all --concurrently --username="${POSTGRES_USER}" |
||||
|
fi |
||||
|
echo "End of reindexing the databases" |
||||
|
fi |
||||
|
|
||||
|
# Stop the temporary PostgreSQL server |
||||
|
unset PGPASSWORD |
||||
|
docker_temp_server_stop |
||||
|
|
||||
|
# Clean up lock files |
||||
|
rm -f "${SOURCE_PGDATA}/upgrade_in_progress.lock" |
||||
|
echo "PostgreSQL upgrade from version ${SOURCE_MAJOR_VERSION} to ${TARGET_MAJOR_VERSION} completed successfully." |
||||
Loading…
Reference in new issue