From 1261687c03de5f60eb2e558afeee133f69d67de7 Mon Sep 17 00:00:00 2001 From: sanchitpanchwtikar2023 <151662417+sanchitpanchwtikar2023@users.noreply.github.com> Date: Thu, 9 Apr 2026 01:32:25 +0530 Subject: [PATCH 1/2] fix: Add PostgreSQL collation refresh script for glibc updates Fixes #1138 When PostgreSQL minor patches are applied through container updates, the glibc library may also be updated. This can cause collation version mismatches that break queries. This commit adds an initialization script that automatically refreshes collation versions for all non-template databases when the container restarts. The script: - Only runs on existing databases (not new installations) - Checks which databases need collation refresh - Runs ALTER DATABASE REFRESH COLLATION VERSION on affected databases - Includes proper error handling and logging The script is mounted in the Docker Compose PostgreSQL service at /docker-entrypoint-initdb.d/ Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- deployment/Compose/compose/compose.yaml | 2 ++ .../setup/init-db/01-refresh-collations.sh | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 deployment/Compose/compose/setup/init-db/01-refresh-collations.sh diff --git a/deployment/Compose/compose/compose.yaml b/deployment/Compose/compose/compose.yaml index a516b67aca..ecbf2228b0 100644 --- a/deployment/Compose/compose/compose.yaml +++ b/deployment/Compose/compose/compose.yaml @@ -39,6 +39,8 @@ services: volumes: # Mounts the container's internal data directory to a named volume - ${SYS_DATA_DIR}/postgres:/var/lib/postgresql + # Mounts initialization scripts to refresh collations on container restart + - ./setup/init-db:/docker-entrypoint-initdb.d environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} diff --git a/deployment/Compose/compose/setup/init-db/01-refresh-collations.sh b/deployment/Compose/compose/setup/init-db/01-refresh-collations.sh new file mode 100644 index 0000000000..0bbac6eafd --- /dev/null +++ b/deployment/Compose/compose/setup/init-db/01-refresh-collations.sh @@ -0,0 +1,24 @@ +#!/bin/bash +set -e + +# Refresh collation versions for all non-template databases +# This fixes collation mismatches when glibc library is updated during PostgreSQL minor version upgrades +# Only run if not a new init (i.e., on container restart/upgrade) +if [ -f /var/lib/postgresql/data/PG_VERSION ]; then + echo "Checking and refreshing collation versions..." + + # Get list of databases that need collation refresh + su postgres -c "psql -d postgres -t -c \"SELECT datname FROM pg_database WHERE datname NOT IN ('template0','template1') AND EXISTS (SELECT 1 FROM pg_collation WHERE collversion <> pg_collation_actual_version COLLATE pg_catalog.default)\" 2>/dev/null" > /tmp/needs_refresh.txt || true + + # Run REFRESH for each DB that needs it + while read -r db; do + # Skip empty lines + if [ -z "$(echo "$db" | xargs)" ]; then + continue + fi + echo "Refreshing collation for database: $db" + su postgres -c "psql -d $db -c 'ALTER DATABASE $db REFRESH COLLATION VERSION'" + done < /tmp/needs_refresh.txt + + rm -f /tmp/needs_refresh.txt +fi From ed5101456e78be84fde615b4e1aae8deec08ad35 Mon Sep 17 00:00:00 2001 From: sanchitpanchwtikar2023 <151662417+sanchitpanchwtikar2023@users.noreply.github.com> Date: Thu, 9 Apr 2026 01:57:42 +0530 Subject: [PATCH 2/2] fix: Resolve PostgreSQL collation refresh issues - Fix docker-entrypoint-initdb.d limitation: Replace mounting init scripts in entrypoint-initdb.d (which only runs on fresh init) with a custom entrypoint wrapper that runs on every container start - Fix SQL syntax: pg_collation_actual_version() requires an OID argument, not a COLLATE clause. Use pg_collation_actual_version(oid) and add IS NOT NULL check for collversion - Improve error logging: Replace suppressed stderr with visible warning messages when collation check fails - Add proper shell quoting: Quote database name variable in psql commands and ALTER DATABASE statement to prevent injection attacks and handle special characters - Remove unnecessary su postgres calls: Script runs as postgres user through the entrypoint, so su is redundant Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- deployment/Compose/compose/compose.yaml | 3 +++ .../compose/setup/docker-entrypoint.sh | 19 +++++++++++++++++++ .../setup/init-db/01-refresh-collations.sh | 5 +++-- 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 deployment/Compose/compose/setup/docker-entrypoint.sh diff --git a/deployment/Compose/compose/compose.yaml b/deployment/Compose/compose/compose.yaml index ecbf2228b0..d3e96e6258 100644 --- a/deployment/Compose/compose/compose.yaml +++ b/deployment/Compose/compose/compose.yaml @@ -41,6 +41,9 @@ services: - ${SYS_DATA_DIR}/postgres:/var/lib/postgresql # Mounts initialization scripts to refresh collations on container restart - ./setup/init-db:/docker-entrypoint-initdb.d + # Custom entrypoint wrapper to execute init scripts on restart, not just init + - ./setup/docker-entrypoint.sh:/usr/local/bin/custom-entrypoint.sh + entrypoint: ["/usr/local/bin/custom-entrypoint.sh"] environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} diff --git a/deployment/Compose/compose/setup/docker-entrypoint.sh b/deployment/Compose/compose/setup/docker-entrypoint.sh new file mode 100644 index 0000000000..9ef42c53f0 --- /dev/null +++ b/deployment/Compose/compose/setup/docker-entrypoint.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -e + +# Custom entrypoint wrapper to run collation refresh before standard postgres entrypoint +# This ensures the refresh runs on container restart, not just initial setup + +# Run our custom initialization scripts +if [ -f /var/lib/postgresql/data/PG_VERSION ]; then + echo "Running custom initialization tasks..." + for script in /docker-entrypoint-initdb.d/*; do + if [ -f "$script" ] && [ -x "$script" ] && [[ "$script" == *.sh ]]; then + echo "Running $script" + "$script" + fi + done +fi + +# Invoke the original postgres entrypoint +exec /usr/local/bin/docker-entrypoint.sh "$@" diff --git a/deployment/Compose/compose/setup/init-db/01-refresh-collations.sh b/deployment/Compose/compose/setup/init-db/01-refresh-collations.sh index 0bbac6eafd..d1be8fb837 100644 --- a/deployment/Compose/compose/setup/init-db/01-refresh-collations.sh +++ b/deployment/Compose/compose/setup/init-db/01-refresh-collations.sh @@ -8,7 +8,7 @@ if [ -f /var/lib/postgresql/data/PG_VERSION ]; then echo "Checking and refreshing collation versions..." # Get list of databases that need collation refresh - su postgres -c "psql -d postgres -t -c \"SELECT datname FROM pg_database WHERE datname NOT IN ('template0','template1') AND EXISTS (SELECT 1 FROM pg_collation WHERE collversion <> pg_collation_actual_version COLLATE pg_catalog.default)\" 2>/dev/null" > /tmp/needs_refresh.txt || true + psql -d postgres -t -c "SELECT datname FROM pg_database WHERE datname NOT IN ('template0','template1') AND EXISTS (SELECT 1 FROM pg_collation WHERE collversion IS NOT NULL AND collversion <> pg_collation_actual_version(oid))" > /tmp/needs_refresh.txt 2>&1 || { echo "Warning: Could not check collation versions"; true; } # Run REFRESH for each DB that needs it while read -r db; do @@ -16,8 +16,9 @@ if [ -f /var/lib/postgresql/data/PG_VERSION ]; then if [ -z "$(echo "$db" | xargs)" ]; then continue fi + db=$(echo "$db" | xargs) # Trim whitespace echo "Refreshing collation for database: $db" - su postgres -c "psql -d $db -c 'ALTER DATABASE $db REFRESH COLLATION VERSION'" + psql -d "$db" -c "ALTER DATABASE \"$db\" REFRESH COLLATION VERSION" done < /tmp/needs_refresh.txt rm -f /tmp/needs_refresh.txt