Skip to content

Commit 002c105

Browse files
committed
In pg_upgrade, remove functions that did sequential array scans looking
up relations, but rather order old/new relations and use the same array index value for both. This should speed up pg_upgrade for databases with many relations.
1 parent ebaf648 commit 002c105

File tree

5 files changed

+37
-109
lines changed

5 files changed

+37
-109
lines changed

contrib/pg_upgrade/function.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313

1414

1515
/*
16-
* install_support_functions_in_db()
16+
* install_support_functions_in_new_db()
1717
*
1818
* pg_upgrade requires some support functions that enable it to modify
1919
* backend behavior.
2020
*/
2121
void
22-
install_support_functions_in_db(const char *db_name)
22+
install_support_functions_in_new_db(const char *db_name)
2323
{
2424
PGconn *conn = connectToServer(&new_cluster, db_name);
2525

@@ -87,7 +87,7 @@ install_support_functions_in_db(const char *db_name)
8787

8888

8989
void
90-
uninstall_support_functions(void)
90+
uninstall_support_functions_from_new_cluster(void)
9191
{
9292
int dbnum;
9393

contrib/pg_upgrade/info.c

Lines changed: 14 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@ static void create_rel_filename_map(const char *old_data, const char *new_data,
2121
const DbInfo *old_db, const DbInfo *new_db,
2222
const RelInfo *old_rel, const RelInfo *new_rel,
2323
FileNameMap *map);
24-
static RelInfo *relarr_lookup_rel_name(ClusterInfo *cluster, RelInfoArr *rel_arr,
25-
const char *nspname, const char *relname);
26-
static RelInfo *relarr_lookup_rel_oid(ClusterInfo *cluster, RelInfoArr *rel_arr,
27-
Oid oid);
2824

2925

3026
/*
@@ -42,18 +38,22 @@ gen_db_file_maps(DbInfo *old_db, DbInfo *new_db,
4238
int relnum;
4339
int num_maps = 0;
4440

41+
if (old_db->rel_arr.nrels != new_db->rel_arr.nrels)
42+
pg_log(PG_FATAL, "old and new databases \"%s\" have a different number of relations\n",
43+
old_db->db_name);
44+
4545
maps = (FileNameMap *) pg_malloc(sizeof(FileNameMap) *
4646
old_db->rel_arr.nrels);
4747

4848
for (relnum = 0; relnum < old_db->rel_arr.nrels; relnum++)
4949
{
5050
RelInfo *old_rel = &old_db->rel_arr.rels[relnum];
51-
RelInfo *new_rel;
52-
53-
/* old/new relation names always match */
54-
new_rel = relarr_lookup_rel_name(&new_cluster, &new_db->rel_arr,
55-
old_rel->nspname, old_rel->relname);
51+
RelInfo *new_rel = &old_db->rel_arr.rels[relnum];
5652

53+
if (old_rel->reloid != new_rel->reloid)
54+
pg_log(PG_FATAL, "mismatch of relation id: database \"%s\", old relid %d, new relid %d\n",
55+
old_db->db_name, old_rel->reloid, new_rel->reloid);
56+
5757
create_rel_filename_map(old_pgdata, new_pgdata, old_db, new_db,
5858
old_rel, new_rel, maps + num_maps);
5959
num_maps++;
@@ -153,7 +153,9 @@ get_db_infos(ClusterInfo *cluster)
153153
"FROM pg_catalog.pg_database d "
154154
" LEFT OUTER JOIN pg_catalog.pg_tablespace t "
155155
" ON d.dattablespace = t.oid "
156-
"WHERE d.datallowconn = true");
156+
"WHERE d.datallowconn = true "
157+
/* we don't preserve pg_database.oid so we sort by name */
158+
"ORDER BY 2");
157159

158160
i_datname = PQfnumber(res, "datname");
159161
i_oid = PQfnumber(res, "oid");
@@ -258,7 +260,8 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo)
258260
"GROUP BY c.oid, n.nspname, c.relname, c.relfilenode,"
259261
" c.reltoastrelid, t.spclocation, "
260262
" n.nspname "
261-
"ORDER BY t.spclocation, n.nspname, c.relname;",
263+
/* we preserve pg_class.oid so we sort by it to match old/new */
264+
"ORDER BY 1;",
262265
FirstNormalObjectId,
263266
/* does pg_largeobject_metadata need to be migrated? */
264267
(GET_MAJOR_VERSION(old_cluster.major_version) <= 804) ?
@@ -308,86 +311,6 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo)
308311

