Skip to content

Commit a898199

Browse files
committed
Add pg_upgrade IMPLEMENTATION file to CVS.
1 parent 6c4a98d commit a898199

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed

contrib/pg_upgrade/IMPLEMENTATION

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
------------------------------------------------------------------------------
2+
PG_MIGRATOR: IN-PLACE UPGRADES FOR POSTGRESQL
3+
------------------------------------------------------------------------------
4+
5+
Upgrading a PostgreSQL database from one major release to another can be
6+
an expensive process. For minor upgrades, you can simply install new
7+
executables and forget about upgrading existing data. But for major
8+
upgrades, you have to export all of your data using pg_dump, install the
9+
new release, run initdb to create a new cluster, and then import your
10+
old data. If you have a lot of data, that can take a considerable amount
11+
of time. If you have too much data, you may have to buy more storage
12+
since you need enough room to hold the original data plus the exported
13+
data. pg_migrator can reduce the amount of time and disk space required
14+
for many upgrades.
15+
16+
The URL http://momjian.us/main/writings/pgsql/pg_migrator.pdf contains a
17+
presentation about pg_migrator internals that mirrors the text
18+
description below.
19+
20+
------------------------------------------------------------------------------
21+
WHAT IT DOES
22+
------------------------------------------------------------------------------
23+
24+
pg_migrator is a tool that performs an in-place upgrade of existing
25+
data. Some upgrades change the on-disk representation of data;
26+
pg_migrator cannot help in those upgrades. However, many upgrades do
27+
not change the on-disk representation of a user-defined table. In those
28+
cases, pg_migrator can move existing user-defined tables from the old
29+
database cluster into the new cluster.
30+
31+
There are two factors that determine whether an in-place upgrade is
32+
practical.
33+
34+
Every table in a cluster shares the same on-disk representation of the
35+
table headers and trailers and the on-disk representation of tuple
36+
headers. If this changes between the old version of PostgreSQL and the
37+
new version, pg_migrator cannot move existing tables to the new cluster;
38+
you will have to pg_dump the old data and then import that data into the
39+
new cluster.
40+
41+
Second, all data types should have the same binary representation
42+
between the two major PostgreSQL versions.
43+
44+
------------------------------------------------------------------------------
45+
HOW IT WORKS
46+
------------------------------------------------------------------------------
47+
48+
To use pg_migrator during an upgrade, start by installing a fresh
49+
cluster using the newest version in a new directory. When you've
50+
finished installation, the new cluster will contain the new executables
51+
and the usual template0, template1, and postgres, but no user-defined
52+
tables. At this point, you can shut down the old and new postmasters and
53+
invoke pg_migrator.
54+
55+
When pg_migrator starts, it ensures that all required executables are
56+
present and contain the expected version numbers. The verification
57+
process also checks the old and new $PGDATA directories to ensure that
58+
the expected files and subdirectories are in place. If the verification
59+
process succeeds, pg_migrator starts the old postmaster and runs
60+
pg_dumpall --schema-only to capture the metadata contained in the old
61+
cluster. The script produced by pg_dumpall will be used in a later step
62+
to recreate all user-defined objects in the new cluster.
63+
64+
Note that the script produced by pg_dumpall will only recreate
65+
user-defined objects, not system-defined objects. The new cluster will
66+
contain the system-defined objects created by the latest version of
67+
PostgreSQL.
68+
69+
Once pg_migrator has extracted the metadata from the old cluster, it
70+
performs a number of bookkeeping tasks required to 'sync up' the new
71+
cluster with the existing data.
72+
73+
First, pg_migrator renames any tablespace directories in the old cluster
74+
--- the new cluster will need to use the same tablespace directories and
75+
will complain if those directories exist when pg_migrator imports the
76+
metadata in a later step. It then freeze all transaction information
77+
stored in old server rows.
78+
79+
Next, pg_migrator copies the commit status information and 'next
80+
transaction ID' from the old cluster to the new cluster. This is the
81+
steps ensures that the proper tuples are visible from the new cluster.
82+
Remember, pg_migrator does not export/import the content of user-defined
83+
tables so the transaction IDs in the new cluster must match the
84+
transaction IDs in the old data. pg_migrator also copies the starting
85+
address for write-ahead logs from the old cluster to the new cluster.
86+
87+
Now pg_migrator begins reconstructing the metadata obtained from the old
88+
cluster using the first part of the pg_dumpall output. Once all of the
89+
databases have been created in the new cluster, pg_migrator tackles the
90+
problem of naming toast relations. Toast tables are used to store
91+
oversized data out-of-line, i.e., in a separate file. When the server
92+
decides to move a datum out of a tuple and into a toast table, it stores
93+
a pointer in the original slot in the tuple. That pointer contains the
94+
relfilenode (i.e. filename) of the toast table. That means that any
95+
table which contains toasted data will contain the filename of the toast
96+
table in each toast pointer. Therefore, it is very important that toast
97+
tables retain their old names when they are created in the new cluster.
98+
CREATE TABLE does not offer any explicit support for naming toast
99+
tables. To ensure that the toast table names retain their old names,
100+
pg_migrator reserves the name of each toast table before importing the
101+
metadata from the old cluster. To reserve a filename, pg_migrator simply
102+
creates an empty file with the appropriate name and the server avoids
103+
that name when it detects a collision.
104+
105+
Next, pg_migrator executes the remainder of the script produced earlier
106+
by pg_dumpall --- this script effectively creates the complete
107+
user-defined metadata from the old cluster to the new cluster. When that
108+
script completes, pg_migrator, after shutting down the new postmaster,
109+
deletes the placeholder toast tables and sets the proper toast tuple
110+
names into the new cluster.
111+
112+
Finally, pg_migrator links or copies each user-defined table and its
113+
supporting indexes and toast tables from the old cluster to the new
114+
cluster. In this last step, pg_migrator assigns a new name to each
115+
relation so it matches the pg_class.relfilenode in the new
116+
cluster. Toast file names are preserved, as outlined above.
117+
118+
An important feature of the pg_migrator design is that it leaves the
119+
original cluster intact --- if a problem occurs during the upgrade, you
120+
can still run the previous version, after renaming the tablespaces back
121+
to the original names.

0 commit comments

Comments
 (0)