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.19 2002/01/0916:08:54 momjian Exp $
6+ # $Header: /cvsroot/pgsql/src/bin/pg_dump/Attic/pg_upgrade,v 1.20 2002/01/0921:50:52 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.
@@ -12,24 +12,31 @@ TMPFILE="/tmp/pgupgrade.$$"
1212
1313trap " rm -f$TMPFILE " 0 1 2 3 15
1414
15- if [" $# " -eq 0 ]
16- then echo " Usage:$0 -f inputfile old_data_dir" 1>&2
17- exit 1
18- fi
19-
20- if [" X$1 " = " X-f" ]
21- then INPUT=" $2 "
22- shift 2
23- if [! -f " $INPUT " ]
24- then echo " $INPUT does not exist" 1>&2
15+ SCHEMA=" "
16+ DATA=" "
17+ while [" $# " -gt 1 ]
18+ do
19+ if [" X$1 " = " X-s" ]
20+ then SCHEMA=" $2 "
21+ if [! -s " $SCHEMA " ]
22+ then echo " $SCHEMA does not exist" 1>&2
23+ exit 1
24+ fi
25+ shift 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
2534exit 1
2635fi
27- else echo " Usage:$0 -f inputfile old_data_dir" 1>&2
28- exit 1
29- fi
36+ done
3037
31- if [" $# " -ne 1 ]
32- then echo " Usage:$0 -f inputfile old_data_dir" 1>&2
38+ if [" $# " -ne 1-o ! " $SCHEMA " ]
39+ then echo " Usage:$0 -s schema_dump [ -d data_dump ] old_data_dir" 1>&2
3340exit 1
3441fi
3542
@@ -38,8 +45,7 @@ OLDDIR="$1"
3845# check things
3946
4047if [! -d " ./data" ]
41- then echo " ` basename$0 ` must be run from the directory containing
42- the database directory\` data\' (` dirname$PGDATA ` .)" 1>&2
48+ then echo " ` basename$0 ` must be run from the directory containing the database directory\` data\' (` dirname$PGDATA ` .)" 1>&2
4349echo " You must have run initdb to create the template1 database." 1>&2
4450exit 1
4551fi
@@ -80,6 +86,12 @@ SRCVERSION=`cat ./$OLDDIR/PG_VERSION`
8086# MYVERSION is the expected output database version
8187MYVERSION=" 7.1"
8288
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
92+ exit 1
93+ fi
94+
8395if [" $DESTVERSION " != " $MYVERSION " -a " $DESTVERSION " != " $SRCVERSION " ]
8496then echo " $0 is for PostgreSQL version$MYVERSION , but ./data/PG_VERSION contains$DESTVERSION ." 1>&2
8597echo " Did you run initdb for version$MYVERSION ?" 1>&2
@@ -103,56 +115,65 @@ esac
103115
104116# OK, ready to proceed.
105117
106- # Execute the input script to create everything, except that we remove
107- # any COPY statements, except for the ones that load pg_shadow/pg_group.
108- # There shouldn't be any others in there anyway...
109-
110- cat$INPUT | awk' {
111- if (tolower($1) == "copy" &&
112- $2 != "pg_shadow" &&
113- $2 != "pg_group")
114- while (getline $0 > 0 && $0 != "\\.")
115- ;
118+ # Execute the schema script to create everything, except modify any
119+ # sequences with int4 maximums if we are upgrading from 7.1.
120+ cat$SCHEMA | awk -F' ' ' {
121+ if ("' " $SRCVERSION " ' " == "7.1" &&
122+ $1 == "CREATE" &&
123+ $2 == "SEQUENCE" &&
124+ ($9 >= 2147483646 && # handle OS round
125+ ($9 <= 2147483648))
126+ {
127+ for(i=1; i < NF; i++)
128+ if (i != 9)
129+ printf "%s ", $i;
130+ else
131+ printf "%s ", "9223372036854775807";
132+ print;
133+ }
116134elseprint $0;
117- }' > $TMPFILE
118-
119- psql" template1" < $TMPFILE
135+ }' |
136+ psql" template1"
120137
121138if [$? -ne 0 ]
122- then echo " There were errors in the input script$INPUT .
139+ then echo " There were errors in the input script$SCHEMA .
123140$0 aborted." 1>&2
124141exit 1
125142fi
126143
127- echo " Input script$INPUT complete, fixing row commit statuses..."
128-
129- # Now vacuum each result database to mark all system-table rows as committed,
130- # because when pg_clog is replaced with the saved version, the transaction
131- # statuses will no longer match the data. VACUUM will force the on-row
132- # status flags to the right value so that pg_clog will not matter anymore.
133- # Note: we used to try to do this as part of the previous step, but that
134- # risks permissions problems if VACUUM is run as the wrong user.
135- # Note: the initial VACUUM does template1, then we do everything else.
136-
137- cat$INPUT | awk' BEGIN{ print "VACUUM;" }
138- {
139- if (tolower($1) == "copy")
140- while (getline $0 > 0 && $0 != "\\.")
141- ;
142- else if (tolower($1) == "\\connect" &&
143- $2 != "-" &&
144- $2 != "template1")
145- printf "\\connect %s\nVACUUM;\n", $2;
146- }' > $TMPFILE
147-
148- psql" template1" < $TMPFILE
144+
145+ if [" $SRCVERSION " != " 7.1" ]
146+ then echo " Input script$SCHEMA complete, fixing row commit statuses..."
147+ else echo " Input script$SCHEMA complete, setting int8 sequences..."
148+
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"
149155
150156if [$? -ne 0 ]
151- then echo " There were errors in thevacuuming step .
157+ then echo " There were errors in theinput script $SCHEMA .
152158$0 aborted." 1>&2
153159exit 1
154160fi
155161
162+ echo " Int8 sequences set, fixing row commit statuses..."
163+ fi
164+
165+ # Now vacuum each result database in case our transaction increase
166+ # causes all the XID's to be marked with the frozen XID.
167+ psql -l| while read DB
168+ do
169+ echo " VACUUM;" | psql" $DB "
170+ if [$? -ne 0 ]
171+ then echo " There were errors during VACUUM.
172+ $0 aborted." 1>&2
173+ exit 1
174+ fi
175+ done
176+
156177# should be pretty small file
157178pg_dumpall -s> $TMPFILE 2> /dev/null
158179
@@ -161,7 +182,7 @@ pg_ctl stop
161182
162183echo " Commit fixes complete, moving data files..."
163184
164- cat" $INPUT " | while read LINE
185+ cat" $SCHEMA " | while read LINE
165186do
166187if /bin/echo" $LINE " | grep -q" ^\\\\ connect"
167188then OLDDB=" $DB "
176197if echo " $LINE " | grep -q" ^-- TOC Entry ID [0-9]* (OID"
177198then OID=" ` echo\" $LINE \" | cut -d' ' -f7| tr -d' )' ` "
178199fi
179- if echo " $LINE " | grep -q" ^-- Name: [^ ]* Type: TABLE"
200+ if echo " $LINE " | egrep -q" ^-- Name: [^ ]* Type:( TABLE|INDEX) "
180201then TABLE=" ` echo\" $LINE \" | cut -d' ' -f3` "
181202# skip system tables
182203if [" ` echo\" $TABLE \" | cut -c 1-3` " = " pg_" ]
194215{print $0 >> "/tmp/x";
195216print $3 >> "/tmp/x";
196217print newdb," ", newoid >> "/tmp/x"}
197- $0 ~ /^-- Name: [^ ]* Type: TABLE / && \
218+ ($0 ~ /^-- Name: [^ ]* Type: TABLE / && \
219+ $0 ~ /^-- Name: [^ ]* Type: INDEX /) && \
198220newdb == "' " $DB " ' " && \
199221$3 == "' " $TABLE " ' " \
200222{ ret=newoid; exit}
229251fi
230252done
231253
254+ # set max transaction id, check < 2gig
255+
256+ # 7.1 has non-compressed log file format
257+ if [" $SRCVERSION " = " 7.1" ]
258+ # pg_log is oid 1269 in 7.1
259+ LOGSIZE=` ls -l" $OLDDIR " /global/1269" $OLDDIR " /global/1269.* 2> /dev/null|
260+ awk -F' *' '
261+ BEGIN {sum=0;}
262+ {sum += $5;}
263+ END{print sum;}' `
264+ fi
265+
232266echo " You must stop/start the postmaster before doing anything else."
233267echo " You may remove the$OLDDIR directory with 'rm -r$OLDDIR '."
234268