Handle int4-int8 sequence migration without full data dump.

This commit is contained in:
Bruce Momjian 2002-01-11 04:39:19 +00:00
parent f43b5de649
commit 6bd45e5264
2 changed files with 101 additions and 60 deletions

View File

@ -1,5 +1,5 @@
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/Attic/pg_upgrade.sgml,v 1.15 2002/01/10 04:58:19 momjian Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/Attic/pg_upgrade.sgml,v 1.16 2002/01/11 04:39:19 momjian Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
@ -24,7 +24,7 @@ PostgreSQL documentation
<date>1999-07-31</date> <date>1999-07-31</date>
</refsynopsisdivinfo> </refsynopsisdivinfo>
<synopsis> <synopsis>
pg_upgrade -s <replaceable class="parameter">filename</replaceable> [ -d <replaceable class="parameter">filename</replaceable> ] <replaceable class="parameter">old_data_dir</replaceable> pg_upgrade -s <replaceable class="parameter">filename</replaceable> <replaceable class="parameter">old_data_dir</replaceable>
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
@ -50,10 +50,14 @@ pg_upgrade -s <replaceable class="parameter">filename</replaceable> [ -d <replac
<step performance="required"> <step performance="required">
<para> <para>
Back up your existing data directory, preferably by making a Back up your existing data directory, preferably by making a
complete dump with pg_dumpall. Those upgrading from 7.1 are complete dump with pg_dumpall.
required to supply this dump filename to pg_upgrade with the </para>
<option>-d</option> option. Other releases should not use the </step>
<option>-d</option> option.
<step performance="required">
<para>
<command>VACUUM</command> your entire database using
<command>vacuumdb -a</command.>
</para> </para>
</step> </step>
@ -111,7 +115,7 @@ $ make install
Change your working directory to the Change your working directory to the
pgsql main directory, and type: pgsql main directory, and type:
<programlisting> <programlisting>
$ pg_upgrade -s schema.out -d data.out data.old $ pg_upgrade -s schema.out data.old
</programlisting> </programlisting>
The program will do some checking to make sure everything is properly The program will do some checking to make sure everything is properly
configured, and will run your db.out script to recreate all the databases configured, and will run your db.out script to recreate all the databases
@ -130,12 +134,6 @@ $ pg_upgrade -s schema.out -d data.out data.old
</para> </para>
</step> </step>
<step performance="required">
<para>
Stop and restart the postmaster.
</para>
</step>
<step performance="required"> <step performance="required">
<para> <para>
<emphasis>Carefully</emphasis> examine the contents of the upgraded <emphasis>Carefully</emphasis> examine the contents of the upgraded
@ -154,6 +152,11 @@ $ pg_upgrade -s schema.out -d data.out data.old
</para> </para>
</step> </step>
<note>
<para>
pg_upgrade does not migrate large objects.
</para>
</note>
</procedure> </procedure>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -3,7 +3,7 @@
# pg_upgrade: update a database without needing a full dump/reload cycle. # pg_upgrade: update a database without needing a full dump/reload cycle.
# CAUTION: read the manual page before trying to use this! # CAUTION: read the manual page before trying to use this!
# $Header: /cvsroot/pgsql/src/bin/pg_dump/Attic/pg_upgrade,v 1.23 2002/01/11 00:27:42 momjian Exp $ # $Header: /cvsroot/pgsql/src/bin/pg_dump/Attic/pg_upgrade,v 1.24 2002/01/11 04:39:19 momjian Exp $
# #
# NOTE: we must be sure to update the version-checking code a few dozen lines # NOTE: we must be sure to update the version-checking code a few dozen lines
# below for each new PostgreSQL release. # below for each new PostgreSQL release.
@ -13,7 +13,6 @@ TMPFILE="/tmp/pgupgrade.$$"
trap "rm -f $TMPFILE" 0 1 2 3 15 trap "rm -f $TMPFILE" 0 1 2 3 15
SCHEMA="" SCHEMA=""
DATA=""
while [ "$#" -gt 1 ] while [ "$#" -gt 1 ]
do do
if [ "X$1" = "X-s" ] if [ "X$1" = "X-s" ]
@ -23,20 +22,13 @@ do
exit 1 exit 1
fi fi
shift 2 shift 2
elif [ "X$1" = "X-d" ] else echo "Usage: $0 -s schema_dump old_data_dir" 1>&2
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 exit 1
fi fi
done done
if [ "$#" -ne 1 -o ! "$SCHEMA" ] if [ "$#" -ne 1 -o ! "$SCHEMA" ]
then echo "Usage: $0 -s schema_dump [ -d data_dump ] old_data_dir" 1>&2 then echo "Usage: $0 -s schema_dump old_data_dir" 1>&2
exit 1 exit 1
fi fi
@ -86,21 +78,6 @@ SRC_VERSION=`cat ./$OLDDIR/PG_VERSION`
# UPGRADE_VERSION is the expected output database version # UPGRADE_VERSION is the expected output database version
UPGRADE_VERSION="7.1" UPGRADE_VERSION="7.1"
if [ "$SRC_VERSION" = "7.1" -a ! "$DATA" ]
then echo "$0 requires a full data dump file to upgrade from version $SRC_VERSION." 1>&2
echo "Use the '-d' parameter to specify the data dump file" 1>&2
echo "If you don't have enough disk space to keep a dump file, grep out the '\\connect' and" 1>&2
echo "'SELECT setval' lines from the dump file and pass that file to $0, e.g:" 1>&2
echo 1>&2
echo " pg_dumpall | egrep '^(\\connect)|SELECT setval \()[^ ]*$' > data.out" 1>&2
exit 1
fi
if [ "$SRC_VERSION" != "7.1" -a "$DATA" ]
then echo "$0 does not require the -d option for this version." 1>&2
exit 1
fi
if [ "$DEST_VERSION" != "$UPGRADE_VERSION" -a "$DEST_VERSION" != "$SRC_VERSION" ] if [ "$DEST_VERSION" != "$UPGRADE_VERSION" -a "$DEST_VERSION" != "$SRC_VERSION" ]
then echo "`basename $0` is for PostgreSQL version $UPGRADE_VERSION, but ./data/PG_VERSION contains $DEST_VERSION." 1>&2 then echo "`basename $0` is for PostgreSQL version $UPGRADE_VERSION, but ./data/PG_VERSION contains $DEST_VERSION." 1>&2
echo "Did you run initdb for version $UPGRADE_VERSION?" 1>&2 echo "Did you run initdb for version $UPGRADE_VERSION?" 1>&2
@ -134,8 +111,8 @@ Install a newer version from pgsql/contrib/pg_resetxlog and continue.; exiting"
exit 1 exit 1
fi fi
# We need a high XID number so there is 1 gig gap in XID numbers so the # If the XID is > 2 billion, 7.1 database will have non-frozen XID's in
# moved-over rows can be frozen on next VACUUM. # low numbers, and 7.2 will think they are in the future --- bad.
XID=`pg_resetxlog -n "$OLDDIR" | grep "NextXID" | awk -F' *' '{print $4}'` XID=`pg_resetxlog -n "$OLDDIR" | grep "NextXID" | awk -F' *' '{print $4}'`
if [ "$SRC_VERSION" = "7.1" -a "$XID" -gt 2000000000 ] if [ "$SRC_VERSION" = "7.1" -a "$XID" -gt 2000000000 ]
@ -171,26 +148,11 @@ $0 aborted." 1>&2
exit 1 exit 1
fi fi
# Set sequence values for 7.1-version sequences, which are int4. echo "Input script $SCHEMA complete, fixing row commit statuses..."
if [ "$SRC_VERSION" != "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 # XXX do we still need this?
# in the schema dump. # Now vacuum each result database because our movement of transaction log
cat $DATA | egrep '^(\\connect)|SELECT setval \()[^ ]*$' | # causes some committed transactions to appear as non-committed
psql "template1"
if [ $? -ne 0 ]
then echo "There were errors in setting the sequence values.
$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 -d template1 -At -c "SELECT datname FROM pg_database" | while read DB psql -d template1 -At -c "SELECT datname FROM pg_database" | while read DB
do do
@ -337,6 +299,82 @@ then echo "Unable to restart database server.; exiting" 1>&2
exit 1 exit 1
fi fi
# Set sequence values for 7.1-version sequences, which were int4.
if [ "$SRC_VERSION" = "7.1" ]
else echo "Set int8 sequence values from 7.1..."
psql -d template1 -At -c "SELECT datname FROM pg_database" |
while read DB
do
echo "$DB"
# XXX is concurrency a problem here?
psql -d "$DB" -At -c "SELECT relname FROM pg_class where relkind = 'S';" |
while read SEQUENCE
do
psql -d "$DB" -At <<SQL_END
-- This table matches the 7.1 sequence schema
CREATE TABLE temp_seq_int4 (
sequence_name name
last_value integer
increment_by integer
max_value integer
min_value integer
cache_value integer
log_cnt integer
is_cycled "char"
is_called "char"
);
-- Move int8 version of sequence out of the way
UPDATE pg_attribute
SET attrelid = 1 -- OID of template1, not used anywhere else XXX correct?
WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = '$SEQUENCE');
-- Replace with int4 sequence schema
UPDATE pg_attribute
SET attrelid = (SELECT oid FROM pg_class WHERE relname = '$SEQUENCE')
WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'temp_seq_int4');
-- Select sequence value into temp table
CREATE TEMP TABLE hold_sequence AS
SELECT last_value
FROM "$SEQUENCE"
-- Prepare int4 sequence table for removal and remove it
UPDATE pg_attribute
SET attrelid = (SELECT oid FROM pg_class WHERE relname = 'temp_seq_int4')
WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = '$SEQUENCE');
DROP TABLE temp_seq_int4;
-- Restore int8 version of sequence
UPDATE pg_attribute
SET attrelid = (SELECT oid FROM pg_class WHERE relname = '$SEQUENCE')
WHERE attrelid = 1;
-- Mark sequence as ordinary table and update it
UPDATE pg_class
SET relkind = 't'
WHERE relname = '$SEQUENCE';
UPDATE "$SEQUENCE"
SET last_value = (SELECT last_value FROM hold_sequence);
-- Restore sequence flag
UPDATE pg_class
SET relkind = 'S'
WHERE relname = '$SEQUENCE';
SQL_END
if [ $? -ne 0 ]
then echo "There were errors during int4 sequence restore.
$0 aborted." 1>&2
exit 1
done
done
fi
echo "You may remove the $OLDDIR directory with 'rm -r $OLDDIR'." echo "You may remove the $OLDDIR directory with 'rm -r $OLDDIR'."
exit 0 exit 0