Backfill missing epic_issues rows from parent links
What does this MR do and why?
Some work_item_parent_links rows for issues under legacy-synced epics have no matching legacy epic_issues row.
- Guard against missing legacy epic_issues row in... (!249710 - merged) made the REST API tolerate the gap
- [Fix] Prevent parent links creation without a l... (!250295 - merged) fixed the write paths that created it.
This MR repairs the ~225 rows that already exist on GitLab.com.
Same repair pattern as FixSyncedEpicWorkItemParentLinks (!156657 (merged)), which fixed this inconsistency in the other direction when epic_issues was still the source of truth.
Query plan
Plan: https://console.postgres.ai/gitlab/projects/gitlab-production-main/sessions/56436/commands/160627
Safety
- Insert-only, no
UPDATEorDELETE; rows that disagree with their parent link are left as-is. - Idempotent:
NOT EXISTSanti-joins plusON CONFLICT DO NOTHINGagainst the unique indexes onissue_idandwork_item_parent_link_id, so retries and races with the live write path are no-ops. - The write paths that created these rows are fixed as of !250295 (merged), so the population only shrinks.
How to validate locally
-
On a GDK with an Ultimate license, create a group-level epic and a project issue, then link them without the legacy row:
link = WorkItems::ParentLink.new(work_item: WorkItem.find(issue.id), work_item_parent: epic.work_item) link.work_item_syncing = true link.save! -
Confirm
EpicIssue.find_by(issue_id: issue.id)is nil. -
Run the migration job and confirm the row is created with the epic, the link id and the issue's
namespace_id:Gitlab::BackgroundMigration::BackfillMissingEpicIssuesFromParentLinks.new( start_cursor: [Epic.minimum(:id)], end_cursor: [Epic.maximum(:id)], batch_table: :epics, batch_column: :id, sub_batch_size: 100, pause_ms: 0, connection: ApplicationRecord.connection ).perform
Related to
Resolves the backfill follow-up from https://gitlab.com/gitlab-org/gitlab/-/issues/612058.