# pg_upgrade: update a database without needing a full dump/reload cycle.
# CAUTION: read the manual page before trying to use this!
-# $Header: /cvsroot/pgsql/src/bin/pg_dump/Attic/pg_upgrade,v 1.19 2002/01/09 16:08:54 momjian Exp $
+# $Header: /cvsroot/pgsql/src/bin/pg_dump/Attic/pg_upgrade,v 1.20 2002/01/09 21:50:52 momjian Exp $
#
# NOTE: we must be sure to update the version-checking code a few dozen lines
# below for each new PostgreSQL release.
trap "rm -f $TMPFILE" 0 1 2 3 15
-if [ "$#" -eq 0 ]
-then echo "Usage: $0 -f inputfile old_data_dir" 1>&2
- exit 1
-fi
-
-if [ "X$1" = "X-f" ]
-then INPUT="$2"
- shift 2
- if [ ! -f "$INPUT" ]
- then echo "$INPUT does not exist" 1>&2
+SCHEMA=""
+DATA=""
+while [ "$#" -gt 1 ]
+do
+ if [ "X$1" = "X-s" ]
+ then SCHEMA="$2"
+ if [ ! -s "$SCHEMA" ]
+ then echo "$SCHEMA does not exist" 1>&2
+ exit 1
+ fi
+ shift 2
+ elif [ "X$1" = "X-d" ]
+ then DATA="$2"
+ if [ ! -s "$DATA" ]
+ then echo "$DATA does not exist" 1>&2
+ exit 1
+ fi
+ shift 2
+ else echo "Usage: $0 -s schema_dump [ -d data_dump ] old_data_dir" 1>&2
exit 1
fi
-else echo "Usage: $0 -f inputfile old_data_dir" 1>&2
- exit 1
-fi
+done
-if [ "$#" -ne 1 ]
-then echo "Usage: $0 -f inputfile old_data_dir" 1>&2
+if [ "$#" -ne 1 -o ! "$SCHEMA" ]
+then echo "Usage: $0 -s schema_dump [ -d data_dump ] old_data_dir" 1>&2
exit 1
fi
# check things
if [ ! -d "./data" ]
-then echo "`basename $0` must be run from the directory containing
-the database directory \`data\' (`dirname $PGDATA`.)" 1>&2
+then echo "`basename $0` must be run from the directory containing the database directory \`data\' (`dirname $PGDATA`.)" 1>&2
echo "You must have run initdb to create the template1 database." 1>&2
exit 1
fi
# MYVERSION is the expected output database version
MYVERSION="7.1"
+if [ "$SRCVERSION" = "7.1" -a ! "$DATA" ]
+then echo "$0 requires a full data dump file to upgrade from version $SRCVERSION." 1>&2
+ echo "Use the '-d' parameter to specify the dump file" 1>&2
+ exit 1
+fi
+
if [ "$DESTVERSION" != "$MYVERSION" -a "$DESTVERSION" != "$SRCVERSION" ]
then echo "$0 is for PostgreSQL version $MYVERSION, but ./data/PG_VERSION contains $DESTVERSION." 1>&2
echo "Did you run initdb for version $MYVERSION?" 1>&2
# OK, ready to proceed.
-# Execute the input script to create everything, except that we remove
-# any COPY statements, except for the ones that load pg_shadow/pg_group.
-# There shouldn't be any others in there anyway...
-
-cat $INPUT | awk ' {
- if (tolower($1) == "copy" &&
- $2 != "pg_shadow" &&
- $2 != "pg_group")
- while (getline $0 > 0 && $0 != "\\.")
- ;
+# Execute the schema script to create everything, except modify any
+# sequences with int4 maximums if we are upgrading from 7.1.
+cat $SCHEMA | awk -F' ' '{
+ if ("'"$SRCVERSION"'" == "7.1" &&
+ $1 == "CREATE" &&
+ $2 == "SEQUENCE" &&
+ ($9 >= 2147483646 && # handle OS round
+ ($9 <= 2147483648))
+ {
+ for(i=1; i < NF; i++)
+ if (i != 9)
+ printf "%s ", $i;
+ else
+ printf "%s ", "9223372036854775807";
+ print;
+ }
else print $0;
- }' > $TMPFILE
-
-psql "template1" < $TMPFILE
+ }' |
+psql "template1"
if [ $? -ne 0 ]
-then echo "There were errors in the input script $INPUT.
+then echo "There were errors in the input script $SCHEMA.
$0 aborted." 1>&2
exit 1
fi
-echo "Input script $INPUT complete, fixing row commit statuses..."
-
-# Now vacuum each result database to mark all system-table rows as committed,
-# because when pg_clog is replaced with the saved version, the transaction
-# statuses will no longer match the data. VACUUM will force the on-row
-# status flags to the right value so that pg_clog will not matter anymore.
-# Note: we used to try to do this as part of the previous step, but that
-# risks permissions problems if VACUUM is run as the wrong user.
-# Note: the initial VACUUM does template1, then we do everything else.
-
-cat $INPUT | awk 'BEGIN { print "VACUUM;" }
- {
- if (tolower($1) == "copy")
- while (getline $0 > 0 && $0 != "\\.")
- ;
- else if (tolower($1) == "\\connect" &&
- $2 != "-" &&
- $2 != "template1")
- printf "\\connect %s\nVACUUM;\n", $2;
- }' > $TMPFILE
-
-psql "template1" < $TMPFILE
+
+if [ "$SRCVERSION" != "7.1" ]
+then echo "Input script $SCHEMA complete, fixing row commit statuses..."
+else echo "Input script $SCHEMA complete, setting int8 sequences..."
+
+# Set all the sequence counters because they are not brought over
+# in the schema dump, and the old 7.1 sequences where int4 in size
+# so bringing over the file wouldn't help us anyway.
+cat $DATA | awk '$0 == "\\connect " || "SELECT setval (" \
+ {print $0;}' |
+psql "template1"
if [ $? -ne 0 ]
-then echo "There were errors in the vacuuming step.
+then echo "There were errors in the input script $SCHEMA.
$0 aborted." 1>&2
exit 1
fi
+echo "Int8 sequences set, fixing row commit statuses..."
+fi
+
+# Now vacuum each result database in case our transaction increase
+# causes all the XID's to be marked with the frozen XID.
+psql -l | while read DB
+do
+ echo "VACUUM;" | psql "$DB"
+ if [ $? -ne 0 ]
+ then echo "There were errors during VACUUM.
+$0 aborted." 1>&2
+ exit 1
+ fi
+done
+
# should be pretty small file
pg_dumpall -s > $TMPFILE 2>/dev/null
echo "Commit fixes complete, moving data files..."
-cat "$INPUT" | while read LINE
+cat "$SCHEMA" | while read LINE
do
if /bin/echo "$LINE" | grep -q "^\\\\connect "
then OLDDB="$DB"
if echo "$LINE" | grep -q "^-- TOC Entry ID [0-9]* (OID "
then OID="`echo \"$LINE\" | cut -d' ' -f7 | tr -d ')'`"
fi
- if echo "$LINE" | grep -q "^-- Name: [^ ]* Type: TABLE "
+ if echo "$LINE" | egrep -q "^-- Name: [^ ]* Type: (TABLE|INDEX) "
then TABLE="`echo \"$LINE\" | cut -d' ' -f3`"
# skip system tables
if [ "`echo \"$TABLE\" | cut -c 1-3`" = "pg_" ]
{print $0 >> "/tmp/x";
print $3 >> "/tmp/x";
print newdb," ", newoid >> "/tmp/x"}
- $0 ~ /^-- Name: [^ ]* Type: TABLE / && \
+ ($0 ~ /^-- Name: [^ ]* Type: TABLE / && \
+ $0 ~ /^-- Name: [^ ]* Type: INDEX /) && \
newdb == "'"$DB"'" && \
$3 == "'"$TABLE"'" \
{ ret=newoid; exit}
fi
done
+# set max transaction id, check < 2gig
+
+# 7.1 has non-compressed log file format
+if [ "$SRCVERSION" = "7.1" ]
+# pg_log is oid 1269 in 7.1
+LOGSIZE=`ls -l "$OLDDIR"/global/1269 "$OLDDIR"/global/1269.* 2>/dev/null |
+awk -F' *' '
+ BEGIN {sum=0;}
+ {sum += $5;}
+ END {print sum;}'`
+fi
+
echo "You must stop/start the postmaster before doing anything else."
echo "You may remove the $OLDDIR directory with 'rm -r $OLDDIR'."