Skip to content

Commit 16f2ead

Browse files
committed
When doing a parallel restore, we must guard against out-of-range dependency
dump IDs, because the array we're using is sized according to the highest dump ID actually defined in the archive file. In a partial dump there could be references to higher dump IDs that weren't dumped. Treat these the same as references to in-range IDs that weren't dumped. (The whole thing is a bit scary because the missing objects might have been part of dependency chains, which we won't know about. Not much we can do though --- throwing an error is probably overreaction.) Also, reject parallel restore with pre-1.8 archive version (made by pre-8.0 pg_dump). In these old versions the dependency entries are OIDs, not dump IDs, and we don't have enough information to interpret them. Per bug #5288 from Jon Erdman.
1 parent 85b587c commit 16f2ead

File tree

1 file changed

+26
-10
lines changed

1 file changed

+26
-10
lines changed

src/bin/pg_dump/pg_backup_archiver.c

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.177 2009/12/14 00:39:10 itagaki Exp $
18+
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.178 2010/01/19 18:39:19 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -134,7 +134,8 @@ static bool has_lock_conflicts(TocEntry *te1, TocEntry *te2);
134134
static void repoint_table_dependencies(ArchiveHandle *AH,
135135
DumpId tableId, DumpId tableDataId);
136136
static void identify_locking_dependencies(TocEntry *te,
137-
TocEntry **tocsByDumpId);
137+
TocEntry **tocsByDumpId,
138+
DumpId maxDumpId);
138139
static void reduce_dependencies(ArchiveHandle *AH, TocEntry *te,
139140
TocEntry *ready_list);
140141
static void mark_create_done(ArchiveHandle *AH, TocEntry *te);
@@ -3091,6 +3092,10 @@ restore_toc_entries_parallel(ArchiveHandle *AH)
30913092
if (AH->ClonePtr == NULL || AH->ReopenPtr == NULL)
30923093
die_horribly(AH, modulename, "parallel restore is not supported with this archive file format\n");
30933094

3095+
/* doesn't work if the archive represents dependencies as OIDs, either */
3096+
if (AH->version < K_VERS_1_8)
3097+
die_horribly(AH, modulename, "parallel restore is not supported with archives made by pre-8.0 pg_dump\n");
3098+
30943099
slots = (ParallelSlot *) calloc(sizeof(ParallelSlot), n_slots);
30953100

30963101
/* Adjust dependency information */
@@ -3649,17 +3654,23 @@ fix_dependencies(ArchiveHandle *AH)
36493654
{
36503655
TocEntry **tocsByDumpId;
36513656
TocEntry *te;
3657+
DumpId maxDumpId;
36523658
int i;
36533659

36543660
/*
36553661
* For some of the steps here, it is convenient to have an array that
36563662
* indexes the TOC entries by dump ID, rather than searching the TOC list
36573663
* repeatedly. Entries for dump IDs not present in the TOC will be NULL.
36583664
*
3665+
* NOTE: because maxDumpId is just the highest dump ID defined in the
3666+
* archive, there might be dependencies for IDs > maxDumpId. All uses
3667+
* of this array must guard against out-of-range dependency numbers.
3668+
*
36593669
* Also, initialize the depCount fields, and make sure all the TOC items
36603670
* are marked as not being in any parallel-processing list.
36613671
*/
3662-
tocsByDumpId = (TocEntry **) calloc(AH->maxDumpId, sizeof(TocEntry *));
3672+
maxDumpId = AH->maxDumpId;
3673+
tocsByDumpId = (TocEntry **) calloc(maxDumpId, sizeof(TocEntry *));
36633674
for (te = AH->toc->next; te != AH->toc; te = te->next)
36643675
{
36653676
tocsByDumpId[te->dumpId - 1] = te;
@@ -3688,7 +3699,8 @@ fix_dependencies(ArchiveHandle *AH)
36883699
{
36893700
DumpId tableId = te->dependencies[0];
36903701

3691-
if (tocsByDumpId[tableId - 1] == NULL ||
3702+
if (tableId > maxDumpId ||
3703+
tocsByDumpId[tableId - 1] == NULL ||
36923704
strcmp(tocsByDumpId[tableId - 1]->desc, "TABLE") == 0)
36933705
{
36943706
repoint_table_dependencies(AH, tableId, te->dumpId);
@@ -3733,7 +3745,9 @@ fix_dependencies(ArchiveHandle *AH)
37333745
{
37343746
for (i = 0; i < te->nDeps; i++)
37353747
{
3736-
if (tocsByDumpId[te->dependencies[i] - 1] == NULL)
3748+
DumpId depid = te->dependencies[i];
3749+
3750+
if (depid > maxDumpId || tocsByDumpId[depid - 1] == NULL)
37373751
te->depCount--;
37383752
}
37393753
}
@@ -3745,7 +3759,7 @@ fix_dependencies(ArchiveHandle *AH)
37453759
{
37463760
te->lockDeps = NULL;
37473761
te->nLockDeps = 0;
3748-
identify_locking_dependencies(te, tocsByDumpId);
3762+
identify_locking_dependencies(te, tocsByDumpId, maxDumpId);
37493763
}
37503764

37513765
free(tocsByDumpId);
@@ -3782,11 +3796,13 @@ repoint_table_dependencies(ArchiveHandle *AH,
37823796
* Identify which objects we'll need exclusive lock on in order to restore
37833797
* the given TOC entry (*other* than the one identified by the TOC entry
37843798
* itself). Record their dump IDs in the entry's lockDeps[] array.
3785-
* tocsByDumpId[] is a convenience array to avoid searching the TOC
3786-
* for each dependency.
3799+
* tocsByDumpId[] is a convenience array (of size maxDumpId) to avoid
3800+
* searching the TOC for each dependency.
37873801
*/
37883802
static void
3789-
identify_locking_dependencies(TocEntry *te, TocEntry **tocsByDumpId)
3803+
identify_locking_dependencies(TocEntry *te,
3804+
TocEntry **tocsByDumpId,
3805+
DumpId maxDumpId)
37903806
{
37913807
DumpId *lockids;
37923808
int nlockids;
@@ -3817,7 +3833,7 @@ identify_locking_dependencies(TocEntry *te, TocEntry **tocsByDumpId)
38173833
{
38183834
DumpId depid = te->dependencies[i];
38193835

3820-
if (tocsByDumpId[depid - 1] &&
3836+
if (depid <= maxDumpId && tocsByDumpId[depid - 1] &&
38213837
strcmp(tocsByDumpId[depid - 1]->desc, "TABLE DATA") == 0)
38223838
lockids[nlockids++] = depid;
38233839
}

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