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.21 2002/01/1003:05:48 momjian Exp $
6+ # $Header: /cvsroot/pgsql/src/bin/pg_dump/Attic/pg_upgrade,v 1.22 2002/01/1004:58: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.
@@ -77,51 +77,60 @@ thenecho "Cannot read ./$OLDDIR/PG_VERSION --- something is wrong." 1>&2
7777fi
7878
7979# Get the actual versions seen in the data dirs.
80- DESTVERSION =` cat ./data/PG_VERSION`
81- SRCVERSION =` cat ./$OLDDIR /PG_VERSION`
80+ DEST_VERSION =` cat ./data/PG_VERSION`
81+ SRC_VERSION =` cat ./$OLDDIR /PG_VERSION`
8282
8383# Check for version compatibility.
8484# This code will need to be updated/reviewed for each new PostgreSQL release.
8585
86- # MYVERSION is the expected output database version
87- MYVERSION =" 7.1"
86+ # UPGRADE_VERSION is the expected output database version
87+ UPGRADE_VERSION =" 7.1"
8888
89- if [" $SRCVERSION " = " 7.1" -a ! " $DATA " ]
90- then echo " $0 requires a full data dump file to upgrade from version$SRCVERSION ." 1>&2
91- echo " Use the '-d' parameter to specify the dump file" 1>&2
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
9296exit 1
9397fi
9498
95- if [" $DESTVERSION " != " $MYVERSION " -a " $DESTVERSION " != " $SRCVERSION " ]
96- then echo " $0 is for PostgreSQL version$MYVERSION , but ./data/PG_VERSION contains$DESTVERSION ." 1>&2
97- echo " Did you run initdb for version$MYVERSION ?" 1>&2
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+
104+ if [" $DEST_VERSION " != " $UPGRADE_VERSION " -a " $DEST_VERSION " != " $SRC_VERSION " ]
105+ then echo " ` basename$0 ` is for PostgreSQL version$UPGRADE_VERSION , but ./data/PG_VERSION contains$DEST_VERSION ." 1>&2
106+ echo " Did you run initdb for version$UPGRADE_VERSION ?" 1>&2
98107exit 1
99108fi
100109
101110# Check that input database is of a compatible version (anything with the same
102111# physical layout of user tables and indexes should be OK). I did not write
103- # something like "$SRCVERSION -ge $MINVERSION " because test(1) isn't bright
112+ # something like "$SRC_VERSION -ge $UPGRADE_VERSION " because test(1) isn't bright
104113# enough to compare dotted version strings properly. Using a case statement
105114# looks uglier but is more flexible.
106115
107- case " $SRCVERSION " in
116+ case " $SRC_VERSION " in
108117# 7.2) ;;
109- * )echo " Sorry,` basename$0 ` cannot upgrade database version$SRCVERSION to$DESTVERSION ." 1>&2
118+ * )echo " Sorry,` basename$0 ` cannot upgrade database version$SRC_VERSION to$DEST_VERSION ." 1>&2
110119echo " The on-disk structure of tables has changed." 1>&2
111- echo " You will need to dump and restore usingpg_dump ." 1>&2
120+ echo " You will need to dump and restore usingpg_dumpall ." 1>&2
112121exit 1;;
113122esac
114123
115124
116- # OK, ready to proceed.
125+ # Checking done. Ready to proceed.
117126
118127# Execute the schema script to create everything, except modify any
119128# sequences with int4 maximums if we are upgrading from 7.1.
120129cat$SCHEMA | awk -F' ' ' {
121- if ("' " $SRCVERSION " ' " == "7.1" &&
130+ if ("' " $SRC_VERSION " ' " == "7.1" &&
122131 $1 == "CREATE" &&
123132 $2 == "SEQUENCE" &&
124- ($9 >= 2147483646 && # handle OSround
133+ ($9 >= 2147483646 && # handle OSrounding
125134 ($9 <= 2147483648))
126135{
127136for(i=1; i < NF; i++)
@@ -134,32 +143,28 @@ cat $SCHEMA | awk -F' ' '{
134143elseprint $0;
135144}' |
136145psql" template1"
137-
138146if [$? -ne 0 ]
139147then echo " There were errors in the input script$SCHEMA .
140148$0 aborted." 1>&2
141149exit 1
142150fi
143151
144-
145- if [" $SRCVERSION " != " 7.1" ]
152+ # Set sequence values for 7.1-version sequences, which are int4.
153+ if [" $SRC_VERSION " != " 7.1" ]
146154then echo " Input script$SCHEMA complete, fixing row commit statuses..."
147155else echo " Input script$SCHEMA complete, setting int8 sequences..."
148156
149- # Set all the sequence counters because they are not brought over
150- # in the schema dump, and the old 7.1 sequences where int4 in size
151- # so bringing over the file wouldn't help us anyway.
152- cat$DATA | awk' $0 == "\\connect " || "SELECT setval (" \
153- {print $0;}' |
154- psql" template1"
155-
156- if [$? -ne 0 ]
157- then echo " There were errors in the input script$SCHEMA .
157+ # Set all the sequence counters because they are not brought over
158+ # in the schema dump.
159+ cat$DATA | egrep' ^(\\connect)|SELECT setval \()[^]*$' |
160+ psql" template1"
161+ if [$? -ne 0 ]
162+ then echo " There were errors in setting the sequence values.
158163$0 aborted." 1>&2
159- exit 1
160- fi
164+ exit 1
165+ fi
161166
162- echo " Int8 sequences set, fixing row commit statuses..."
167+ echo " Int8 sequences set, fixing row commit statuses..."
163168fi
164169
165170# Now vacuum each result database in case our transaction increase
@@ -174,10 +179,16 @@ $0 aborted." 1>&2
174179fi
175180done
176181
177- # should be pretty small file
182+ # Used for scans looking for a database/tablename match
183+ # New oid is looked up
178184pg_dumpall -s> $TMPFILE 2> /dev/null
185+ if [" $? " -ne 0 ]
186+ then echo " Unable to dump schema of new database.; exiting" 1>&2
187+ exit 1
188+ fi
179189
180- # flush buffers to disk
190+ # we are done with SQL database access
191+ # shutdown forces buffers to disk
181192pg_ctl stop
182193if [" $? " -ne 0 ]
183194then echo " Unable to stop database server.; exiting" 1>&2
@@ -188,7 +199,7 @@ echo "Commit fixes complete, moving data files..."
188199
189200cat" $SCHEMA " | while read LINE
190201do
191- if /bin/echo" $LINE " | grep -q" ^\\\\ connect [^]*$"
202+ if /bin/echo" $LINE " | grep -q' ^\\connect [^]*$'
192203then OLDDB=" $DB "
193204DB=" ` /bin/echo\" $LINE \" | cut -d' ' -f2` "
194205if [" $DB " = " -" ]
208219then TABLE=" "
209220fi
210221fi
222+ # 7.1 sequences were handled earlier because they were int4.
223+ if test " $SRC_VERSION " ! =" 7.1" &&
224+ echo " $LINE " | egrep -q" ^-- Name: [^ ]* Type: SEQUENCE"
225+ then TABLE=" ` echo\" $LINE \" | cut -d' ' -f3` "
226+ # skip system tables
227+ if [" ` echo\" $TABLE \" | cut -c 1-3` " = " pg_" ]
228+ then TABLE=" "
229+ fi
230+ fi
211231if [" $DB " -a " $OID " -a " $TABLE " ]
212232then
213233NEWOID=` awk -F' ' '
214- BEGIN { newdb=""; newoid="";
234+ BEGIN { newdb=""; newoid="";
215235 newtable=""; ret=0;}
216236$1 == "\\\\connect" && $2 != "-" {newdb=$2;}
217237$0 ~ /^-- TOC Entry ID [0-9]* .OID / \
218238{ newoid = substr($7, 1, length($7)-1);}
219239{print $0 >> "/tmp/x";
220240print $3 >> "/tmp/x";
221241print newdb," ", newoid >> "/tmp/x"}
222- ($0 ~ /^-- Name: [^ ]* Type: TABLE / && \
223- $0 ~ /^-- Name: [^ ]* Type: INDEX /) && \
242+ ($0 ~ /^-- Name: [^ ]* Type: TABLE / || \
243+ $0 ~ /^-- Name: [^ ]* Type: INDEX / || \
244+ $0 ~ /^-- Name: [^ ]* Type: SEQUENCE /) && \
224245newdb == "' " $DB " ' " && \
225246$3 == "' " $TABLE " ' " \
226247{ ret=newoid; exit}
227248END { print ret;}' $TMPFILE `
228249if [" $NEWOID " -eq 0 ]
229- then echo " Move of database$DB , OID$OID , table$TABLE failed.\nNew oid not found; exiting" 1>&2
250+ then echo " Move of database$DB , OID$OID , table$TABLE failed.
251+ New oid not found; exiting" 1>&2
230252exit 1
231253fi
232254# We use stars so we don't have to worry about database oids
233255if [` ls" $OLDDIR " /base/* /" $OID " | wc -l` -eq 0 ]
234- then echo " Move of database$DB , OID$OID , table$TABLE failed.\nFile not found; exiting" 1>&2
256+ then echo " Move of database$DB , OID$OID , table$TABLE failed.
257+ File not found; exiting" 1>&2
235258exit 1
236259fi
237260if [` ls" $OLDDIR " /base/* /" $OID " | wc -l` -gt 1 ]
238- then echo " Move of database$DB , OID$OID , table$TABLE failed.\nToo many found; exiting" 1>&2
261+ then echo " Move of database$DB , OID$OID , table$TABLE failed.
262+ Too many found; exiting" 1>&2
239263exit 1
240264fi
241265if [` ls data/base/* /" $NEWOID " | wc -l` -eq 0 ]
242- then echo " Move of database$DB , OID$OID , table$TABLE to$NEWOID failed.\nFile not found; exiting" 1>&2
266+ then echo " Move of database$DB , OID$OID , table$TABLE to$NEWOID failed.
267+ File not found; exiting" 1>&2
243268exit 1
244269fi
245270if [` ls data/base/* /" $NEWOID " | wc -l` -gt 1 ]
246- then echo " Move of database$DB , OID$OID , table$TABLE to$NEWOID failed.\nToo many found; exiting" 1>&2
271+ then echo " Move of database$DB , OID$OID , table$TABLE to$NEWOID failed.
272+ Too many found; exiting" 1>&2
247273exit 1
248274fi
249275mv -f" $OLDDIR " /base/* /" $OID " data/base/* /" $NEWOID "
250276if [" $? " -ne 0 ]
251- then echo " Move of database$DB , OID$OID , table$TABLE \n to$NEWOID failed.; exiting" 1>&2
277+ then echo " Move of database$DB , OID$OID , table$TABLE
278+ to$NEWOID failed.; exiting" 1>&2
252279exit 1
253280fi
254281TABLE=" "
255282fi
256283done
257284
258285# 7.1 has non-compressed log file format
259- if [" $SRCVERSION " = " 7.1" ]
286+ if [" $SRC_VERSION " = " 7.1" ]
260287then
261288# pg_log is oid 1269 in 7.1
262289LOGSIZE=` ls -l" $OLDDIR " /global/1269" $OLDDIR " /global/1269.* 2> /dev/null|
270297# set max transaction id
271298
272299else
273- # how to handle 7.2?
274300rm -r data/pg_clog&&
275301mv" $OLDDIR " /data/pg_clog data/pg_clog&&
276302mv" $OLDDIR " /data/global/pg_control data/global/pg_control