309312
dbinfo->rel_arr.rels = relinfos;
310313
dbinfo->rel_arr.nrels = num_rels;
311-
dbinfo->rel_arr.last_relname_lookup = 0;
312-
}
313-
314-
315-
/*
316-
* dbarr_lookup_db()
317-
*
318-
* Returns the pointer to the DbInfo structure
319-
*/
320-
DbInfo *
321-
dbarr_lookup_db(DbInfoArr *db_arr, const char *db_name)
322-
{
323-
int dbnum;
324-
325-
for (dbnum = 0; dbnum < db_arr->ndbs; dbnum++)
326-
{
327-
if (strcmp(db_arr->dbs[dbnum].db_name, db_name) == 0)
328-
return &db_arr->dbs[dbnum];
329-
}
330-
331-
return NULL;
332-
}
333-
334-
335-
/*
336-
* relarr_lookup_rel_name()
337-
*
338-
* Searches "relname" in rel_arr. Returns the *real* pointer to the
339-
* RelInfo structure.
340-
*/
341-
static RelInfo *
342-
relarr_lookup_rel_name(ClusterInfo *cluster, RelInfoArr *rel_arr,
343-
const char *nspname, const char *relname)
344-
{
345-
int relnum;
346-
347-
/* Test next lookup first, for speed */
348-
if (rel_arr->last_relname_lookup + 1 < rel_arr->nrels &&
349-
strcmp(rel_arr->rels[rel_arr->last_relname_lookup + 1].nspname, nspname) == 0 &&
350-
strcmp(rel_arr->rels[rel_arr->last_relname_lookup + 1].relname, relname) == 0)
351-
{
352-
rel_arr->last_relname_lookup++;
353-
return &rel_arr->rels[rel_arr->last_relname_lookup];
354-
}
355-
356-
for (relnum = 0; relnum < rel_arr->nrels; relnum++)
357-
{
358-
if (strcmp(rel_arr->rels[relnum].nspname, nspname) == 0 &&
359-
strcmp(rel_arr->rels[relnum].relname, relname) == 0)
360-
{
361-
rel_arr->last_relname_lookup = relnum;
362-
return &rel_arr->rels[relnum];
363-
}
364-
}
365-
pg_log(PG_FATAL, "Could not find %s.%s in %s cluster\n",
366-
nspname, relname, CLUSTER_NAME(cluster));
367-
return NULL;
368-
}
369-
370-
371-
/*
372-
* relarr_lookup_rel_oid()
373-
*
374-
* Returns a pointer to the RelInfo structure for the
375-
* given oid or NULL if the desired entry cannot be
376-
* found.
377-
*/
378-
static RelInfo *
379-
relarr_lookup_rel_oid(ClusterInfo *cluster, RelInfoArr *rel_arr, Oid oid)
380-
{
381-
int relnum;
382-
383-
for (relnum = 0; relnum < rel_arr->nrels; relnum++)
384-
{
385-
if (rel_arr->rels[relnum].reloid == oid)
386-
return &rel_arr->rels[relnum];
387-
}
388-
pg_log(PG_FATAL, "Could not find %d in %s cluster\n",
389-
oid, CLUSTER_NAME(cluster));
390-
return NULL;
391314
}
392315

393316

@@ -396,7 +319,6 @@ free_rel_arr(RelInfoArr *rel_arr)
396319
{
397320
pg_free(rel_arr->rels);
398321
rel_arr->nrels = 0;
399-
rel_arr->last_relname_lookup = 0;
400322
}
401323

402324

contrib/pg_upgrade/pg_upgrade.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ prepare_new_databases(void)
229229
* Install support functions in the database accessed by
230230
* GLOBALS_DUMP_FILE because it can preserve pg_authid.oid.
231231
*/
232-
install_support_functions_in_db(os_info.user);
232+
install_support_functions_in_new_db(os_info.user);
233233

