Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically do post upgrade steps (vacuum analyze, database reindexing) #50

Merged
merged 4 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Dockerfile.alpine
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ARG PGTARGET=16
ARG PGTARGET=17

### Things we need in all build containers
FROM alpine:3.20 AS base-build
Expand Down Expand Up @@ -179,6 +179,9 @@ RUN apk update && \
# Pass the PG build target through to the running image
ENV PGTARGET=${PGTARGET}

# Copy across the post-upgrade shell script
COPY pgautoupgrade-postupgrade.sh /usr/local/bin/

# Set up the script run by the container when it starts
WORKDIR /var/lib/postgresql
COPY docker-entrypoint.sh /usr/local/bin/
Expand Down
5 changes: 4 additions & 1 deletion Dockerfile.bookworm
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ARG PGTARGET=16
ARG PGTARGET=17

### Things we need in all build containers
FROM debian:bookworm AS base-build
Expand Down Expand Up @@ -174,6 +174,9 @@ RUN apt update && \
# Pass the PG build target through to the running image
ENV PGTARGET=${PGTARGET}

# Copy across the post-upgrade shell script
COPY pgautoupgrade-postupgrade.sh /usr/local/bin/

# Set up the script run by the container when it starts
WORKDIR /var/lib/postgresql
COPY docker-entrypoint.sh /usr/local/bin/
Expand Down
21 changes: 14 additions & 7 deletions docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ _main() {

# For development of pgautoupgrade. This spot leaves the container running, prior to the pgautoupgrade scripting
# executing
local UPGRADE_PERFORMED=0
if [ "x${PGAUTO_DEVEL}" = "xbefore" ]; then
echo "---------------------------------------------------------------------------"
echo "In pgautoupgrade development mode, paused prior to pgautoupgrade scripting."
Expand Down Expand Up @@ -540,7 +541,7 @@ _main() {
echo "Running pg_upgrade command, from $(pwd)"
echo "---------------------------------------"
bin_path=$(get_bin_path)
${bin_path}/pg_upgrade --username="${POSTGRES_USER}" --link -d "${OLD}" -D "${NEW}" -b "${OLDPATH}/bin" -B "${bin_path}" --socketdir="/var/run/postgresql"
"${bin_path}/pg_upgrade" --username="${POSTGRES_USER}" --link -d "${OLD}" -D "${NEW}" -b "${OLDPATH}/bin" -B "${bin_path}" --socketdir="/var/run/postgresql"
echo "--------------------------------------"
echo "Running pg_upgrade command is complete"
echo "--------------------------------------"
Expand Down Expand Up @@ -572,6 +573,8 @@ _main() {
echo "Removing left over database files is complete"
echo "---------------------------------------------"

UPGRADE_PERFORMED=1

echo "**********************************************************"
echo "Automatic upgrade process finished with no errors reported"
echo "**********************************************************"
Expand All @@ -588,13 +591,17 @@ _main() {
sleep 5
done
else
if [ "x${PGAUTO_ONESHOT}" = "xyes" ]; then
echo "*****************************************************************************************************"
echo "'One shot' automatic upgrade was requested, so exiting now rather than starting the PostgreSQL server"
echo "*****************************************************************************************************"
else
exec "$@"
# If the upgrade process ran, then we need to launch the post-upgrade script in the background
if [ "${UPGRADE_PERFORMED}" -eq 1 ]; then
TIMESTAMP_NOW=$(date +'%Y.%m.%d-%H.%M')
echo "**********************************************************************************************************************"
/usr/local/bin/pgautoupgrade-postupgrade.sh "${PGDATA}" "${PGAUTO_ONESHOT}" 2>&1 | tee "${PGDATA}/${TIMESTAMP_NOW}-pgautoupgrade.log" &
echo "Post upgrade script launched, with output being saved to ${PGDATA}/${TIMESTAMP_NOW}-pgautoupgrade.log in the container"
justinclift marked this conversation as resolved.
Show resolved Hide resolved
echo "**********************************************************************************************************************"
fi

# Start PostgreSQL
exec "$@"
justinclift marked this conversation as resolved.
Show resolved Hide resolved
fi
}

Expand Down
87 changes: 87 additions & 0 deletions pgautoupgrade-postupgrade.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/usr/bin/env bash

set -e

if [ $# -ne 2 ]; then
echo "Required number of arguments not passed to post upgrade script. 2 expected, $# received"
exit 1
fi

PGDATA=$1
PGAUTO_ONESHOT=$2

# Wait for PostgreSQL to start and become available
COUNT=0
RUNNING=1
while [ $RUNNING -ne 0 ] && [ $COUNT -le 20 ]; do
# Check if PostgreSQL is running yet
echo "------ Checking if PostgreSQL is running, loop count ${COUNT} ------"
set +e
pg_isready -q
RUNNING=$?
set -e

if [ $RUNNING -eq 0 ]; then
echo "PostgreSQL is running. Post upgrade tasks will start shortly"
else
echo "PostgreSQL is not yet running, lets wait then try again..."
sleep 3
fi

COUNT=$((COUNT+1))
done

if [ $RUNNING -ne 0 ]; then
echo "PostgreSQL did not start before timeout expired"
exit 2
fi

# Get the list of databases in the database cluster
DB_LIST=$(echo 'SELECT datname FROM pg_catalog.pg_database WHERE datistemplate IS FALSE' | psql -1t --csv postgres)

# Update query planner statistics
echo "----------------------------"
echo "Updating query planner stats"
echo "----------------------------"

for DATABASE in ${DB_LIST}; do
echo "VACUUM (ANALYZE, VERBOSE, INDEX_CLEANUP FALSE)" | psql -t --csv "${DATABASE}"
done

echo "-------------------------------------"
echo "Finished updating query planner stats"
echo "-------------------------------------"

# Reindex the databases
echo "------------------------"
echo "Reindexing the databases"
echo "------------------------"

# For each database, reindex it
for DATABASE in ${DB_LIST}; do
echo "-------------------------------"
echo "Starting reindex of ${DATABASE}"
echo "-------------------------------"

echo 'REINDEX DATABASE CONCURRENTLY' | psql -t --csv "${DATABASE}"

echo "-------------------------------"
echo "Finished reindex of ${DATABASE}"
echo "-------------------------------"
done

echo "-------------------------------"
echo "End of reindexing the databases"
echo "-------------------------------"

# If "one shot" mode was requested, then shut down PostgreSQL
if [ "x${PGAUTO_ONESHOT}" = "xyes" ]; then
andyundso marked this conversation as resolved.
Show resolved Hide resolved
echo "****************************************************************************************************"
echo "'One shot' automatic upgrade was requested, so exiting now that the post upgrade tasks have finished"
echo "****************************************************************************************************"
pg_ctl stop -D "${PGDATA}"
else
echo "*************************************************************************************************"
echo "Post upgrade tasks have finished successfully. PostgreSQL should now be fully updated and usable"
echo "*************************************************************************************************"
fi