33# pg_upgrade: update a database without needing a full dump/reload cycle.
44# CAUTION: read the manual page before trying to use this!
55
6- # $Header: /cvsroot/pgsql/src/bin/pg_dump/Attic/pg_upgrade,v 1.23 2002/01/1100:27:42 momjian Exp $
6+ # $Header: /cvsroot/pgsql/src/bin/pg_dump/Attic/pg_upgrade,v 1.24 2002/01/1104:39:19 momjian Exp $
77#
88# NOTE: we must be sure to update the version-checking code a few dozen lines
99# below for each new PostgreSQL release.
@@ -13,7 +13,6 @@ TMPFILE="/tmp/pgupgrade.$$"
1313trap " rm -f$TMPFILE " 0 1 2 3 15
1414
1515SCHEMA=" "
16- DATA=" "
1716while [" $# " -gt 1 ]
1817do
1918if [" X$1 " = " X-s" ]
2322exit 1
2423fi
2524shift 2
26- elif [" X$1 " = " X-d" ]
27- then DATA=" $2 "
28- if [! -s " $DATA " ]
29- then echo " $DATA does not exist" 1>&2
30- exit 1
31- fi
32- shift 2
33- else echo " Usage:$0 -s schema_dump [ -d data_dump ] old_data_dir" 1>&2
25+ else echo " Usage:$0 -s schema_dump old_data_dir" 1>&2
3426exit 1
3527fi
3628done
3729
3830if [" $# " -ne 1-o ! " $SCHEMA " ]
39- then echo " Usage:$0 -s schema_dump[ -d data_dump ] old_data_dir" 1>&2
31+ then echo " Usage:$0 -s schema_dump old_data_dir" 1>&2
4032exit 1
4133fi
4234
@@ -86,21 +78,6 @@ SRC_VERSION=`cat ./$OLDDIR/PG_VERSION`
8678# UPGRADE_VERSION is the expected output database version
8779UPGRADE_VERSION=" 7.1"
8880
89- if [" $SRC_VERSION " = " 7.1" -a ! " $DATA " ]
90- then echo " $0 requires a full data dump file to upgrade from version$SRC_VERSION ." 1>&2
91- echo " Use the '-d' parameter to specify the data dump file" 1>&2
92- echo " If you don't have enough disk space to keep a dump file, grep out the '\\ connect' and" 1>&2
93- echo " 'SELECT setval' lines from the dump file and pass that file to$0 , e.g:" 1>&2
94- echo 1>&2
95- echo " pg_dumpall | egrep '^(\\ connect)|SELECT setval \()[^]*$' > data.out" 1>&2
96- exit 1
97- fi
98-
99- if [" $SRC_VERSION " != " 7.1" -a " $DATA " ]
100- then echo " $0 does not require the -d option for this version." 1>&2
101- exit 1
102- fi
103-
10481if [" $DEST_VERSION " != " $UPGRADE_VERSION " -a " $DEST_VERSION " != " $SRC_VERSION " ]
10582then echo " ` basename$0 ` is for PostgreSQL version$UPGRADE_VERSION , but ./data/PG_VERSION contains$DEST_VERSION ." 1>&2
10683echo " 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"
134111exit 1
135112fi
136113
137- # We need a high XIDnumber so there is 1 gig gap in XID numbers so the
138- # moved-over rows can be frozen on next VACUUM .
114+ # If the XIDis > 2 billion, 7.1 database will have non-frozen XID's in
115+ # low numbers, and 7.2 will think they are in the future --- bad .
139116
140117XID=` pg_resetxlog -n" $OLDDIR " | grep" NextXID" | awk -F' *' ' {print $4}' `
141118if [" $SRC_VERSION " = " 7.1" -a " $XID " -gt 2000000000 ]
@@ -171,26 +148,11 @@ $0 aborted." 1>&2
171148exit 1
172149fi
173150
174- # Set sequence values for 7.1-version sequences, which are int4.
175- if [" $SRC_VERSION " != " 7.1" ]
176- then echo " Input script$SCHEMA complete, fixing row commit statuses..."
177- else echo " Input script$SCHEMA complete, setting int8 sequences..."
151+ echo " Input script$SCHEMA complete, fixing row commit statuses..."
178152
179- # Set all the sequence counters because they are not brought over
180- # in the schema dump.
181- cat$DATA | egrep' ^(\\connect)|SELECT setval \()[^]*$' |
182- psql" template1"
183- if [$? -ne 0 ]
184- then echo " There were errors in setting the sequence values.
185- $0 aborted." 1>&2
186- exit 1
187- fi
188-
189- echo " Int8 sequences set, fixing row commit statuses..."
190- fi
191-
192- # Now vacuum each result database in case our transaction increase
193- # causes all the XID's to be marked with the frozen XID.
153+ # XXX do we still need this?
154+ # Now vacuum each result database because our movement of transaction log
155+ # causes some committed transactions to appear as non-committed
194156
195157psql -d template1 -At -c" SELECT datname FROM pg_database" | while read DB
196158do
@@ -337,6 +299,82 @@ thenecho "Unable to restart database server.; exiting" 1>&2
337299exit 1
338300fi
339301
302+ # Set sequence values for 7.1-version sequences, which were int4.
303+ if [" $SRC_VERSION " = " 7.1" ]
304+ else echo " Set int8 sequence values from 7.1..."
305+
306+ psql -d template1 -At -c" SELECT datname FROM pg_database" |
307+ while read DB
308+ do
309+ echo " $DB "
310+ # XXX is concurrency a problem here?
311+ psql -d" $DB " -At -c" SELECT relname FROM pg_class where relkind = 'S';" |
312+ while read SEQUENCE
313+ do
314+ psql -d" $DB " -At<< SQL_END
315+
316+ -- This table matches the 7.1 sequence schema
317+ CREATE TABLE temp_seq_int4 (
318+ sequence_name name
319+ last_value integer
320+ increment_by integer
321+ max_value integer
322+ min_value integer
323+ cache_value integer
324+ log_cnt integer
325+ is_cycled "char"
326+ is_called "char"
327+ );
328+
329+ -- Move int8 version of sequence out of the way
330+ UPDATE pg_attribute
331+ SET attrelid = 1 -- OID of template1, not used anywhere else XXX correct?
332+ WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = '$SEQUENCE ');
333+
334+ -- Replace with int4 sequence schema
335+ UPDATE pg_attribute
336+ SET attrelid = (SELECT oid FROM pg_class WHERE relname = '$SEQUENCE ')
337+ WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'temp_seq_int4');
338+
339+ -- Select sequence value into temp table
340+ CREATE TEMP TABLE hold_sequence AS
341+ SELECT last_value
342+ FROM "$SEQUENCE "
343+
344+ -- Prepare int4 sequence table for removal and remove it
345+ UPDATE pg_attribute
346+ SET attrelid = (SELECT oid FROM pg_class WHERE relname = 'temp_seq_int4')
347+ WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = '$SEQUENCE ');
348+
349+ DROP TABLE temp_seq_int4;
350+
351+ -- Restore int8 version of sequence
352+ UPDATE pg_attribute
353+ SET attrelid = (SELECT oid FROM pg_class WHERE relname = '$SEQUENCE ')
354+ WHERE attrelid = 1;
355+
356+ -- Mark sequence as ordinary table and update it
357+ UPDATE pg_class
358+ SET relkind = 't'
359+ WHERE relname = '$SEQUENCE ';
360+
361+ UPDATE "$SEQUENCE "
362+ SET last_value = (SELECT last_value FROM hold_sequence);
363+
364+ -- Restore sequence flag
365+ UPDATE pg_class
366+ SET relkind = 'S'
367+ WHERE relname = '$SEQUENCE ';
368+
369+ SQL_END
370+ if [$? -ne 0 ]
371+ then echo " There were errors during int4 sequence restore.
372+ $0 aborted." 1>&2
373+ exit 1
374+ done
375+ done
376+ fi
377+
340378echo " You may remove the$OLDDIR directory with 'rm -r$OLDDIR '."
341379
342380exit 0