Recount blocking_issues_count left too high by deleted blocked issues

Why are we doing this work

Before !265408 (merged), deleting an open blocked issue left the issues.blocking_issues_count of every issue blocking it too high (#636333 (closed)): its issue_links rows are removed by the ON DELETE CASCADE on target_id, which runs no link callback. Group deletion (fk_c78fbacd64, a cascade on issues.namespace_id) still does. GraphQL blockingCount, the work items REST API's blocking_count and the BLOCKING_ISSUES_* sorts read the column, and a count left too high stays that way until something recounts it.

As agreed in the review of !265408 (merged), a batched background migration should repair the counts that are already wrong.

Non-functional requirements

  • Performance: batch over issues with blocking_issues_count > 0 (the bug only leaves counts too high), recount with the query blocking_issuables_for_collection builds (it returns no row for a blocker with no blocking link left, whose count must become 0), and update only the rows that differ.
  • Testing: a migration spec with a count left too high, with and without blocking links left, a correct count, and a blocker whose blocked issues are all closed.

Implementation plan

  • backend A batched background migration that recounts blocking_issues_count, and the post-deployment migration that queues it.
  • database Database review of the batching and the recount query.

Verification steps

  1. Leave a blocker's count too high (block an issue, then delete it on a build without !265408 (merged)) and run the migration.
  2. GraphQL blockingCount then matches blocking_issues_count in GET /api/v4/projects/:id/issues/:issue_iid, which counts live.
Edited by 🤖 GitLab Bot 🤖