#!/bin/bash # upgrade-check.sh MODE OLD NEW # Do TOAST values written by an unpatched server read the same with the # patched one? OLD and NEW are install prefixes (directories holding bin/). # Reads go through toast-oracle.sh.txt, expected next to this script. # same : fill a cluster with OLD, read it with OLD, then start the same # data directory with NEW and read it again (only when the # catalog version is the same, as in this series) # upgrade : fill with OLD, read with OLD, pg_upgrade --copy to NEW, read # with NEW; then write zstd values next to the old ones and run # verify_heapam(check_toast => true) on every table # Prints "identical" or the diff. Under "upgrade" the logical slot is not # made (pg_upgrade refuses a slot with pending changes), so the decoding # lines are absent from both sides. set -eu MODE=$1; OLD=$2; NEW=$3 H=$(cd "$(dirname "$0")" && pwd); O="bash $H/toast-oracle.sh.txt" export ASAN_OPTIONS=detect_leaks=0 D=$(mktemp -d ${TMPDIR:-/tmp}/upg.XXXXXX) trap 'rm -rf $D' EXIT same() { if cmp -s "$1" "$2"; then echo " $3: identical ($(wc -l < $2) lines)" else echo " $3: DIFFERS"; diff "$1" "$2" | head -20; fi; } case $MODE in same) $O $OLD $D/old.txt fill $D/c > /dev/null $O $OLD $D/old.txt read $D/c > /dev/null $O $NEW $D/new.txt read $D/c > /dev/null same $D/old.txt $D/new.txt "written by $($OLD/bin/postgres --version | cut -d' ' -f3), read by the new build" ;; upgrade) NOSLOT=1 $O $OLD $D/old.txt fill $D/c > /dev/null NOSLOT=1 $O $OLD $D/old.txt read $D/c > /dev/null "$NEW/bin/initdb" -D $D/new -A trust --no-sync --no-data-checksums -U postgres -E UTF8 --locale=C > /dev/null printf 'autovacuum = off\nwal_level = logical\nmax_replication_slots = 4\n' >> $D/new/postgresql.conf PO=$((61000 + RANDOM % 900)) (cd $D && "$NEW/bin/pg_upgrade" -b $OLD/bin -B $NEW/bin -d $D/c/data -D $D/new -p $PO -P $((PO + 1)) \ -s $D -U postgres --copy > $D/upgrade.out 2>&1) || { echo "pg_upgrade failed"; tail -20 $D/upgrade.out; exit 1; } rm -rf $D/c/data; mv $D/new $D/c/data NOSLOT=1 $O $NEW $D/new.txt read $D/c > /dev/null same $D/old.txt $D/new.txt "$($OLD/bin/postgres --version | cut -d' ' -f3) after pg_upgrade" P=$((61000 + RANDOM % 900)) "$NEW/bin/pg_ctl" -D $D/c/data -l $D/log -w -o "-p $P -k $D -c listen_addresses=''" start > /dev/null "$NEW/bin/psql" -X -qAt -h $D -p $P -U postgres -d postgres -v ON_ERROR_STOP=1 <<'SQL' ALTER TABLE c ALTER tp SET COMPRESSION zstd; INSERT INTO c (kind, n, tp, tl) SELECT 'new-zstd', n, soft(n + 9, n), soft(n + 10, n) FROM sizes; SELECT ' methods now in c.tp: ' || string_agg(DISTINCT coalesce(pg_column_compression(tp), 'none'), ', ') || '; verify_heapam rows: ' || ((SELECT count(*) FROM verify_heapam('c', check_toast => true)) + (SELECT count(*) FROM verify_heapam('u', check_toast => true)) + (SELECT count(*) FROM verify_heapam('m', check_toast => true))) || '; new values read back: ' || (SELECT bool_and(tp = soft(n + 9, n)) FROM c WHERE kind = 'new-zstd') FROM c; SQL "$NEW/bin/pg_ctl" -D $D/c/data -m fast -w stop > /dev/null ;; esac