55
66# set -x
77
8- # $Header: /cvsroot/pgsql/src/bin/pg_dump/Attic/pg_upgrade,v 1.28 2002/01/11 06:48:41 momjian Exp $
8+ # Set this to "Y" to enable this program
9+ ENABLE=" N"
10+
11+ # UPGRADE_VERSION is the expected old database version
12+ UPGRADE_VERSION=" 7.1"
13+
14+ # Hard-wired from pg_class in 7.1. I wish there was another way.
15+ # Are these fixed values for that release? XXX
16+ SRC_LARGEOBJECT_OID=16948
17+ SRC_LARGEOBJECT_IDX_OID=17148
18+
19+ # $Header: /cvsroot/pgsql/src/bin/pg_dump/Attic/pg_upgrade,v 1.29 2002/01/11 20:34:14 momjian Exp $
920#
1021# NOTE: we must be sure to update the version-checking code a few dozen lines
1122# below for each new PostgreSQL release.
1223
13- TMPFILE=" /tmp/pgupgrade.$$ "
14-
15- trap " rm -f$TMPFILE " 0 1 2 3 15
24+ trap " rm -f /tmp/$$ .*" 0 1 2 3 15
1625
1726SCHEMA=" "
1827while [" $# " -gt 1 ]
@@ -71,15 +80,13 @@ thenecho "Cannot read ./$OLDDIR/PG_VERSION --- something is wrong." 1>&2
7180fi
7281
7382# Get the actual versions seen in the data dirs.
83+
7484DEST_VERSION=` cat ./data/PG_VERSION`
7585SRC_VERSION=` cat ./$OLDDIR /PG_VERSION`
7686
7787# Check for version compatibility.
7888# This code will need to be updated/reviewed for each new PostgreSQL release.
7989
80- # UPGRADE_VERSION is the expected output database version
81- UPGRADE_VERSION=" 7.1"
82-
8390if [" $DEST_VERSION " != " $UPGRADE_VERSION " -a " $DEST_VERSION " != " $SRC_VERSION " ]
8491then echo " ` basename$0 ` is for PostgreSQL version$UPGRADE_VERSION , but ./data/PG_VERSION contains$DEST_VERSION ." 1>&2
8592echo " Did you run initdb for version$UPGRADE_VERSION ?" 1>&2
9299# enough to compare dotted version strings properly. Using a case statement
93100# looks uglier but is more flexible.
94101
95- case " $SRC_VERSION " in
96- # 7.2) ;;
97- * )echo " Sorry,` basename$0 ` cannot upgrade database version$SRC_VERSION to$DEST_VERSION ." 1>&2
98- echo " The on-disk structure of tables has changed." 1>&2
99- echo " You will need to dump and restore using pg_dumpall." 1>&2
100- exit 1;;
101- esac
102+ if [" $ENABLE " != " Y" ]
103+ then
104+ case " $SRC_VERSION " in
105+ # 7.2) ;;
106+ * )echo " Sorry,` basename$0 ` cannot upgrade database version$SRC_VERSION to$DEST_VERSION ." 1>&2
107+ echo " The on-disk structure of tables has changed." 1>&2
108+ echo " You will need to dump and restore using pg_dumpall." 1>&2
109+ exit 1;;
110+ esac
111+ fi
112+
113+ # check for proper pg_resetxlog version
102114
103115pg_resetxlog2> /dev/null
104116# file not found status is normally 127, not 1
117129# If the XID is > 2 billion, 7.1 database will have non-frozen XID's in
118130# low numbers, and 7.2 will think they are in the future --- bad.
119131
120- XID =` pg_resetxlog -n" $OLDDIR " | grep" NextXID" | awk -F' *' ' {print $4}' `
132+ SRC_XID =` pg_resetxlog -n" $OLDDIR " | grep" NextXID" | awk -F' *' ' {print $4}' `
121133if [" $SRC_VERSION " = " 7.1" -a " $XID " -gt 2000000000 ]
122134then echo " XID too high for$0 .; exiting" 1>&2
123135exit 1
124136fi
137+ DST_XID=` pg_resetxlog -n data| grep" NextXID" | awk -F' *' ' {print $4}' `
125138
139+ # compare locales to make sure they match
140+
141+ pg_resetxlog -n" $OLDDIR " | grep" ^LC_" > /tmp/$$ .0
142+ pg_resetxlog -n data| grep" ^LC_" > /tmp/$$ .1
143+ if ! diff /tmp/$$ .0 /tmp/$$ .1> /dev/null
144+ then echo " Locales do not match between the two versions.; exiting" 1>&2
145+ exit 1
146+ fi
147+
148+
149+ # ##################################
126150# Checking done. Ready to proceed.
151+ # ##################################
152+
127153
128154# Execute the schema script to create everything
129155
149175
150176# Used for scans looking for a database/table name match
151177# New oid is looked up
152- pg_dumpall -s> $TMPFILE 2> /dev/null
178+ pg_dumpall -s> /tmp/ $$ .3 2> /dev/null
153179if [" $? " -ne 0 ]
154180then echo " Unable to dump schema of new database.; exiting" 1>&2
155181exit 1
156182fi
157183
184+ # Get pg_largeobject oids for movement
185+
186+ DST_LARGEOBJECT_OID=` psql -d template1 -At -c" SELECT oid from pg_class where relname = 'pg_largeobject';" `
187+ DST_LARGEOBJECT_IDX_OID=` psql -d template1 -At -c" SELECT oid from pg_class where relname = 'pg_largeobject_loid_pn_index';" `
188+ if [" $LARGEOBJECT_OID " -eq 0-o " $LARGEOBJECT_IDX_OID " -eq 0 ]
189+ then echo " Unable to find large object oid.; exiting" 1>&2
190+ exit 1
191+ fi
192+
193+ if [" $SRC_VERSION " = " $DST_VERSION " ]
194+ then # Versions are the same so we can get pg_largeobject oid this way
195+ SRC_LARGEOBJECT_IDX_OID=" $DST_LARGEOBJECT_OID "
196+ SRC_LARGEOBJECT_IDX_OID=" $DST_LARGEOBJECT_IDX_OID "
197+ fi
198+
158199# we are done with SQL database access
159200# shutdown forces buffers to disk
160201
166207
167208echo " Commit fixes complete, moving data files..."
168209
210+ # Move table/index/sequence files
211+
169212cat" $SCHEMA " | while read LINE
170213do
171214if /bin/echo" $LINE " | grep -q' ^\\connect [^]*$'
205248newdb == "' " $DB " ' " && \
206249$3 == "' " $TABLE " ' " \
207250{ ret=newoid; exit}
208- END { print ret;}' $TMPFILE `
251+ END { print ret;}' /tmp/ $$ .3 `
209252if [" $NEWOID " -eq 0 ]
210253then echo " Move of database$DB , OID$OID , table$TABLE failed.
211254New oid not found; exiting" 1>&2
212255exit 1
213256fi
257+
214258# We use stars so we don't have to worry about database oids
259+
260+ # Test to make sure there is exactly one matching file on each place
261+
215262if [` ls" $OLDDIR " /base/* /" $OID " | wc -l` -eq 0 ]
216263then echo " Move of database$DB , OID$OID , table$TABLE failed.
217264File not found; exiting" 1>&2
@@ -232,26 +279,101 @@ File not found; exiting" 1>&2
232279Too many found; exiting" 1>&2
233280exit 1
234281fi
235- mv -f" $OLDDIR " /base/* /" $OID " data/base/* /" $NEWOID "
282+
283+ # Move files
284+
285+ SRCDB=` basename\` dirname$OLDDIR " /base/*/" $OID " \` `
286+ DSTDB=` basename \'dirname data/base/*/" $NEWOID " \` `
287+ mv -f" $OLDIR " /base/" $SRCDB " /" $OID " data/base/" $DSTDB " /" $NEWOID "
236288if [" $? " -ne 0 ]
237289then echo " Move of database$DB , OID$OID , table$TABLE
238290to$NEWOID failed.; exiting" 1>&2
239291exit 1
240292fi
293+ # handle table extents
294+ ls" $OLDDIR " /base/" $SRCDB " /" $OID " .* | while read FILE
295+ do
296+ EXT=` basename" $FILE " | sed' s/[^[^\.]*\.\(.*\)$/\1/' `
297+ mv -f" $FILE " data/base/" $DSTDB " /" $NEWOID " ." $EXT "
298+ if [" $? " -ne 0 ]
299+ then echo " Move of database$DB , OID$OID , table$TABLE
300+ to$NEWOID failed.; exiting" 1>&2
301+ exit 1
302+ fi
303+ done
304+
305+ # handle pg_largeobject
306+ # We use the unique oid's to tell use where to move the
307+ # pg_largeobject files.
308+
309+ if [-f " $OLDIR " /base/" $SRCDB " /" $SRC_LARGEOBJECT_OID " ]
310+ then mv" $OLDIR " /base/" $SRCDB " /" $SRC_LARGEOBJECT_OID " \
311+ data/base/" $DSTDB " /" $DST_LARGEOBJECT_OID "
312+ if [" $? " -ne 0 ]
313+ then echo " Move of large object for database$DB
314+ to$NEWOID failed.; exiting" 1>&2
315+ exit 1
316+ fi
317+ # handle table extents
318+ ls" $OLDDIR " /base/" $SRCDB " /" $SRC_LARGEOBJECT_OID " .* | while read FILE
319+ do
320+ EXT=` basename" $FILE " | sed' s/[^[^\.]*\.\(.*\)$/\1/' `
321+ mv -f" $FILE " data/base/" $DSTDB " /" $DST_LARGEOBJECT_OID " ." $EXT "
322+ if [" $? " -ne 0 ]
323+ then echo " Move of large object for database$DB
324+ to$NEWOID failed.; exiting" 1>&2
325+ exit 1
326+ fi
327+ done
328+ fi
329+
330+ # Handle pg_largeobject_loid_pn_index
331+ if [-f " $OLDIR " /base/" $SRCDB " /" $SRC_LARGEOBJECT_IDX_OID " ]
332+ then mv" $OLDIR " /base/" $SRCDB " /" $SRC_LARGEOBJECT_IDX_OID " \
333+ data/base/" $DSTDB " /" $DST_LARGEOBJECT_IDX_OID "
334+ if [" $? " -ne 0 ]
335+ then echo " Move of large object for database$DB
336+ to$NEWOID failed.; exiting" 1>&2
337+ exit 1
338+ fi
339+ # handle table extents
340+ ls" $OLDDIR " /base/" $SRCDB " /" $SRC_LARGEOBJECT_IDX_OID " .* | while read FILE
341+ do
342+ EXT=` basename" $FILE " | sed' s/[^[^\.]*\.\(.*\)$/\1/' `
343+ mv -f" $FILE " data/base/" $DSTDB " /" $DST_LARGEOBJECT_IDX_OID " ." $EXT "
344+ if [" $? " -ne 0 ]
345+ then echo " Move of large object for database$DB
346+ to$NEWOID failed.; exiting" 1>&2
347+ exit 1
348+ fi
349+ done
350+ fi
241351TABLE=" "
242352fi
243353done
244354
245355
246- # Set this so the next VACUUM sets the old row XID's as "frozen"
356+ # Set this so future backends don't think these tuples are their own
357+ # because it matches their own XID.
247358# Commit status already updated by vacuum above
359+ # Set to maximum XID just in case SRC wrapped around recently and
360+ # is lower than DST's database
361+ if [" $SRC_XID " -gt " $DST_XID " ]
362+ then MAX_XID=" $SRC_XID "
363+ else MAX_XID=" $DST_XID "
364+ fi
248365
249- pg_resetxlog -x" $XID " data
366+ pg_resetxlog -x" $MAX_XID " data
250367if [" $? " -ne 0 ]
251368then echo " Unable to set new XID.; exiting" 1>&2
252369exit 1
253370fi
254371
372+ # Move over old WAL
373+
374+ rm -r data/pg_xlog
375+ mv -f" $OLDDIR " /pg_xlog data
376+
255377# Set last checkpoint location from old database
256378
257379CHKPOINT=` pg_resetxlog -n" $OLDDIR " | grep" checkpoint location:" |
@@ -283,8 +405,7 @@ if [ "$SRC_VERSION" = "7.1" ]
283405then echo " Set int8 sequence values from 7.1..."
284406
285407psql -d template1 -At -c" SELECT datname FROM pg_database" |
286- grep -v' ^template0$' | # no system databases
287- grep -v' ^template1$' | # no system databases
408+ grep -v' ^template0$' | # template1 OK
288409while read DB
289410do
290411echo " $DB "