From 5b2ebe95e944f9d93b030e513eaa24127c9abab2 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Sun, 13 Jan 2002 01:13:59 +0000 Subject: [PATCH] Wow, it actually worked for the regression database. More testing needed. --- doc/src/sgml/ref/pg_upgrade.sgml | 56 +-- src/bin/pg_dump/pg_upgrade | 670 ++++++++++++++++--------------- 2 files changed, 370 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_upgrade.sgml b/doc/src/sgml/ref/pg_upgrade.sgml index 1e3681984c..17e36158f1 100644 --- a/doc/src/sgml/ref/pg_upgrade.sgml +++ b/doc/src/sgml/ref/pg_upgrade.sgml @@ -1,5 +1,5 @@ @@ -23,9 +23,10 @@ PostgreSQL documentation 1999-07-31 - -pg_upgrade -s filename old_data_dir - + + pg_upgrade + -1-2 + @@ -56,31 +57,20 @@ pg_upgrade -s filename - Then do: - -$ pg_dumpall -s > schema.out - - to dump out your old database's table definitions without any data. - - - - - - VACUUM your entire database using - vacuumdb -a + Copy the program pgsql/src/bin/pg_dump/pg_upgrade + from the current PostgreSQL distribution into somewhere in your path. - Stop the old postmaster and all backends. - - - - - - Rename (using mv) your old pgsql data/ directory to - data.old/. + Change your working directory to the + pgsql main directory, and type: + +$ pg_upgrade -1 + + to collect information about the old database needed for the + upgrade. @@ -109,14 +99,15 @@ $ make install Run initdb to create a new template1 database - containing the system tables for the new release. + containing the system tables for the new release. Make sure you use + settings similar to those used in your previous version. Start the new postmaster. (Note: it is critical that no users connect - to the database until the upgrade is complete. You may wish to start + to the server until the upgrade is complete. You may wish to start the postmaster without -i and/or alter pg_hba.conf temporarily.) @@ -127,7 +118,7 @@ $ make install Change your working directory to the pgsql main directory, and type: -$ pg_upgrade -s schema.out data.old +$ pg_upgrade -2 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 @@ -149,7 +140,7 @@ $ pg_upgrade -s schema.out data.old Carefully examine the contents of the upgraded - database. If you detect problems, you'll need to recover by restoring + databases. If you detect problems, you'll need to recover by restoring from your full pg_dump backup. You can delete the data.old/ directory when you are satisfied. @@ -158,18 +149,11 @@ $ pg_upgrade -s schema.out data.old - The upgraded database will be in an un-vacuumed state. You will probably + The upgraded databases will be in an un-vacuumed state. You will probably want to run a VACUUM ANALYZE before beginning production work. - - - - pg_upgrade does not handle custom tables/indexes/sequences in template1. - It does handle other template1 object customizations. - - diff --git a/src/bin/pg_dump/pg_upgrade b/src/bin/pg_dump/pg_upgrade index 36f0b4d046..808928f960 100755 --- a/src/bin/pg_dump/pg_upgrade +++ b/src/bin/pg_dump/pg_upgrade @@ -3,111 +3,327 @@ # pg_upgrade: update a database without needing a full dump/reload cycle. # CAUTION: Read the manual page before trying to use this! -#set -x +# $Header: /cvsroot/pgsql/src/bin/pg_dump/Attic/pg_upgrade,v 1.30 2002/01/13 01:13:59 momjian Exp $ +# +# NOTE: we must be sure to update the version-checking code a few dozen lines +# below for each new PostgreSQL release. + +set -x # Set this to "Y" to enable this program -ENABLE="N" +ENABLE="Y" # UPGRADE_VERSION is the expected old database version UPGRADE_VERSION="7.1" +CUR_VERSION="7.2" -# Hard-wired from pg_class in 7.1. I wish there was another way. -# Are these fixed values for that release? XXX -SRC_LARGEOBJECT_OID=16948 -SRC_LARGEOBJECT_IDX_OID=17148 +trap "rm -f /tmp/$$.*" 0 1 2 3 15 -# $Header: /cvsroot/pgsql/src/bin/pg_dump/Attic/pg_upgrade,v 1.29 2002/01/11 20:34:14 momjian Exp $ -# -# NOTE: we must be sure to update the version-checking code a few dozen lines -# below for each new PostgreSQL release. +PHASE="" +if [ "$#" -eq 1 ] +then + if [ "X$1" = "X-1" ] + then PHASE="1" + shift + elif [ "X$1" = "X-2" ] + then PHASE="2" + shift + fi +fi -trap "rm -f /tmp/$$.*" 0 1 2 3 15 +if [ "$PHASE" = "" ] +then echo "You must run $0 in either mode 1 or mode 2." 1>&2 + echo "Usage: $0 [ -1 | -2 ]" 1>&2 + exit 1 +fi -SCHEMA="" -while [ "$#" -gt 1 ] -do - if [ "X$1" = "X-s" ] - then SCHEMA="$2" - if [ ! -s "$SCHEMA" ] - then echo "$SCHEMA does not exist" 1>&2 +if [ ! -e data ] +then echo "$0 must be run from the directory above your /data directory. +$0 aborted." 1>&2 + if [ "$PHASE" -eq 2 ] + then echo "You must run initdb to create a template1 database." 1>&2 + fi + exit 1 +fi + +INFODIR="pg_upgrade_info" +OLDDIR="$INFODIR/data" + +make_dbobjoidmap() +{ + psql -d template1 -At -c "SELECT datname FROM pg_database" | + grep -v '^template0$' | # template1 OK + while read DB + do + QUERY="`echo \" SELECT relname, oid + FROM pg_class + WHERE relkind = 'r' OR + relkind = 'i' OR + relkind = 't'\"`" + # Don't move over 7.1 sequences; use setval() file + if [ "$SRC_VERSION" != "7.1" ] + then QUERY="$QUERY OR relkind = 'S';"; + QUERY="$QUERY;" + fi + + psql -d "$DB" -At -F' ' -c "$QUERY" | + while read RELNAME_OID + do + echo "$DB $RELNAME_OID" + done + done +} + + +make_dboidmap() +{ + psql -d template1 -At -F' ' -c \ + 'SELECT datname, oid FROM pg_database;' +} + + +move_objfiles() +{ + # Test to make sure there is a matching file in each place + + if [ ! -e "$OLDDIR"/base/"$SRC_DBOID"/"$SRC_OID" ] + then echo "Move of database $DB, OID $SRC_OID, object $OBJ failed. +File not found; exiting" 1>&2 + exit 1 + fi + + if [ ! -e data/base/"$DST_DBOID"/"$DST_OID" ] + then echo "Move of database $DB, OID $DST_OID, object $OBJ failed. +File not found; exiting" 1>&2 + exit 1 + fi + + # Move files + + mv -f "$OLDDIR"/base/"$SRC_DBOID"/"$SRC_OID" data/base/"$DST_DBOID"/"$DST_OID" + if [ "$?" -ne 0 ] + then echo "Move of database $DB, OID $SRC_OID, object $OBJ +to $DST_OID failed.; exiting" 1>&2 + exit 1 + fi + + # handle table extents + + ls "$OLDDIR"/base/"$SRC_DBOID"/"$SRC_OID".* 2>/dev/null | while read FILE + do + EXT=`basename "$FILE" | sed 's/^.*\.\(.*\)$/\1/'` + mv -f "$FILE" data/base/"$DST_DBOID"/"$DST_OID"."$EXT" + if [ "$?" -ne 0 ] + then echo "Move of database $DB, OID $SRC_OID, object $OBJ +to $DST_OID failed.; exiting" 1>&2 exit 1 fi - shift 2 - else echo "Usage: $0 -s schema_dump old_data_dir" 1>&2 + done +} + +if [ "$PHASE" -eq 1 ] +then + + ########################## + # Phase 1 starts here # + ########################## + + + if [ ! -d data/base/1 ] + then echo "There is no database template1 in data/base." 1>&2 exit 1 fi -done -if [ "$#" -ne 1 -o ! "$SCHEMA" ] -then echo "Usage: $0 -s schema_dump old_data_dir" 1>&2 - exit 1 -fi + # get version + SRC_VERSION="`cat data/PG_VERSION`" + if [ "$SRC_VERSION" = "" ] + then echo "$0 can not find PostgreSQL version file 'data/PG_VERSION'. +$0 aborted." 1>&2 + exit 1 + fi -OLDDIR="$1" + if [ "$SRC_VERSION" != "$CUR_VERSION" -a \ + "$SRC_VERSION" != "$UPGRADE_VERSION" ] + then echo + "$0 supports versions $UPGRADE_VERSION and $CUR_VERSION only." 1>&2 + echo + "However, your database is version $SRC_VERSION; +$0 aborted." 1>&2 + exit 1 + fi -# check things + # Check that input database is of a compatible version (anything with the same + # physical layout of user tables and indexes should be OK). I did not write + # something like "$SRC_VERSION -ge $UPGRADE_VERSION" because test(1) isn't bright + # enough to compare dotted version strings properly. Using a case statement + # looks uglier but is more flexible. + if [ "$ENABLE" != "Y" ] + then + echo "Sorry, $0 cannot upgrade database +version $SRC_VERSION to $DST_VERSION." 1>&2 + echo "The on-disk structure of tables has changed." 1>&2 + echo "You will need to dump and restore using pg_dumpall." 1>&2 + exit 1 + fi -if [ ! -d "./data" ] -then echo "`basename $0` must be run from the directory containing the database directory \`data\' (`dirname $PGDATA`.)" 1>&2 - echo "You must have run initdb to create the template1 database." 1>&2 - exit 1 + + # Start server, if needed, so we can do some work. + if ! pg_ctl status | head -1 | grep -q "is running" + then pg_ctl -w start + if [ $? -ne 0 ] + then echo "Can not start server. +$0 aborted." 1>&2 + exit 1 + fi + fi + + # create directory for our data + rm -rf "$INFODIR" + mkdir "$INFODIR" + chmod og-rwx "$INFODIR" + + # Dump schema + pg_dumpall -s | + awk -F' *' ' + { + # Modify sequences with int8 maximums if we are upgrading from 7.1. + if ("'"$SRC_VERSION"'" == "7.1" && + $1 == "CREATE" && + $2 == "SEQUENCE" && + # handle OS rounding + $9 >= 2147483646 && + $9 <= 2147483648) + { + for(i=1; i < NF; i++) + { + if (i != 9) + printf "%s ", $i; + else + printf "%s ", "9223372036854775807"; + } + print; + } + else print $0; + }' > "$INFODIR"/schema + if [ $? -ne 0 ] + then echo "Can not dump schema. +$0 aborted." 1>&2 + exit 1 + fi + + # Generate mappings for database + make_dboidmap > "$INFODIR"/dboidmap + make_dbobjoidmap > "$INFODIR"/dbobjoidmap + + # Generate setval() script for 7.1 because it has int4 sequences + + if [ "$SRC_VERSION" = "7.1" ] + then + psql -d template1 -At -c "SELECT datname FROM pg_database" | + grep -v '^template0$' | # template1 OK + while read DB + do + echo "\\connect $DB" + psql -d "$DB" -At -c " + SELECT relname + FROM pg_class + WHERE relkind = 'S';" | + while read SEQUENCE + do + VALUE=`psql -d template1 -At -c "SELECT last_value + FROM \"$SEQUENCE\";"` + echo "SELECT setval ('$SEQUENCE', $VALUE, true);" + done + done > "$INFODIR"/setval + else rm -f "$INFODIR"/setval + fi + + # Vacuum all databases to remove exipired rows. + # We will lose our transaction log file during the upgrade so we + # have to do this. + + vacuumdb -a + if [ $? -ne 0 ] + then echo "Can not vacuum server. +$0 aborted." 1>&2 + exit 1 + fi + + # Stop server so we can move the directory. + pg_ctl -w stop + if [ $? -ne 0 ] + then echo "Can not stop server. +$0 aborted." 1>&2 + exit 1 + fi + + mv data "$INFODIR" + if [ $? -ne 0 ] + then echo "Can not move old /data out of the way. +$0 aborted." 1>&2 + exit 1 + fi + echo "Plase 1 completed. Continue with the steps outlined in the $0 manual page." + exit 0 fi -if [ ! -d "./$OLDDIR" ] -then echo "You must rename your old data directory to $OLDDIR and run initdb." 1>&2 - exit 1 + + ########################## + # Phase 2 starts here # + ########################## + +# check things + +if [ ! -d "$INFODIR" ] +then echo "There is no '$INFODIR' directory from a phase 1 run of $0." 1>&2 + exit 1 fi -if [ ! -d "./data/base/1" ] -then echo "Cannot find database template1 in ./data/base." 1>&2 - echo "Are you running $0 as the postgres superuser?" 1>&2 - exit 1 +if [ ! -e "$OLDDIR" ] +then echo "There is no '$OLDDIR' directory from the phase 1 run of $0." 1>&2 + exit 1 fi -if [ ! -d "./$OLDDIR/base/1" ] -then echo "There is no database template1 in ./$OLDDIR/base." 1>&2 +if [ ! -f "$OLDDIR/PG_VERSION" ] +then echo "Cannot read '$OLDDIR/PG_VERSION' --- something is wrong." 1>&2 exit 1 fi -if [ ! -r "./data/PG_VERSION" ] -then echo "Cannot read ./data/PG_VERSION --- something is wrong." 1>&2 +if [ ! -f "data/PG_VERSION" ] +then echo "Cannot read 'data/PG_VERSION' --- something is wrong." 1>&2 exit 1 fi -if [ ! -r "./$OLDDIR/PG_VERSION" ] -then echo "Cannot read ./$OLDDIR/PG_VERSION --- something is wrong." 1>&2 +if [ ! -d "data/base/1" ] +then echo "Cannot find database template1 in 'data/base'." 1>&2 + echo "Are you running $0 as the postgres superuser?" 1>&2 exit 1 fi # Get the actual versions seen in the data dirs. -DEST_VERSION=`cat ./data/PG_VERSION` -SRC_VERSION=`cat ./$OLDDIR/PG_VERSION` +SRC_VERSION=`cat "$OLDDIR"/PG_VERSION` +DST_VERSION=`cat data/PG_VERSION` # Check for version compatibility. # This code will need to be updated/reviewed for each new PostgreSQL release. -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 - echo "Did you run initdb for version $UPGRADE_VERSION?" 1>&2 +if [ "$DST_VERSION" != "$CUR_VERSION" ] +then echo "$0 is for PostgreSQL version $CUR_VERSION +but data/PG_VERSION contains $DST_VERSION." 1>&2 + echo "Did you run initdb for version $UPGRADE_VERSION by mistake?" 1>&2 exit 1 fi -# Check that input database is of a compatible version (anything with the same -# physical layout of user tables and indexes should be OK). I did not write -# something like "$SRC_VERSION -ge $UPGRADE_VERSION" because test(1) isn't bright -# enough to compare dotted version strings properly. Using a case statement -# looks uglier but is more flexible. +# Stop server for pg_resetxlog use -if [ "$ENABLE" != "Y" ] -then - case "$SRC_VERSION" in -# 7.2) ;; - *) echo "Sorry, `basename $0` cannot upgrade database version $SRC_VERSION to $DEST_VERSION." 1>&2 - echo "The on-disk structure of tables has changed." 1>&2 - echo "You will need to dump and restore using pg_dumpall." 1>&2 - exit 1;; - esac +if pg_ctl status | head -1 | grep -q "is running" +then pg_ctl -w stop + if [ $? -ne 0 ] + then echo "Can no start server. +$0 aborted." 1>&2 + exit 1 + fi fi # check for proper pg_resetxlog version @@ -120,7 +336,7 @@ Install it from pgsql/contrib/pg_resetxlog and continue.; exiting" 1>&2 exit 1 fi -if ! pg_resetxlog -x 2>&1 | grep -q XID +if ! pg_resetxlog -x 2>&1 | grep -q 'xid' then echo "Old version of pg_resetxlog found in path. Install a newer version from pgsql/contrib/pg_resetxlog.; exiting" 1>&2 exit 1 @@ -130,7 +346,7 @@ fi # low numbers, and 7.2 will think they are in the future --- bad. SRC_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 "$SRC_XID" -gt 2000000000 ] then echo "XID too high for $0.; exiting" 1>&2 exit 1 fi @@ -145,6 +361,15 @@ then echo "Locales do not match between the two versions.; exiting" 1>&2 exit 1 fi +# Restart postmaster + +pg_ctl -w start +if [ $? -ne 0 ] +then echo "Can not start server. +$0 aborted." 1>&2 + exit 1 +fi + ################################### # Checking done. Ready to proceed. @@ -153,14 +378,14 @@ fi # Execute the schema script to create everything -psql "template1" < "$SCHEMA" +psql template1 < "$INFODIR"/schema if [ $? -ne 0 ] -then echo "There were errors in the input script $SCHEMA. +then echo "There were errors in the input script. $0 aborted." 1>&2 exit 1 fi -echo "Input script $SCHEMA complete, fixing row commit statuses..." +echo "Input script complete, fixing row commit statuses..." # XXX do we still need this? # Now vacuum each result database because our movement of transaction log @@ -173,28 +398,9 @@ $0 aborted." 1>&2 exit 1 fi -# Used for scans looking for a database/table name match -# New oid is looked up -pg_dumpall -s > /tmp/$$.3 2>/dev/null -if [ "$?" -ne 0 ] -then echo "Unable to dump schema of new database.; exiting" 1>&2 - exit 1 -fi - -# Get pg_largeobject oids for movement - -DST_LARGEOBJECT_OID=`psql -d template1 -At -c "SELECT oid from pg_class where relname = 'pg_largeobject';"` -DST_LARGEOBJECT_IDX_OID=`psql -d template1 -At -c "SELECT oid from pg_class where relname = 'pg_largeobject_loid_pn_index';"` -if [ "$LARGEOBJECT_OID" -eq 0 -o "$LARGEOBJECT_IDX_OID" -eq 0 ] -then echo "Unable to find large object oid.; exiting" 1>&2 - exit 1 -fi - -if [ "$SRC_VERSION" = "$DST_VERSION" ] -then # Versions are the same so we can get pg_largeobject oid this way - SRC_LARGEOBJECT_IDX_OID="$DST_LARGEOBJECT_OID" - SRC_LARGEOBJECT_IDX_OID="$DST_LARGEOBJECT_IDX_OID" -fi +# Generate mappings for database +make_dboidmap > /tmp/$$.dboidmap +make_dbobjoidmap > /tmp/$$.dbobjoidmap # we are done with SQL database access # shutdown forces buffers to disk @@ -209,155 +415,52 @@ echo "Commit fixes complete, moving data files..." # Move table/index/sequence files -cat "$SCHEMA" | while read LINE +cat "$INFODIR"/dbobjoidmap | while read LINE do - if /bin/echo "$LINE" | grep -q '^\\connect [^ ]*$' - then OLDDB="$DB" - DB="`/bin/echo \"$LINE\" | cut -d' ' -f2`" - if [ "$DB" = "-" ] - then DB="$OLDDB" - fi - if [ "$DB" = "template1" -o "$DB" = "template0" ] - then DB="" - fi - fi - if echo "$LINE" | grep -q "^-- TOC Entry ID [0-9]* (OID " - then OID="`echo \"$LINE\" | cut -d' ' -f7 | tr -d ')'`" + DB=`echo "$LINE" | awk '{print $1}'` + OBJ=`echo "$LINE" | awk '{print $2}'` + + # Skip system tables, except for pg_largeobject + # pg_toast tables are handled later as part of the + # base table move + if [ `expr "$OBJ" : 'pg_'` -eq 3 -a \ + `expr "$OBJ" : 'pg_largeobject'` -ne 14 ] + then continue fi - if echo "$LINE" | egrep -q "^-- Name: [^ ]* Type: (TABLE|INDEX|SEQUENCE) " - then TABLE="`echo \"$LINE\" | cut -d' ' -f3`" - # skip system tables - if [ "`echo \"$TABLE\" | cut -c 1-3`" = "pg_" ] - then TABLE="" - fi - fi - if [ "$DB" -a "$OID" -a "$TABLE" ] - then - NEWOID=`awk -F' ' ' - BEGIN { newdb=""; newoid=""; - newtable=""; ret=0;} - $1 == "\\\\connect" && $2 != "-" {newdb=$2;} - $0 ~ /^-- TOC Entry ID [0-9]* .OID / \ - { newoid = substr($7, 1, length($7)-1);} - {print $0 >> "/tmp/x"; - print $3 >> "/tmp/x"; - print newdb," ", newoid >> "/tmp/x"} - ($0 ~ /^-- Name: [^ ]* Type: TABLE / || \ - $0 ~ /^-- Name: [^ ]* Type: INDEX / || \ - $0 ~ /^-- Name: [^ ]* Type: SEQUENCE /) && \ - newdb == "'"$DB"'" && \ - $3 == "'"$TABLE"'" \ - { ret=newoid; exit} - END { print ret;}' /tmp/$$.3` - if [ "$NEWOID" -eq 0 ] - then echo "Move of database $DB, OID $OID, table $TABLE failed. -New oid not found; exiting" 1>&2 - exit 1 - fi - - # We use stars so we don't have to worry about database oids - - # Test to make sure there is exactly one matching file on each place - - if [ `ls "$OLDDIR"/base/*/"$OID" | wc -l` -eq 0 ] - then echo "Move of database $DB, OID $OID, table $TABLE failed. -File not found; exiting" 1>&2 - exit 1 - fi - if [ `ls "$OLDDIR"/base/*/"$OID" | wc -l` -gt 1 ] - then echo "Move of database $DB, OID $OID, table $TABLE failed. -Too many found; exiting" 1>&2 - exit 1 - fi - if [ `ls data/base/*/"$NEWOID" | wc -l` -eq 0 ] - then echo "Move of database $DB, OID $OID, table $TABLE to $NEWOID failed. -File not found; exiting" 1>&2 - exit 1 - fi - if [ `ls data/base/*/"$NEWOID" | wc -l` -gt 1 ] - then echo "Move of database $DB, OID $OID, table $TABLE to $NEWOID failed. -Too many found; exiting" 1>&2 - exit 1 - fi - - # Move files - SRCDB=`basename \`dirname $OLDDIR"/base/*/"$OID"\`` - DSTDB=`basename \'dirname data/base/*/"$NEWOID"\`` - mv -f "$OLDIR"/base/"$SRCDB"/"$OID" data/base/"$DSTDB"/"$NEWOID" - if [ "$?" -ne 0 ] - then echo "Move of database $DB, OID $OID, table $TABLE -to $NEWOID failed.; exiting" 1>&2 - exit 1 - fi - # handle table extents - ls "$OLDDIR"/base/"$SRCDB"/"$OID".* | while read FILE - do - EXT=`basename "$FILE" | sed 's/[^[^\.]*\.\(.*\)$/\1/'` - mv -f "$FILE" data/base/"$DSTDB"/"$NEWOID"."$EXT" - if [ "$?" -ne 0 ] - then echo "Move of database $DB, OID $OID, table $TABLE -to $NEWOID failed.; exiting" 1>&2 - exit 1 - fi - done - - # handle pg_largeobject - # We use the unique oid's to tell use where to move the - # pg_largeobject files. - - if [ -f "$OLDIR"/base/"$SRCDB"/"$SRC_LARGEOBJECT_OID" ] - then mv "$OLDIR"/base/"$SRCDB"/"$SRC_LARGEOBJECT_OID" \ - data/base/"$DSTDB"/"$DST_LARGEOBJECT_OID" - if [ "$?" -ne 0 ] - then echo "Move of large object for database $DB -to $NEWOID failed.; exiting" 1>&2 - exit 1 - fi - # handle table extents - ls "$OLDDIR"/base/"$SRCDB"/"$SRC_LARGEOBJECT_OID".* | while read FILE - do - EXT=`basename "$FILE" | sed 's/[^[^\.]*\.\(.*\)$/\1/'` - mv -f "$FILE" data/base/"$DSTDB"/"$DST_LARGEOBJECT_OID"."$EXT" - if [ "$?" -ne 0 ] - then echo "Move of large object for database $DB -to $NEWOID failed.; exiting" 1>&2 - exit 1 - fi - done - fi - - # Handle pg_largeobject_loid_pn_index - if [ -f "$OLDIR"/base/"$SRCDB"/"$SRC_LARGEOBJECT_IDX_OID" ] - then mv "$OLDIR"/base/"$SRCDB"/"$SRC_LARGEOBJECT_IDX_OID" \ - data/base/"$DSTDB"/"$DST_LARGEOBJECT_IDX_OID" - if [ "$?" -ne 0 ] - then echo "Move of large object for database $DB -to $NEWOID failed.; exiting" 1>&2 - exit 1 - fi - # handle table extents - ls "$OLDDIR"/base/"$SRCDB"/"$SRC_LARGEOBJECT_IDX_OID".* | while read FILE - do - EXT=`basename "$FILE" | sed 's/[^[^\.]*\.\(.*\)$/\1/'` - mv -f "$FILE" data/base/"$DSTDB"/"$DST_LARGEOBJECT_IDX_OID"."$EXT" - if [ "$?" -ne 0 ] - then echo "Move of large object for database $DB -to $NEWOID failed.; exiting" 1>&2 - exit 1 - fi - done - fi - TABLE="" + SRC_OID=`echo "$LINE" | awk '{print $3}'` + SRC_DBOID=`grep "^$DB " "$INFODIR"/dboidmap | awk '{print $2}'` + DST_DBOID=`grep "^$DB " /tmp/$$.dboidmap | awk '{print $2}'` + DST_OID=`grep "^$DB $OBJ " /tmp/$$.dbobjoidmap | awk '{print $3}'` + + move_objfiles + + # Handle TOAST files if they exist + if grep -q "^$DB pg_toast_$SRC_OID " "$INFODIR"/dbobjoidmap + then # toast heap + SAVE_SRC_OID="$SRC_OID" + SAVE_DST_OID="$DST_OID" + SRC_OID=`grep "^$DB pg_toast_$SAVE_SRC_OID " \ + "$INFODIR"/dbobjoidmap | awk '{print $3}'` + DST_OID=`grep "^$DB pg_toast_$SAVE_DST_OID " \ + /tmp/$$.dbobjoidmap | awk '{print $3}'` + move_objfiles + # toast index + SRC_OID=`grep "^$DB pg_toast_${SAVE_SRC_OID}_idx " \ + "$INFODIR"/dbobjoidmap | awk '{print $3}'` + DST_OID=`grep "^$DB pg_toast_${SAVE_DST_OID}_idx " \ + /tmp/$$.dbobjoidmap | awk '{print $3}'` + move_objfiles fi done - + # Set this so future backends don't think these tuples are their own # because it matches their own XID. # Commit status already updated by vacuum above # Set to maximum XID just in case SRC wrapped around recently and # is lower than DST's database + if [ "$SRC_XID" -gt "$DST_XID" ] then MAX_XID="$SRC_XID" else MAX_XID="$DST_XID" @@ -374,20 +477,26 @@ fi rm -r data/pg_xlog mv -f "$OLDDIR"/pg_xlog data -# Set last checkpoint location from old database +# Set last log file id and segment from old database -CHKPOINT=`pg_resetxlog -n "$OLDDIR" | grep "checkpoint location:" | - awk -F' *' '{print $4}'` -if [ "$CHKPOINT" = "" ] -then echo "Unable to get old checkpoint location.; exiting" 1>&2 +LOG_ID=`pg_resetxlog -n "$OLDDIR" | grep "Current log file id:" | + awk -F' *' '{print $5}'` +if [ "$LOG_ID" = "" ] +then echo "Unable to get old log file id.; exiting" 1>&2 + exit 1 +fi +SEG_ID=`pg_resetxlog -n "$OLDDIR" | grep "Next log file segment:" | + awk -F' *' '{print $5}'` +if [ "$SEG_ID" = "" ] +then echo "Unable to get old log segment id.; exiting" 1>&2 exit 1 fi # Set checkpoint location of new database -pg_resetxlog -l `echo "$CHKPOINT" | tr '/' ' '` data +pg_resetxlog -l "$LOG_ID" "$SEG_ID" data if [ "$?" -ne 0 ] -then echo "Unable to set new checkpoint location.; exiting" 1>&2 +then echo "Unable to set new log file/segment id.; exiting" 1>&2 exit 1 fi @@ -403,93 +512,14 @@ fi if [ "$SRC_VERSION" = "7.1" ] then echo "Set int8 sequence values from 7.1..." - - psql -d template1 -At -c "SELECT datname FROM pg_database" | - grep -v '^template0$' | # template1 OK - 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';" | - grep -v '^pg_' | # no system tables - while read SEQUENCE - do - psql -d "$DB" -At <&2 - exit 1 - fi - done - done + exit 1 + fi fi -echo "You may remove the $OLDDIR directory with 'rm -r $OLDDIR'." +echo "You may remove the old database files with 'rm -r pg_upgrade'." exit 0 -- GitLab