234234
/*
235235
* We have to create the databases first so we can install support
@@ -244,6 +244,7 @@ prepare_new_databases(void)
244244
GLOBALS_DUMP_FILE, log_opts.filename);
245245
check_ok();
246246

247+
/* we load this to get a current list of databases */
247248
get_db_and_rel_infos(&new_cluster);
248249

249250
stop_postmaster(false, false);
@@ -266,7 +267,7 @@ create_new_objects(void)
266267

267268
/* skip db we already installed */
268269
if (strcmp(new_db->db_name, os_info.user) != 0)
269-
install_support_functions_in_db(new_db->db_name);
270+
install_support_functions_in_new_db(new_db->db_name);
270271
}
271272
check_ok();
272273

@@ -279,11 +280,11 @@ create_new_objects(void)
279280
DB_DUMP_FILE, log_opts.filename);
280281
check_ok();
281282

282-
/* regenerate now that we have db schemas */
283+
/* regenerate now that we have objects in the databases */
283284
dbarr_free(&new_cluster.dbarr);
284285
get_db_and_rel_infos(&new_cluster);
285286

286-
uninstall_support_functions();
287+
uninstall_support_functions_from_new_cluster();
287288

288289
stop_postmaster(false, false);
289290
}

contrib/pg_upgrade/pg_upgrade.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ typedef struct
7777
{
7878
RelInfo *rels;
7979
int nrels;
80-
int last_relname_lookup; /* cache of last lookup location */
8180
} RelInfoArr;
8281

8382
/*
@@ -321,8 +320,8 @@ void check_hard_link(void);
321320

322321
/* function.c */
323322

324-
void install_support_functions_in_db(const char *db_name);
325-
void uninstall_support_functions(void);
323+
void install_support_functions_in_new_db(const char *db_name);
324+
void uninstall_support_functions_from_new_cluster(void);
326325
void get_loadable_libraries(void);
327326
void check_loadable_libraries(void);
328327

@@ -331,8 +330,7 @@ void check_loadable_libraries(void);
331330
FileNameMap *gen_db_file_maps(DbInfo *old_db,
332331
DbInfo *new_db, int *nmaps, const char *old_pgdata,
333332
const char *new_pgdata);
334-
void get_db_and_rel_infos(ClusterInfo *cluster);
335-
DbInfo *dbarr_lookup_db(DbInfoArr *db_arr, const char *db_name);
333+
void get_db_and_rel_infos(ClusterInfo *cluster);
336334
void dbarr_free(DbInfoArr *db_arr);
337335
void print_maps(FileNameMap *maps, int n,
338336
const char *dbName);

contrib/pg_upgrade/relfilenode.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,29 @@ char scandir_file_pattern[MAXPGPATH];
2929
* physically link the databases.
3030
*/
3131
const char *
32-
transfer_all_new_dbs(DbInfoArr *olddb_arr,
33-
DbInfoArr *newdb_arr, char *old_pgdata, char *new_pgdata)
32+
transfer_all_new_dbs(DbInfoArr *old_db_arr,
33+
DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata)
3434
{
3535
int dbnum;
3636
const char *msg = NULL;
3737

3838
prep_status("Restoring user relation files\n");
3939

40-
for (dbnum = 0; dbnum < newdb_arr->ndbs; dbnum++)
40+
if (old_db_arr->ndbs != new_db_arr->ndbs)
41+
pg_log(PG_FATAL, "old and new clusters have a different number of databases\n");
42+
43+
for (dbnum = 0; dbnum < old_db_arr->ndbs; dbnum++)
4144
{
42-
DbInfo *new_db = &newdb_arr->dbs[dbnum];
43-
DbInfo *old_db = dbarr_lookup_db(olddb_arr, new_db->db_name);
45+
DbInfo *old_db = &old_db_arr->dbs[dbnum];
46+
DbInfo *new_db = &new_db_arr->dbs[dbnum];
4447
FileNameMap *mappings;
4548
int n_maps;
4649
pageCnvCtx *pageConverter = NULL;
4750

51+
if (strcmp(old_db->db_name, new_db->db_name) != 0)
52+
pg_log(PG_FATAL, "old and new databases have a different names: old \"%s\", new \"%s\"\n",
53+
old_db->db_name, new_db->db_name);
54+
4855
n_maps = 0;
4956
mappings = gen_db_file_maps(old_db, new_db, &n_maps, old_pgdata,
5057
new_pgdata);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy