Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/bin/pgcopydb/cli_clone_follow.c
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,21 @@ cloneDB(CopyDataSpec *copySpecs)
return false;
}

/*
* On --resume the per-run part/index election tables still hold the pids of
* dead prior-run workers. Clear them now, single-threaded and before any
* table-data worker is forked, so a fresh election among live workers
* re-drives index/constraint creation for split (multi-part) tables.
*/
if (copySpecs->resume)
{
if (!copydb_resume_reset_part_election(copySpecs))
{
/* errors have already been logged */
return false;
}
}

/* now register in the catalogs the already known startTime */
if (!summary_start_timing(sourceDB, TIMING_SECTION_TOTAL))
{
Expand Down
1 change: 1 addition & 0 deletions src/bin/pgcopydb/copydb.h
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@ bool copydb_prepare_sequence_specs(CopyDataSpec *specs, PGSQL *pgsql, bool reset

/* copydb_schema.c */
bool copydb_fetch_schema_and_prepare_specs(CopyDataSpec *specs);
bool copydb_resume_reset_part_election(CopyDataSpec *specs);
bool copydb_objectid_is_filtered_out(CopyDataSpec *specs,
uint32_t catalogOid,
uint32_t oid,
Expand Down
39 changes: 39 additions & 0 deletions src/bin/pgcopydb/copydb_schema.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,45 @@ copydb_fetch_schema_and_prepare_specs(CopyDataSpec *specs)
}


/*
* copydb_resume_reset_part_election clears the per-run "who finished last"
* election tables (s_table_parts_done, s_table_indexes_done) so that a
* --resume run holds a fresh election among live workers.
*
* These tables only ever store per-run election tokens (a tableoid and the
* getpid() of the worker that observed the last part/index as done); progress
* itself lives in the summary table (done_time_epoch). On resume the stored
* pids belong to dead prior-run processes, so no live worker matches and the
* index/constraint enqueue for a split (multi-part) table is never re-driven.
* Clearing the tokens loses no progress and re-enqueue is idempotent
* (IF NOT EXISTS / doneTime / foundConstraintOnTarget checks).
*
* Must run single-threaded before any COPY/table-data worker is forked, or the
* workers would race and wipe freshly-elected tokens.
*/
bool
copydb_resume_reset_part_election(CopyDataSpec *specs)
{
DatabaseCatalog *sourceDB = &(specs->catalogs.source);

log_notice("Resetting stale part/index election state for --resume");

if (!catalog_execute(sourceDB, "delete from s_table_parts_done"))
{
/* errors have already been logged */
return false;
}

if (!catalog_execute(sourceDB, "delete from s_table_indexes_done"))
{
/* errors have already been logged */
return false;
}

return true;
}


/*
* copydb_fetch_source_catalog_setup initializes our local catalog cache and
* checks the setup and cache state.
Expand Down
Loading