Update sharding_key_id for runners tables sharded by project when original project is deleted
We use a new ci_runners.sharding_key_id
column to keep track of which cell a runner belongs to. When the project that is associated with a project runner (i.e. assigned to the sharding_key_id
field) is deleted, we are in a situation where the sharding_key_id
cannot fulfill its role to determine the owning organization (for example, in the event of an organization move to a new cell). We should therefore recompute the sharding_key_id
field for each affected runner, runner manager, and runner tagging. The logic so far has been to use the next most-recent associated project (as determined by the ci_runner_projects
table), so for simplicity we should do the same. We could also decide to delete runners that are no longer associated with any project, but that is optional.
Note: we also need to update the respective ci_runner_machines
and ci_runner_taggings
records.
Example
- Picture the following records:
-
projects
withid: 10
-
ci_runners
withid: 1, sharding_key_id: 10
-
ci_runner_machines
withrunner_id: 1, sharding_key_id: 10
-
ci_runner_machines
withrunner_id: 1, sharding_key_id: 11
-
ci_runner_projects
withid: 1, runner_id: 1, project_id: 10
-
ci_runner_projects
withid: 1, runner_id: 1, project_id: 11
-
- Now
projects
with id 10 is deleted. We want to have:-
ci_runners
withid: 1, sharding_key_id: 11
-
ci_runner_machines
withrunner_id: 1, sharding_key_id: 11
-
ci_runner_projects
withid: 1, runner_id: 1, project_id: 11
-
Proposal
-
Leverage the ::Projects::ProjectDeletedEvent
to trigger a new::Ci::Runners::UpdateProjectRunnersOwnerWorker
to go through the affected runners and update thesharding_key_id
fields. We'll need indices onci_runners.sharding_key_id
andci_runner_machines.sharding_key_id
for efficient lookup (currently only exists on the partitioned table). -
If the runner is not associated with any other projects, delete the runner (source). -
Ensure the behaviors are documented in the relevant documentation page (source).
Verification
With this issue solved, we should see no increase over time in the result of the following queries:
SELECT COUNT(*) FROM ci_runners WHERE runner_type = 3 AND sharding_key_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM ci_runner_projects WHERE ci_runners.sharding_key_id = ci_runner_projects.project_id AND ci_runners.id = ci_runner_projects.runner_id)
ℹ️ info Data state at: 2025-01-08 04:45:30 UTC7952
SELECT COUNT(*) FROM ci_runners_e59bb2812d WHERE runner_type = 3 AND sharding_key_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM ci_runner_projects WHERE ci_runners_e59bb2812d.sharding_key_id = ci_runner_projects.project_id AND ci_runners_e59bb2812d.id = ci_runner_projects.runner_id)
ℹ️ info Data state at: 2025-01-08 04:45:30 UTC7977