Skip to content

Commit 4cff100

Browse files
committed
Fix parallel pg_restore to handle comments on POST_DATA items correctly.
The previous coding would try to process all SECTION_NONE items in the initial sequential-restore pass, which failed if they were dependencies of not-yet-restored items. Fix by postponing such items into the parallel processing pass once we have skipped any non-PRE_DATA item. Back-patch into 9.0; the original parallel-restore coding in 8.4 did not have this bug, so no need to change it. Report and diagnosis by Arnd Hannemann.
1 parent 472f608 commit 4cff100

File tree

1 file changed

+50
-15
lines changed

1 file changed

+50
-15
lines changed

src/bin/pg_dump/pg_backup_archiver.c

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3218,12 +3218,12 @@ dumpTimestamp(ArchiveHandle *AH, const char *msg, time_t tim)
32183218
* Main engine for parallel restore.
32193219
*
32203220
* Work is done in three phases.
3221-
* First we process tocEntries until we come to one that is marked
3222-
* SECTION_DATA or SECTION_POST_DATA, in a single connection, just as for a
3223-
* standard restore. Second we process the remaining non-ACL steps in
3224-
* parallel worker children (threads on Windows, processes on Unix), each of
3225-
* which connects separately to the database. Finally we process all the ACL
3226-
* entries in a single connection (that happens back in RestoreArchive).
3221+
* First we process all SECTION_PRE_DATA tocEntries, in a single connection,
3222+
* just as for a standard restore. Second we process the remaining non-ACL
3223+
* steps in parallel worker children (threads on Windows, processes on Unix),
3224+
* each of which connects separately to the database. Finally we process all
3225+
* the ACL entries in a single connection (that happens back in
3226+
* RestoreArchive).
32273227
*/
32283228
static void
32293229
restore_toc_entries_parallel(ArchiveHandle *AH)
@@ -3233,6 +3233,7 @@ restore_toc_entries_parallel(ArchiveHandle *AH)
32333233
ParallelSlot *slots;
32343234
int work_status;
32353235
int next_slot;
3236+
bool skipped_some;
32363237
TocEntry pending_list;
32373238
TocEntry ready_list;
32383239
TocEntry *next_work_item;
@@ -3262,12 +3263,31 @@ restore_toc_entries_parallel(ArchiveHandle *AH)
32623263
* showing all the dependencies of SECTION_PRE_DATA items, so we do not
32633264
* risk trying to process them out-of-order.
32643265
*/
3266+
skipped_some = false;
32653267
for (next_work_item = AH->toc->next; next_work_item != AH->toc; next_work_item = next_work_item->next)
32663268
{
3267-
/* Non-PRE_DATA items are just ignored for now */
3268-
if (next_work_item->section == SECTION_DATA ||
3269-
next_work_item->section == SECTION_POST_DATA)
3270-
continue;
3269+
/* NB: process-or-continue logic must be the inverse of loop below */
3270+
if (next_work_item->section != SECTION_PRE_DATA)
3271+
{
3272+
/* DATA and POST_DATA items are just ignored for now */
3273+
if (next_work_item->section == SECTION_DATA ||
3274+
next_work_item->section == SECTION_POST_DATA)
3275+
{
3276+
skipped_some = true;
3277+
continue;
3278+
}
3279+
else
3280+
{
3281+
/*
3282+
* SECTION_NONE items, such as comments, can be processed now
3283+
* if we are still in the PRE_DATA part of the archive. Once
3284+
* we've skipped any items, we have to consider whether the
3285+
* comment's dependencies are satisfied, so skip it for now.
3286+
*/
3287+
if (skipped_some)
3288+
continue;
3289+
}
3290+
}
32713291

32723292
ahlog(AH, 1, "processing item %d %s %s\n",
32733293
next_work_item->dumpId,
@@ -3310,17 +3330,32 @@ restore_toc_entries_parallel(ArchiveHandle *AH)
33103330
*/
33113331
par_list_header_init(&pending_list);
33123332
par_list_header_init(&ready_list);
3333+
skipped_some = false;
33133334
for (next_work_item = AH->toc->next; next_work_item != AH->toc; next_work_item = next_work_item->next)
33143335
{
3315-
/* All PRE_DATA items were dealt with above */
3336+
/* NB: process-or-continue logic must be the inverse of loop above */
3337+
if (next_work_item->section == SECTION_PRE_DATA)
3338+
{
3339+
/* All PRE_DATA items were dealt with above */
3340+
continue;
3341+
}
33163342
if (next_work_item->section == SECTION_DATA ||
33173343
next_work_item->section == SECTION_POST_DATA)
33183344
{
3319-
if (next_work_item->depCount > 0)
3320-
par_list_append(&pending_list, next_work_item);
3321-
else
3322-
par_list_append(&ready_list, next_work_item);
3345+
/* set this flag at same point that previous loop did */
3346+
skipped_some = true;
33233347
}
3348+
else
3349+
{
3350+
/* SECTION_NONE items must be processed if previous loop didn't */
3351+
if (!skipped_some)
3352+
continue;
3353+
}
3354+
3355+
if (next_work_item->depCount > 0)
3356+
par_list_append(&pending_list, next_work_item);
3357+
else
3358+
par_list_append(&ready_list, next_work_item);
33243359
}
33253360

33263361
/*

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