Skip to content

Commit b1c2d76

Browse files
committed
Fix possible core dump in parallel restore when using a TOC list.
Commit 3eb9a5e unintentionally introduced an ordering dependency into restore_toc_entries_prefork(). The existing coding of reduce_dependencies() contains a check to skip moving a TOC entry to the ready_list if it wasn't initially in the pending_list. This used to suffice to prevent reduce_dependencies() from trying to move anything into the ready_list during restore_toc_entries_prefork(), because the pending_list stayed empty throughout that phase; but it no longer does. The problem doesn't manifest unless the TOC has been reordered by SortTocFromFile, which is how I missed it in testing. To fix, just add a test for ready_list == NULL, converting the call with NULL from a poor man's sanity check into an explicit command not to touch TOC items' list membership. Clarify some of the comments around this; in particular, note the primary purpose of the check for pending_list membership, which is to ensure that we can't try to restore the same item twice, in case a TOC list forces it to be restored before its dependency count goes to zero. Per report from Fabrízio de Royes Mello. Back-patch to 9.3, like the previous commit. Discussion: https://postgr.es/m/CAFcNs+pjuv0JL_x4+=71TPUPjdLHOXA4YfT32myj_OrrZb4ohA@mail.gmail.com
1 parent 24620fc commit b1c2d76

File tree

1 file changed

+14
-9
lines changed

1 file changed

+14
-9
lines changed

src/bin/pg_dump/pg_backup_archiver.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3851,8 +3851,9 @@ restore_toc_entries_prefork(ArchiveHandle *AH, TocEntry *pending_list)
38513851
*
38523852
* Note: as of 9.2, it should be guaranteed that all PRE_DATA items appear
38533853
* before DATA items, and all DATA items before POST_DATA items. That is
3854-
* not certain to be true in older archives, though, so this loop is coded
3855-
* to not assume it.
3854+
* not certain to be true in older archives, though, and in any case use
3855+
* of a list file would destroy that ordering (cf. SortTocFromFile). So
3856+
* this loop cannot assume that it holds.
38563857
*/
38573858
AH->restorePass = RESTORE_PASS_MAIN;
38583859
skipped_some = false;
@@ -3899,7 +3900,7 @@ restore_toc_entries_prefork(ArchiveHandle *AH, TocEntry *pending_list)
38993900

39003901
(void) restore_toc_entry(AH, next_work_item, false);
39013902

3902-
/* there should be no touch of ready_list here, so pass NULL */
3903+
/* Reduce dependencies, but don't move anything to ready_list */
39033904
reduce_dependencies(AH, next_work_item, NULL);
39043905
}
39053906
else
@@ -4545,7 +4546,7 @@ identify_locking_dependencies(ArchiveHandle *AH, TocEntry *te)
45454546
/*
45464547
* Remove the specified TOC entry from the depCounts of items that depend on
45474548
* it, thereby possibly making them ready-to-run. Any pending item that
4548-
* becomes ready should be moved to the ready list.
4549+
* becomes ready should be moved to the ready_list, if that's provided.
45494550
*/
45504551
static void
45514552
reduce_dependencies(ArchiveHandle *AH, TocEntry *te, TocEntry *ready_list)
@@ -4562,15 +4563,19 @@ reduce_dependencies(ArchiveHandle *AH, TocEntry *te, TocEntry *ready_list)
45624563
otherte->depCount--;
45634564

45644565
/*
4565-
* It's ready if it has no remaining dependencies and it belongs in
4566-
* the current restore pass. However, don't move it if it has not yet
4567-
* been put into the pending list.
4566+
* It's ready if it has no remaining dependencies, and it belongs in
4567+
* the current restore pass, and it is currently a member of the
4568+
* pending list (that check is needed to prevent double restore in
4569+
* some cases where a list-file forces out-of-order restoring).
4570+
* However, if ready_list == NULL then caller doesn't want any list
4571+
* memberships changed.
45684572
*/
45694573
if (otherte->depCount == 0 &&
45704574
_tocEntryRestorePass(otherte) == AH->restorePass &&
4571-
otherte->par_prev != NULL)
4575+
otherte->par_prev != NULL &&
4576+
ready_list != NULL)
45724577
{
4573-
/* It must be in the pending list, so remove it ... */
4578+
/* Remove it from pending list ... */
45744579
par_list_remove(otherte);
45754580
/* ... and add to ready_list */
45764581
par_list_append(ready_list, otherte);

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