Swap issues bigint columns batch one

What does this MR do and why?

Swaps the first batch of issues integer ID columns to their bigint counterparts, as part of the conversion tracked in #629827 (closed).

The prerequisites for this batch are already merged: the bigint indexes were prepared asynchronously (!251347 (merged)) and created synchronously (!253447 (merged)), and the foreign keys were added and validated (!253725 (merged)). This MR performs the swap and cleans up the temporary objects.

Columns swapped (6)

closed_by_id, duplicated_to_id, last_edited_by_id, moved_to_id, promoted_to_epic_id, updated_by_id

id, project_id, milestone_id, and author_id are not in this batch — they are coupled through composite indexes and handled in later batches.

Migrations

Migration Action
20260916090001 Swap the six columns, indexes, and foreign keys (single transaction)
20260916090002 Drop fk_c63cbf6c25_tmp (closed_by_id → users)
20260916090003 Drop fk_9c4516d665_tmp (duplicated_to_id → issues)
20260916090004 Drop fk_a194299be1_tmp (moved_to_id → issues)
20260916090005 Drop fk_df75a7c8b8_tmp (promoted_to_epic_id → epics)
20260916090006 Drop fk_ffed080f01_tmp (updated_by_id → users)
20260916090007 Drop the six temporary bigint_idx_* indexes

The swap (20260916090001)

In a single with_lock_retries transaction it swaps the six columns with their *_convert_to_bigint counterparts, resets the sync trigger, swaps the 6 indexes (canonical name ↔️ bigint_idx_*), and swaps the 5 foreign keys (canonical name ↔️ *_tmp). Running everything in one transaction guarantees the schema is never left partially swapped, which is why this step is not split per column.

Cleaning up the temporary objects

After the swap, the bigint_idx_* indexes and *_tmp foreign keys sit on the old integer columns and are removed. Following the bigint conversion guidelines:

  • Each temporary foreign key is dropped in its own migration, so one drop failing to acquire its lock does not block the others.
  • Foreign keys are dropped before the indexes. A live foreign key with no supporting index makes deletes from the referenced table (users, issues, epics) time out, so the temporary indexes are removed last.

All migrations are guarded on the conversion columns' existence and type, so they are no-ops on instances that already have native bigint IDs.

Scope

Item Count Notes
Columns 6 none has a column default, so no default swap
Indexes 6 one per column, no composites
Foreign keys 5 last_edited_by_id has no FK

There is no primary key swap in this batch (id is converted later).

Why the backfill assurance helper is omitted

The swap intentionally does not call ensure_backfill_conversion_of_integer_to_bigint_is_finished. That helper checks for a CopyColumnUsingBackgroundMigrationJob record, but the issues bigint columns were backfilled by the custom BackfillIssuesCorrectWorkItemTypeId batched background migration (introduced in !167972 (merged), finalized by 20241030165330). Calling the helper would raise because no matching record exists for this table. The backfill is complete: the sync trigger was created in the same migration as the columns, so every write since has been kept in sync, and the batched background migration backfilled all pre-existing rows.

Migration output

db/structure.sql is unchanged: after the swap the six columns are bigint, which already matches the committed schema, and the temporary indexes/foreign keys live on *_convert_to_bigint columns that are not part of that schema. (Danger flags "new migrations added but db/structure.sql wasn't updated"; this is expected for ID conversions.)

Verification before merge

Confirmed on a production clone that all five temporary foreign keys are VALID and all six bigint_idx_* indexes are valid before the swap.

MR acceptance checklist

  • Database review requested — column swap with index and foreign key swaps, plus temporary object cleanup.
Edited by Mario Celi

Merge request reports

Loading
Loading