diff --git a/.rubocop.yml b/.rubocop.yml
index 12eee5702bc539aa53ac5e23bb9bc66cfc5b85cc..6aa0e1ca4d7eb99688a61ede109533b6432a0ebc 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -54,6 +54,10 @@ AllCops:
     - 'shared/packages/**/*'
     - 'spec/support/*.git/**/*'  # e.g. spec/support/gitlab-git-test.git
     - 'db/ci_migrate/*.rb'      # since the `db/ci_migrate` is a symlinked to `db/migrate`
+    # Adding this specifically for a large revert: !118368
+    <% File.readlines('.rubocop_revert_ignores.txt').map(&:chomp).each do |f| %>
+    - '<%= f %>'
+    <% end %>
   # Use absolute path to avoid orphan directories with changed workspace root.
   CacheRootDirectory: <%= Dir.getwd %>/tmp
   MaxFilesInCache: 1_000_000
diff --git a/.rubocop_revert_ignores.txt b/.rubocop_revert_ignores.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e3c30ea9bad822c9dc8c2bf046ef2bff67ae52b4
--- /dev/null
+++ b/.rubocop_revert_ignores.txt
@@ -0,0 +1,390 @@
+db/migrate/20211202041233_init_schema.rb
+db/migrate/20211202094944_move_loose_fk_deleted_records_to_dynamic_schema.rb
+db/migrate/20211202135508_add_index_on_packages_build_infos_package_id_pipeline_id.rb
+db/migrate/20211203160952_add_updated_state_by_user_id_to_merge_request_reviewers.rb
+db/migrate/20211203161149_add_index_to_merge_request_reviewers_updated_state_by_user_id.rb
+db/migrate/20211203161840_add_updated_state_by_user_id_to_merge_request_assignees.rb
+db/migrate/20211203161942_add_index_to_merge_request_assignees_updated_state_by_user_id.rb
+db/migrate/20211204010826_add_index_snippets_on_project_id_and_title.rb
+db/migrate/20211207154413_add_ci_runners_index_on_created_at_where_active_is_false.rb
+db/migrate/20211207154414_add_ci_runners_index_on_contacted_at_where_active_is_false.rb
+db/migrate/20211207165508_add_protected_environments_required_approval_count_check_constraint.rb
+db/migrate/20211208111425_add_executor_type_column_to_ci_runners.rb
+db/migrate/20211209230042_add_status_to_cluster_agent_tokens.rb
+db/migrate/20211210025754_alter_constraint_of_phone.rb
+db/migrate/20211210031721_change_user_details_phone_text_limit.rb
+db/migrate/20211213130324_update_timelogs_spent_at_default.rb
+db/migrate/20211213142344_add_settings_user_email_lookup_limit.rb
+db/migrate/20211213154259_add_status_to_packages_package_files.rb
+db/migrate/20211213154704_add_status_index_to_packages_package_files.rb
+db/migrate/20211214110307_remove_temp_index_from_vulnerability_occurrences.rb
+db/migrate/20211215182006_update_application_settings_protected_paths.rb
+db/migrate/20211216133107_add_cluster_agent_id_to_vulnerability_reads.rb
+db/migrate/20211216134134_add_text_limit_to_vulnerability_reads_cluster_agent_id.rb
+db/migrate/20211216135651_add_index_to_cluster_agent_id.rb
+db/migrate/20211216220939_add_group_crm_settings.rb
+db/migrate/20211217050753_remove_artifacts_archive_id_foreign_key_from_project_pages_metadata.rb
+db/migrate/20211220174504_add_secure_scanning_actions_to_onboarding_progresses.rb
+db/migrate/20211223125921_add_temp_index_to_members_state.rb
+db/migrate/20211224112937_add_packages_cleanup_package_file_worker_capacity_to_application_settings.rb
+db/migrate/20211224114539_add_packages_cleanup_package_file_worker_capacity_check_constraint_to_app_settings.rb
+db/migrate/20220104174445_add_ci_runners_index_on_active_state.rb
+db/migrate/20220105082217_add_verification_token_to_external_ae_destinations.rb
+db/migrate/20220105121325_add_route_namespace_reference.rb
+db/migrate/20220105152547_add_foreign_key_to_updated_state_by_user_id_to_merge_request_assignees.rb
+db/migrate/20220105153149_add_foreign_key_to_updated_state_by_user_id_to_merge_request_reviewers.rb
+db/migrate/20220106111958_add_insert_or_update_vulnerability_reads_trigger.rb
+db/migrate/20220106112043_add_update_vulnerability_reads_trigger.rb
+db/migrate/20220106112085_add_update_vulnerability_reads_location_trigger.rb
+db/migrate/20220106141756_remove_lock_version_indexes.rb
+db/migrate/20220106163326_add_has_issues_on_vulnerability_reads_trigger.rb
+db/migrate/20220106230629_add_registry_migration_application_settings.rb
+db/migrate/20220106230712_add_migration_columns_to_container_repositories.rb
+db/migrate/20220107091629_add_route_namespace_index.rb
+db/migrate/20220107165036_remove_note_id_index.rb
+db/migrate/20220109133006_remove_ci_pipelines_lock_version_index.rb
+db/migrate/20220110170953_create_ci_secure_files.rb
+db/migrate/20220111095006_add_maintainer_note_to_ci_runners.rb
+db/migrate/20220111095007_add_text_limit_to_ci_runners_maintainer_note.rb
+db/migrate/20220111154950_add_token_expires_at_to_ci_runners.rb
+db/migrate/20220111154951_add_index_to_ci_runners_token_expires_at.rb
+db/migrate/20220111200254_remove_index_from_merge_requests.rb
+db/migrate/20220112115413_add_requires_verification_to_user_details.rb
+db/migrate/20220112205111_create_security_training_providers.rb
+db/migrate/20220112232037_add_member_namespace_reference.rb
+db/migrate/20220112232605_add_member_namespace_index.rb
+db/migrate/20220113125401_create_security_trainings.rb
+db/migrate/20220113135449_add_package_files_limit_to_application_settings.rb
+db/migrate/20220113135924_add_application_settings_package_files_limit_constraints.rb
+db/migrate/20220113164801_add_diffs_colors_to_user_preferences.rb
+db/migrate/20220113164901_add_text_limit_to_user_preferences_diffs_colors.rb
+db/migrate/20220114131950_add_status_only_index_to_packages_package_files.rb
+db/migrate/20220117082611_add_text_limit_to_exad_verification_tokens.rb
+db/migrate/20220117225936_add_text_limits_to_container_repositories_migration_columns.rb
+db/migrate/20220118015633_add_url_text_to_issuable_metric_images.rb
+db/migrate/20220118020026_add_url_text_limit_to_issuable_metric_images.rb
+db/migrate/20220118141950_add_text_limit_to_container_registry_import_target_plan.rb
+db/migrate/20220118155846_add_runner_token_expiration_interval_settings_to_application_settings.rb
+db/migrate/20220118155847_add_runner_token_expiration_interval_settings_to_namespace_settings.rb
+db/migrate/20220118155848_add_runner_token_expiration_interval_settings_to_project_settings.rb
+db/migrate/20220119094023_add_unique_index_to_aed_verification_token.rb
+db/migrate/20220119141407_add_dependency_proxy_size_to_namespace_statistics.rb
+db/migrate/20220119144253_add_dependency_proxy_size_to_namespace_root_storage_statistics.rb
+db/migrate/20220119170426_remove_temporary_vulnerability_occurrences_deduplication_index.rb
+db/migrate/20220119220620_add_scan_method_to_dast_site_profile.rb
+db/migrate/20220120033115_create_alert_management_alert_metric_images.rb
+db/migrate/20220120085655_add_ci_runner_project_index_to_runner_id_and_project_id.rb
+db/migrate/20220120160625_remove_temp_index_on_id_from_vulnerability_occurrences.rb
+db/migrate/20220120211831_temp_index_for_group_namespace_member_backfill.rb
+db/migrate/20220124200927_add_index_to_issues.rb
+db/migrate/20220125084127_add_cleanup_attempts_to_loose_foreign_keys_deleted_records.rb
+db/migrate/20220125122228_add_topics_non_private_projects_count.rb
+db/migrate/20220125122725_add_topics_non_private_projects_count_index.rb
+db/migrate/20220125230538_add_compound_index_on_project_id_and_id_for_vulnerabilities.rb
+db/migrate/20220126191624_add_scan_file_path_to_dast_site_profile.rb
+db/migrate/20220128093756_add_ecdsa_sk_and_ed25519_sk_key_restrictions_to_application_settings.rb
+db/migrate/20220128194722_add_index_on_migration_state_and_import_done_at_to_container_repositories.rb
+db/migrate/20220131135725_add_severity_level_to_merge_requests_compliance_violations.rb
+db/migrate/20220131192643_add_show_diff_preview_in_email_to_project_settings.rb
+db/migrate/20220201205300_remove_index_for_vulnerability_occurrences.rb
+db/migrate/20220202034409_add_tmp_index_on_id_and_migration_state_to_container_repositories.rb
+db/migrate/20220202115350_add_migration_indexes_to_container_repositories.rb
+db/migrate/20220203074916_add_topics_lower_name_index.rb
+db/migrate/20220203091304_fix_unique_packages_index_excluding_pending_destruction_status.rb
+db/migrate/20220203123333_add_batched_migration_max_batch.rb
+db/migrate/20220203133652_add_legacy_open_source_license_available_to_project_settings.rb
+db/migrate/20220203134942_add_hidden_to_projects.rb
+db/migrate/20220204093120_create_analytics_cycle_analytics_aggregations.rb
+db/migrate/20220204154220_add_index_on_greatest_done_at_to_container_repositories.rb
+db/migrate/20220204193000_add_integrations_encrypted_properties.rb
+db/migrate/20220207083129_add_users_get_by_id_limit_to_application_setting.rb
+db/migrate/20220208170445_add_not_valid_foreign_key_to_ci_builds_runner_id.rb
+db/migrate/20220208171826_update_default_scan_method_of_dast_site_profile.rb
+db/migrate/20220211090920_cleanup_populate_topics_non_private_projects_count.rb
+db/migrate/20220211125954_create_related_epic_links.rb
+db/migrate/20220211214605_update_integrations_trigger_type_new_on_insert_null_safe.rb
+db/migrate/20220213100000_remove_integration_type_triggers.rb
+db/migrate/20220215164709_update_application_settings_container_registry_exp_pol_worker_capacity_default.rb
+db/migrate/20220216110023_create_saved_replies.rb
+db/migrate/20220217100008_add_container_registry_expiration_policies_caching_to_application_settings.rb
+db/migrate/20220217113058_add_status_to_status_check_responses.rb
+db/migrate/20220221102333_change_maintainer_note_limit_in_ci_runner.rb
+db/migrate/20220222072536_add_target_access_levels_to_broadcast_messages.rb
+db/migrate/20220301002101_add_security_orchestration_policy_configuration_namespace_reference.rb
+db/migrate/20220301003502_add_security_orchestration_policy_configuration_namespace_index.rb
+db/migrate/20220301091503_add_not_null_constraint_to_security_policy_configurations.rb
+db/migrate/20220301175104_change_security_orchestration_policy_configuration_project_index.rb
+db/migrate/20220301175426_create_project_build_artifacts_size_refresh.rb
+db/migrate/20220302110724_add_group_features_table.rb
+db/migrate/20220303190555_add_comment_to_deployment_approvals.rb
+db/migrate/20220303191047_add_text_limit_to_deployment_approvals_comment.rb
+db/migrate/20220304052335_remove_not_null_contraint_on_title_from_sprints.rb
+db/migrate/20220304061631_remove_unique_index_for_sprints_on_iterations_cadence_id_and_title.rb
+db/migrate/20220304062107_remove_unique_index_for_sprints_on_project_id_and_title.rb
+db/migrate/20220304152729_add_default_to_required_python_on_packages_pypi_metadata.rb
+db/migrate/20220307203458_rename_user_email_lookup_limit_setting_to_search_settings.rb
+db/migrate/20220309100648_add_time_to_restore_service_dora_metric.rb
+db/migrate/20220310011530_add_database_grafana_config_to_application_settings.rb
+db/migrate/20220310011613_add_text_limit_to_database_grafana_application_settings.rb
+db/migrate/20220310101118_update_holder_name_limit.rb
+db/migrate/20220314094841_add_package_registry_access_level_into_project_features.rb
+db/migrate/20220314184009_create_protected_environment_approval_rules.rb
+db/post_migrate/20211202145237_add_todos_project_and_id_index.rb
+db/post_migrate/20211203091642_add_index_to_projects_on_marked_for_deletion_at.rb
+db/post_migrate/20211206073851_create_calendar_events_index_synchronously.rb
+db/post_migrate/20211206074547_remove_old_calendar_events_index.rb
+db/post_migrate/20211206161271_add_indexes_for_primary_email_cleanup_migration.rb
+db/post_migrate/20211207081708_add_index_ci_job_artifacts_project_id_file_type.rb
+db/post_migrate/20211207090503_cleanup_first_mentioned_in_commit_jobs.rb
+db/post_migrate/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid.rb
+db/post_migrate/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4.rb
+db/post_migrate/20211207173510_remove_extra_finding_evidence_tables_foreign_keys.rb
+db/post_migrate/20211207173511_remove_extra_finding_evidence_tables.rb
+db/post_migrate/20211208122200_schedule_backfill_ci_namespace_mirrors.rb
+db/post_migrate/20211208122201_schedule_backfill_ci_project_mirrors.rb
+db/post_migrate/20211208171402_reschedule_recalculate_vulnerability_finding_signatures_for_findings.rb
+db/post_migrate/20211209093636_track_ci_job_artifacts_deletes.rb
+db/post_migrate/20211209093828_track_users_deletes.rb
+db/post_migrate/20211209093923_track_external_pull_requests_deletes.rb
+db/post_migrate/20211209094222_track_merge_requests_deletes.rb
+db/post_migrate/20211209103048_backfill_project_namespaces_for_group.rb
+db/post_migrate/20211209203820_add_tmp_index_on_report_type.rb
+db/post_migrate/20211209203821_convert_stringified_raw_metadata_hash_to_json.rb
+db/post_migrate/20211210140000_add_temporary_static_object_token_index.rb
+db/post_migrate/20211210140629_encrypt_static_object_token.rb
+db/post_migrate/20211210173137_remove_vulnerability_finding_links_again.rb
+db/post_migrate/20211213064821_add_agent_id_location_index_to_vulnerability_occurrences.rb
+db/post_migrate/20211213102111_drop_ci_pipelines_mr_metrics_fk.rb
+db/post_migrate/20211214012507_backfill_incident_issue_escalation_statuses.rb
+db/post_migrate/20211215090620_schedule_update_timelogs_null_spent_at.rb
+db/post_migrate/20211217120000_modify_kubernetes_resource_location_index_to_vulnerability_occurrences.rb
+db/post_migrate/20211217145923_add_index_to_events_on_author_id_and_action_and_id.rb
+db/post_migrate/20211217174331_mark_recalculate_finding_signatures_as_completed.rb
+db/post_migrate/20211220064757_drop_temporary_indexes_for_primary_email_migration.rb
+db/post_migrate/20211220120402_add_index_on_ci_pipelines_user_id_id_failure_reason.rb
+db/post_migrate/20211220123956_update_invalid_member_states.rb
+db/post_migrate/20211229023654_add_async_index_ci_job_artifacts_project_id_file_type.rb
+db/post_migrate/20211230112517_remove_index_events_on_author_id_and_action_and_id.rb
+db/post_migrate/20211230113031_add_index_to_events_on_author_id_and_id.rb
+db/post_migrate/20220104060049_remove_foreign_key_ci_group_variables_group_id.rb
+db/post_migrate/20220105020514_remove_ci_minutes_additional_packs_namespace_id_foreign_key_constraint.rb
+db/post_migrate/20220106185033_remove_finding_evidence_summary.rb
+db/post_migrate/20220106231518_remove_foreign_key_ci_daily_build_group_report_results_group_id.rb
+db/post_migrate/20220106233459_remove_foreign_key_ci_pending_builds_namespace_id.rb
+db/post_migrate/20220106235626_remove_foreign_key_ci_runner_namespaces_namespace_id.rb
+db/post_migrate/20220107064845_populate_vulnerability_reads.rb
+db/post_migrate/20220109134455_add_idx_vulnerability_occurrences_dedup_again.rb
+db/post_migrate/20220110171049_schedule_populate_test_reports_issue_id.rb
+db/post_migrate/20220110224913_remove_dast_scanner_profiles_builds_ci_build_id_fk.rb
+db/post_migrate/20220110231420_remove_requirements_management_test_reports_build_id_fk.rb
+db/post_migrate/20220110233155_remove_dast_site_profiles_builds_ci_build_id_fk.rb
+db/post_migrate/20220111002756_remove_security_scans_build_id_fk.rb
+db/post_migrate/20220111023852_index_cluster_agent_tokens_on_status.rb
+db/post_migrate/20220111093534_remove_index_on_auto_stop_in.rb
+db/post_migrate/20220111101421_remove_index_on_merge_request_id.rb
+db/post_migrate/20220111102314_truncate_ci_mirror_tables.rb
+db/post_migrate/20220111221516_remove_projects_ci_pending_builds_fk.rb
+db/post_migrate/20220112015940_remove_projects_ci_running_builds_fk.rb
+db/post_migrate/20220112090556_remove_cascade_delete_from_project_namespace_foreign_key.rb
+db/post_migrate/20220112230642_remove_projects_ci_unit_tests_project_id_fk.rb
+db/post_migrate/20220112232723_remove_projects_ci_daily_build_group_report_results_project_id_fk.rb
+db/post_migrate/20220113013319_remove_projects_ci_freeze_periods_project_id_fk.rb
+db/post_migrate/20220113014438_remove_projects_ci_resource_groups_project_id_fk.rb
+db/post_migrate/20220113015830_remove_projects_ci_build_report_results_project_id_fk.rb
+db/post_migrate/20220113035519_remove_users_ci_job_token_project_scope_links_added_by_id_fk.rb
+db/post_migrate/20220113040447_remove_users_ci_pipeline_schedules_owner_id_fk.rb
+db/post_migrate/20220113111440_schedule_fix_incorrect_max_seats_used.rb
+db/post_migrate/20220114105525_add_index_on_projects_path.rb
+db/post_migrate/20220116175851_add_author_index_to_design_management_versions.rb
+db/post_migrate/20220117034056_remove_index_cluster_agent_tokens_on_agent_id_and_last_used_at.rb
+db/post_migrate/20220118204039_self_managed_reschedule_recalculate_vulnerability_finding_signatures_for_findings.rb
+db/post_migrate/20220119094503_populate_audit_event_streaming_verification_token.rb
+db/post_migrate/20220119141736_remove_projects_ci_pipeline_artifacts_project_id_fk.rb
+db/post_migrate/20220119143130_remove_projects_ci_sources_pipelines_source_project_id_fk.rb
+db/post_migrate/20220119144458_remove_users_ci_triggers_owner_id_fk.rb
+db/post_migrate/20220119151221_remove_merge_requests_ci_pipelines_merge_request_id_fk.rb
+db/post_migrate/20220119153706_remove_ci_pipelines_merge_trains_pipeline_id_fk.rb
+db/post_migrate/20220119154442_remove_ci_pipelines_merge_requests_head_pipeline_id_fk.rb
+db/post_migrate/20220119193130_remove_ci_pipelines_dast_profiles_pipelines_ci_pipeline_id_fk.rb
+db/post_migrate/20220119201340_remove_ci_pipelines_vulnerability_statistics_latest_pipeline_id_fk.rb
+db/post_migrate/20220119203119_remove_ci_pipelines_vulnerability_occurrence_pipelines_pipeline_id_fk.rb
+db/post_migrate/20220120094340_drop_position_from_security_findings.rb
+db/post_migrate/20220120123700_add_tmp_index_routes_id_for_namespaces.rb
+db/post_migrate/20220120123800_backfill_namespace_id_for_namespace_routes.rb
+db/post_migrate/20220120211832_backfill_member_namespace_id_for_group_members.rb
+db/post_migrate/20220121214752_remove_projects_ci_stages_project_id_fk.rb
+db/post_migrate/20220121214753_re_remove_projects_ci_stages_project_id_fk.rb
+db/post_migrate/20220121221651_remove_projects_ci_variables_project_id_fk.rb
+db/post_migrate/20220124130028_dedup_runner_projects.rb
+db/post_migrate/20220124145019_remove_projects_external_pull_requests_project_id_fk.rb
+db/post_migrate/20220124151456_remove_projects_ci_triggers_project_id_fk.rb
+db/post_migrate/20220124151949_remove_projects_ci_runner_projects_project_id_fk.rb
+db/post_migrate/20220124152824_remove_projects_ci_subscriptions_projects_downstream_project_id_fk.rb
+db/post_migrate/20220124153233_remove_projects_ci_job_artifacts_project_id_fk.rb
+db/post_migrate/20220124153234_re_remove_projects_ci_job_artifacts_project_id_fk.rb
+db/post_migrate/20220124180704_remove_projects_ci_builds_metadata_project_id_fk.rb
+db/post_migrate/20220124180705_re_remove_projects_ci_builds_metadata_project_id_fk.rb
+db/post_migrate/20220124184338_remove_projects_ci_subscriptions_projects_upstream_project_id_fk.rb
+db/post_migrate/20220124204046_remove_projects_ci_sources_pipelines_project_id_fk.rb
+db/post_migrate/20220124214131_remove_projects_ci_refs_project_id_fk.rb
+db/post_migrate/20220124215857_remove_projects_ci_job_token_project_scope_links_source_project_id_fk.rb
+db/post_migrate/20220124221521_remove_projects_ci_project_monthly_usages_project_id_fk.rb
+db/post_migrate/20220125083520_remove_ci_pipelines_dast_site_profiles_pipelines_ci_pipeline_id_fk.rb
+db/post_migrate/20220125084348_remove_ci_pipelines_vulnerability_feedback_pipeline_id_fk.rb
+db/post_migrate/20220125122640_schedule_populate_topics_non_private_projects_count.rb
+db/post_migrate/20220126201752_remove_projects_ci_job_token_project_scope_links_target_project_id_fk.rb
+db/post_migrate/20220126202654_remove_projects_ci_sources_projects_source_project_id_fk.rb
+db/post_migrate/20220126203421_remove_projects_ci_pipeline_schedules_project_id_fk.rb
+db/post_migrate/20220126210021_remove_projects_ci_builds_project_id_fk.rb
+db/post_migrate/20220126210022_re_remove_projects_ci_builds_project_id_fk.rb
+db/post_migrate/20220126210657_remove_projects_ci_pipelines_project_id_fk.rb
+db/post_migrate/20220127112243_add_index_to_merge_request_assignees_state.rb
+db/post_migrate/20220127112412_add_index_to_merge_request_reviewers_state.rb
+db/post_migrate/20220127132200_cleanup_backfill_ci_namespace_mirrors.rb
+db/post_migrate/20220127132201_cleanup_backfill_ci_project_mirrors.rb
+db/post_migrate/20220128103042_schedule_delete_invalid_epic_issues_revised.rb
+db/post_migrate/20220128155251_remove_dangling_running_builds.rb
+db/post_migrate/20220128155814_fix_approval_rules_code_owners_rule_type_index.rb
+db/post_migrate/20220131000000_index_job_artifacts_on_trace_type_and_expire_at.rb
+db/post_migrate/20220131000001_schedule_trace_expiry_removal.rb
+db/post_migrate/20220201034731_remove_index_clusters_kubernetes_namespaces_on_cluster_id.rb
+db/post_migrate/20220201141705_cleanup_background_migration_populate_test_reports_issue_id.rb
+db/post_migrate/20220201173212_add_user_details_provisioning_index.rb
+db/post_migrate/20220201193033_add_unique_index_to_vulnerability_finding_links_with_truncate.rb
+db/post_migrate/20220202105733_delete_service_template_records.rb
+db/post_migrate/20220204053655_remove_index_epic_issues_on_epic_id.rb
+db/post_migrate/20220204095121_backfill_namespace_statistics_with_dependency_proxy_size.rb
+db/post_migrate/20220204110725_backfill_cycle_analytics_aggregations.rb
+db/post_migrate/20220204194347_encrypt_integration_properties.rb
+db/post_migrate/20220207080758_update_api_indexes_for_projects.rb
+db/post_migrate/20220208080921_schedule_migrate_personal_namespace_project_maintainer_to_owner.rb
+db/post_migrate/20220208115439_start_backfill_ci_queuing_tables.rb
+db/post_migrate/20220209111007_add_partial_index_for_batching_active_cluster_image_scanning_vulnerabilities.rb
+db/post_migrate/20220212120735_schedule_fix_incorrect_max_seats_used2.rb
+db/post_migrate/20220213103859_remove_integrations_type.rb
+db/post_migrate/20220213104531_create_indexes_on_integration_type_new.rb
+db/post_migrate/20220215190020_rerun_convert_stringified_raw_metadata_hash_to_json.rb
+db/post_migrate/20220216201949_remove_package_files_limit_from_application_settings.rb
+db/post_migrate/20220217135229_validate_not_null_constraint_on_security_findings_uuid.rb
+db/post_migrate/20220221214928_remove_show_diff_preview_in_email_column.rb
+db/post_migrate/20220222191845_remove_not_null_constraint_for_security_scan_succeeded.rb
+db/post_migrate/20220222192524_create_not_null_constraint_releases_tag.rb
+db/post_migrate/20220222192525_remove_null_releases.rb
+db/post_migrate/20220223112304_schedule_nullify_orphan_runner_id_on_ci_builds.rb
+db/post_migrate/20220223124428_schedule_merge_topics_with_same_name.rb
+db/post_migrate/20220224000000_async_build_trace_expire_at_index.rb
+db/post_migrate/20220224204415_recreate_index_security_ci_builds_on_name_and_id_parser_with_new_features.rb
+db/post_migrate/20220225133705_cleanup_backfill_ci_queuing_tables.rb
+db/post_migrate/20220301093434_backfill_all_project_namespaces.rb
+db/post_migrate/20220302114046_backfill_group_features.rb
+db/post_migrate/20220302203410_create_index_security_ci_builds_on_name_and_id_parser_with_new_features.rb
+db/post_migrate/20220304165107_drop_partitioned_foreign_keys.rb
+db/post_migrate/20220304201847_add_unique_index_on_security_training_providers.rb
+db/post_migrate/20220305223212_add_security_training_providers.rb
+db/post_migrate/20220307192534_create_index_for_remove_duplicate_project_tag_releases.rb
+db/post_migrate/20220307192610_remove_duplicate_project_tag_releases.rb
+db/post_migrate/20220307192645_remove_index_for_remove_duplicate_project_tag_releases.rb
+db/post_migrate/20220307192725_create_unique_index_release_tag_project.rb
+db/post_migrate/20220307203459_rename_user_email_lookup_limit_setting_to_search_settings_cleanup.rb
+db/post_migrate/20220308000205_drop_old_index_security_ci_builds_on_name_and_id_parser_features.rb
+db/post_migrate/20220308115219_schedule_reset_duplicate_ci_runners_token_encrypted_values_on_projects.rb
+db/post_migrate/20220308115502_schedule_reset_duplicate_ci_runners_token_values_on_projects.rb
+db/post_migrate/20220309084838_remove_external_pull_request_tracking.rb
+db/post_migrate/20220309084954_remove_leftover_external_pull_request_deletions.rb
+db/post_migrate/20220309154855_add_index_on_issues_closed_incidents.rb
+db/post_migrate/20220310095341_add_async_index_ci_job_artifacts_project_id_created_at.rb
+db/post_migrate/20220310134207_add_index_project_id_and_released_at_and_id_on_releases.rb
+db/post_migrate/20220310141349_remove_dependency_list_usage_data_from_redis.rb
+db/post_migrate/20220311010352_create_scan_id_and_id_index_on_security_findings.rb
+db/post_migrate/20220314154235_migrate_vulnerability_approval_rules.rb
+db/post_migrate/20220314162342_add_index_ci_job_artifacts_project_id_created_at.rb
+ee/lib/ee/gitlab/background_migration/fix_incorrect_max_seats_used.rb
+ee/lib/ee/gitlab/background_migration/populate_namespace_statistics.rb
+ee/lib/ee/gitlab/background_migration/populate_test_reports_issue_id.rb
+ee/lib/ee/gitlab/background_migration/recalculate_vulnerability_finding_signatures_for_findings.rb
+ee/spec/lib/ee/gitlab/background_migration/fix_incorrect_max_seats_used_spec.rb
+ee/spec/lib/ee/gitlab/background_migration/populate_namespace_statistics_spec.rb
+ee/spec/lib/ee/gitlab/background_migration/recalculate_vulnerability_finding_signatures_for_findings_spec.rb
+ee/spec/lib/gitlab/background_migration/populate_test_reports_issue_id_spec.rb
+ee/spec/lib/gitlab/background_migration/remove_all_trace_expiration_dates_spec.rb
+ee/spec/migrations/async_build_trace_expire_at_index_spec.rb
+ee/spec/migrations/schedule_delete_invalid_epic_issues_revised_spec.rb
+ee/spec/migrations/schedule_populate_test_reports_issue_id_spec.rb
+ee/spec/migrations/schedule_trace_expiry_removal_spec.rb
+lib/gitlab/background_migration/backfill_ci_queuing_tables.rb
+lib/gitlab/background_migration/backfill_integrations_type_new.rb
+lib/gitlab/background_migration/encrypt_static_object_token.rb
+lib/gitlab/background_migration/fix_incorrect_max_seats_used.rb
+lib/gitlab/background_migration/merge_topics_with_same_name.rb
+lib/gitlab/background_migration/populate_namespace_statistics.rb
+lib/gitlab/background_migration/populate_test_reports_issue_id.rb
+lib/gitlab/background_migration/populate_topics_non_private_projects_count.rb
+lib/gitlab/background_migration/populate_vulnerability_reads.rb
+lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid.rb
+lib/gitlab/background_migration/recalculate_vulnerability_finding_signatures_for_findings.rb
+lib/gitlab/background_migration/remove_all_trace_expiration_dates.rb
+lib/gitlab/background_migration/update_timelogs_null_spent_at.rb
+spec/lib/gitlab/background_migration/backfill_ci_queuing_tables_spec.rb
+spec/lib/gitlab/background_migration/backfill_group_features_spec.rb
+spec/lib/gitlab/background_migration/backfill_integrations_type_new_spec.rb
+spec/lib/gitlab/background_migration/backfill_member_namespace_for_group_members_spec.rb
+spec/lib/gitlab/background_migration/backfill_namespace_id_for_namespace_route_spec.rb
+spec/lib/gitlab/background_migration/backfill_snippet_repositories_spec.rb
+spec/lib/gitlab/background_migration/encrypt_integration_properties_spec.rb
+spec/lib/gitlab/background_migration/encrypt_static_object_token_spec.rb
+spec/lib/gitlab/background_migration/fix_vulnerability_occurrences_with_hashes_as_raw_metadata_spec.rb
+spec/lib/gitlab/background_migration/merge_topics_with_same_name_spec.rb
+spec/lib/gitlab/background_migration/migrate_personal_namespace_project_maintainer_to_owner_spec.rb
+spec/lib/gitlab/background_migration/nullify_orphan_runner_id_on_ci_builds_spec.rb
+spec/lib/gitlab/background_migration/populate_namespace_statistics_spec.rb
+spec/lib/gitlab/background_migration/populate_topics_non_private_projects_count_spec.rb
+spec/lib/gitlab/background_migration/populate_vulnerability_reads_spec.rb
+spec/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid_spec.rb
+spec/lib/gitlab/background_migration/remove_all_trace_expiration_dates_spec.rb
+spec/lib/gitlab/background_migration/remove_vulnerability_finding_links_spec.rb
+spec/lib/gitlab/background_migration/update_timelogs_null_spent_at_spec.rb
+spec/migrations/20211203091642_add_index_to_projects_on_marked_for_deletion_at_spec.rb
+spec/migrations/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb
+spec/migrations/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4_spec.rb
+spec/migrations/20211210140629_encrypt_static_object_token_spec.rb
+spec/migrations/20211214012507_backfill_incident_issue_escalation_statuses_spec.rb
+spec/migrations/20211217174331_mark_recalculate_finding_signatures_as_completed_spec.rb
+spec/migrations/20220106111958_add_insert_or_update_vulnerability_reads_trigger_spec.rb
+spec/migrations/20220106112043_add_update_vulnerability_reads_trigger_spec.rb
+spec/migrations/20220106112085_add_update_vulnerability_reads_location_trigger_spec.rb
+spec/migrations/20220106163326_add_has_issues_on_vulnerability_reads_trigger_spec.rb
+spec/migrations/20220107064845_populate_vulnerability_reads_spec.rb
+spec/migrations/20220120094340_drop_position_from_security_findings_spec.rb
+spec/migrations/20220124130028_dedup_runner_projects_spec.rb
+spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb
+spec/migrations/20220128155814_fix_approval_rules_code_owners_rule_type_index_spec.rb
+spec/migrations/20220202105733_delete_service_template_records_spec.rb
+spec/migrations/20220204095121_backfill_namespace_statistics_with_dependency_proxy_size_spec.rb
+spec/migrations/20220204194347_encrypt_integration_properties_spec.rb
+spec/migrations/20220208080921_schedule_migrate_personal_namespace_project_maintainer_to_owner_spec.rb
+spec/migrations/20220211214605_update_integrations_trigger_type_new_on_insert_null_safe_spec.rb
+spec/migrations/20220213103859_remove_integrations_type_spec.rb
+spec/migrations/20220222192524_create_not_null_constraint_releases_tag_spec.rb
+spec/migrations/20220222192525_remove_null_releases_spec.rb
+spec/migrations/20220223124428_schedule_merge_topics_with_same_name_spec.rb
+spec/migrations/20220305223212_add_security_training_providers_spec.rb
+spec/migrations/20220307192610_remove_duplicate_project_tag_releases_spec.rb
+spec/migrations/20220309084954_remove_leftover_external_pull_request_deletions_spec.rb
+spec/migrations/20220310141349_remove_dependency_list_usage_data_from_redis_spec.rb
+spec/migrations/backfill_all_project_namespaces_spec.rb
+spec/migrations/backfill_cycle_analytics_aggregations_spec.rb
+spec/migrations/backfill_group_features_spec.rb
+spec/migrations/backfill_member_namespace_id_for_group_members_spec.rb
+spec/migrations/backfill_namespace_id_for_namespace_routes_spec.rb
+spec/migrations/backfill_project_namespaces_for_group_spec.rb
+spec/migrations/populate_audit_event_streaming_verification_token_spec.rb
+spec/migrations/recreate_index_security_ci_builds_on_name_and_id_parser_with_new_features_spec.rb
+spec/migrations/remove_not_null_contraint_on_title_from_sprints_spec.rb
+spec/migrations/schedule_fix_incorrect_max_seats_used2_spec.rb
+spec/migrations/schedule_fix_incorrect_max_seats_used_spec.rb
+spec/migrations/schedule_update_timelogs_null_spent_at_spec.rb
+spec/migrations/start_backfill_ci_queuing_tables_spec.rb
+spec/migrations/update_application_settings_container_registry_exp_pol_worker_capacity_default_spec.rb
+spec/migrations/update_application_settings_protected_paths_spec.rb
+spec/migrations/update_default_scan_method_of_dast_site_profile_spec.rb
+spec/migrations/update_invalid_member_states_spec.rb
diff --git a/.yamllint b/.yamllint
index 5b49a617a57de9c462d47fa087ed879cf270aaab..896db4c101ea058a0311cf3039dd43a8767f6087 100644
--- a/.yamllint
+++ b/.yamllint
@@ -22,6 +22,9 @@ ignore: |
   generator_templates/snowplow_event_definition/event_definition.yml
   generator_templates/usage_metric_definition/metric_definition.yml
 
+  # Contains ERB code that keeps throwing syntax errors
+  .rubocop.yml
+
   # Has some special indentation
   doc/user/project/integrations/samples/cloudwatch.yml
 
diff --git a/db/init_structure.sql b/db/init_structure.sql
index 63961f05c6b2845c3d9ff11f85e13d3922b8988b..aee0f7679962a2962269cd0b63461642c304ab7d 100644
--- a/db/init_structure.sql
+++ b/db/init_structure.sql
@@ -45,45 +45,23 @@ RETURN NULL;
 END
 $$;
 
-CREATE FUNCTION insert_or_update_vulnerability_reads() RETURNS trigger
+CREATE FUNCTION insert_projects_sync_event() RETURNS trigger
     LANGUAGE plpgsql
     AS $$
-DECLARE
-  severity smallint;
-  state smallint;
-  report_type smallint;
-  resolved_on_default_branch boolean;
 BEGIN
-  IF (NEW.vulnerability_id IS NULL AND (TG_OP = 'INSERT' OR TG_OP = 'UPDATE')) THEN
-    RETURN NULL;
-  END IF;
-
-  IF (TG_OP = 'UPDATE' AND OLD.vulnerability_id IS NOT NULL AND NEW.vulnerability_id IS NOT NULL) THEN
-    RETURN NULL;
-  END IF;
-
-  SELECT
-    vulnerabilities.severity, vulnerabilities.state, vulnerabilities.report_type, vulnerabilities.resolved_on_default_branch
-  INTO
-    severity, state, report_type, resolved_on_default_branch
-  FROM
-     vulnerabilities
-  WHERE
-    vulnerabilities.id = NEW.vulnerability_id;
-
-  INSERT INTO vulnerability_reads (vulnerability_id, project_id, scanner_id, report_type, severity, state, resolved_on_default_branch, uuid, location_image, cluster_agent_id)
-    VALUES (NEW.vulnerability_id, NEW.project_id, NEW.scanner_id, report_type, severity, state, resolved_on_default_branch, NEW.uuid::uuid, NEW.location->>'image', NEW.location->'kubernetes_resource'->>'agent_id')
-    ON CONFLICT(vulnerability_id) DO NOTHING;
-  RETURN NULL;
+INSERT INTO projects_sync_events (project_id)
+VALUES(COALESCE(NEW.id, OLD.id));
+RETURN NULL;
+
 END
 $$;
 
-CREATE FUNCTION insert_projects_sync_event() RETURNS trigger
+CREATE FUNCTION integrations_set_type_new() RETURNS trigger
     LANGUAGE plpgsql
     AS $$
 BEGIN
-INSERT INTO projects_sync_events (project_id)
-VALUES(COALESCE(NEW.id, OLD.id));
+UPDATE integrations SET type_new = regexp_replace(NEW.type, '\A(.+)Service\Z', 'Integrations::\1')
+WHERE integrations.id = NEW.id;
 RETURN NULL;
 
 END
@@ -129,83 +107,6 @@ RETURN NULL;
 END
 $$;
 
-CREATE FUNCTION set_has_issues_on_vulnerability_reads() RETURNS trigger
-    LANGUAGE plpgsql
-    AS $$
-BEGIN
-UPDATE
-  vulnerability_reads
-SET
-  has_issues = true
-WHERE
-  vulnerability_id = NEW.vulnerability_id AND has_issues IS FALSE;
-RETURN NULL;
-
-END
-$$;
-
-CREATE FUNCTION unset_has_issues_on_vulnerability_reads() RETURNS trigger
-    LANGUAGE plpgsql
-    AS $$
-DECLARE
-  has_issue_links integer;
-BEGIN
-  PERFORM 1
-  FROM
-    vulnerability_reads
-  WHERE
-    vulnerability_id = OLD.vulnerability_id
-  FOR UPDATE;
-
-  SELECT 1 INTO has_issue_links FROM vulnerability_issue_links WHERE vulnerability_id = OLD.vulnerability_id LIMIT 1;
-
-  IF (has_issue_links = 1) THEN
-    RETURN NULL;
-  END IF;
-
-  UPDATE
-    vulnerability_reads
-  SET
-    has_issues = false
-  WHERE
-    vulnerability_id = OLD.vulnerability_id;
-
-  RETURN NULL;
-END
-$$;
-
-CREATE FUNCTION update_location_from_vulnerability_occurrences() RETURNS trigger
-    LANGUAGE plpgsql
-    AS $$
-BEGIN
-UPDATE
-  vulnerability_reads
-SET
-  location_image = NEW.location->>'image',
-  cluster_agent_id = NEW.location->'kubernetes_resource'->>'agent_id'
-WHERE
-  vulnerability_id = NEW.vulnerability_id;
-RETURN NULL;
-
-END
-$$;
-
-CREATE FUNCTION update_vulnerability_reads_from_vulnerability() RETURNS trigger
-    LANGUAGE plpgsql
-    AS $$
-BEGIN
-UPDATE
-  vulnerability_reads
-SET
-  severity = NEW.severity,
-  state = NEW.state,
-  resolved_on_default_branch = NEW.resolved_on_default_branch
-WHERE vulnerability_id = NEW.id;
-RETURN NULL;
-
-END
-$$;
-
 CREATE TABLE audit_events (
     id bigint NOT NULL,
     author_id integer NOT NULL,
@@ -491,7 +392,7 @@ CREATE TABLE gitlab_partitions_dynamic.batched_background_migration_job_transiti
     CONSTRAINT check_50e580811a CHECK ((char_length(exception_message) <= 1000)),
     CONSTRAINT check_76e202c37a CHECK ((char_length(exception_class) <= 100))
 );
-ALTER TABLE ONLY batched_background_migration_job_transition_logs ATTACH PARTITION gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_000000 FOR VALUES FROM (MINVALUE) TO ('2023-03-01 00:00:00+00');
+ALTER TABLE ONLY batched_background_migration_job_transition_logs ATTACH PARTITION gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_000000 FOR VALUES FROM (MINVALUE) TO ('2023-02-28 18:00:00-06');
 
 CREATE TABLE gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_202303 (
     id bigint DEFAULT nextval('batched_background_migration_job_transition_logs_id_seq'::regclass) NOT NULL,
@@ -505,7 +406,7 @@ CREATE TABLE gitlab_partitions_dynamic.batched_background_migration_job_transiti
     CONSTRAINT check_50e580811a CHECK ((char_length(exception_message) <= 1000)),
     CONSTRAINT check_76e202c37a CHECK ((char_length(exception_class) <= 100))
 );
-ALTER TABLE ONLY batched_background_migration_job_transition_logs ATTACH PARTITION gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_202303 FOR VALUES FROM ('2023-03-01 00:00:00+00') TO ('2023-04-01 00:00:00+00');
+ALTER TABLE ONLY batched_background_migration_job_transition_logs ATTACH PARTITION gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_202303 FOR VALUES FROM ('2023-02-28 18:00:00-06') TO ('2023-03-31 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_202304 (
     id bigint DEFAULT nextval('batched_background_migration_job_transition_logs_id_seq'::regclass) NOT NULL,
@@ -519,7 +420,7 @@ CREATE TABLE gitlab_partitions_dynamic.batched_background_migration_job_transiti
     CONSTRAINT check_50e580811a CHECK ((char_length(exception_message) <= 1000)),
     CONSTRAINT check_76e202c37a CHECK ((char_length(exception_class) <= 100))
 );
-ALTER TABLE ONLY batched_background_migration_job_transition_logs ATTACH PARTITION gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_202304 FOR VALUES FROM ('2023-04-01 00:00:00+00') TO ('2023-05-01 00:00:00+00');
+ALTER TABLE ONLY batched_background_migration_job_transition_logs ATTACH PARTITION gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_202304 FOR VALUES FROM ('2023-03-31 19:00:00-05') TO ('2023-04-30 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_202305 (
     id bigint DEFAULT nextval('batched_background_migration_job_transition_logs_id_seq'::regclass) NOT NULL,
@@ -533,7 +434,7 @@ CREATE TABLE gitlab_partitions_dynamic.batched_background_migration_job_transiti
     CONSTRAINT check_50e580811a CHECK ((char_length(exception_message) <= 1000)),
     CONSTRAINT check_76e202c37a CHECK ((char_length(exception_class) <= 100))
 );
-ALTER TABLE ONLY batched_background_migration_job_transition_logs ATTACH PARTITION gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_202305 FOR VALUES FROM ('2023-05-01 00:00:00+00') TO ('2023-06-01 00:00:00+00');
+ALTER TABLE ONLY batched_background_migration_job_transition_logs ATTACH PARTITION gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_202305 FOR VALUES FROM ('2023-04-30 19:00:00-05') TO ('2023-05-31 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_202306 (
     id bigint DEFAULT nextval('batched_background_migration_job_transition_logs_id_seq'::regclass) NOT NULL,
@@ -547,7 +448,7 @@ CREATE TABLE gitlab_partitions_dynamic.batched_background_migration_job_transiti
     CONSTRAINT check_50e580811a CHECK ((char_length(exception_message) <= 1000)),
     CONSTRAINT check_76e202c37a CHECK ((char_length(exception_class) <= 100))
 );
-ALTER TABLE ONLY batched_background_migration_job_transition_logs ATTACH PARTITION gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_202306 FOR VALUES FROM ('2023-06-01 00:00:00+00') TO ('2023-07-01 00:00:00+00');
+ALTER TABLE ONLY batched_background_migration_job_transition_logs ATTACH PARTITION gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_202306 FOR VALUES FROM ('2023-05-31 19:00:00-05') TO ('2023-06-30 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_202307 (
     id bigint DEFAULT nextval('batched_background_migration_job_transition_logs_id_seq'::regclass) NOT NULL,
@@ -561,7 +462,7 @@ CREATE TABLE gitlab_partitions_dynamic.batched_background_migration_job_transiti
     CONSTRAINT check_50e580811a CHECK ((char_length(exception_message) <= 1000)),
     CONSTRAINT check_76e202c37a CHECK ((char_length(exception_class) <= 100))
 );
-ALTER TABLE ONLY batched_background_migration_job_transition_logs ATTACH PARTITION gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_202307 FOR VALUES FROM ('2023-07-01 00:00:00+00') TO ('2023-08-01 00:00:00+00');
+ALTER TABLE ONLY batched_background_migration_job_transition_logs ATTACH PARTITION gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_202307 FOR VALUES FROM ('2023-06-30 19:00:00-05') TO ('2023-07-31 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_202308 (
     id bigint DEFAULT nextval('batched_background_migration_job_transition_logs_id_seq'::regclass) NOT NULL,
@@ -575,7 +476,7 @@ CREATE TABLE gitlab_partitions_dynamic.batched_background_migration_job_transiti
     CONSTRAINT check_50e580811a CHECK ((char_length(exception_message) <= 1000)),
     CONSTRAINT check_76e202c37a CHECK ((char_length(exception_class) <= 100))
 );
-ALTER TABLE ONLY batched_background_migration_job_transition_logs ATTACH PARTITION gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_202308 FOR VALUES FROM ('2023-08-01 00:00:00+00') TO ('2023-09-01 00:00:00+00');
+ALTER TABLE ONLY batched_background_migration_job_transition_logs ATTACH PARTITION gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_202308 FOR VALUES FROM ('2023-07-31 19:00:00-05') TO ('2023-08-31 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_202309 (
     id bigint DEFAULT nextval('batched_background_migration_job_transition_logs_id_seq'::regclass) NOT NULL,
@@ -589,7 +490,7 @@ CREATE TABLE gitlab_partitions_dynamic.batched_background_migration_job_transiti
     CONSTRAINT check_50e580811a CHECK ((char_length(exception_message) <= 1000)),
     CONSTRAINT check_76e202c37a CHECK ((char_length(exception_class) <= 100))
 );
-ALTER TABLE ONLY batched_background_migration_job_transition_logs ATTACH PARTITION gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_202309 FOR VALUES FROM ('2023-09-01 00:00:00+00') TO ('2023-10-01 00:00:00+00');
+ALTER TABLE ONLY batched_background_migration_job_transition_logs ATTACH PARTITION gitlab_partitions_dynamic.batched_background_migration_job_transition_logs_202309 FOR VALUES FROM ('2023-08-31 19:00:00-05') TO ('2023-09-30 19:00:00-05');
 
 CREATE TABLE incident_management_pending_alert_escalations (
     id bigint NOT NULL,
@@ -636,7 +537,7 @@ CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_alert_escalat
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL
 );
-ALTER TABLE ONLY incident_management_pending_alert_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202301 FOR VALUES FROM ('2023-01-01 00:00:00+00') TO ('2023-02-01 00:00:00+00');
+ALTER TABLE ONLY incident_management_pending_alert_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202301 FOR VALUES FROM ('2022-12-31 18:00:00-06') TO ('2023-01-31 18:00:00-06');
 
 CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202302 (
     id bigint DEFAULT nextval('incident_management_pending_alert_escalations_id_seq'::regclass) NOT NULL,
@@ -646,7 +547,7 @@ CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_alert_escalat
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL
 );
-ALTER TABLE ONLY incident_management_pending_alert_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202302 FOR VALUES FROM ('2023-02-01 00:00:00+00') TO ('2023-03-01 00:00:00+00');
+ALTER TABLE ONLY incident_management_pending_alert_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202302 FOR VALUES FROM ('2023-01-31 18:00:00-06') TO ('2023-02-28 18:00:00-06');
 
 CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202303 (
     id bigint DEFAULT nextval('incident_management_pending_alert_escalations_id_seq'::regclass) NOT NULL,
@@ -656,7 +557,7 @@ CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_alert_escalat
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL
 );
-ALTER TABLE ONLY incident_management_pending_alert_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202303 FOR VALUES FROM ('2023-03-01 00:00:00+00') TO ('2023-04-01 00:00:00+00');
+ALTER TABLE ONLY incident_management_pending_alert_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202303 FOR VALUES FROM ('2023-02-28 18:00:00-06') TO ('2023-03-31 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202304 (
     id bigint DEFAULT nextval('incident_management_pending_alert_escalations_id_seq'::regclass) NOT NULL,
@@ -666,7 +567,7 @@ CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_alert_escalat
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL
 );
-ALTER TABLE ONLY incident_management_pending_alert_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202304 FOR VALUES FROM ('2023-04-01 00:00:00+00') TO ('2023-05-01 00:00:00+00');
+ALTER TABLE ONLY incident_management_pending_alert_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202304 FOR VALUES FROM ('2023-03-31 19:00:00-05') TO ('2023-04-30 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202305 (
     id bigint DEFAULT nextval('incident_management_pending_alert_escalations_id_seq'::regclass) NOT NULL,
@@ -676,7 +577,7 @@ CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_alert_escalat
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL
 );
-ALTER TABLE ONLY incident_management_pending_alert_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202305 FOR VALUES FROM ('2023-05-01 00:00:00+00') TO ('2023-06-01 00:00:00+00');
+ALTER TABLE ONLY incident_management_pending_alert_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202305 FOR VALUES FROM ('2023-04-30 19:00:00-05') TO ('2023-05-31 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202306 (
     id bigint DEFAULT nextval('incident_management_pending_alert_escalations_id_seq'::regclass) NOT NULL,
@@ -686,7 +587,7 @@ CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_alert_escalat
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL
 );
-ALTER TABLE ONLY incident_management_pending_alert_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202306 FOR VALUES FROM ('2023-06-01 00:00:00+00') TO ('2023-07-01 00:00:00+00');
+ALTER TABLE ONLY incident_management_pending_alert_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202306 FOR VALUES FROM ('2023-05-31 19:00:00-05') TO ('2023-06-30 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202307 (
     id bigint DEFAULT nextval('incident_management_pending_alert_escalations_id_seq'::regclass) NOT NULL,
@@ -696,7 +597,7 @@ CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_alert_escalat
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL
 );
-ALTER TABLE ONLY incident_management_pending_alert_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202307 FOR VALUES FROM ('2023-07-01 00:00:00+00') TO ('2023-08-01 00:00:00+00');
+ALTER TABLE ONLY incident_management_pending_alert_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202307 FOR VALUES FROM ('2023-06-30 19:00:00-05') TO ('2023-07-31 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202308 (
     id bigint DEFAULT nextval('incident_management_pending_alert_escalations_id_seq'::regclass) NOT NULL,
@@ -706,7 +607,7 @@ CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_alert_escalat
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL
 );
-ALTER TABLE ONLY incident_management_pending_alert_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202308 FOR VALUES FROM ('2023-08-01 00:00:00+00') TO ('2023-09-01 00:00:00+00');
+ALTER TABLE ONLY incident_management_pending_alert_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202308 FOR VALUES FROM ('2023-07-31 19:00:00-05') TO ('2023-08-31 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202309 (
     id bigint DEFAULT nextval('incident_management_pending_alert_escalations_id_seq'::regclass) NOT NULL,
@@ -716,7 +617,7 @@ CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_alert_escalat
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL
 );
-ALTER TABLE ONLY incident_management_pending_alert_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202309 FOR VALUES FROM ('2023-09-01 00:00:00+00') TO ('2023-10-01 00:00:00+00');
+ALTER TABLE ONLY incident_management_pending_alert_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_alert_escalations_202309 FOR VALUES FROM ('2023-08-31 19:00:00-05') TO ('2023-09-30 19:00:00-05');
 
 CREATE TABLE incident_management_pending_issue_escalations (
     id bigint NOT NULL,
@@ -763,7 +664,7 @@ CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_issue_escalat
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL
 );
-ALTER TABLE ONLY incident_management_pending_issue_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202301 FOR VALUES FROM ('2023-01-01 00:00:00+00') TO ('2023-02-01 00:00:00+00');
+ALTER TABLE ONLY incident_management_pending_issue_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202301 FOR VALUES FROM ('2022-12-31 18:00:00-06') TO ('2023-01-31 18:00:00-06');
 
 CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202302 (
     id bigint DEFAULT nextval('incident_management_pending_issue_escalations_id_seq'::regclass) NOT NULL,
@@ -773,7 +674,7 @@ CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_issue_escalat
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL
 );
-ALTER TABLE ONLY incident_management_pending_issue_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202302 FOR VALUES FROM ('2023-02-01 00:00:00+00') TO ('2023-03-01 00:00:00+00');
+ALTER TABLE ONLY incident_management_pending_issue_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202302 FOR VALUES FROM ('2023-01-31 18:00:00-06') TO ('2023-02-28 18:00:00-06');
 
 CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202303 (
     id bigint DEFAULT nextval('incident_management_pending_issue_escalations_id_seq'::regclass) NOT NULL,
@@ -783,7 +684,7 @@ CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_issue_escalat
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL
 );
-ALTER TABLE ONLY incident_management_pending_issue_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202303 FOR VALUES FROM ('2023-03-01 00:00:00+00') TO ('2023-04-01 00:00:00+00');
+ALTER TABLE ONLY incident_management_pending_issue_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202303 FOR VALUES FROM ('2023-02-28 18:00:00-06') TO ('2023-03-31 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202304 (
     id bigint DEFAULT nextval('incident_management_pending_issue_escalations_id_seq'::regclass) NOT NULL,
@@ -793,7 +694,7 @@ CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_issue_escalat
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL
 );
-ALTER TABLE ONLY incident_management_pending_issue_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202304 FOR VALUES FROM ('2023-04-01 00:00:00+00') TO ('2023-05-01 00:00:00+00');
+ALTER TABLE ONLY incident_management_pending_issue_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202304 FOR VALUES FROM ('2023-03-31 19:00:00-05') TO ('2023-04-30 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202305 (
     id bigint DEFAULT nextval('incident_management_pending_issue_escalations_id_seq'::regclass) NOT NULL,
@@ -803,7 +704,7 @@ CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_issue_escalat
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL
 );
-ALTER TABLE ONLY incident_management_pending_issue_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202305 FOR VALUES FROM ('2023-05-01 00:00:00+00') TO ('2023-06-01 00:00:00+00');
+ALTER TABLE ONLY incident_management_pending_issue_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202305 FOR VALUES FROM ('2023-04-30 19:00:00-05') TO ('2023-05-31 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202306 (
     id bigint DEFAULT nextval('incident_management_pending_issue_escalations_id_seq'::regclass) NOT NULL,
@@ -813,7 +714,7 @@ CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_issue_escalat
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL
 );
-ALTER TABLE ONLY incident_management_pending_issue_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202306 FOR VALUES FROM ('2023-06-01 00:00:00+00') TO ('2023-07-01 00:00:00+00');
+ALTER TABLE ONLY incident_management_pending_issue_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202306 FOR VALUES FROM ('2023-05-31 19:00:00-05') TO ('2023-06-30 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202307 (
     id bigint DEFAULT nextval('incident_management_pending_issue_escalations_id_seq'::regclass) NOT NULL,
@@ -823,7 +724,7 @@ CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_issue_escalat
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL
 );
-ALTER TABLE ONLY incident_management_pending_issue_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202307 FOR VALUES FROM ('2023-07-01 00:00:00+00') TO ('2023-08-01 00:00:00+00');
+ALTER TABLE ONLY incident_management_pending_issue_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202307 FOR VALUES FROM ('2023-06-30 19:00:00-05') TO ('2023-07-31 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202308 (
     id bigint DEFAULT nextval('incident_management_pending_issue_escalations_id_seq'::regclass) NOT NULL,
@@ -833,7 +734,7 @@ CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_issue_escalat
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL
 );
-ALTER TABLE ONLY incident_management_pending_issue_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202308 FOR VALUES FROM ('2023-08-01 00:00:00+00') TO ('2023-09-01 00:00:00+00');
+ALTER TABLE ONLY incident_management_pending_issue_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202308 FOR VALUES FROM ('2023-07-31 19:00:00-05') TO ('2023-08-31 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202309 (
     id bigint DEFAULT nextval('incident_management_pending_issue_escalations_id_seq'::regclass) NOT NULL,
@@ -843,42 +744,7 @@ CREATE TABLE gitlab_partitions_dynamic.incident_management_pending_issue_escalat
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL
 );
-ALTER TABLE ONLY incident_management_pending_issue_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202309 FOR VALUES FROM ('2023-09-01 00:00:00+00') TO ('2023-10-01 00:00:00+00');
-
-CREATE TABLE loose_foreign_keys_deleted_records (
-    id bigint NOT NULL,
-    partition bigint DEFAULT 1 NOT NULL,
-    primary_key_value bigint NOT NULL,
-    status smallint DEFAULT 1 NOT NULL,
-    created_at timestamp with time zone DEFAULT now() NOT NULL,
-    fully_qualified_table_name text NOT NULL,
-    consume_after timestamp with time zone DEFAULT now(),
-    cleanup_attempts smallint DEFAULT 0,
-    CONSTRAINT check_1a541f3235 CHECK ((char_length(fully_qualified_table_name) <= 150))
-)
-PARTITION BY LIST (partition);
-
-CREATE SEQUENCE loose_foreign_keys_deleted_records_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
-
-ALTER SEQUENCE loose_foreign_keys_deleted_records_id_seq OWNED BY loose_foreign_keys_deleted_records.id;
-
-CREATE TABLE gitlab_partitions_dynamic.loose_foreign_keys_deleted_records_1 (
-    id bigint DEFAULT nextval('loose_foreign_keys_deleted_records_id_seq'::regclass) NOT NULL,
-    partition bigint DEFAULT 1 NOT NULL,
-    primary_key_value bigint NOT NULL,
-    status smallint DEFAULT 1 NOT NULL,
-    created_at timestamp with time zone DEFAULT now() NOT NULL,
-    fully_qualified_table_name text NOT NULL,
-    consume_after timestamp with time zone DEFAULT now(),
-    cleanup_attempts smallint DEFAULT 0,
-    CONSTRAINT check_1a541f3235 CHECK ((char_length(fully_qualified_table_name) <= 150))
-);
-ALTER TABLE ONLY loose_foreign_keys_deleted_records ATTACH PARTITION gitlab_partitions_dynamic.loose_foreign_keys_deleted_records_1 FOR VALUES IN ('1');
+ALTER TABLE ONLY incident_management_pending_issue_escalations ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202309 FOR VALUES FROM ('2023-08-31 19:00:00-05') TO ('2023-09-30 19:00:00-05');
 
 CREATE TABLE verification_codes (
     created_at timestamp with time zone DEFAULT now() NOT NULL,
@@ -887,7 +753,7 @@ CREATE TABLE verification_codes (
     phone text NOT NULL,
     CONSTRAINT check_9b84e6aaff CHECK ((char_length(code) <= 8)),
     CONSTRAINT check_ccc542256b CHECK ((char_length(visitor_id_code) <= 64)),
-    CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 50))
+    CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 32))
 )
 PARTITION BY RANGE (created_at);
 
@@ -900,9 +766,9 @@ CREATE TABLE gitlab_partitions_dynamic.verification_codes_000000 (
     phone text NOT NULL,
     CONSTRAINT check_9b84e6aaff CHECK ((char_length(code) <= 8)),
     CONSTRAINT check_ccc542256b CHECK ((char_length(visitor_id_code) <= 64)),
-    CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 50))
+    CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 32))
 );
-ALTER TABLE ONLY verification_codes ATTACH PARTITION gitlab_partitions_dynamic.verification_codes_000000 FOR VALUES FROM (MINVALUE) TO ('2023-02-01 00:00:00+00');
+ALTER TABLE ONLY verification_codes ATTACH PARTITION gitlab_partitions_dynamic.verification_codes_000000 FOR VALUES FROM (MINVALUE) TO ('2023-01-31 18:00:00-06');
 
 CREATE TABLE gitlab_partitions_dynamic.verification_codes_202302 (
     created_at timestamp with time zone DEFAULT now() NOT NULL,
@@ -911,9 +777,9 @@ CREATE TABLE gitlab_partitions_dynamic.verification_codes_202302 (
     phone text NOT NULL,
     CONSTRAINT check_9b84e6aaff CHECK ((char_length(code) <= 8)),
     CONSTRAINT check_ccc542256b CHECK ((char_length(visitor_id_code) <= 64)),
-    CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 50))
+    CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 32))
 );
-ALTER TABLE ONLY verification_codes ATTACH PARTITION gitlab_partitions_dynamic.verification_codes_202302 FOR VALUES FROM ('2023-02-01 00:00:00+00') TO ('2023-03-01 00:00:00+00');
+ALTER TABLE ONLY verification_codes ATTACH PARTITION gitlab_partitions_dynamic.verification_codes_202302 FOR VALUES FROM ('2023-01-31 18:00:00-06') TO ('2023-02-28 18:00:00-06');
 
 CREATE TABLE gitlab_partitions_dynamic.verification_codes_202303 (
     created_at timestamp with time zone DEFAULT now() NOT NULL,
@@ -922,9 +788,9 @@ CREATE TABLE gitlab_partitions_dynamic.verification_codes_202303 (
     phone text NOT NULL,
     CONSTRAINT check_9b84e6aaff CHECK ((char_length(code) <= 8)),
     CONSTRAINT check_ccc542256b CHECK ((char_length(visitor_id_code) <= 64)),
-    CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 50))
+    CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 32))
 );
-ALTER TABLE ONLY verification_codes ATTACH PARTITION gitlab_partitions_dynamic.verification_codes_202303 FOR VALUES FROM ('2023-03-01 00:00:00+00') TO ('2023-04-01 00:00:00+00');
+ALTER TABLE ONLY verification_codes ATTACH PARTITION gitlab_partitions_dynamic.verification_codes_202303 FOR VALUES FROM ('2023-02-28 18:00:00-06') TO ('2023-03-31 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.verification_codes_202304 (
     created_at timestamp with time zone DEFAULT now() NOT NULL,
@@ -933,9 +799,9 @@ CREATE TABLE gitlab_partitions_dynamic.verification_codes_202304 (
     phone text NOT NULL,
     CONSTRAINT check_9b84e6aaff CHECK ((char_length(code) <= 8)),
     CONSTRAINT check_ccc542256b CHECK ((char_length(visitor_id_code) <= 64)),
-    CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 50))
+    CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 32))
 );
-ALTER TABLE ONLY verification_codes ATTACH PARTITION gitlab_partitions_dynamic.verification_codes_202304 FOR VALUES FROM ('2023-04-01 00:00:00+00') TO ('2023-05-01 00:00:00+00');
+ALTER TABLE ONLY verification_codes ATTACH PARTITION gitlab_partitions_dynamic.verification_codes_202304 FOR VALUES FROM ('2023-03-31 19:00:00-05') TO ('2023-04-30 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.verification_codes_202305 (
     created_at timestamp with time zone DEFAULT now() NOT NULL,
@@ -944,9 +810,9 @@ CREATE TABLE gitlab_partitions_dynamic.verification_codes_202305 (
     phone text NOT NULL,
     CONSTRAINT check_9b84e6aaff CHECK ((char_length(code) <= 8)),
     CONSTRAINT check_ccc542256b CHECK ((char_length(visitor_id_code) <= 64)),
-    CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 50))
+    CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 32))
 );
-ALTER TABLE ONLY verification_codes ATTACH PARTITION gitlab_partitions_dynamic.verification_codes_202305 FOR VALUES FROM ('2023-05-01 00:00:00+00') TO ('2023-06-01 00:00:00+00');
+ALTER TABLE ONLY verification_codes ATTACH PARTITION gitlab_partitions_dynamic.verification_codes_202305 FOR VALUES FROM ('2023-04-30 19:00:00-05') TO ('2023-05-31 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.verification_codes_202306 (
     created_at timestamp with time zone DEFAULT now() NOT NULL,
@@ -955,9 +821,9 @@ CREATE TABLE gitlab_partitions_dynamic.verification_codes_202306 (
     phone text NOT NULL,
     CONSTRAINT check_9b84e6aaff CHECK ((char_length(code) <= 8)),
     CONSTRAINT check_ccc542256b CHECK ((char_length(visitor_id_code) <= 64)),
-    CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 50))
+    CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 32))
 );
-ALTER TABLE ONLY verification_codes ATTACH PARTITION gitlab_partitions_dynamic.verification_codes_202306 FOR VALUES FROM ('2023-06-01 00:00:00+00') TO ('2023-07-01 00:00:00+00');
+ALTER TABLE ONLY verification_codes ATTACH PARTITION gitlab_partitions_dynamic.verification_codes_202306 FOR VALUES FROM ('2023-05-31 19:00:00-05') TO ('2023-06-30 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.verification_codes_202307 (
     created_at timestamp with time zone DEFAULT now() NOT NULL,
@@ -966,9 +832,9 @@ CREATE TABLE gitlab_partitions_dynamic.verification_codes_202307 (
     phone text NOT NULL,
     CONSTRAINT check_9b84e6aaff CHECK ((char_length(code) <= 8)),
     CONSTRAINT check_ccc542256b CHECK ((char_length(visitor_id_code) <= 64)),
-    CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 50))
+    CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 32))
 );
-ALTER TABLE ONLY verification_codes ATTACH PARTITION gitlab_partitions_dynamic.verification_codes_202307 FOR VALUES FROM ('2023-07-01 00:00:00+00') TO ('2023-08-01 00:00:00+00');
+ALTER TABLE ONLY verification_codes ATTACH PARTITION gitlab_partitions_dynamic.verification_codes_202307 FOR VALUES FROM ('2023-06-30 19:00:00-05') TO ('2023-07-31 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.verification_codes_202308 (
     created_at timestamp with time zone DEFAULT now() NOT NULL,
@@ -977,9 +843,9 @@ CREATE TABLE gitlab_partitions_dynamic.verification_codes_202308 (
     phone text NOT NULL,
     CONSTRAINT check_9b84e6aaff CHECK ((char_length(code) <= 8)),
     CONSTRAINT check_ccc542256b CHECK ((char_length(visitor_id_code) <= 64)),
-    CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 50))
+    CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 32))
 );
-ALTER TABLE ONLY verification_codes ATTACH PARTITION gitlab_partitions_dynamic.verification_codes_202308 FOR VALUES FROM ('2023-08-01 00:00:00+00') TO ('2023-09-01 00:00:00+00');
+ALTER TABLE ONLY verification_codes ATTACH PARTITION gitlab_partitions_dynamic.verification_codes_202308 FOR VALUES FROM ('2023-07-31 19:00:00-05') TO ('2023-08-31 19:00:00-05');
 
 CREATE TABLE gitlab_partitions_dynamic.verification_codes_202309 (
     created_at timestamp with time zone DEFAULT now() NOT NULL,
@@ -988,9 +854,9 @@ CREATE TABLE gitlab_partitions_dynamic.verification_codes_202309 (
     phone text NOT NULL,
     CONSTRAINT check_9b84e6aaff CHECK ((char_length(code) <= 8)),
     CONSTRAINT check_ccc542256b CHECK ((char_length(visitor_id_code) <= 64)),
-    CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 50))
+    CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 32))
 );
-ALTER TABLE ONLY verification_codes ATTACH PARTITION gitlab_partitions_dynamic.verification_codes_202309 FOR VALUES FROM ('2023-09-01 00:00:00+00') TO ('2023-10-01 00:00:00+00');
+ALTER TABLE ONLY verification_codes ATTACH PARTITION gitlab_partitions_dynamic.verification_codes_202309 FOR VALUES FROM ('2023-08-31 19:00:00-05') TO ('2023-09-30 19:00:00-05');
 
 CREATE TABLE web_hook_logs (
     id bigint NOT NULL,
@@ -2648,6 +2514,39 @@ CREATE TABLE gitlab_partitions_static.issue_search_data_63 (
 );
 ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_63 FOR VALUES WITH (modulus 64, remainder 63);
 
+CREATE TABLE loose_foreign_keys_deleted_records (
+    id bigint NOT NULL,
+    partition bigint DEFAULT 1 NOT NULL,
+    primary_key_value bigint NOT NULL,
+    status smallint DEFAULT 1 NOT NULL,
+    created_at timestamp with time zone DEFAULT now() NOT NULL,
+    fully_qualified_table_name text NOT NULL,
+    consume_after timestamp with time zone DEFAULT now(),
+    CONSTRAINT check_1a541f3235 CHECK ((char_length(fully_qualified_table_name) <= 150))
+)
+PARTITION BY LIST (partition);
+
+CREATE SEQUENCE loose_foreign_keys_deleted_records_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+ALTER SEQUENCE loose_foreign_keys_deleted_records_id_seq OWNED BY loose_foreign_keys_deleted_records.id;
+
+CREATE TABLE gitlab_partitions_static.loose_foreign_keys_deleted_records_1 (
+    id bigint DEFAULT nextval('loose_foreign_keys_deleted_records_id_seq'::regclass) NOT NULL,
+    partition bigint DEFAULT 1 NOT NULL,
+    primary_key_value bigint NOT NULL,
+    status smallint DEFAULT 1 NOT NULL,
+    created_at timestamp with time zone DEFAULT now() NOT NULL,
+    fully_qualified_table_name text NOT NULL,
+    consume_after timestamp with time zone DEFAULT now(),
+    CONSTRAINT check_1a541f3235 CHECK ((char_length(fully_qualified_table_name) <= 150))
+);
+ALTER TABLE ONLY loose_foreign_keys_deleted_records ATTACH PARTITION gitlab_partitions_static.loose_foreign_keys_deleted_records_1 FOR VALUES IN ('1');
+
 CREATE TABLE product_analytics_events_experimental (
     id bigint NOT NULL,
     project_id integer NOT NULL,
@@ -11394,29 +11293,6 @@ CREATE SEQUENCE alert_management_alert_assignees_id_seq
 
 ALTER SEQUENCE alert_management_alert_assignees_id_seq OWNED BY alert_management_alert_assignees.id;
 
-CREATE TABLE alert_management_alert_metric_images (
-    id bigint NOT NULL,
-    alert_id bigint NOT NULL,
-    created_at timestamp with time zone NOT NULL,
-    updated_at timestamp with time zone NOT NULL,
-    file_store smallint,
-    file text NOT NULL,
-    url text,
-    url_text text,
-    CONSTRAINT check_2587666252 CHECK ((char_length(url_text) <= 128)),
-    CONSTRAINT check_4d811d9007 CHECK ((char_length(url) <= 255)),
-    CONSTRAINT check_70fafae519 CHECK ((char_length(file) <= 255))
-);
-
-CREATE SEQUENCE alert_management_alert_metric_images_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
-
-ALTER SEQUENCE alert_management_alert_metric_images_id_seq OWNED BY alert_management_alert_metric_images.id;
-
 CREATE TABLE alert_management_alert_user_mentions (
     id bigint NOT NULL,
     alert_management_alert_id bigint NOT NULL,
@@ -11516,30 +11392,6 @@ CREATE SEQUENCE allowed_email_domains_id_seq
 
 ALTER SEQUENCE allowed_email_domains_id_seq OWNED BY allowed_email_domains.id;
 
-CREATE TABLE analytics_cycle_analytics_aggregations (
-    group_id bigint NOT NULL,
-    incremental_runtimes_in_seconds integer[] DEFAULT '{}'::integer[] NOT NULL,
-    incremental_processed_records integer[] DEFAULT '{}'::integer[] NOT NULL,
-    last_full_run_runtimes_in_seconds integer[] DEFAULT '{}'::integer[] NOT NULL,
-    last_full_run_processed_records integer[] DEFAULT '{}'::integer[] NOT NULL,
-    last_incremental_issues_id integer,
-    last_incremental_merge_requests_id integer,
-    last_full_run_issues_id integer,
-    last_full_run_merge_requests_id integer,
-    last_incremental_run_at timestamp with time zone,
-    last_incremental_issues_updated_at timestamp with time zone,
-    last_incremental_merge_requests_updated_at timestamp with time zone,
-    last_full_run_at timestamp with time zone,
-    last_full_run_issues_updated_at timestamp with time zone,
-    last_full_run_mrs_updated_at timestamp with time zone,
-    last_consistency_check_updated_at timestamp with time zone,
-    enabled boolean DEFAULT true NOT NULL,
-    CONSTRAINT chk_rails_1ef688e577 CHECK ((cardinality(incremental_runtimes_in_seconds) <= 10)),
-    CONSTRAINT chk_rails_7810292ec9 CHECK ((cardinality(last_full_run_processed_records) <= 10)),
-    CONSTRAINT chk_rails_8b9e89687c CHECK ((cardinality(last_full_run_runtimes_in_seconds) <= 10)),
-    CONSTRAINT chk_rails_e16bf3913a CHECK ((cardinality(incremental_processed_records) <= 10))
-);
-
 CREATE TABLE analytics_cycle_analytics_group_stages (
     id bigint NOT NULL,
     created_at timestamp with time zone NOT NULL,
@@ -11671,7 +11523,7 @@ CREATE TABLE analytics_devops_adoption_snapshots (
     runner_configured boolean NOT NULL,
     pipeline_succeeded boolean NOT NULL,
     deploy_succeeded boolean NOT NULL,
-    security_scan_succeeded boolean,
+    security_scan_succeeded boolean NOT NULL,
     end_time timestamp with time zone NOT NULL,
     total_projects_count integer,
     code_owners_used_count integer,
@@ -11947,7 +11799,7 @@ CREATE TABLE application_settings (
     throttle_protected_paths_enabled boolean DEFAULT false NOT NULL,
     throttle_protected_paths_requests_per_period integer DEFAULT 10 NOT NULL,
     throttle_protected_paths_period_in_seconds integer DEFAULT 60 NOT NULL,
-    protected_paths character varying(255)[] DEFAULT '{/users/password,/users/sign_in,/api/v3/session.json,/api/v3/session,/api/v4/session.json,/api/v4/session,/users,/users/confirmation,/unsubscribes/,/import/github/personal_access_token,/admin/session}'::character varying[],
+    protected_paths character varying(255)[] DEFAULT '{/users/password,/users/sign_in,/api/v3/session.json,/api/v3/session,/api/v4/session.json,/api/v4/session,/users,/users/confirmation,/unsubscribes/,/import/github/personal_access_token,/admin/session,/oauth/authorize,/oauth/token}'::character varying[],
     snowplow_collector_hostname character varying,
     sourcegraph_enabled boolean DEFAULT false NOT NULL,
     sourcegraph_url character varying(255),
@@ -12030,7 +11882,7 @@ CREATE TABLE application_settings (
     kroki_url text,
     kroki_enabled boolean DEFAULT false NOT NULL,
     help_page_documentation_base_url text,
-    container_registry_expiration_policies_worker_capacity integer DEFAULT 4 NOT NULL,
+    container_registry_expiration_policies_worker_capacity integer DEFAULT 0 NOT NULL,
     require_admin_approval_after_user_signup boolean DEFAULT true NOT NULL,
     automatic_purchased_storage_allocation boolean DEFAULT false NOT NULL,
     encrypted_ci_jwt_signing_key text,
@@ -12132,41 +11984,15 @@ CREATE TABLE application_settings (
     max_ssh_key_lifetime integer,
     static_objects_external_storage_auth_token_encrypted text,
     future_subscriptions jsonb DEFAULT '[]'::jsonb NOT NULL,
-    user_email_lookup_limit integer DEFAULT 60 NOT NULL,
-    packages_cleanup_package_file_worker_capacity smallint DEFAULT 2 NOT NULL,
-    container_registry_import_max_tags_count integer DEFAULT 100 NOT NULL,
-    container_registry_import_max_retries integer DEFAULT 3 NOT NULL,
-    container_registry_import_start_max_retries integer DEFAULT 50 NOT NULL,
-    container_registry_import_max_step_duration integer DEFAULT 300 NOT NULL,
-    container_registry_import_target_plan text DEFAULT 'free'::text NOT NULL,
-    container_registry_import_created_before timestamp with time zone DEFAULT '2022-01-23 00:00:00+00'::timestamp with time zone NOT NULL,
-    runner_token_expiration_interval integer,
-    group_runner_token_expiration_interval integer,
-    project_runner_token_expiration_interval integer,
-    ecdsa_sk_key_restriction integer DEFAULT 0 NOT NULL,
-    ed25519_sk_key_restriction integer DEFAULT 0 NOT NULL,
-    users_get_by_id_limit integer DEFAULT 300 NOT NULL,
-    users_get_by_id_limit_allowlist text[] DEFAULT '{}'::text[] NOT NULL,
-    container_registry_expiration_policies_caching boolean DEFAULT true NOT NULL,
-    search_rate_limit integer DEFAULT 30 NOT NULL,
-    search_rate_limit_unauthenticated integer DEFAULT 10 NOT NULL,
-    encrypted_database_grafana_api_key bytea,
-    encrypted_database_grafana_api_key_iv bytea,
-    database_grafana_api_url text,
-    database_grafana_tag text,
     CONSTRAINT app_settings_container_reg_cleanup_tags_max_list_size_positive CHECK ((container_registry_cleanup_tags_service_max_list_size >= 0)),
     CONSTRAINT app_settings_dep_proxy_ttl_policies_worker_capacity_positive CHECK ((dependency_proxy_ttl_group_policy_worker_capacity >= 0)),
     CONSTRAINT app_settings_ext_pipeline_validation_service_url_text_limit CHECK ((char_length(external_pipeline_validation_service_url) <= 255)),
-    CONSTRAINT app_settings_p_cleanup_package_file_worker_capacity_positive CHECK ((packages_cleanup_package_file_worker_capacity >= 0)),
     CONSTRAINT app_settings_registry_exp_policies_worker_capacity_positive CHECK ((container_registry_expiration_policies_worker_capacity >= 0)),
     CONSTRAINT app_settings_yaml_max_depth_positive CHECK ((max_yaml_depth > 0)),
     CONSTRAINT app_settings_yaml_max_size_positive CHECK ((max_yaml_size_bytes > 0)),
     CONSTRAINT check_17d9558205 CHECK ((char_length(kroki_url) <= 1024)),
-    CONSTRAINT check_2b820eaac3 CHECK ((char_length(database_grafana_tag) <= 255)),
     CONSTRAINT check_2dba05b802 CHECK ((char_length(gitpod_url) <= 255)),
     CONSTRAINT check_32710817e9 CHECK ((char_length(static_objects_external_storage_auth_token_encrypted) <= 255)),
-    CONSTRAINT check_3455368420 CHECK ((char_length(database_grafana_api_url) <= 255)),
-    CONSTRAINT check_3559645ae5 CHECK ((char_length(container_registry_import_target_plan) <= 255)),
     CONSTRAINT check_3def0f1829 CHECK ((char_length(sentry_clientside_dsn) <= 255)),
     CONSTRAINT check_4f8b811780 CHECK ((char_length(sentry_dsn) <= 255)),
     CONSTRAINT check_51700b31b5 CHECK ((char_length(default_branch_name) <= 255)),
@@ -12437,9 +12263,7 @@ CREATE TABLE audit_events_external_audit_event_destinations (
     destination_url text NOT NULL,
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL,
-    verification_token text,
-    CONSTRAINT check_2feafb9daf CHECK ((char_length(destination_url) <= 255)),
-    CONSTRAINT check_8ec80a7d06 CHECK ((char_length(verification_token) <= 24))
+    CONSTRAINT check_2feafb9daf CHECK ((char_length(destination_url) <= 255))
 );
 
 CREATE SEQUENCE audit_events_external_audit_event_destinations_id_seq
@@ -12592,7 +12416,6 @@ CREATE TABLE batched_background_migrations (
     job_arguments jsonb DEFAULT '"[]"'::jsonb NOT NULL,
     total_tuple_count bigint,
     pause_ms integer DEFAULT 100 NOT NULL,
-    max_batch_size integer,
     CONSTRAINT check_5bb0382d6f CHECK ((char_length(column_name) <= 63)),
     CONSTRAINT check_6b6a06254a CHECK ((char_length(table_name) <= 63)),
     CONSTRAINT check_batch_size_in_range CHECK ((batch_size >= sub_batch_size)),
@@ -12862,8 +12685,7 @@ CREATE TABLE broadcast_messages (
     cached_markdown_version integer,
     dismissable boolean,
     target_path character varying(255),
-    broadcast_type smallint DEFAULT 1 NOT NULL,
-    target_access_levels integer[] DEFAULT '{}'::integer[] NOT NULL
+    broadcast_type smallint DEFAULT 1 NOT NULL
 );
 
 CREATE SEQUENCE broadcast_messages_id_seq
@@ -13885,11 +13707,7 @@ CREATE TABLE ci_runners (
     token_encrypted character varying,
     public_projects_minutes_cost_factor double precision DEFAULT 0.0 NOT NULL,
     private_projects_minutes_cost_factor double precision DEFAULT 1.0 NOT NULL,
-    config jsonb DEFAULT '{}'::jsonb NOT NULL,
-    executor_type smallint,
-    maintainer_note text,
-    token_expires_at timestamp with time zone,
-    CONSTRAINT check_ce275cee06 CHECK ((char_length(maintainer_note) <= 1024))
+    config jsonb DEFAULT '{}'::jsonb NOT NULL
 );
 
 CREATE SEQUENCE ci_runners_id_seq
@@ -13920,29 +13738,6 @@ CREATE SEQUENCE ci_running_builds_id_seq
 
 ALTER SEQUENCE ci_running_builds_id_seq OWNED BY ci_running_builds.id;
 
-CREATE TABLE ci_secure_files (
-    id bigint NOT NULL,
-    project_id bigint NOT NULL,
-    created_at timestamp with time zone NOT NULL,
-    updated_at timestamp with time zone NOT NULL,
-    file_store smallint DEFAULT 1 NOT NULL,
-    permissions smallint DEFAULT 0 NOT NULL,
-    name text NOT NULL,
-    file text NOT NULL,
-    checksum bytea NOT NULL,
-    CONSTRAINT check_320790634d CHECK ((char_length(file) <= 255)),
-    CONSTRAINT check_402c7b4a56 CHECK ((char_length(name) <= 255))
-);
-
-CREATE SEQUENCE ci_secure_files_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
-
-ALTER SEQUENCE ci_secure_files_id_seq OWNED BY ci_secure_files.id;
-
 CREATE TABLE ci_sources_pipelines (
     id integer NOT NULL,
     project_id integer,
@@ -14124,7 +13919,6 @@ CREATE TABLE cluster_agent_tokens (
     description text,
     name text,
     last_used_at timestamp with time zone,
-    status smallint DEFAULT 0 NOT NULL,
     CONSTRAINT check_0fb634d04d CHECK ((name IS NOT NULL)),
     CONSTRAINT check_2b79dbb315 CHECK ((char_length(name) <= 255)),
     CONSTRAINT check_4e4ec5070a CHECK ((char_length(description) <= 1024)),
@@ -14633,19 +14427,7 @@ CREATE TABLE container_repositories (
     status smallint,
     expiration_policy_started_at timestamp with time zone,
     expiration_policy_cleanup_status smallint DEFAULT 0 NOT NULL,
-    expiration_policy_completed_at timestamp with time zone,
-    migration_pre_import_started_at timestamp with time zone,
-    migration_pre_import_done_at timestamp with time zone,
-    migration_import_started_at timestamp with time zone,
-    migration_import_done_at timestamp with time zone,
-    migration_aborted_at timestamp with time zone,
-    migration_skipped_at timestamp with time zone,
-    migration_retries_count integer DEFAULT 0 NOT NULL,
-    migration_skipped_reason smallint,
-    migration_state text DEFAULT 'default'::text NOT NULL,
-    migration_aborted_in_state text,
-    CONSTRAINT check_13c58fe73a CHECK ((char_length(migration_state) <= 255)),
-    CONSTRAINT check_97f0249439 CHECK ((char_length(migration_aborted_in_state) <= 255))
+    expiration_policy_completed_at timestamp with time zone
 );
 
 CREATE SEQUENCE container_repositories_id_seq
@@ -14965,8 +14747,6 @@ CREATE TABLE dast_site_profiles (
     auth_password_field text,
     auth_username text,
     target_type smallint DEFAULT 0 NOT NULL,
-    scan_method smallint DEFAULT 0 NOT NULL,
-    scan_file_path text,
     CONSTRAINT check_5203110fee CHECK ((char_length(auth_username_field) <= 255)),
     CONSTRAINT check_6cfab17b48 CHECK ((char_length(name) <= 255)),
     CONSTRAINT check_c329dffdba CHECK ((char_length(auth_password_field) <= 255)),
@@ -15193,9 +14973,7 @@ CREATE TABLE deployment_approvals (
     user_id bigint NOT NULL,
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL,
-    status smallint NOT NULL,
-    comment text,
-    CONSTRAINT check_e2eb6a17d8 CHECK ((char_length(comment) <= 255))
+    status smallint NOT NULL
 );
 
 CREATE SEQUENCE deployment_approvals_id_seq
@@ -15389,7 +15167,6 @@ CREATE TABLE dora_daily_metrics (
     date date NOT NULL,
     deployment_frequency integer,
     lead_time_for_changes_in_seconds integer,
-    time_to_restore_service_in_seconds integer,
     CONSTRAINT dora_daily_metrics_deployment_frequency_positive CHECK ((deployment_frequency >= 0)),
     CONSTRAINT dora_daily_metrics_lead_time_for_changes_in_seconds_positive CHECK ((lead_time_for_changes_in_seconds >= 0))
 );
@@ -16510,22 +16287,6 @@ CREATE SEQUENCE grafana_integrations_id_seq
 
 ALTER SEQUENCE grafana_integrations_id_seq OWNED BY grafana_integrations.id;
 
-CREATE TABLE group_crm_settings (
-    group_id bigint NOT NULL,
-    created_at timestamp with time zone NOT NULL,
-    updated_at timestamp with time zone NOT NULL,
-    enabled boolean DEFAULT false NOT NULL
-);
-
-CREATE SEQUENCE group_crm_settings_group_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
-
-ALTER SEQUENCE group_crm_settings_group_id_seq OWNED BY group_crm_settings.group_id;
-
 CREATE TABLE group_custom_attributes (
     id integer NOT NULL,
     created_at timestamp with time zone NOT NULL,
@@ -16611,13 +16372,6 @@ CREATE SEQUENCE group_deploy_tokens_id_seq
 
 ALTER SEQUENCE group_deploy_tokens_id_seq OWNED BY group_deploy_tokens.id;
 
-CREATE TABLE group_features (
-    group_id bigint NOT NULL,
-    created_at timestamp with time zone NOT NULL,
-    updated_at timestamp with time zone NOT NULL,
-    wiki_access_level smallint DEFAULT 20 NOT NULL
-);
-
 CREATE TABLE group_group_links (
     id bigint NOT NULL,
     created_at timestamp with time zone NOT NULL,
@@ -17010,6 +16764,7 @@ ALTER SEQUENCE insights_id_seq OWNED BY insights.id;
 
 CREATE TABLE integrations (
     id integer NOT NULL,
+    type character varying,
     project_id integer,
     created_at timestamp without time zone,
     updated_at timestamp without time zone,
@@ -17038,8 +16793,6 @@ CREATE TABLE integrations (
     vulnerability_events boolean DEFAULT false NOT NULL,
     type_new text,
     archive_trace_events boolean DEFAULT false NOT NULL,
-    encrypted_properties bytea,
-    encrypted_properties_iv bytea,
     CONSTRAINT check_a948a0aa7e CHECK ((char_length(type_new) <= 255))
 );
 
@@ -17093,8 +16846,6 @@ CREATE TABLE issuable_metric_images (
     file_store smallint,
     file text NOT NULL,
     url text,
-    url_text text,
-    CONSTRAINT check_3bc6d47661 CHECK ((char_length(url_text) <= 128)),
     CONSTRAINT check_5b3011e234 CHECK ((char_length(url) <= 255)),
     CONSTRAINT check_7ed527062f CHECK ((char_length(file) <= 255))
 );
@@ -17754,8 +17505,7 @@ CREATE TABLE members (
     ldap boolean DEFAULT false NOT NULL,
     override boolean DEFAULT false NOT NULL,
     invite_email_success boolean DEFAULT true NOT NULL,
-    state smallint DEFAULT 0,
-    member_namespace_id bigint
+    state smallint DEFAULT 0
 );
 
 CREATE SEQUENCE members_id_seq
@@ -17773,8 +17523,7 @@ CREATE TABLE merge_request_assignees (
     user_id integer NOT NULL,
     merge_request_id integer NOT NULL,
     created_at timestamp with time zone,
-    state smallint DEFAULT 0 NOT NULL,
-    updated_state_by_user_id bigint
+    state smallint DEFAULT 0 NOT NULL
 );
 
 CREATE SEQUENCE merge_request_assignees_id_seq
@@ -18003,8 +17752,7 @@ CREATE TABLE merge_request_reviewers (
     user_id bigint NOT NULL,
     merge_request_id bigint NOT NULL,
     created_at timestamp with time zone NOT NULL,
-    state smallint DEFAULT 0 NOT NULL,
-    updated_state_by_user_id bigint
+    state smallint DEFAULT 0 NOT NULL
 );
 
 CREATE SEQUENCE merge_request_reviewers_id_seq
@@ -18101,8 +17849,7 @@ CREATE TABLE merge_requests_compliance_violations (
     id bigint NOT NULL,
     violating_user_id bigint NOT NULL,
     merge_request_id bigint NOT NULL,
-    reason smallint NOT NULL,
-    severity_level smallint DEFAULT 0 NOT NULL
+    reason smallint NOT NULL
 );
 
 CREATE SEQUENCE merge_requests_compliance_violations_id_seq
@@ -18278,8 +18025,7 @@ CREATE TABLE namespace_root_storage_statistics (
     packages_size bigint DEFAULT 0 NOT NULL,
     snippets_size bigint DEFAULT 0 NOT NULL,
     pipeline_artifacts_size bigint DEFAULT 0 NOT NULL,
-    uploads_size bigint DEFAULT 0 NOT NULL,
-    dependency_proxy_size bigint DEFAULT 0 NOT NULL
+    uploads_size bigint DEFAULT 0 NOT NULL
 );
 
 CREATE SEQUENCE namespace_root_storage_statistics_namespace_id_seq
@@ -18307,9 +18053,6 @@ CREATE TABLE namespace_settings (
     new_user_signups_cap integer,
     setup_for_company boolean,
     jobs_to_be_done smallint,
-    runner_token_expiration_interval integer,
-    subgroup_runner_token_expiration_interval integer,
-    project_runner_token_expiration_interval integer,
     CONSTRAINT check_0ba93c78c7 CHECK ((char_length(default_branch_name) <= 255))
 );
 
@@ -18319,8 +18062,7 @@ CREATE TABLE namespace_statistics (
     shared_runners_seconds integer DEFAULT 0 NOT NULL,
     shared_runners_seconds_last_reset timestamp without time zone,
     storage_size bigint DEFAULT 0 NOT NULL,
-    wiki_size bigint DEFAULT 0 NOT NULL,
-    dependency_proxy_size bigint DEFAULT 0 NOT NULL
+    wiki_size bigint DEFAULT 0 NOT NULL
 );
 
 CREATE SEQUENCE namespace_statistics_id_seq
@@ -18622,14 +18364,7 @@ CREATE TABLE onboarding_progresses (
     issue_auto_closed_at timestamp with time zone,
     repository_imported_at timestamp with time zone,
     repository_mirrored_at timestamp with time zone,
-    issue_created_at timestamp with time zone,
-    secure_dependency_scanning_run_at timestamp with time zone,
-    secure_container_scanning_run_at timestamp with time zone,
-    secure_dast_run_at timestamp with time zone,
-    secure_secret_detection_run_at timestamp with time zone,
-    secure_coverage_fuzzing_run_at timestamp with time zone,
-    secure_cluster_image_scanning_run_at timestamp with time zone,
-    secure_api_fuzzing_run_at timestamp with time zone
+    issue_created_at timestamp with time zone
 );
 
 CREATE SEQUENCE onboarding_progresses_id_seq
@@ -19269,7 +19004,6 @@ CREATE TABLE packages_package_files (
     verification_checksum bytea,
     verification_state smallint DEFAULT 0 NOT NULL,
     verification_started_at timestamp with time zone,
-    status smallint DEFAULT 0 NOT NULL,
     CONSTRAINT check_4c5e6bb0b3 CHECK ((file_store IS NOT NULL))
 );
 
@@ -19305,7 +19039,7 @@ ALTER SEQUENCE packages_packages_id_seq OWNED BY packages_packages.id;
 
 CREATE TABLE packages_pypi_metadata (
     package_id bigint NOT NULL,
-    required_python text DEFAULT ''::text,
+    required_python text,
     CONSTRAINT check_0d9aed55b2 CHECK ((required_python IS NOT NULL)),
     CONSTRAINT check_379019d5da CHECK ((char_length(required_python) <= 255))
 );
@@ -19479,6 +19213,28 @@ CREATE SEQUENCE pages_domains_id_seq
 
 ALTER SEQUENCE pages_domains_id_seq OWNED BY pages_domains.id;
 
+CREATE TABLE partitioned_foreign_keys (
+    id bigint NOT NULL,
+    cascade_delete boolean DEFAULT true NOT NULL,
+    from_table text NOT NULL,
+    from_column text NOT NULL,
+    to_table text NOT NULL,
+    to_column text NOT NULL,
+    CONSTRAINT check_2c2e02a62b CHECK ((char_length(from_column) <= 63)),
+    CONSTRAINT check_40738efb57 CHECK ((char_length(to_table) <= 63)),
+    CONSTRAINT check_741676d405 CHECK ((char_length(from_table) <= 63)),
+    CONSTRAINT check_7e98be694f CHECK ((char_length(to_column) <= 63))
+);
+
+CREATE SEQUENCE partitioned_foreign_keys_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+ALTER SEQUENCE partitioned_foreign_keys_id_seq OWNED BY partitioned_foreign_keys.id;
+
 CREATE TABLE path_locks (
     id integer NOT NULL,
     path character varying NOT NULL,
@@ -19958,25 +19714,6 @@ CREATE SEQUENCE project_auto_devops_id_seq
 
 ALTER SEQUENCE project_auto_devops_id_seq OWNED BY project_auto_devops.id;
 
-CREATE TABLE project_build_artifacts_size_refreshes (
-    id bigint NOT NULL,
-    project_id bigint NOT NULL,
-    last_job_artifact_id bigint,
-    state smallint DEFAULT 1 NOT NULL,
-    refresh_started_at timestamp with time zone,
-    created_at timestamp with time zone NOT NULL,
-    updated_at timestamp with time zone NOT NULL
-);
-
-CREATE SEQUENCE project_build_artifacts_size_refreshes_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
-
-ALTER SEQUENCE project_build_artifacts_size_refreshes_id_seq OWNED BY project_build_artifacts_size_refreshes.id;
-
 CREATE TABLE project_ci_cd_settings (
     id integer NOT NULL,
     project_id integer NOT NULL,
@@ -19988,8 +19725,7 @@ CREATE TABLE project_ci_cd_settings (
     auto_rollback_enabled boolean DEFAULT false NOT NULL,
     keep_latest_artifact boolean DEFAULT true NOT NULL,
     restrict_user_defined_variables boolean DEFAULT false NOT NULL,
-    job_token_scope_enabled boolean DEFAULT false NOT NULL,
-    runner_token_expiration_interval integer
+    job_token_scope_enabled boolean DEFAULT false NOT NULL
 );
 
 CREATE SEQUENCE project_ci_cd_settings_id_seq
@@ -20138,8 +19874,7 @@ CREATE TABLE project_features (
     requirements_access_level integer DEFAULT 20 NOT NULL,
     operations_access_level integer DEFAULT 20 NOT NULL,
     security_and_compliance_access_level integer DEFAULT 10 NOT NULL,
-    container_registry_access_level integer DEFAULT 0 NOT NULL,
-    package_registry_access_level integer DEFAULT 0 NOT NULL
+    container_registry_access_level integer DEFAULT 0 NOT NULL
 );
 
 CREATE SEQUENCE project_features_id_seq
@@ -20343,7 +20078,6 @@ CREATE TABLE project_settings (
     merge_commit_template text,
     has_shimo boolean DEFAULT false NOT NULL,
     squash_commit_template text,
-    legacy_open_source_license_available boolean DEFAULT true NOT NULL,
     CONSTRAINT check_3a03e7557a CHECK ((char_length(previous_default_branch) <= 4096)),
     CONSTRAINT check_b09644994b CHECK ((char_length(squash_commit_template) <= 500)),
     CONSTRAINT check_eaf7cfb6a7 CHECK ((char_length(merge_commit_template) <= 500))
@@ -20493,8 +20227,7 @@ CREATE TABLE projects (
     remove_source_branch_after_merge boolean,
     suggestion_commit_message character varying(255),
     autoclose_referenced_issues boolean,
-    project_namespace_id bigint,
-    hidden boolean DEFAULT false NOT NULL
+    project_namespace_id bigint
 );
 
 CREATE SEQUENCE projects_id_seq
@@ -20669,28 +20402,6 @@ CREATE SEQUENCE protected_branches_id_seq
 
 ALTER SEQUENCE protected_branches_id_seq OWNED BY protected_branches.id;
 
-CREATE TABLE protected_environment_approval_rules (
-    id bigint NOT NULL,
-    protected_environment_id bigint NOT NULL,
-    user_id bigint,
-    group_id bigint,
-    created_at timestamp with time zone NOT NULL,
-    updated_at timestamp with time zone NOT NULL,
-    access_level smallint,
-    required_approvals smallint NOT NULL,
-    CONSTRAINT chk_rails_bed75249bc CHECK ((((access_level IS NOT NULL) AND (group_id IS NULL) AND (user_id IS NULL)) OR ((user_id IS NOT NULL) AND (access_level IS NULL) AND (group_id IS NULL)) OR ((group_id IS NOT NULL) AND (user_id IS NULL) AND (access_level IS NULL)))),
-    CONSTRAINT chk_rails_cfa90ae3b5 CHECK ((required_approvals > 0))
-);
-
-CREATE SEQUENCE protected_environment_approval_rules_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
-
-ALTER SEQUENCE protected_environment_approval_rules_id_seq OWNED BY protected_environment_approval_rules.id;
-
 CREATE TABLE protected_environment_deploy_access_levels (
     id integer NOT NULL,
     created_at timestamp with time zone NOT NULL,
@@ -20719,8 +20430,7 @@ CREATE TABLE protected_environments (
     name character varying NOT NULL,
     group_id bigint,
     required_approval_count integer DEFAULT 0 NOT NULL,
-    CONSTRAINT protected_environments_project_or_group_existence CHECK (((project_id IS NULL) <> (group_id IS NULL))),
-    CONSTRAINT protected_environments_required_approval_count_positive CHECK ((required_approval_count >= 0))
+    CONSTRAINT protected_environments_project_or_group_existence CHECK (((project_id IS NULL) <> (group_id IS NULL)))
 );
 
 CREATE SEQUENCE protected_environments_id_seq
@@ -20853,24 +20563,6 @@ CREATE SEQUENCE redirect_routes_id_seq
 
 ALTER SEQUENCE redirect_routes_id_seq OWNED BY redirect_routes.id;
 
-CREATE TABLE related_epic_links (
-    id bigint NOT NULL,
-    source_id bigint NOT NULL,
-    target_id bigint NOT NULL,
-    created_at timestamp with time zone NOT NULL,
-    updated_at timestamp with time zone NOT NULL,
-    link_type smallint DEFAULT 0 NOT NULL
-);
-
-CREATE SEQUENCE related_epic_links_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
-
-ALTER SEQUENCE related_epic_links_id_seq OWNED BY related_epic_links.id;
-
 CREATE TABLE release_links (
     id bigint NOT NULL,
     release_id integer NOT NULL,
@@ -21142,8 +20834,7 @@ CREATE TABLE routes (
     path character varying NOT NULL,
     created_at timestamp without time zone,
     updated_at timestamp without time zone,
-    name character varying,
-    namespace_id bigint
+    name character varying
 );
 
 CREATE SEQUENCE routes_id_seq
@@ -21198,26 +20889,6 @@ CREATE SEQUENCE saml_providers_id_seq
 
 ALTER SEQUENCE saml_providers_id_seq OWNED BY saml_providers.id;
 
-CREATE TABLE saved_replies (
-    id bigint NOT NULL,
-    user_id bigint NOT NULL,
-    created_at timestamp with time zone NOT NULL,
-    updated_at timestamp with time zone NOT NULL,
-    name text NOT NULL,
-    content text NOT NULL,
-    CONSTRAINT check_0cb57dc22a CHECK ((char_length(content) <= 10000)),
-    CONSTRAINT check_2eb3366d7f CHECK ((char_length(name) <= 255))
-);
-
-CREATE SEQUENCE saved_replies_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
-
-ALTER SEQUENCE saved_replies_id_seq OWNED BY saved_replies.id;
-
 CREATE TABLE scim_identities (
     id bigint NOT NULL,
     group_id bigint NOT NULL,
@@ -21263,9 +20934,9 @@ CREATE TABLE security_findings (
     confidence smallint NOT NULL,
     project_fingerprint text,
     deduplicated boolean DEFAULT false NOT NULL,
+    "position" integer,
     uuid uuid,
     overridden_uuid uuid,
-    CONSTRAINT check_6c2851a8c9 CHECK ((uuid IS NOT NULL)),
     CONSTRAINT check_b9508c6df8 CHECK ((char_length(project_fingerprint) <= 40))
 );
 
@@ -21280,13 +20951,11 @@ ALTER SEQUENCE security_findings_id_seq OWNED BY security_findings.id;
 
 CREATE TABLE security_orchestration_policy_configurations (
     id bigint NOT NULL,
-    project_id bigint,
+    project_id bigint NOT NULL,
     security_policy_management_project_id bigint NOT NULL,
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL,
-    configured_at timestamp with time zone,
-    namespace_id bigint,
-    CONSTRAINT cop_configs_project_or_namespace_existence CHECK (((project_id IS NULL) <> (namespace_id IS NULL)))
+    configured_at timestamp with time zone
 );
 
 COMMENT ON TABLE security_orchestration_policy_configurations IS '{"owner":"group::container security","description":"Configuration used to store relationship between project and security policy repository"}';
@@ -21346,47 +21015,6 @@ CREATE SEQUENCE security_scans_id_seq
 
 ALTER SEQUENCE security_scans_id_seq OWNED BY security_scans.id;
 
-CREATE TABLE security_training_providers (
-    id bigint NOT NULL,
-    name text NOT NULL,
-    description text,
-    url text NOT NULL,
-    logo_url text,
-    created_at timestamp with time zone NOT NULL,
-    updated_at timestamp with time zone NOT NULL,
-    CONSTRAINT check_544b3dc935 CHECK ((char_length(url) <= 512)),
-    CONSTRAINT check_6fe222f071 CHECK ((char_length(logo_url) <= 512)),
-    CONSTRAINT check_a8ff21ced5 CHECK ((char_length(description) <= 512)),
-    CONSTRAINT check_dae433eed6 CHECK ((char_length(name) <= 256))
-);
-
-CREATE SEQUENCE security_training_providers_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
-
-ALTER SEQUENCE security_training_providers_id_seq OWNED BY security_training_providers.id;
-
-CREATE TABLE security_trainings (
-    id bigint NOT NULL,
-    project_id bigint NOT NULL,
-    provider_id bigint NOT NULL,
-    is_primary boolean DEFAULT false NOT NULL,
-    created_at timestamp with time zone NOT NULL,
-    updated_at timestamp with time zone NOT NULL
-);
-
-CREATE SEQUENCE security_trainings_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
-
-ALTER SEQUENCE security_trainings_id_seq OWNED BY security_trainings.id;
-
 CREATE TABLE self_managed_prometheus_alert_events (
     id bigint NOT NULL,
     project_id bigint NOT NULL,
@@ -21682,7 +21310,7 @@ CREATE TABLE sprints (
     group_id bigint,
     iid integer NOT NULL,
     cached_markdown_version integer,
-    title text,
+    title text NOT NULL,
     title_html text,
     description text,
     description_html text,
@@ -21707,8 +21335,7 @@ CREATE TABLE status_check_responses (
     merge_request_id bigint NOT NULL,
     external_approval_rule_id bigint,
     sha bytea NOT NULL,
-    external_status_check_id bigint NOT NULL,
-    status smallint DEFAULT 0 NOT NULL
+    external_status_check_id bigint NOT NULL
 );
 
 CREATE SEQUENCE status_check_responses_id_seq
@@ -21940,7 +21567,7 @@ CREATE TABLE timelogs (
     updated_at timestamp without time zone NOT NULL,
     issue_id integer,
     merge_request_id integer,
-    spent_at timestamp with time zone DEFAULT now(),
+    spent_at timestamp with time zone,
     note_id integer,
     project_id integer,
     summary text,
@@ -22008,7 +21635,6 @@ CREATE TABLE topics (
     avatar text,
     description text,
     total_projects_count bigint DEFAULT 0 NOT NULL,
-    non_private_projects_count bigint DEFAULT 0 NOT NULL,
     CONSTRAINT check_26753fb43a CHECK ((char_length(avatar) <= 255)),
     CONSTRAINT check_5d1a07c8c8 CHECK ((char_length(description) <= 1024)),
     CONSTRAINT check_7a90d4c757 CHECK ((char_length(name) <= 255))
@@ -22188,7 +21814,7 @@ CREATE TABLE user_credit_card_validations (
     network text,
     CONSTRAINT check_1765e2b30f CHECK ((char_length(network) <= 32)),
     CONSTRAINT check_3eea080c91 CHECK (((last_digits >= 0) AND (last_digits <= 9999))),
-    CONSTRAINT check_cc0c8dc0fe CHECK ((char_length(holder_name) <= 50))
+    CONSTRAINT check_eafe45d88b CHECK ((char_length(holder_name) <= 26))
 );
 
 CREATE TABLE user_custom_attributes (
@@ -22221,9 +21847,8 @@ CREATE TABLE user_details (
     pronunciation text,
     registration_objective smallint,
     phone text,
-    requires_credit_card_verification boolean DEFAULT false NOT NULL,
     CONSTRAINT check_245664af82 CHECK ((char_length(webauthn_xid) <= 100)),
-    CONSTRAINT check_a73b398c60 CHECK ((char_length(phone) <= 50)),
+    CONSTRAINT check_a73b398c60 CHECK ((char_length(phone) <= 32)),
     CONSTRAINT check_b132136b01 CHECK ((char_length(other_role) <= 100)),
     CONSTRAINT check_eeeaf8d4f0 CHECK ((char_length(pronouns) <= 50)),
     CONSTRAINT check_f932ed37db CHECK ((char_length(pronunciation) <= 255))
@@ -22319,11 +21944,7 @@ CREATE TABLE user_preferences (
     experience_level smallint,
     view_diffs_file_by_file boolean DEFAULT false NOT NULL,
     gitpod_enabled boolean DEFAULT false NOT NULL,
-    markdown_surround_selection boolean DEFAULT true NOT NULL,
-    diffs_deletion_color text,
-    diffs_addition_color text,
-    CONSTRAINT check_89bf269f41 CHECK ((char_length(diffs_deletion_color) <= 7)),
-    CONSTRAINT check_d07ccd35f7 CHECK ((char_length(diffs_addition_color) <= 7))
+    markdown_surround_selection boolean DEFAULT true NOT NULL
 );
 
 CREATE SEQUENCE user_preferences_id_seq
@@ -22658,12 +22279,140 @@ CREATE SEQUENCE vulnerability_feedback_id_seq
 
 ALTER SEQUENCE vulnerability_feedback_id_seq OWNED BY vulnerability_feedback.id;
 
+CREATE TABLE vulnerability_finding_evidence_assets (
+    id bigint NOT NULL,
+    created_at timestamp with time zone NOT NULL,
+    updated_at timestamp with time zone NOT NULL,
+    vulnerability_finding_evidence_id bigint NOT NULL,
+    type text,
+    name text,
+    url text,
+    CONSTRAINT check_5adf5d69de CHECK ((char_length(type) <= 2048)),
+    CONSTRAINT check_839f29d7ca CHECK ((char_length(name) <= 2048)),
+    CONSTRAINT check_9272d912c0 CHECK ((char_length(url) <= 2048))
+);
+
+CREATE SEQUENCE vulnerability_finding_evidence_assets_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+ALTER SEQUENCE vulnerability_finding_evidence_assets_id_seq OWNED BY vulnerability_finding_evidence_assets.id;
+
+CREATE TABLE vulnerability_finding_evidence_headers (
+    id bigint NOT NULL,
+    created_at timestamp with time zone NOT NULL,
+    updated_at timestamp with time zone NOT NULL,
+    vulnerability_finding_evidence_request_id bigint,
+    vulnerability_finding_evidence_response_id bigint,
+    name text NOT NULL,
+    value text NOT NULL,
+    CONSTRAINT check_01d21e8d92 CHECK ((char_length(name) <= 255)),
+    CONSTRAINT check_3f9011f903 CHECK ((char_length(value) <= 8192))
+);
+
+CREATE SEQUENCE vulnerability_finding_evidence_headers_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+ALTER SEQUENCE vulnerability_finding_evidence_headers_id_seq OWNED BY vulnerability_finding_evidence_headers.id;
+
+CREATE TABLE vulnerability_finding_evidence_requests (
+    id bigint NOT NULL,
+    created_at timestamp with time zone NOT NULL,
+    updated_at timestamp with time zone NOT NULL,
+    vulnerability_finding_evidence_id bigint,
+    method text,
+    url text,
+    body text,
+    vulnerability_finding_evidence_supporting_message_id bigint,
+    CONSTRAINT check_7e37f2d01a CHECK ((char_length(body) <= 2048)),
+    CONSTRAINT check_8152fbb236 CHECK ((char_length(url) <= 2048)),
+    CONSTRAINT check_d9d11300f4 CHECK ((char_length(method) <= 32))
+);
+
+CREATE SEQUENCE vulnerability_finding_evidence_requests_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+ALTER SEQUENCE vulnerability_finding_evidence_requests_id_seq OWNED BY vulnerability_finding_evidence_requests.id;
+
+CREATE TABLE vulnerability_finding_evidence_responses (
+    id bigint NOT NULL,
+    created_at timestamp with time zone NOT NULL,
+    updated_at timestamp with time zone NOT NULL,
+    vulnerability_finding_evidence_id bigint,
+    status_code integer,
+    reason_phrase text,
+    body text,
+    vulnerability_finding_evidence_supporting_message_id bigint,
+    CONSTRAINT check_58b124ab48 CHECK ((char_length(reason_phrase) <= 2048)),
+    CONSTRAINT check_76bac0c32b CHECK ((char_length(body) <= 2048))
+);
+
+CREATE SEQUENCE vulnerability_finding_evidence_responses_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+ALTER SEQUENCE vulnerability_finding_evidence_responses_id_seq OWNED BY vulnerability_finding_evidence_responses.id;
+
+CREATE TABLE vulnerability_finding_evidence_sources (
+    id bigint NOT NULL,
+    created_at timestamp with time zone NOT NULL,
+    updated_at timestamp with time zone NOT NULL,
+    vulnerability_finding_evidence_id bigint NOT NULL,
+    name text,
+    url text,
+    CONSTRAINT check_0fe01298d6 CHECK ((char_length(url) <= 2048)),
+    CONSTRAINT check_86b537ba1a CHECK ((char_length(name) <= 2048))
+);
+
+CREATE SEQUENCE vulnerability_finding_evidence_sources_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+ALTER SEQUENCE vulnerability_finding_evidence_sources_id_seq OWNED BY vulnerability_finding_evidence_sources.id;
+
+CREATE TABLE vulnerability_finding_evidence_supporting_messages (
+    id bigint NOT NULL,
+    created_at timestamp with time zone NOT NULL,
+    updated_at timestamp with time zone NOT NULL,
+    vulnerability_finding_evidence_id bigint NOT NULL,
+    name text,
+    CONSTRAINT check_fa33b9ae85 CHECK ((char_length(name) <= 2048))
+);
+
+CREATE SEQUENCE vulnerability_finding_evidence_supporting_messages_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+ALTER SEQUENCE vulnerability_finding_evidence_supporting_messages_id_seq OWNED BY vulnerability_finding_evidence_supporting_messages.id;
+
 CREATE TABLE vulnerability_finding_evidences (
     id bigint NOT NULL,
     created_at timestamp with time zone NOT NULL,
     updated_at timestamp with time zone NOT NULL,
     vulnerability_occurrence_id bigint NOT NULL,
-    data jsonb DEFAULT '{}'::jsonb NOT NULL
+    summary text,
+    data jsonb DEFAULT '{}'::jsonb NOT NULL,
+    CONSTRAINT check_5773b236fb CHECK ((char_length(summary) <= 8000000))
 );
 
 CREATE SEQUENCE vulnerability_finding_evidences_id_seq
@@ -22901,9 +22650,7 @@ CREATE TABLE vulnerability_reads (
     resolved_on_default_branch boolean DEFAULT false NOT NULL,
     uuid uuid NOT NULL,
     location_image text,
-    cluster_agent_id text,
-    CONSTRAINT check_380451bdbe CHECK ((char_length(location_image) <= 2048)),
-    CONSTRAINT check_a105eb825a CHECK ((char_length(cluster_agent_id) <= 10))
+    CONSTRAINT check_380451bdbe CHECK ((char_length(location_image) <= 2048))
 );
 
 CREATE SEQUENCE vulnerability_reads_id_seq
@@ -23241,8 +22988,6 @@ ALTER TABLE ONLY agent_project_authorizations ALTER COLUMN id SET DEFAULT nextva
 
 ALTER TABLE ONLY alert_management_alert_assignees ALTER COLUMN id SET DEFAULT nextval('alert_management_alert_assignees_id_seq'::regclass);
 
-ALTER TABLE ONLY alert_management_alert_metric_images ALTER COLUMN id SET DEFAULT nextval('alert_management_alert_metric_images_id_seq'::regclass);
-
 ALTER TABLE ONLY alert_management_alert_user_mentions ALTER COLUMN id SET DEFAULT nextval('alert_management_alert_user_mentions_id_seq'::regclass);
 
 ALTER TABLE ONLY alert_management_alerts ALTER COLUMN id SET DEFAULT nextval('alert_management_alerts_id_seq'::regclass);
@@ -23437,8 +23182,6 @@ ALTER TABLE ONLY ci_runners ALTER COLUMN id SET DEFAULT nextval('ci_runners_id_s
 
 ALTER TABLE ONLY ci_running_builds ALTER COLUMN id SET DEFAULT nextval('ci_running_builds_id_seq'::regclass);
 
-ALTER TABLE ONLY ci_secure_files ALTER COLUMN id SET DEFAULT nextval('ci_secure_files_id_seq'::regclass);
-
 ALTER TABLE ONLY ci_sources_pipelines ALTER COLUMN id SET DEFAULT nextval('ci_sources_pipelines_id_seq'::regclass);
 
 ALTER TABLE ONLY ci_sources_projects ALTER COLUMN id SET DEFAULT nextval('ci_sources_projects_id_seq'::regclass);
@@ -23663,8 +23406,6 @@ ALTER TABLE ONLY gpg_signatures ALTER COLUMN id SET DEFAULT nextval('gpg_signatu
 
 ALTER TABLE ONLY grafana_integrations ALTER COLUMN id SET DEFAULT nextval('grafana_integrations_id_seq'::regclass);
 
-ALTER TABLE ONLY group_crm_settings ALTER COLUMN group_id SET DEFAULT nextval('group_crm_settings_group_id_seq'::regclass);
-
 ALTER TABLE ONLY group_custom_attributes ALTER COLUMN id SET DEFAULT nextval('group_custom_attributes_id_seq'::regclass);
 
 ALTER TABLE ONLY group_deploy_keys ALTER COLUMN id SET DEFAULT nextval('group_deploy_keys_id_seq'::regclass);
@@ -23913,6 +23654,8 @@ ALTER TABLE ONLY pages_domain_acme_orders ALTER COLUMN id SET DEFAULT nextval('p
 
 ALTER TABLE ONLY pages_domains ALTER COLUMN id SET DEFAULT nextval('pages_domains_id_seq'::regclass);
 
+ALTER TABLE ONLY partitioned_foreign_keys ALTER COLUMN id SET DEFAULT nextval('partitioned_foreign_keys_id_seq'::regclass);
+
 ALTER TABLE ONLY path_locks ALTER COLUMN id SET DEFAULT nextval('path_locks_id_seq'::regclass);
 
 ALTER TABLE ONLY personal_access_tokens ALTER COLUMN id SET DEFAULT nextval('personal_access_tokens_id_seq'::regclass);
@@ -23937,8 +23680,6 @@ ALTER TABLE ONLY project_aliases ALTER COLUMN id SET DEFAULT nextval('project_al
 
 ALTER TABLE ONLY project_auto_devops ALTER COLUMN id SET DEFAULT nextval('project_auto_devops_id_seq'::regclass);
 
-ALTER TABLE ONLY project_build_artifacts_size_refreshes ALTER COLUMN id SET DEFAULT nextval('project_build_artifacts_size_refreshes_id_seq'::regclass);
-
 ALTER TABLE ONLY project_ci_cd_settings ALTER COLUMN id SET DEFAULT nextval('project_ci_cd_settings_id_seq'::regclass);
 
 ALTER TABLE ONLY project_ci_feature_usages ALTER COLUMN id SET DEFAULT nextval('project_ci_feature_usages_id_seq'::regclass);
@@ -23993,8 +23734,6 @@ ALTER TABLE ONLY protected_branch_unprotect_access_levels ALTER COLUMN id SET DE
 
 ALTER TABLE ONLY protected_branches ALTER COLUMN id SET DEFAULT nextval('protected_branches_id_seq'::regclass);
 
-ALTER TABLE ONLY protected_environment_approval_rules ALTER COLUMN id SET DEFAULT nextval('protected_environment_approval_rules_id_seq'::regclass);
-
 ALTER TABLE ONLY protected_environment_deploy_access_levels ALTER COLUMN id SET DEFAULT nextval('protected_environment_deploy_access_levels_id_seq'::regclass);
 
 ALTER TABLE ONLY protected_environments ALTER COLUMN id SET DEFAULT nextval('protected_environments_id_seq'::regclass);
@@ -24009,8 +23748,6 @@ ALTER TABLE ONLY raw_usage_data ALTER COLUMN id SET DEFAULT nextval('raw_usage_d
 
 ALTER TABLE ONLY redirect_routes ALTER COLUMN id SET DEFAULT nextval('redirect_routes_id_seq'::regclass);
 
-ALTER TABLE ONLY related_epic_links ALTER COLUMN id SET DEFAULT nextval('related_epic_links_id_seq'::regclass);
-
 ALTER TABLE ONLY release_links ALTER COLUMN id SET DEFAULT nextval('release_links_id_seq'::regclass);
 
 ALTER TABLE ONLY releases ALTER COLUMN id SET DEFAULT nextval('releases_id_seq'::regclass);
@@ -24041,8 +23778,6 @@ ALTER TABLE ONLY saml_group_links ALTER COLUMN id SET DEFAULT nextval('saml_grou
 
 ALTER TABLE ONLY saml_providers ALTER COLUMN id SET DEFAULT nextval('saml_providers_id_seq'::regclass);
 
-ALTER TABLE ONLY saved_replies ALTER COLUMN id SET DEFAULT nextval('saved_replies_id_seq'::regclass);
-
 ALTER TABLE ONLY scim_identities ALTER COLUMN id SET DEFAULT nextval('scim_identities_id_seq'::regclass);
 
 ALTER TABLE ONLY scim_oauth_access_tokens ALTER COLUMN id SET DEFAULT nextval('scim_oauth_access_tokens_id_seq'::regclass);
@@ -24055,10 +23790,6 @@ ALTER TABLE ONLY security_orchestration_policy_rule_schedules ALTER COLUMN id SE
 
 ALTER TABLE ONLY security_scans ALTER COLUMN id SET DEFAULT nextval('security_scans_id_seq'::regclass);
 
-ALTER TABLE ONLY security_training_providers ALTER COLUMN id SET DEFAULT nextval('security_training_providers_id_seq'::regclass);
-
-ALTER TABLE ONLY security_trainings ALTER COLUMN id SET DEFAULT nextval('security_trainings_id_seq'::regclass);
-
 ALTER TABLE ONLY self_managed_prometheus_alert_events ALTER COLUMN id SET DEFAULT nextval('self_managed_prometheus_alert_events_id_seq'::regclass);
 
 ALTER TABLE ONLY sent_notifications ALTER COLUMN id SET DEFAULT nextval('sent_notifications_id_seq'::regclass);
@@ -24161,6 +23892,18 @@ ALTER TABLE ONLY vulnerability_external_issue_links ALTER COLUMN id SET DEFAULT
 
 ALTER TABLE ONLY vulnerability_feedback ALTER COLUMN id SET DEFAULT nextval('vulnerability_feedback_id_seq'::regclass);
 
+ALTER TABLE ONLY vulnerability_finding_evidence_assets ALTER COLUMN id SET DEFAULT nextval('vulnerability_finding_evidence_assets_id_seq'::regclass);
+
+ALTER TABLE ONLY vulnerability_finding_evidence_headers ALTER COLUMN id SET DEFAULT nextval('vulnerability_finding_evidence_headers_id_seq'::regclass);
+
+ALTER TABLE ONLY vulnerability_finding_evidence_requests ALTER COLUMN id SET DEFAULT nextval('vulnerability_finding_evidence_requests_id_seq'::regclass);
+
+ALTER TABLE ONLY vulnerability_finding_evidence_responses ALTER COLUMN id SET DEFAULT nextval('vulnerability_finding_evidence_responses_id_seq'::regclass);
+
+ALTER TABLE ONLY vulnerability_finding_evidence_sources ALTER COLUMN id SET DEFAULT nextval('vulnerability_finding_evidence_sources_id_seq'::regclass);
+
+ALTER TABLE ONLY vulnerability_finding_evidence_supporting_messages ALTER COLUMN id SET DEFAULT nextval('vulnerability_finding_evidence_supporting_messages_id_seq'::regclass);
+
 ALTER TABLE ONLY vulnerability_finding_evidences ALTER COLUMN id SET DEFAULT nextval('vulnerability_finding_evidences_id_seq'::regclass);
 
 ALTER TABLE ONLY vulnerability_finding_links ALTER COLUMN id SET DEFAULT nextval('vulnerability_finding_links_id_seq'::regclass);
@@ -24350,12 +24093,6 @@ ALTER TABLE ONLY gitlab_partitions_dynamic.incident_management_pending_issue_esc
 ALTER TABLE ONLY gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202309
     ADD CONSTRAINT incident_management_pending_issue_escalations_202309_pkey PRIMARY KEY (id, process_at);
 
-ALTER TABLE ONLY loose_foreign_keys_deleted_records
-    ADD CONSTRAINT loose_foreign_keys_deleted_records_pkey PRIMARY KEY (partition, id);
-
-ALTER TABLE ONLY gitlab_partitions_dynamic.loose_foreign_keys_deleted_records_1
-    ADD CONSTRAINT loose_foreign_keys_deleted_records_1_pkey PRIMARY KEY (partition, id);
-
 ALTER TABLE ONLY verification_codes
     ADD CONSTRAINT verification_codes_pkey PRIMARY KEY (created_at, visitor_id_code, code, phone);
 
@@ -24815,6 +24552,12 @@ ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_62
 ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_63
     ADD CONSTRAINT issue_search_data_63_pkey PRIMARY KEY (project_id, issue_id);
 
+ALTER TABLE ONLY loose_foreign_keys_deleted_records
+    ADD CONSTRAINT loose_foreign_keys_deleted_records_pkey PRIMARY KEY (partition, id);
+
+ALTER TABLE ONLY gitlab_partitions_static.loose_foreign_keys_deleted_records_1
+    ADD CONSTRAINT loose_foreign_keys_deleted_records_1_pkey PRIMARY KEY (partition, id);
+
 ALTER TABLE ONLY product_analytics_events_experimental
     ADD CONSTRAINT product_analytics_events_experimental_pkey PRIMARY KEY (id, project_id);
 
@@ -25025,9 +24768,6 @@ ALTER TABLE ONLY agent_project_authorizations
 ALTER TABLE ONLY alert_management_alert_assignees
     ADD CONSTRAINT alert_management_alert_assignees_pkey PRIMARY KEY (id);
 
-ALTER TABLE ONLY alert_management_alert_metric_images
-    ADD CONSTRAINT alert_management_alert_metric_images_pkey PRIMARY KEY (id);
-
 ALTER TABLE ONLY alert_management_alert_user_mentions
     ADD CONSTRAINT alert_management_alert_user_mentions_pkey PRIMARY KEY (id);
 
@@ -25040,9 +24780,6 @@ ALTER TABLE ONLY alert_management_http_integrations
 ALTER TABLE ONLY allowed_email_domains
     ADD CONSTRAINT allowed_email_domains_pkey PRIMARY KEY (id);
 
-ALTER TABLE ONLY analytics_cycle_analytics_aggregations
-    ADD CONSTRAINT analytics_cycle_analytics_aggregations_pkey PRIMARY KEY (group_id);
-
 ALTER TABLE ONLY analytics_cycle_analytics_group_stages
     ADD CONSTRAINT analytics_cycle_analytics_group_stages_pkey PRIMARY KEY (id);
 
@@ -25217,6 +24954,9 @@ ALTER TABLE ONLY chat_teams
 ALTER TABLE vulnerability_scanners
     ADD CONSTRAINT check_37608c9db5 CHECK ((char_length(vendor) <= 255)) NOT VALID;
 
+ALTER TABLE security_findings
+    ADD CONSTRAINT check_6c2851a8c9 CHECK ((uuid IS NOT NULL)) NOT VALID;
+
 ALTER TABLE sprints
     ADD CONSTRAINT check_ccd8a1eae0 CHECK ((start_date IS NOT NULL)) NOT VALID;
 
@@ -25343,9 +25083,6 @@ ALTER TABLE ONLY ci_runners
 ALTER TABLE ONLY ci_running_builds
     ADD CONSTRAINT ci_running_builds_pkey PRIMARY KEY (id);
 
-ALTER TABLE ONLY ci_secure_files
-    ADD CONSTRAINT ci_secure_files_pkey PRIMARY KEY (id);
-
 ALTER TABLE ONLY ci_sources_pipelines
     ADD CONSTRAINT ci_sources_pipelines_pkey PRIMARY KEY (id);
 
@@ -25718,9 +25455,6 @@ ALTER TABLE ONLY gpg_signatures
 ALTER TABLE ONLY grafana_integrations
     ADD CONSTRAINT grafana_integrations_pkey PRIMARY KEY (id);
 
-ALTER TABLE ONLY group_crm_settings
-    ADD CONSTRAINT group_crm_settings_pkey PRIMARY KEY (group_id);
-
 ALTER TABLE ONLY group_custom_attributes
     ADD CONSTRAINT group_custom_attributes_pkey PRIMARY KEY (id);
 
@@ -25736,9 +25470,6 @@ ALTER TABLE ONLY group_deploy_keys
 ALTER TABLE ONLY group_deploy_tokens
     ADD CONSTRAINT group_deploy_tokens_pkey PRIMARY KEY (id);
 
-ALTER TABLE ONLY group_features
-    ADD CONSTRAINT group_features_pkey PRIMARY KEY (group_id);
-
 ALTER TABLE ONLY group_group_links
     ADD CONSTRAINT group_group_links_pkey PRIMARY KEY (id);
 
@@ -26159,6 +25890,9 @@ ALTER TABLE ONLY pages_domain_acme_orders
 ALTER TABLE ONLY pages_domains
     ADD CONSTRAINT pages_domains_pkey PRIMARY KEY (id);
 
+ALTER TABLE ONLY partitioned_foreign_keys
+    ADD CONSTRAINT partitioned_foreign_keys_pkey PRIMARY KEY (id);
+
 ALTER TABLE ONLY path_locks
     ADD CONSTRAINT path_locks_pkey PRIMARY KEY (id);
 
@@ -26201,9 +25935,6 @@ ALTER TABLE ONLY project_authorizations
 ALTER TABLE ONLY project_auto_devops
     ADD CONSTRAINT project_auto_devops_pkey PRIMARY KEY (id);
 
-ALTER TABLE ONLY project_build_artifacts_size_refreshes
-    ADD CONSTRAINT project_build_artifacts_size_refreshes_pkey PRIMARY KEY (id);
-
 ALTER TABLE ONLY project_ci_cd_settings
     ADD CONSTRAINT project_ci_cd_settings_pkey PRIMARY KEY (id);
 
@@ -26303,9 +26034,6 @@ ALTER TABLE ONLY protected_branch_unprotect_access_levels
 ALTER TABLE ONLY protected_branches
     ADD CONSTRAINT protected_branches_pkey PRIMARY KEY (id);
 
-ALTER TABLE ONLY protected_environment_approval_rules
-    ADD CONSTRAINT protected_environment_approval_rules_pkey PRIMARY KEY (id);
-
 ALTER TABLE ONLY protected_environment_deploy_access_levels
     ADD CONSTRAINT protected_environment_deploy_access_levels_pkey PRIMARY KEY (id);
 
@@ -26330,15 +26058,9 @@ ALTER TABLE ONLY raw_usage_data
 ALTER TABLE ONLY redirect_routes
     ADD CONSTRAINT redirect_routes_pkey PRIMARY KEY (id);
 
-ALTER TABLE ONLY related_epic_links
-    ADD CONSTRAINT related_epic_links_pkey PRIMARY KEY (id);
-
 ALTER TABLE ONLY release_links
     ADD CONSTRAINT release_links_pkey PRIMARY KEY (id);
 
-ALTER TABLE releases
-    ADD CONSTRAINT releases_not_null_tag CHECK ((tag IS NOT NULL)) NOT VALID;
-
 ALTER TABLE ONLY releases
     ADD CONSTRAINT releases_pkey PRIMARY KEY (id);
 
@@ -26384,9 +26106,6 @@ ALTER TABLE ONLY saml_group_links
 ALTER TABLE ONLY saml_providers
     ADD CONSTRAINT saml_providers_pkey PRIMARY KEY (id);
 
-ALTER TABLE ONLY saved_replies
-    ADD CONSTRAINT saved_replies_pkey PRIMARY KEY (id);
-
 ALTER TABLE ONLY scim_identities
     ADD CONSTRAINT scim_identities_pkey PRIMARY KEY (id);
 
@@ -26405,12 +26124,6 @@ ALTER TABLE ONLY security_orchestration_policy_rule_schedules
 ALTER TABLE ONLY security_scans
     ADD CONSTRAINT security_scans_pkey PRIMARY KEY (id);
 
-ALTER TABLE ONLY security_training_providers
-    ADD CONSTRAINT security_training_providers_pkey PRIMARY KEY (id);
-
-ALTER TABLE ONLY security_trainings
-    ADD CONSTRAINT security_trainings_pkey PRIMARY KEY (id);
-
 ALTER TABLE ONLY self_managed_prometheus_alert_events
     ADD CONSTRAINT self_managed_prometheus_alert_events_pkey PRIMARY KEY (id);
 
@@ -26594,6 +26307,24 @@ ALTER TABLE ONLY vulnerability_external_issue_links
 ALTER TABLE ONLY vulnerability_feedback
     ADD CONSTRAINT vulnerability_feedback_pkey PRIMARY KEY (id);
 
+ALTER TABLE ONLY vulnerability_finding_evidence_assets
+    ADD CONSTRAINT vulnerability_finding_evidence_assets_pkey PRIMARY KEY (id);
+
+ALTER TABLE ONLY vulnerability_finding_evidence_headers
+    ADD CONSTRAINT vulnerability_finding_evidence_headers_pkey PRIMARY KEY (id);
+
+ALTER TABLE ONLY vulnerability_finding_evidence_requests
+    ADD CONSTRAINT vulnerability_finding_evidence_requests_pkey PRIMARY KEY (id);
+
+ALTER TABLE ONLY vulnerability_finding_evidence_responses
+    ADD CONSTRAINT vulnerability_finding_evidence_responses_pkey PRIMARY KEY (id);
+
+ALTER TABLE ONLY vulnerability_finding_evidence_sources
+    ADD CONSTRAINT vulnerability_finding_evidence_sources_pkey PRIMARY KEY (id);
+
+ALTER TABLE ONLY vulnerability_finding_evidence_supporting_messages
+    ADD CONSTRAINT vulnerability_finding_evidence_supporting_messages_pkey PRIMARY KEY (id);
+
 ALTER TABLE ONLY vulnerability_finding_evidences
     ADD CONSTRAINT vulnerability_finding_evidences_pkey PRIMARY KEY (id);
 
@@ -26834,10 +26565,6 @@ CREATE INDEX incident_management_pending_issue_escalations_202_issue_id_idx8 ON
 
 CREATE INDEX incident_management_pending_issue_escalations_202_issue_id_idx9 ON gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202309 USING btree (issue_id);
 
-CREATE INDEX index_loose_foreign_keys_deleted_records_for_partitioned_query ON ONLY loose_foreign_keys_deleted_records USING btree (partition, fully_qualified_table_name, consume_after, id) WHERE (status = 1);
-
-CREATE INDEX index_01e3390fac ON gitlab_partitions_dynamic.loose_foreign_keys_deleted_records_1 USING btree (partition, fully_qualified_table_name, consume_after, id) WHERE (status = 1);
-
 CREATE INDEX index_web_hook_logs_part_on_web_hook_id ON ONLY web_hook_logs USING btree (web_hook_id);
 
 CREATE INDEX index_1554dc6f11 ON gitlab_partitions_dynamic.web_hook_logs_202301 USING btree (web_hook_id);
@@ -26916,6 +26643,10 @@ CREATE INDEX index_merge_request_stage_events_project_duration ON ONLY analytics
 
 CREATE INDEX index_006f943df6 ON gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_16 USING btree (stage_event_hash_id, project_id, end_event_timestamp, merge_request_id, start_event_timestamp) WHERE (end_event_timestamp IS NOT NULL);
 
+CREATE INDEX index_loose_foreign_keys_deleted_records_for_partitioned_query ON ONLY loose_foreign_keys_deleted_records USING btree (partition, fully_qualified_table_name, consume_after, id) WHERE (status = 1);
+
+CREATE INDEX index_01e3390fac ON gitlab_partitions_static.loose_foreign_keys_deleted_records_1 USING btree (partition, fully_qualified_table_name, consume_after, id) WHERE (status = 1);
+
 CREATE INDEX index_02749b504c ON gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_11 USING btree (stage_event_hash_id, project_id, end_event_timestamp, merge_request_id, start_event_timestamp) WHERE (end_event_timestamp IS NOT NULL);
 
 CREATE INDEX index_merge_request_stage_events_group_duration ON ONLY analytics_cycle_analytics_merge_request_stage_events USING btree (stage_event_hash_id, group_id, end_event_timestamp, merge_request_id, start_event_timestamp) WHERE (end_event_timestamp IS NOT NULL);
@@ -27840,12 +27571,6 @@ CREATE INDEX approval_mr_rule_index_merge_request_id ON approval_merge_request_r
 
 CREATE UNIQUE INDEX bulk_import_trackers_uniq_relation_by_entity ON bulk_import_trackers USING btree (bulk_import_entity_id, relation);
 
-CREATE INDEX ca_aggregations_last_consistency_check_updated_at ON analytics_cycle_analytics_aggregations USING btree (last_consistency_check_updated_at NULLS FIRST) WHERE (enabled IS TRUE);
-
-CREATE INDEX ca_aggregations_last_full_run_at ON analytics_cycle_analytics_aggregations USING btree (last_full_run_at NULLS FIRST) WHERE (enabled IS TRUE);
-
-CREATE INDEX ca_aggregations_last_incremental_run_at ON analytics_cycle_analytics_aggregations USING btree (last_incremental_run_at NULLS FIRST) WHERE (enabled IS TRUE);
-
 CREATE INDEX cadence_create_iterations_automation ON iterations_cadences USING btree (automatic, duration_in_weeks, date((COALESCE(last_run_date, '1970-01-01'::date) + ((duration_in_weeks)::double precision * '7 days'::interval)))) WHERE (duration_in_weeks IS NOT NULL);
 
 CREATE INDEX ci_builds_gitlab_monitor_metrics ON ci_builds USING btree (status, created_at, project_id) WHERE ((type)::text = 'Ci::Build'::text);
@@ -27870,11 +27595,25 @@ CREATE UNIQUE INDEX epic_user_mentions_on_epic_id_and_note_id_index ON epic_user
 
 CREATE UNIQUE INDEX epic_user_mentions_on_epic_id_index ON epic_user_mentions USING btree (epic_id) WHERE (note_id IS NULL);
 
-CREATE UNIQUE INDEX finding_evidences_on_unique_vulnerability_occurrence_id ON vulnerability_finding_evidences USING btree (vulnerability_occurrence_id);
+CREATE INDEX finding_evidence_assets_on_finding_evidence_id ON vulnerability_finding_evidence_assets USING btree (vulnerability_finding_evidence_id);
+
+CREATE INDEX finding_evidence_header_on_finding_evidence_request_id ON vulnerability_finding_evidence_headers USING btree (vulnerability_finding_evidence_request_id);
+
+CREATE INDEX finding_evidence_header_on_finding_evidence_response_id ON vulnerability_finding_evidence_headers USING btree (vulnerability_finding_evidence_response_id);
+
+CREATE INDEX finding_evidence_requests_on_finding_evidence_id ON vulnerability_finding_evidence_requests USING btree (vulnerability_finding_evidence_id);
+
+CREATE INDEX finding_evidence_requests_on_supporting_evidence_id ON vulnerability_finding_evidence_requests USING btree (vulnerability_finding_evidence_supporting_message_id);
 
-CREATE UNIQUE INDEX finding_link_name_url_idx ON vulnerability_finding_links USING btree (vulnerability_occurrence_id, name, url);
+CREATE INDEX finding_evidence_responses_on_finding_evidences_id ON vulnerability_finding_evidence_responses USING btree (vulnerability_finding_evidence_id);
 
-CREATE UNIQUE INDEX finding_link_url_idx ON vulnerability_finding_links USING btree (vulnerability_occurrence_id, url) WHERE (name IS NULL);
+CREATE INDEX finding_evidence_responses_on_supporting_evidence_id ON vulnerability_finding_evidence_responses USING btree (vulnerability_finding_evidence_supporting_message_id);
+
+CREATE INDEX finding_evidence_sources_on_finding_evidence_id ON vulnerability_finding_evidence_sources USING btree (vulnerability_finding_evidence_id);
+
+CREATE INDEX finding_evidence_supporting_messages_on_finding_evidence_id ON vulnerability_finding_evidence_supporting_messages USING btree (vulnerability_finding_evidence_id);
+
+CREATE UNIQUE INDEX finding_evidences_on_unique_vulnerability_occurrence_id ON vulnerability_finding_evidences USING btree (vulnerability_occurrence_id);
 
 CREATE INDEX finding_links_on_vulnerability_occurrence_id ON vulnerability_finding_links USING btree (vulnerability_occurrence_id);
 
@@ -27886,8 +27625,6 @@ CREATE INDEX idx_analytics_devops_adoption_snapshots_finalized ON analytics_devo
 
 CREATE INDEX idx_award_emoji_on_user_emoji_name_awardable_type_awardable_id ON award_emoji USING btree (user_id, name, awardable_type, awardable_id);
 
-CREATE INDEX idx_build_artifacts_size_refreshes_state_updated_at ON project_build_artifacts_size_refreshes USING btree (state, updated_at);
-
 CREATE INDEX idx_ci_pipelines_artifacts_locked ON ci_pipelines USING btree (ci_ref_id, id) WHERE (locked = 1);
 
 CREATE INDEX idx_container_exp_policies_on_project_id_next_run_at ON container_expiration_policies USING btree (project_id, next_run_at) WHERE (enabled = true);
@@ -27896,12 +27633,6 @@ CREATE INDEX idx_container_exp_policies_on_project_id_next_run_at_enabled ON con
 
 CREATE INDEX idx_container_repos_on_exp_cleanup_status_project_id_start_date ON container_repositories USING btree (expiration_policy_cleanup_status, project_id, expiration_policy_started_at);
 
-CREATE INDEX idx_container_repos_on_import_started_at_when_importing ON container_repositories USING btree (migration_import_started_at) WHERE (migration_state = 'importing'::text);
-
-CREATE INDEX idx_container_repos_on_pre_import_done_at_when_pre_import_done ON container_repositories USING btree (migration_pre_import_done_at) WHERE (migration_state = 'pre_import_done'::text);
-
-CREATE INDEX idx_container_repos_on_pre_import_started_at_when_pre_importing ON container_repositories USING btree (migration_pre_import_started_at) WHERE (migration_state = 'pre_importing'::text);
-
 CREATE INDEX idx_deployment_clusters_on_cluster_id_and_kubernetes_namespace ON deployment_clusters USING btree (cluster_id, kubernetes_namespace);
 
 CREATE INDEX idx_devops_adoption_segments_namespace_end_time ON analytics_devops_adoption_snapshots USING btree (namespace_id, end_time);
@@ -27970,16 +27701,12 @@ CREATE UNIQUE INDEX idx_on_external_status_checks_project_id_external_url ON ext
 
 CREATE UNIQUE INDEX idx_on_external_status_checks_project_id_name ON external_status_checks USING btree (project_id, name);
 
+CREATE INDEX idx_packages_build_infos_on_package_id ON packages_build_infos USING btree (package_id);
+
 CREATE INDEX idx_packages_debian_group_component_files_on_architecture_id ON packages_debian_group_component_files USING btree (architecture_id);
 
 CREATE INDEX idx_packages_debian_project_component_files_on_architecture_id ON packages_debian_project_component_files USING btree (architecture_id);
 
-CREATE UNIQUE INDEX idx_packages_on_project_id_name_version_unique_when_generic ON packages_packages USING btree (project_id, name, version) WHERE ((package_type = 7) AND (status <> 4));
-
-CREATE UNIQUE INDEX idx_packages_on_project_id_name_version_unique_when_golang ON packages_packages USING btree (project_id, name, version) WHERE ((package_type = 8) AND (status <> 4));
-
-CREATE UNIQUE INDEX idx_packages_on_project_id_name_version_unique_when_helm ON packages_packages USING btree (project_id, name, version) WHERE ((package_type = 11) AND (status <> 4));
-
 CREATE INDEX idx_packages_packages_on_project_id_name_version_package_type ON packages_packages USING btree (project_id, name, version, package_type);
 
 CREATE INDEX idx_pkgs_debian_group_distribution_keys_on_distribution_id ON packages_debian_group_distribution_keys USING btree (distribution_id);
@@ -27996,12 +27723,6 @@ CREATE UNIQUE INDEX idx_project_id_payload_key_self_managed_prometheus_alert_eve
 
 CREATE INDEX idx_project_repository_check_partial ON projects USING btree (repository_storage, created_at) WHERE (last_repository_check_at IS NULL);
 
-CREATE INDEX idx_projects_api_created_at_id_for_archived ON projects USING btree (created_at, id) WHERE ((archived = true) AND (pending_delete = false) AND (hidden = false));
-
-CREATE INDEX idx_projects_api_created_at_id_for_archived_vis20 ON projects USING btree (created_at, id) WHERE ((archived = true) AND (visibility_level = 20) AND (pending_delete = false) AND (hidden = false));
-
-CREATE INDEX idx_projects_api_created_at_id_for_vis10 ON projects USING btree (created_at, id) WHERE ((visibility_level = 10) AND (pending_delete = false) AND (hidden = false));
-
 CREATE INDEX idx_projects_id_created_at_disable_overriding_approvers_false ON projects USING btree (id, created_at) WHERE ((disable_overriding_approvers_per_merge_request = false) OR (disable_overriding_approvers_per_merge_request IS NULL));
 
 CREATE INDEX idx_projects_id_created_at_disable_overriding_approvers_true ON projects USING btree (id, created_at) WHERE (disable_overriding_approvers_per_merge_request = true);
@@ -28026,8 +27747,6 @@ CREATE INDEX idx_security_scans_on_scan_type ON security_scans USING btree (scan
 
 CREATE UNIQUE INDEX idx_serverless_domain_cluster_on_clusters_applications_knative ON serverless_domain_cluster USING btree (clusters_applications_knative_id);
 
-CREATE INDEX idx_user_details_on_provisioned_by_group_id_user_id ON user_details USING btree (provisioned_by_group_id, user_id);
-
 CREATE UNIQUE INDEX idx_vuln_signatures_on_occurrences_id_and_signature_sha ON vulnerability_finding_signatures USING btree (finding_id, signature_sha);
 
 CREATE UNIQUE INDEX idx_vuln_signatures_uniqueness_signature_sha ON vulnerability_finding_signatures USING btree (finding_id, algorithm_type, signature_sha);
@@ -28066,8 +27785,6 @@ CREATE INDEX index_alert_assignees_on_alert_id ON alert_management_alert_assigne
 
 CREATE UNIQUE INDEX index_alert_assignees_on_user_id_and_alert_id ON alert_management_alert_assignees USING btree (user_id, alert_id);
 
-CREATE INDEX index_alert_management_alert_metric_images_on_alert_id ON alert_management_alert_metric_images USING btree (alert_id);
-
 CREATE INDEX index_alert_management_alerts_on_domain ON alert_management_alerts USING btree (domain);
 
 CREATE INDEX index_alert_management_alerts_on_environment_id ON alert_management_alerts USING btree (environment_id) WHERE (environment_id IS NOT NULL);
@@ -28168,9 +27885,7 @@ CREATE UNIQUE INDEX index_approval_rule_name_for_code_owners_rule_type ON approv
 
 CREATE UNIQUE INDEX index_approval_rule_name_for_sectional_code_owners_rule_type ON approval_merge_request_rules USING btree (merge_request_id, name, section) WHERE (rule_type = 2);
 
-CREATE INDEX index_approval_rule_on_protected_environment_id ON protected_environment_approval_rules USING btree (protected_environment_id);
-
-CREATE INDEX index_approval_rules_code_owners_rule_type ON approval_merge_request_rules USING btree (merge_request_id) WHERE (rule_type = 2);
+CREATE INDEX index_approval_rules_code_owners_rule_type ON approval_merge_request_rules USING btree (merge_request_id, rule_type) WHERE (rule_type = 2);
 
 CREATE INDEX index_approvals_on_merge_request_id ON approvals USING btree (merge_request_id);
 
@@ -28188,8 +27903,6 @@ CREATE INDEX index_approvers_on_user_id ON approvers USING btree (user_id);
 
 CREATE UNIQUE INDEX index_atlassian_identities_on_extern_uid ON atlassian_identities USING btree (extern_uid);
 
-CREATE UNIQUE INDEX index_audit_events_external_audit_on_verification_token ON audit_events_external_audit_event_destinations USING btree (verification_token);
-
 CREATE INDEX index_authentication_events_on_provider ON authentication_events USING btree (provider);
 
 CREATE INDEX index_authentication_events_on_provider_user_id_created_at ON authentication_events USING btree (provider, user_id, created_at) WHERE (result = 1);
@@ -28412,10 +28125,6 @@ CREATE INDEX index_ci_job_artifacts_on_file_store ON ci_job_artifacts USING btre
 
 CREATE INDEX index_ci_job_artifacts_on_file_type_for_devops_adoption ON ci_job_artifacts USING btree (file_type, project_id, created_at) WHERE (file_type = ANY (ARRAY[5, 6, 8, 23]));
 
-CREATE INDEX index_ci_job_artifacts_on_id_project_id_and_created_at ON ci_job_artifacts USING btree (project_id, created_at, id);
-
-CREATE INDEX index_ci_job_artifacts_on_id_project_id_and_file_type ON ci_job_artifacts USING btree (project_id, file_type, id);
-
 CREATE UNIQUE INDEX index_ci_job_artifacts_on_job_id_and_file_type ON ci_job_artifacts USING btree (job_id, file_type);
 
 CREATE INDEX index_ci_job_artifacts_on_project_id ON ci_job_artifacts USING btree (project_id);
@@ -28522,8 +28231,6 @@ CREATE INDEX index_ci_pipelines_on_user_id_and_created_at_and_source ON ci_pipel
 
 CREATE INDEX index_ci_pipelines_on_user_id_and_id_and_cancelable_status ON ci_pipelines USING btree (user_id, id) WHERE ((status)::text = ANY (ARRAY[('running'::character varying)::text, ('waiting_for_resource'::character varying)::text, ('preparing'::character varying)::text, ('pending'::character varying)::text, ('created'::character varying)::text, ('scheduled'::character varying)::text]));
 
-CREATE INDEX index_ci_pipelines_on_user_id_and_id_desc_and_user_not_verified ON ci_pipelines USING btree (user_id, id DESC) WHERE (failure_reason = 3);
-
 CREATE INDEX index_ci_project_mirrors_on_namespace_id ON ci_project_mirrors USING btree (namespace_id);
 
 CREATE UNIQUE INDEX index_ci_project_mirrors_on_project_id ON ci_project_mirrors USING btree (project_id);
@@ -28544,18 +28251,14 @@ CREATE UNIQUE INDEX index_ci_runner_namespaces_on_runner_id_and_namespace_id ON
 
 CREATE INDEX index_ci_runner_projects_on_project_id ON ci_runner_projects USING btree (project_id);
 
-CREATE INDEX index_ci_runners_on_active ON ci_runners USING btree (active, id);
+CREATE INDEX index_ci_runner_projects_on_runner_id ON ci_runner_projects USING btree (runner_id);
 
 CREATE INDEX index_ci_runners_on_contacted_at_and_id_desc ON ci_runners USING btree (contacted_at, id DESC);
 
-CREATE INDEX index_ci_runners_on_contacted_at_and_id_where_inactive ON ci_runners USING btree (contacted_at DESC, id DESC) WHERE (active = false);
-
 CREATE INDEX index_ci_runners_on_contacted_at_desc_and_id_desc ON ci_runners USING btree (contacted_at DESC, id DESC);
 
 CREATE INDEX index_ci_runners_on_created_at_and_id_desc ON ci_runners USING btree (created_at, id DESC);
 
-CREATE INDEX index_ci_runners_on_created_at_and_id_where_inactive ON ci_runners USING btree (created_at DESC, id DESC) WHERE (active = false);
-
 CREATE INDEX index_ci_runners_on_created_at_desc_and_id_desc ON ci_runners USING btree (created_at DESC, id DESC);
 
 CREATE INDEX index_ci_runners_on_description_trigram ON ci_runners USING gin (description gin_trgm_ops);
@@ -28568,18 +28271,12 @@ CREATE INDEX index_ci_runners_on_token ON ci_runners USING btree (token);
 
 CREATE INDEX index_ci_runners_on_token_encrypted ON ci_runners USING btree (token_encrypted);
 
-CREATE INDEX index_ci_runners_on_token_expires_at_and_id_desc ON ci_runners USING btree (token_expires_at, id DESC);
-
-CREATE INDEX index_ci_runners_on_token_expires_at_desc_and_id_desc ON ci_runners USING btree (token_expires_at DESC, id DESC);
-
 CREATE UNIQUE INDEX index_ci_running_builds_on_build_id ON ci_running_builds USING btree (build_id);
 
 CREATE INDEX index_ci_running_builds_on_project_id ON ci_running_builds USING btree (project_id);
 
 CREATE INDEX index_ci_running_builds_on_runner_id ON ci_running_builds USING btree (runner_id);
 
-CREATE INDEX index_ci_secure_files_on_project_id ON ci_secure_files USING btree (project_id);
-
 CREATE INDEX index_ci_sources_pipelines_on_pipeline_id ON ci_sources_pipelines USING btree (pipeline_id);
 
 CREATE INDEX index_ci_sources_pipelines_on_project_id ON ci_sources_pipelines USING btree (project_id);
@@ -28624,7 +28321,7 @@ CREATE INDEX index_ci_variables_on_key ON ci_variables USING btree (key);
 
 CREATE UNIQUE INDEX index_ci_variables_on_project_id_and_key_and_environment_scope ON ci_variables USING btree (project_id, key, environment_scope);
 
-CREATE INDEX index_cluster_agent_tokens_on_agent_id_status_last_used_at ON cluster_agent_tokens USING btree (agent_id, status, last_used_at DESC NULLS LAST);
+CREATE INDEX index_cluster_agent_tokens_on_agent_id_and_last_used_at ON cluster_agent_tokens USING btree (agent_id, last_used_at DESC NULLS LAST);
 
 CREATE INDEX index_cluster_agent_tokens_on_created_by_user_id ON cluster_agent_tokens USING btree (created_by_user_id);
 
@@ -28680,6 +28377,8 @@ CREATE INDEX index_clusters_integration_elasticstack_enabled ON clusters_integra
 
 CREATE INDEX index_clusters_integration_prometheus_enabled ON clusters_integration_prometheus USING btree (enabled, created_at, cluster_id);
 
+CREATE INDEX index_clusters_kubernetes_namespaces_on_cluster_id ON clusters_kubernetes_namespaces USING btree (cluster_id);
+
 CREATE INDEX index_clusters_kubernetes_namespaces_on_cluster_project_id ON clusters_kubernetes_namespaces USING btree (cluster_project_id);
 
 CREATE INDEX index_clusters_kubernetes_namespaces_on_environment_id ON clusters_kubernetes_namespaces USING btree (environment_id);
@@ -28702,10 +28401,6 @@ CREATE INDEX index_composer_cache_files_where_namespace_id_is_null ON packages_c
 
 CREATE INDEX index_container_expiration_policies_on_next_run_at_and_enabled ON container_expiration_policies USING btree (next_run_at, enabled);
 
-CREATE INDEX index_container_repositories_on_greatest_done_at ON container_repositories USING btree (GREATEST(migration_pre_import_done_at, migration_import_done_at, migration_aborted_at)) WHERE (migration_state = ANY (ARRAY['import_done'::text, 'pre_import_done'::text, 'import_aborted'::text]));
-
-CREATE INDEX index_container_repositories_on_migration_state_import_done_at ON container_repositories USING btree (migration_state, migration_import_done_at);
-
 CREATE INDEX index_container_repositories_on_project_id ON container_repositories USING btree (project_id);
 
 CREATE INDEX index_container_repositories_on_project_id_and_id ON container_repositories USING btree (project_id, id);
@@ -28932,6 +28627,8 @@ CREATE UNIQUE INDEX index_epic_board_list_preferences_on_user_and_list ON boards
 
 CREATE UNIQUE INDEX index_epic_board_recent_visits_on_user_group_and_board ON boards_epic_board_recent_visits USING btree (user_id, group_id, epic_board_id);
 
+CREATE INDEX index_epic_issues_on_epic_id ON epic_issues USING btree (epic_id);
+
 CREATE INDEX index_epic_issues_on_epic_id_and_issue_id ON epic_issues USING btree (epic_id, issue_id);
 
 CREATE UNIQUE INDEX index_epic_issues_on_issue_id ON epic_issues USING btree (issue_id);
@@ -28964,6 +28661,8 @@ CREATE INDEX index_epics_on_iid ON epics USING btree (iid);
 
 CREATE INDEX index_epics_on_last_edited_by_id ON epics USING btree (last_edited_by_id);
 
+CREATE INDEX index_epics_on_lock_version ON epics USING btree (lock_version) WHERE (lock_version IS NULL);
+
 CREATE INDEX index_epics_on_parent_id ON epics USING btree (parent_id);
 
 CREATE INDEX index_epics_on_start_date ON epics USING btree (start_date);
@@ -28994,15 +28693,13 @@ CREATE INDEX index_et_errors_on_project_id_and_status_first_seen_at_id_desc ON e
 
 CREATE INDEX index_et_errors_on_project_id_and_status_last_seen_at_id_desc ON error_tracking_errors USING btree (project_id, status, last_seen_at DESC, id DESC);
 
-CREATE INDEX index_events_author_id_project_id_action_target_type_created_at ON events USING btree (author_id, project_id, action, target_type, created_at);
-
 CREATE INDEX index_events_on_action ON events USING btree (action);
 
 CREATE INDEX index_events_on_author_id_and_created_at ON events USING btree (author_id, created_at);
 
 CREATE INDEX index_events_on_author_id_and_created_at_merge_requests ON events USING btree (author_id, created_at) WHERE ((target_type)::text = 'MergeRequest'::text);
 
-CREATE INDEX index_events_on_author_id_and_id ON events USING btree (author_id, id);
+CREATE INDEX index_events_on_author_id_and_project_id ON events USING btree (author_id, project_id);
 
 CREATE INDEX index_events_on_created_at_and_id ON events USING btree (created_at, id) WHERE (created_at > '2021-08-27 00:00:00+00'::timestamp with time zone);
 
@@ -29156,8 +28853,6 @@ CREATE INDEX index_grafana_integrations_on_enabled ON grafana_integrations USING
 
 CREATE INDEX index_grafana_integrations_on_project_id ON grafana_integrations USING btree (project_id);
 
-CREATE INDEX index_group_crm_settings_on_group_id ON group_crm_settings USING btree (group_id);
-
 CREATE UNIQUE INDEX index_group_custom_attributes_on_group_id_and_key ON group_custom_attributes USING btree (group_id, key);
 
 CREATE INDEX index_group_custom_attributes_on_key_and_value ON group_custom_attributes USING btree (key, value);
@@ -29266,21 +28961,21 @@ CREATE INDEX index_insights_on_project_id ON insights USING btree (project_id);
 
 CREATE INDEX index_integrations_on_inherit_from_id ON integrations USING btree (inherit_from_id);
 
-CREATE INDEX index_integrations_on_project_and_type_new_where_inherit_null ON integrations USING btree (project_id, type_new) WHERE (inherit_from_id IS NULL);
+CREATE INDEX index_integrations_on_project_and_type_where_inherit_null ON integrations USING btree (project_id, type) WHERE (inherit_from_id IS NULL);
 
-CREATE UNIQUE INDEX index_integrations_on_project_id_and_type_new_unique ON integrations USING btree (project_id, type_new);
+CREATE UNIQUE INDEX index_integrations_on_project_id_and_type_unique ON integrations USING btree (project_id, type);
 
 CREATE INDEX index_integrations_on_template ON integrations USING btree (template);
 
-CREATE INDEX index_integrations_on_type_new ON integrations USING btree (type_new);
+CREATE INDEX index_integrations_on_type ON integrations USING btree (type);
 
-CREATE INDEX index_integrations_on_type_new_and_instance_partial ON integrations USING btree (type_new, instance) WHERE (instance = true);
+CREATE UNIQUE INDEX index_integrations_on_type_and_instance_partial ON integrations USING btree (type, instance) WHERE (instance = true);
 
-CREATE INDEX index_integrations_on_type_new_and_template_partial ON integrations USING btree (type_new, template) WHERE (template = true);
+CREATE UNIQUE INDEX index_integrations_on_type_and_template_partial ON integrations USING btree (type, template) WHERE (template = true);
 
-CREATE INDEX index_integrations_on_type_new_id_when_active_and_has_project ON integrations USING btree (type_new, id) WHERE ((active = true) AND (project_id IS NOT NULL));
+CREATE INDEX index_integrations_on_type_id_when_active_and_project_id_not_nu ON integrations USING btree (type, id) WHERE ((active = true) AND (project_id IS NOT NULL));
 
-CREATE INDEX index_integrations_on_unique_group_id_and_type_new ON integrations USING btree (group_id, type_new);
+CREATE UNIQUE INDEX index_integrations_on_unique_group_id_and_type ON integrations USING btree (group_id, type);
 
 CREATE INDEX index_internal_ids_on_namespace_id ON internal_ids USING btree (namespace_id);
 
@@ -29318,6 +29013,8 @@ CREATE UNIQUE INDEX index_issue_links_on_source_id_and_target_id ON issue_links
 
 CREATE INDEX index_issue_links_on_target_id ON issue_links USING btree (target_id);
 
+CREATE INDEX index_issue_metrics_first_mentioned_in_commit ON issue_metrics USING btree (issue_id) WHERE (date_part('year'::text, first_mentioned_in_commit_at) > (2019)::double precision);
+
 CREATE INDEX index_issue_metrics_on_issue_id_and_timestamps ON issue_metrics USING btree (issue_id, first_mentioned_in_commit_at, first_associated_with_milestone_at, first_added_to_board_at);
 
 CREATE INDEX index_issue_on_project_id_state_id_and_blocking_issues_count ON issues USING btree (project_id, state_id, blocking_issues_count);
@@ -29338,12 +29035,12 @@ CREATE INDEX index_issues_on_description_trigram ON issues USING gin (descriptio
 
 CREATE INDEX index_issues_on_duplicated_to_id ON issues USING btree (duplicated_to_id) WHERE (duplicated_to_id IS NOT NULL);
 
-CREATE INDEX index_issues_on_id_and_weight ON issues USING btree (id, weight);
-
 CREATE INDEX index_issues_on_incident_issue_type ON issues USING btree (issue_type) WHERE (issue_type = 1);
 
 CREATE INDEX index_issues_on_last_edited_by_id ON issues USING btree (last_edited_by_id);
 
+CREATE INDEX index_issues_on_lock_version ON issues USING btree (lock_version) WHERE (lock_version IS NULL);
+
 CREATE INDEX index_issues_on_milestone_id ON issues USING btree (milestone_id);
 
 CREATE INDEX index_issues_on_moved_to_id ON issues USING btree (moved_to_id) WHERE (moved_to_id IS NOT NULL);
@@ -29486,8 +29183,6 @@ CREATE INDEX index_members_on_invite_email ON members USING btree (invite_email)
 
 CREATE UNIQUE INDEX index_members_on_invite_token ON members USING btree (invite_token);
 
-CREATE INDEX index_members_on_member_namespace_id ON members USING btree (member_namespace_id);
-
 CREATE INDEX index_members_on_requested_at ON members USING btree (requested_at);
 
 CREATE INDEX index_members_on_source_id_and_source_type ON members USING btree (source_id, source_type);
@@ -29510,6 +29205,8 @@ CREATE UNIQUE INDEX index_merge_request_cleanup_schedules_on_merge_request_id ON
 
 CREATE INDEX index_merge_request_cleanup_schedules_on_status ON merge_request_cleanup_schedules USING btree (status);
 
+CREATE INDEX index_merge_request_context_commits_on_merge_request_id ON merge_request_context_commits USING btree (merge_request_id);
+
 CREATE UNIQUE INDEX index_merge_request_diff_commit_users_on_name_and_email ON merge_request_diff_commit_users USING btree (name, email);
 
 CREATE INDEX index_merge_request_diff_commits_on_sha ON merge_request_diff_commits USING btree (sha);
@@ -29574,6 +29271,8 @@ CREATE INDEX index_merge_requests_on_head_pipeline_id ON merge_requests USING bt
 
 CREATE INDEX index_merge_requests_on_latest_merge_request_diff_id ON merge_requests USING btree (latest_merge_request_diff_id);
 
+CREATE INDEX index_merge_requests_on_lock_version ON merge_requests USING btree (lock_version) WHERE (lock_version IS NULL);
+
 CREATE INDEX index_merge_requests_on_merge_user_id ON merge_requests USING btree (merge_user_id) WHERE (merge_user_id IS NOT NULL);
 
 CREATE INDEX index_merge_requests_on_milestone_id ON merge_requests USING btree (milestone_id);
@@ -29604,6 +29303,8 @@ CREATE INDEX index_merge_requests_on_target_project_id_and_updated_at_and_id ON
 
 CREATE INDEX index_merge_requests_on_target_project_id_iid_jira_description ON merge_requests USING btree (target_project_id, iid) WHERE (description ~ '[A-Z][A-Z_0-9]+-\d+'::text);
 
+CREATE INDEX index_merge_requests_on_title ON merge_requests USING btree (title);
+
 CREATE INDEX index_merge_requests_on_title_trigram ON merge_requests USING gin (title gin_trgm_ops);
 
 CREATE INDEX index_merge_requests_on_tp_id_and_merge_commit_sha_and_id ON merge_requests USING btree (target_project_id, merge_commit_sha, id);
@@ -29762,18 +29463,8 @@ CREATE INDEX index_on_identities_lower_extern_uid_and_provider ON identities USI
 
 CREATE UNIQUE INDEX index_on_instance_statistics_recorded_at_and_identifier ON analytics_usage_trends_measurements USING btree (identifier, recorded_at);
 
-CREATE INDEX index_on_issues_closed_incidents_by_project_id_and_closed_at ON issues USING btree (project_id, closed_at) WHERE ((issue_type = 1) AND (state_id = 2));
-
 CREATE INDEX index_on_label_links_all_columns ON label_links USING btree (target_id, label_id, target_type);
 
-CREATE INDEX index_on_merge_request_assignees_state ON merge_request_assignees USING btree (state) WHERE (state = 2);
-
-CREATE INDEX index_on_merge_request_assignees_updated_state_by_user_id ON merge_request_assignees USING btree (updated_state_by_user_id);
-
-CREATE INDEX index_on_merge_request_reviewers_state ON merge_request_reviewers USING btree (state) WHERE (state = 2);
-
-CREATE INDEX index_on_merge_request_reviewers_updated_state_by_user_id ON merge_request_reviewers USING btree (updated_state_by_user_id);
-
 CREATE INDEX index_on_merge_requests_for_latest_diffs ON merge_requests USING btree (target_project_id) INCLUDE (id, latest_merge_request_diff_id);
 
 COMMENT ON INDEX index_on_merge_requests_for_latest_diffs IS 'Index used to efficiently obtain the oldest merge request for a commit SHA';
@@ -29790,8 +29481,6 @@ CREATE UNIQUE INDEX index_on_project_id_escalation_policy_name_unique ON inciden
 
 CREATE INDEX index_on_projects_lower_path ON projects USING btree (lower((path)::text));
 
-CREATE INDEX index_on_projects_path ON projects USING btree (path);
-
 CREATE INDEX index_on_routes_lower_path ON routes USING btree (lower((path)::text));
 
 CREATE INDEX index_on_users_lower_email ON users USING btree (lower((email)::text));
@@ -29834,8 +29523,6 @@ CREATE UNIQUE INDEX index_ops_strategies_user_lists_on_strategy_id_and_user_list
 
 CREATE INDEX index_packages_build_infos_on_pipeline_id ON packages_build_infos USING btree (pipeline_id);
 
-CREATE INDEX index_packages_build_infos_package_id_pipeline_id ON packages_build_infos USING btree (package_id, pipeline_id);
-
 CREATE UNIQUE INDEX index_packages_composer_cache_namespace_and_sha ON packages_composer_cache_files USING btree (namespace_id, file_sha256);
 
 CREATE UNIQUE INDEX index_packages_composer_metadata_on_package_id_and_target_sha ON packages_composer_metadata USING btree (package_id, target_sha);
@@ -29876,6 +29563,12 @@ CREATE INDEX index_packages_maven_metadata_on_path ON packages_maven_metadata US
 
 CREATE INDEX index_packages_nuget_dl_metadata_on_dependency_link_id ON packages_nuget_dependency_link_metadata USING btree (dependency_link_id);
 
+CREATE UNIQUE INDEX index_packages_on_project_id_name_version_unique_when_generic ON packages_packages USING btree (project_id, name, version) WHERE (package_type = 7);
+
+CREATE UNIQUE INDEX index_packages_on_project_id_name_version_unique_when_golang ON packages_packages USING btree (project_id, name, version) WHERE (package_type = 8);
+
+CREATE UNIQUE INDEX index_packages_on_project_id_name_version_unique_when_helm ON packages_packages USING btree (project_id, name, version) WHERE (package_type = 11);
+
 CREATE INDEX index_packages_package_file_build_infos_on_package_file_id ON packages_package_file_build_infos USING btree (package_file_id);
 
 CREATE INDEX index_packages_package_file_build_infos_on_pipeline_id ON packages_package_file_build_infos USING btree (pipeline_id);
@@ -29886,10 +29579,6 @@ CREATE INDEX index_packages_package_files_on_package_id_and_file_name ON package
 
 CREATE INDEX index_packages_package_files_on_package_id_id ON packages_package_files USING btree (package_id, id);
 
-CREATE INDEX index_packages_package_files_on_package_id_status_and_id ON packages_package_files USING btree (package_id, status, id);
-
-CREATE INDEX index_packages_package_files_on_status ON packages_package_files USING btree (status);
-
 CREATE INDEX index_packages_package_files_on_verification_state ON packages_package_files USING btree (verification_state);
 
 CREATE INDEX index_packages_packages_on_creator_id ON packages_packages USING btree (creator_id);
@@ -29960,6 +29649,8 @@ CREATE UNIQUE INDEX index_partial_am_alerts_on_project_id_and_fingerprint ON ale
 
 CREATE INDEX index_partial_ci_builds_on_user_id_name_parser_features ON ci_builds USING btree (user_id, name) WHERE (((type)::text = 'Ci::Build'::text) AND ((name)::text = ANY (ARRAY[('container_scanning'::character varying)::text, ('dast'::character varying)::text, ('dependency_scanning'::character varying)::text, ('license_management'::character varying)::text, ('license_scanning'::character varying)::text, ('sast'::character varying)::text, ('coverage_fuzzing'::character varying)::text, ('secret_detection'::character varying)::text])));
 
+CREATE UNIQUE INDEX index_partitioned_foreign_keys_unique_index ON partitioned_foreign_keys USING btree (to_table, from_table, from_column);
+
 CREATE INDEX index_pat_on_user_id_and_expires_at ON personal_access_tokens USING btree (user_id, expires_at);
 
 CREATE INDEX index_path_locks_on_path ON path_locks USING btree (path);
@@ -29998,8 +29689,6 @@ CREATE INDEX index_project_aliases_on_project_id ON project_aliases USING btree
 
 CREATE UNIQUE INDEX index_project_auto_devops_on_project_id ON project_auto_devops USING btree (project_id);
 
-CREATE UNIQUE INDEX index_project_build_artifacts_size_refreshes_on_project_id ON project_build_artifacts_size_refreshes USING btree (project_id);
-
 CREATE UNIQUE INDEX index_project_ci_cd_settings_on_project_id ON project_ci_cd_settings USING btree (project_id);
 
 CREATE UNIQUE INDEX index_project_ci_feature_usages_unique_columns ON project_ci_feature_usages USING btree (project_id, feature, default_branch);
@@ -30100,6 +29789,12 @@ CREATE INDEX index_projects_aimed_for_deletion ON projects USING btree (marked_f
 
 CREATE INDEX index_projects_api_created_at_id_desc ON projects USING btree (created_at, id DESC);
 
+CREATE INDEX index_projects_api_created_at_id_for_archived ON projects USING btree (created_at, id) WHERE ((archived = true) AND (pending_delete = false));
+
+CREATE INDEX index_projects_api_created_at_id_for_archived_vis20 ON projects USING btree (created_at, id) WHERE ((archived = true) AND (visibility_level = 20) AND (pending_delete = false));
+
+CREATE INDEX index_projects_api_created_at_id_for_vis10 ON projects USING btree (created_at, id) WHERE ((visibility_level = 10) AND (pending_delete = false));
+
 CREATE INDEX index_projects_api_last_activity_at_id_desc ON projects USING btree (last_activity_at, id DESC);
 
 CREATE INDEX index_projects_api_name_id_desc ON projects USING btree (name, id DESC);
@@ -30118,8 +29813,6 @@ CREATE INDEX index_projects_api_vis20_path ON projects USING btree (path, id) WH
 
 CREATE INDEX index_projects_api_vis20_updated_at ON projects USING btree (updated_at, id) WHERE (visibility_level = 20);
 
-CREATE INDEX index_projects_not_aimed_for_deletion ON projects USING btree (id) WHERE (marked_for_deletion_at IS NULL);
-
 CREATE INDEX index_projects_on_created_at_and_id ON projects USING btree (created_at, id);
 
 CREATE INDEX index_projects_on_creator_id_and_created_at_and_id ON projects USING btree (creator_id, created_at, id);
@@ -30224,10 +29917,6 @@ CREATE INDEX index_protected_branch_unprotect_access_levels_on_user_id ON protec
 
 CREATE INDEX index_protected_branches_on_project_id ON protected_branches USING btree (project_id);
 
-CREATE INDEX index_protected_environment_approval_rules_on_group_id ON protected_environment_approval_rules USING btree (group_id);
-
-CREATE INDEX index_protected_environment_approval_rules_on_user_id ON protected_environment_approval_rules USING btree (user_id);
-
 CREATE INDEX index_protected_environment_deploy_access ON protected_environment_deploy_access_levels USING btree (protected_environment_id);
 
 CREATE INDEX index_protected_environment_deploy_access_levels_on_group_id ON protected_environment_deploy_access_levels USING btree (group_id);
@@ -30262,21 +29951,13 @@ CREATE UNIQUE INDEX index_redirect_routes_on_path_unique_text_pattern_ops ON red
 
 CREATE INDEX index_redirect_routes_on_source_type_and_source_id ON redirect_routes USING btree (source_type, source_id);
 
-CREATE INDEX index_related_epic_links_on_source_id ON related_epic_links USING btree (source_id);
-
-CREATE UNIQUE INDEX index_related_epic_links_on_source_id_and_target_id ON related_epic_links USING btree (source_id, target_id);
-
-CREATE INDEX index_related_epic_links_on_target_id ON related_epic_links USING btree (target_id);
-
 CREATE UNIQUE INDEX index_release_links_on_release_id_and_name ON release_links USING btree (release_id, name);
 
 CREATE UNIQUE INDEX index_release_links_on_release_id_and_url ON release_links USING btree (release_id, url);
 
 CREATE INDEX index_releases_on_author_id_id_created_at ON releases USING btree (author_id, id, created_at);
 
-CREATE INDEX index_releases_on_project_id_and_released_at_and_id ON releases USING btree (project_id, released_at, id);
-
-CREATE UNIQUE INDEX index_releases_on_project_tag_unique ON releases USING btree (project_id, tag);
+CREATE INDEX index_releases_on_project_id_and_tag ON releases USING btree (project_id, tag);
 
 CREATE INDEX index_releases_on_released_at ON releases USING btree (released_at);
 
@@ -30366,8 +30047,6 @@ CREATE INDEX index_reviews_on_project_id ON reviews USING btree (project_id);
 
 CREATE INDEX index_route_on_name_trigram ON routes USING gin (name gin_trgm_ops);
 
-CREATE UNIQUE INDEX index_routes_on_namespace_id ON routes USING btree (namespace_id);
-
 CREATE UNIQUE INDEX index_routes_on_path ON routes USING btree (path);
 
 CREATE INDEX index_routes_on_path_text_pattern_ops ON routes USING btree (path varchar_pattern_ops);
@@ -30380,8 +30059,6 @@ CREATE UNIQUE INDEX index_saml_group_links_on_group_id_and_saml_group_name ON sa
 
 CREATE INDEX index_saml_providers_on_group_id ON saml_providers USING btree (group_id);
 
-CREATE UNIQUE INDEX index_saved_replies_on_name_text_pattern_ops ON saved_replies USING btree (user_id, name text_pattern_ops);
-
 CREATE INDEX index_scim_identities_on_group_id ON scim_identities USING btree (group_id);
 
 CREATE UNIQUE INDEX index_scim_identities_on_lower_extern_uid_and_group_id ON scim_identities USING btree (lower((extern_uid)::text), group_id);
@@ -30392,7 +30069,7 @@ CREATE UNIQUE INDEX index_scim_oauth_access_tokens_on_group_id_and_token_encrypt
 
 CREATE INDEX index_secure_ci_builds_on_user_id_name_created_at ON ci_builds USING btree (user_id, name, created_at) WHERE (((type)::text = 'Ci::Build'::text) AND ((name)::text = ANY (ARRAY[('container_scanning'::character varying)::text, ('dast'::character varying)::text, ('dependency_scanning'::character varying)::text, ('license_management'::character varying)::text, ('license_scanning'::character varying)::text, ('sast'::character varying)::text, ('coverage_fuzzing'::character varying)::text, ('apifuzzer_fuzz'::character varying)::text, ('apifuzzer_fuzz_dnd'::character varying)::text, ('secret_detection'::character varying)::text])));
 
-CREATE INDEX index_security_ci_builds_on_name_and_id_parser_features ON ci_builds USING btree (name, id) WHERE (((name)::text = ANY (ARRAY[('container_scanning'::character varying)::text, ('dast'::character varying)::text, ('dependency_scanning'::character varying)::text, ('license_management'::character varying)::text, ('sast'::character varying)::text, ('secret_detection'::character varying)::text, ('coverage_fuzzing'::character varying)::text, ('license_scanning'::character varying)::text, ('apifuzzer_fuzz'::character varying)::text, ('apifuzzer_fuzz_dnd'::character varying)::text])) AND ((type)::text = 'Ci::Build'::text));
+CREATE INDEX index_security_ci_builds_on_name_and_id_parser_features ON ci_builds USING btree (name, id) WHERE (((name)::text = ANY (ARRAY[('container_scanning'::character varying)::text, ('dast'::character varying)::text, ('dependency_scanning'::character varying)::text, ('license_management'::character varying)::text, ('sast'::character varying)::text, ('secret_detection'::character varying)::text, ('coverage_fuzzing'::character varying)::text, ('license_scanning'::character varying)::text])) AND ((type)::text = 'Ci::Build'::text));
 
 CREATE INDEX index_security_findings_on_confidence ON security_findings USING btree (confidence);
 
@@ -30400,7 +30077,7 @@ CREATE INDEX index_security_findings_on_project_fingerprint ON security_findings
 
 CREATE INDEX index_security_findings_on_scan_id_and_deduplicated ON security_findings USING btree (scan_id, deduplicated);
 
-CREATE INDEX index_security_findings_on_scan_id_and_id ON security_findings USING btree (scan_id, id);
+CREATE UNIQUE INDEX index_security_findings_on_scan_id_and_position ON security_findings USING btree (scan_id, "position");
 
 CREATE INDEX index_security_findings_on_scanner_id ON security_findings USING btree (scanner_id);
 
@@ -30416,14 +30093,6 @@ CREATE INDEX index_security_scans_on_pipeline_id ON security_scans USING btree (
 
 CREATE INDEX index_security_scans_on_project_id ON security_scans USING btree (project_id);
 
-CREATE UNIQUE INDEX index_security_training_providers_on_unique_name ON security_training_providers USING btree (name);
-
-CREATE INDEX index_security_trainings_on_project_id ON security_trainings USING btree (project_id);
-
-CREATE INDEX index_security_trainings_on_provider_id ON security_trainings USING btree (provider_id);
-
-CREATE UNIQUE INDEX index_security_trainings_on_unique_project_id ON security_trainings USING btree (project_id) WHERE (is_primary IS TRUE);
-
 CREATE INDEX index_self_managed_prometheus_alert_events_on_environment_id ON self_managed_prometheus_alert_events USING btree (environment_id);
 
 CREATE INDEX index_sent_notifications_on_noteable_type_noteable_id ON sent_notifications USING btree (noteable_id) WHERE ((noteable_type)::text = 'Issue'::text);
@@ -30486,8 +30155,6 @@ CREATE INDEX index_snippets_on_id_and_created_at ON snippets USING btree (id, cr
 
 CREATE INDEX index_snippets_on_id_and_type ON snippets USING btree (id, type);
 
-CREATE INDEX index_snippets_on_project_id_and_title ON snippets USING btree (project_id, title);
-
 CREATE INDEX index_snippets_on_project_id_and_visibility_level ON snippets USING btree (project_id, visibility_level);
 
 CREATE INDEX index_snippets_on_title_trigram ON snippets USING gin (title gin_trgm_ops);
@@ -30504,6 +30171,8 @@ CREATE INDEX index_software_licenses_on_spdx_identifier ON software_licenses USI
 
 CREATE UNIQUE INDEX index_software_licenses_on_unique_name ON software_licenses USING btree (name);
 
+CREATE UNIQUE INDEX index_sop_configs_on_project_id ON security_orchestration_policy_configurations USING btree (project_id);
+
 CREATE INDEX index_sop_configurations_project_id_policy_project_id ON security_orchestration_policy_configurations USING btree (security_policy_management_project_id, project_id);
 
 CREATE INDEX index_sop_schedules_on_sop_configuration_id ON security_orchestration_policy_rule_schedules USING btree (security_orchestration_policy_configuration_id);
@@ -30520,8 +30189,12 @@ CREATE INDEX index_sprints_on_due_date ON sprints USING btree (due_date);
 
 CREATE INDEX index_sprints_on_group_id ON sprints USING btree (group_id);
 
+CREATE UNIQUE INDEX index_sprints_on_iterations_cadence_id_and_title ON sprints USING btree (iterations_cadence_id, title);
+
 CREATE UNIQUE INDEX index_sprints_on_project_id_and_iid ON sprints USING btree (project_id, iid);
 
+CREATE UNIQUE INDEX index_sprints_on_project_id_and_title ON sprints USING btree (project_id, title) WHERE (project_id IS NOT NULL);
+
 CREATE INDEX index_sprints_on_title ON sprints USING btree (title);
 
 CREATE INDEX index_sprints_on_title_trigram ON sprints USING gin (title gin_trgm_ops);
@@ -30542,6 +30215,8 @@ CREATE UNIQUE INDEX index_subscriptions_on_subscribable_and_user_id_and_project_
 
 CREATE INDEX index_successful_deployments_on_cluster_id_and_environment_id ON deployments USING btree (cluster_id, environment_id) WHERE (status = 2);
 
+CREATE INDEX index_suggestions_on_note_id ON suggestions USING btree (note_id);
+
 CREATE UNIQUE INDEX index_suggestions_on_note_id_and_relative_order ON suggestions USING btree (note_id, relative_order);
 
 CREATE UNIQUE INDEX index_system_note_metadata_on_description_version_id ON system_note_metadata USING btree (description_version_id) WHERE (description_version_id IS NOT NULL);
@@ -30604,7 +30279,7 @@ CREATE INDEX index_todos_on_group_id ON todos USING btree (group_id);
 
 CREATE INDEX index_todos_on_note_id ON todos USING btree (note_id);
 
-CREATE INDEX index_todos_on_project_id_and_id ON todos USING btree (project_id, id);
+CREATE INDEX index_todos_on_project_id ON todos USING btree (project_id);
 
 CREATE INDEX index_todos_on_project_id_and_user_id_and_id ON todos USING btree (project_id, user_id, id);
 
@@ -30620,10 +30295,6 @@ CREATE UNIQUE INDEX index_token_with_ivs_on_hashed_plaintext_token ON token_with
 
 CREATE UNIQUE INDEX index_token_with_ivs_on_hashed_token ON token_with_ivs USING btree (hashed_token);
 
-CREATE INDEX index_topics_non_private_projects_count ON topics USING btree (non_private_projects_count DESC, id);
-
-CREATE INDEX index_topics_on_lower_name ON topics USING btree (lower(name));
-
 CREATE UNIQUE INDEX index_topics_on_name ON topics USING btree (name);
 
 CREATE INDEX index_topics_on_name_trigram ON topics USING gin (name gin_trgm_ops);
@@ -30638,8 +30309,6 @@ CREATE INDEX index_u2f_registrations_on_user_id ON u2f_registrations USING btree
 
 CREATE UNIQUE INDEX index_uniq_im_issuable_escalation_statuses_on_issue_id ON incident_management_issuable_escalation_statuses USING btree (issue_id);
 
-CREATE UNIQUE INDEX index_unique_ci_runner_projects_on_runner_id_and_project_id ON ci_runner_projects USING btree (runner_id, project_id);
-
 CREATE UNIQUE INDEX index_unique_issue_metrics_issue_id ON issue_metrics USING btree (issue_id);
 
 CREATE UNIQUE INDEX index_unique_project_authorizations_on_project_id_user_id ON project_authorizations USING btree (project_id, user_id);
@@ -30692,6 +30361,8 @@ CREATE UNIQUE INDEX index_user_details_on_phone ON user_details USING btree (pho
 
 COMMENT ON INDEX index_user_details_on_phone IS 'JiHu-specific index';
 
+CREATE INDEX index_user_details_on_provisioned_by_group_id ON user_details USING btree (provisioned_by_group_id);
+
 CREATE UNIQUE INDEX index_user_details_on_user_id ON user_details USING btree (user_id);
 
 CREATE INDEX index_user_group_callouts_on_group_id ON user_group_callouts USING btree (group_id);
@@ -30772,8 +30443,6 @@ CREATE INDEX index_users_star_projects_on_project_id ON users_star_projects USIN
 
 CREATE UNIQUE INDEX index_users_star_projects_on_user_id_and_project_id ON users_star_projects USING btree (user_id, project_id);
 
-CREATE INDEX index_users_with_static_object_token ON users USING btree (id) WHERE ((static_object_token IS NOT NULL) AND (static_object_token_encrypted IS NULL));
-
 CREATE UNIQUE INDEX index_vuln_historical_statistics_on_project_id_and_date ON vulnerability_historical_statistics USING btree (project_id, date);
 
 CREATE INDEX index_vuln_reads_on_project_id_state_severity_and_vuln_id ON vulnerability_reads USING btree (project_id, state, severity, vulnerability_id DESC);
@@ -30792,10 +30461,6 @@ CREATE INDEX index_vulnerabilities_on_last_edited_by_id ON vulnerabilities USING
 
 CREATE INDEX index_vulnerabilities_on_milestone_id ON vulnerabilities USING btree (milestone_id);
 
-CREATE INDEX index_vulnerabilities_on_project_id_and_id ON vulnerabilities USING btree (project_id, id);
-
-CREATE INDEX index_vulnerabilities_on_project_id_and_id_active_cis ON vulnerabilities USING btree (project_id, id) WHERE ((report_type = 7) AND (state = ANY (ARRAY[1, 4])));
-
 CREATE INDEX index_vulnerabilities_on_project_id_and_state_and_severity ON vulnerabilities USING btree (project_id, state, severity);
 
 CREATE INDEX index_vulnerabilities_on_resolved_by_id ON vulnerabilities USING btree (resolved_by_id);
@@ -30860,11 +30525,9 @@ CREATE INDEX index_vulnerability_occurrences_deduplication ON vulnerability_occu
 
 CREATE INDEX index_vulnerability_occurrences_for_issue_links_migration ON vulnerability_occurrences USING btree (project_id, report_type, encode(project_fingerprint, 'hex'::text));
 
-CREATE INDEX index_vulnerability_occurrences_on_location_image ON vulnerability_occurrences USING gin (((location -> 'image'::text))) WHERE (report_type = ANY (ARRAY[2, 7]));
-
-CREATE INDEX index_vulnerability_occurrences_on_location_k8s_agent_id ON vulnerability_occurrences USING gin ((((location -> 'kubernetes_resource'::text) -> 'agent_id'::text))) WHERE (report_type = 7);
+CREATE INDEX index_vulnerability_occurrences_on_location_cluster_id ON vulnerability_occurrences USING gin (((location -> 'cluster_id'::text))) WHERE (report_type = 7);
 
-CREATE INDEX index_vulnerability_occurrences_on_location_k8s_cluster_id ON vulnerability_occurrences USING gin ((((location -> 'kubernetes_resource'::text) -> 'cluster_id'::text))) WHERE (report_type = 7);
+CREATE INDEX index_vulnerability_occurrences_on_location_image ON vulnerability_occurrences USING gin (((location -> 'image'::text))) WHERE (report_type = ANY (ARRAY[2, 7]));
 
 CREATE INDEX index_vulnerability_occurrences_on_migrated_to_new_structure ON vulnerability_occurrences USING btree (migrated_to_new_structure, id);
 
@@ -30874,12 +30537,12 @@ CREATE INDEX index_vulnerability_occurrences_on_project_fingerprint ON vulnerabi
 
 CREATE INDEX index_vulnerability_occurrences_on_scanner_id ON vulnerability_occurrences USING btree (scanner_id);
 
+CREATE UNIQUE INDEX index_vulnerability_occurrences_on_unique_keys ON vulnerability_occurrences USING btree (project_id, primary_identifier_id, location_fingerprint, scanner_id);
+
 CREATE UNIQUE INDEX index_vulnerability_occurrences_on_uuid ON vulnerability_occurrences USING btree (uuid);
 
 CREATE INDEX index_vulnerability_occurrences_on_vulnerability_id ON vulnerability_occurrences USING btree (vulnerability_id);
 
-CREATE INDEX index_vulnerability_reads_on_cluster_agent_id ON vulnerability_reads USING btree (cluster_agent_id) WHERE (report_type = 7);
-
 CREATE INDEX index_vulnerability_reads_on_location_image ON vulnerability_reads USING btree (location_image) WHERE (report_type = ANY (ARRAY[2, 7]));
 
 CREATE INDEX index_vulnerability_reads_on_scanner_id ON vulnerability_reads USING btree (scanner_id);
@@ -30988,10 +30651,6 @@ CREATE INDEX partial_index_deployments_for_legacy_successful_deployments ON depl
 
 CREATE INDEX partial_index_deployments_for_project_id_and_tag ON deployments USING btree (project_id) WHERE (tag IS TRUE);
 
-CREATE UNIQUE INDEX partial_index_sop_configs_on_namespace_id ON security_orchestration_policy_configurations USING btree (namespace_id) WHERE (namespace_id IS NOT NULL);
-
-CREATE UNIQUE INDEX partial_index_sop_configs_on_project_id ON security_orchestration_policy_configurations USING btree (project_id) WHERE (project_id IS NOT NULL);
-
 CREATE UNIQUE INDEX snippet_user_mentions_on_snippet_id_and_note_id_index ON snippet_user_mentions USING btree (snippet_id, note_id);
 
 CREATE UNIQUE INDEX snippet_user_mentions_on_snippet_id_index ON snippet_user_mentions USING btree (snippet_id) WHERE (note_id IS NULL);
@@ -31000,19 +30659,9 @@ CREATE UNIQUE INDEX taggings_idx ON taggings USING btree (tag_id, taggable_id, t
 
 CREATE UNIQUE INDEX term_agreements_unique_index ON term_agreements USING btree (user_id, term_id);
 
-CREATE INDEX tmp_gitlab_subscriptions_max_seats_used_migration ON gitlab_subscriptions USING btree (id) WHERE ((start_date >= '2021-08-02'::date) AND (start_date <= '2021-11-20'::date) AND (max_seats_used <> 0) AND (max_seats_used > seats_in_use) AND (max_seats_used > seats));
-
-CREATE INDEX tmp_gitlab_subscriptions_max_seats_used_migration_2 ON gitlab_subscriptions USING btree (id) WHERE ((start_date < '2021-08-02'::date) AND (max_seats_used <> 0) AND (max_seats_used > seats_in_use) AND (max_seats_used > seats));
-
-CREATE INDEX tmp_index_ci_job_artifacts_on_id_where_trace_and_expire_at ON ci_job_artifacts USING btree (id) WHERE ((file_type = 3) AND (expire_at = ANY (ARRAY['2021-04-22 00:00:00+00'::timestamp with time zone, '2021-05-22 00:00:00+00'::timestamp with time zone, '2021-06-22 00:00:00+00'::timestamp with time zone, '2022-01-22 00:00:00+00'::timestamp with time zone, '2022-02-22 00:00:00+00'::timestamp with time zone, '2022-03-22 00:00:00+00'::timestamp with time zone, '2022-04-22 00:00:00+00'::timestamp with time zone])));
+CREATE INDEX tmp_idx_deduplicate_vulnerability_occurrences ON vulnerability_occurrences USING btree (project_id, report_type, location_fingerprint, primary_identifier_id, id);
 
-CREATE INDEX tmp_index_container_repositories_on_id_migration_state ON container_repositories USING btree (id, migration_state);
-
-CREATE INDEX tmp_index_for_namespace_id_migration_on_group_members ON members USING btree (id) WHERE ((member_namespace_id IS NULL) AND ((type)::text = 'GroupMember'::text));
-
-CREATE INDEX tmp_index_for_namespace_id_migration_on_routes ON routes USING btree (id) WHERE ((namespace_id IS NULL) AND ((source_type)::text = 'Namespace'::text));
-
-CREATE INDEX tmp_index_members_on_state ON members USING btree (state) WHERE (state = 2);
+CREATE INDEX tmp_index_ci_pipelines_lock_version ON ci_pipelines USING btree (id) WHERE (lock_version IS NULL);
 
 CREATE INDEX tmp_index_namespaces_empty_traversal_ids_with_child_namespaces ON namespaces USING btree (id) WHERE ((parent_id IS NOT NULL) AND (traversal_ids = '{}'::integer[]));
 
@@ -31022,10 +30671,6 @@ CREATE UNIQUE INDEX tmp_index_on_tmp_project_id_on_namespaces ON namespaces USIN
 
 CREATE INDEX tmp_index_on_vulnerabilities_non_dismissed ON vulnerabilities USING btree (id) WHERE (state <> 2);
 
-CREATE INDEX tmp_index_projects_on_id_and_runners_token ON projects USING btree (id, runners_token) WHERE (runners_token IS NOT NULL);
-
-CREATE INDEX tmp_index_projects_on_id_and_runners_token_encrypted ON projects USING btree (id, runners_token_encrypted) WHERE (runners_token_encrypted IS NOT NULL);
-
 CREATE UNIQUE INDEX uniq_pkgs_deb_grp_architectures_on_distribution_id_and_name ON packages_debian_group_architectures USING btree (distribution_id, name);
 
 CREATE UNIQUE INDEX uniq_pkgs_deb_grp_components_on_distribution_id_and_name ON packages_debian_group_components USING btree (distribution_id, name);
@@ -31050,6 +30695,8 @@ CREATE UNIQUE INDEX vulnerability_feedback_unique_idx ON vulnerability_feedback
 
 CREATE UNIQUE INDEX vulnerability_occurrence_pipelines_on_unique_keys ON vulnerability_occurrence_pipelines USING btree (occurrence_id, pipeline_id);
 
+CREATE INDEX vulnerability_occurrences_location_temp_index ON vulnerability_occurrences USING btree (id) WHERE (location IS NULL);
+
 CREATE UNIQUE INDEX work_item_types_namespace_id_and_name_unique ON work_item_types USING btree (namespace_id, btrim(lower(name)));
 
 ALTER INDEX analytics_index_audit_events_part_on_created_at_and_author_id ATTACH PARTITION gitlab_partitions_dynamic.audit_events_000000_created_at_author_id_idx;
@@ -31258,8 +30905,6 @@ ALTER INDEX index_incident_management_pending_issue_escalations_on_issue_id ATTA
 
 ALTER INDEX index_incident_management_pending_issue_escalations_on_issue_id ATTACH PARTITION gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202_issue_id_idx9;
 
-ALTER INDEX index_loose_foreign_keys_deleted_records_for_partitioned_query ATTACH PARTITION gitlab_partitions_dynamic.index_01e3390fac;
-
 ALTER INDEX index_web_hook_logs_part_on_web_hook_id ATTACH PARTITION gitlab_partitions_dynamic.index_1554dc6f11;
 
 ALTER INDEX index_web_hook_logs_part_on_web_hook_id ATTACH PARTITION gitlab_partitions_dynamic.index_719c6187cb;
@@ -31268,8 +30913,6 @@ ALTER INDEX index_web_hook_logs_part_on_created_at_and_web_hook_id ATTACH PARTIT
 
 ALTER INDEX index_web_hook_logs_part_on_created_at_and_web_hook_id ATTACH PARTITION gitlab_partitions_dynamic.index_fdb8d5eeea;
 
-ALTER INDEX loose_foreign_keys_deleted_records_pkey ATTACH PARTITION gitlab_partitions_dynamic.loose_foreign_keys_deleted_records_1_pkey;
-
 ALTER INDEX verification_codes_pkey ATTACH PARTITION gitlab_partitions_dynamic.verification_codes_000000_pkey;
 
 ALTER INDEX index_verification_codes_on_phone_and_visitor_id_code ATTACH PARTITION gitlab_partitions_dynamic.verification_codes_000000_visitor_id_code_phone_created_at_idx;
@@ -31490,6 +31133,8 @@ ALTER INDEX index_issue_stage_events_project_duration ATTACH PARTITION gitlab_pa
 
 ALTER INDEX index_merge_request_stage_events_project_duration ATTACH PARTITION gitlab_partitions_static.index_006f943df6;
 
+ALTER INDEX index_loose_foreign_keys_deleted_records_for_partitioned_query ATTACH PARTITION gitlab_partitions_static.index_01e3390fac;
+
 ALTER INDEX index_merge_request_stage_events_project_duration ATTACH PARTITION gitlab_partitions_static.index_02749b504c;
 
 ALTER INDEX index_merge_request_stage_events_group_duration ATTACH PARTITION gitlab_partitions_static.index_0287f5ba09;
@@ -32382,6 +32027,8 @@ ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.iss
 
 ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_63_search_vector_idx;
 
+ALTER INDEX loose_foreign_keys_deleted_records_pkey ATTACH PARTITION gitlab_partitions_static.loose_foreign_keys_deleted_records_1_pkey;
+
 ALTER INDEX index_product_analytics_events_experimental_project_and_time ATTACH PARTITION gitlab_partitions_static.product_analytics_events_expe_project_id_collector_tstamp_idx10;
 
 ALTER INDEX index_product_analytics_events_experimental_project_and_time ATTACH PARTITION gitlab_partitions_static.product_analytics_events_expe_project_id_collector_tstamp_idx11;
@@ -32642,14 +32289,10 @@ CREATE TRIGGER chat_names_loose_fk_trigger AFTER DELETE ON chat_names REFERENCIN
 
 CREATE TRIGGER ci_builds_loose_fk_trigger AFTER DELETE ON ci_builds REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION insert_into_loose_foreign_keys_deleted_records();
 
-CREATE TRIGGER ci_job_artifacts_loose_fk_trigger AFTER DELETE ON ci_job_artifacts REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION insert_into_loose_foreign_keys_deleted_records();
-
 CREATE TRIGGER ci_pipelines_loose_fk_trigger AFTER DELETE ON ci_pipelines REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION insert_into_loose_foreign_keys_deleted_records();
 
 CREATE TRIGGER ci_runners_loose_fk_trigger AFTER DELETE ON ci_runners REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION insert_into_loose_foreign_keys_deleted_records();
 
-CREATE TRIGGER merge_requests_loose_fk_trigger AFTER DELETE ON merge_requests REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION insert_into_loose_foreign_keys_deleted_records();
-
 CREATE TRIGGER namespaces_loose_fk_trigger AFTER DELETE ON namespaces REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION insert_into_loose_foreign_keys_deleted_records();
 
 CREATE TRIGGER projects_loose_fk_trigger AFTER DELETE ON projects REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION insert_into_loose_foreign_keys_deleted_records();
@@ -32670,8 +32313,6 @@ CREATE TRIGGER trigger_has_external_wiki_on_type_new_updated AFTER UPDATE OF typ
 
 CREATE TRIGGER trigger_has_external_wiki_on_update AFTER UPDATE ON integrations FOR EACH ROW WHEN (((new.type_new = 'Integrations::ExternalWiki'::text) AND (old.active <> new.active) AND (new.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_wiki();
 
-CREATE TRIGGER trigger_insert_or_update_vulnerability_reads_from_occurrences AFTER INSERT OR UPDATE ON vulnerability_occurrences FOR EACH ROW EXECUTE FUNCTION insert_or_update_vulnerability_reads();
-
 CREATE TRIGGER trigger_namespaces_parent_id_on_insert AFTER INSERT ON namespaces FOR EACH ROW EXECUTE FUNCTION insert_namespaces_sync_event();
 
 CREATE TRIGGER trigger_namespaces_parent_id_on_update AFTER UPDATE ON namespaces FOR EACH ROW WHEN ((old.parent_id IS DISTINCT FROM new.parent_id)) EXECUTE FUNCTION insert_namespaces_sync_event();
@@ -32680,15 +32321,7 @@ CREATE TRIGGER trigger_projects_parent_id_on_insert AFTER INSERT ON projects FOR
 
 CREATE TRIGGER trigger_projects_parent_id_on_update AFTER UPDATE ON projects FOR EACH ROW WHEN ((old.namespace_id IS DISTINCT FROM new.namespace_id)) EXECUTE FUNCTION insert_projects_sync_event();
 
-CREATE TRIGGER trigger_update_has_issues_on_vulnerability_issue_links_delete AFTER DELETE ON vulnerability_issue_links FOR EACH ROW EXECUTE FUNCTION unset_has_issues_on_vulnerability_reads();
-
-CREATE TRIGGER trigger_update_has_issues_on_vulnerability_issue_links_update AFTER INSERT ON vulnerability_issue_links FOR EACH ROW EXECUTE FUNCTION set_has_issues_on_vulnerability_reads();
-
-CREATE TRIGGER trigger_update_location_on_vulnerability_occurrences_update AFTER UPDATE ON vulnerability_occurrences FOR EACH ROW WHEN (((new.report_type = ANY (ARRAY[2, 7])) AND (((old.location ->> 'image'::text) IS DISTINCT FROM (new.location ->> 'image'::text)) OR (((old.location -> 'kubernetes_resource'::text) ->> 'agent_id'::text) IS DISTINCT FROM ((new.location -> 'kubernetes_resource'::text) ->> 'agent_id'::text))))) EXECUTE FUNCTION update_location_from_vulnerability_occurrences();
-
-CREATE TRIGGER trigger_update_vulnerability_reads_on_vulnerability_update AFTER UPDATE ON vulnerabilities FOR EACH ROW WHEN (((old.severity IS DISTINCT FROM new.severity) OR (old.state IS DISTINCT FROM new.state) OR (old.resolved_on_default_branch IS DISTINCT FROM new.resolved_on_default_branch))) EXECUTE FUNCTION update_vulnerability_reads_from_vulnerability();
-
-CREATE TRIGGER users_loose_fk_trigger AFTER DELETE ON users REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION insert_into_loose_foreign_keys_deleted_records();
+CREATE TRIGGER trigger_type_new_on_insert AFTER INSERT ON integrations FOR EACH ROW EXECUTE FUNCTION integrations_set_type_new();
 
 ALTER TABLE ONLY gitlab_partitions_dynamic.incident_management_pending_issue_escalations_202211
     ADD CONSTRAINT fk_rails_0470889ee5 FOREIGN KEY (rule_id) REFERENCES incident_management_escalation_rules(id) ON DELETE CASCADE;
@@ -32816,6 +32449,9 @@ ALTER TABLE ONLY agent_project_authorizations
 ALTER TABLE ONLY vulnerabilities
     ADD CONSTRAINT fk_1d37cddf91 FOREIGN KEY (epic_id) REFERENCES epics(id) ON DELETE SET NULL;
 
+ALTER TABLE ONLY ci_sources_pipelines
+    ADD CONSTRAINT fk_1e53c97c0a FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY epics
     ADD CONSTRAINT fk_1fbed67632 FOREIGN KEY (start_date_sourcing_milestone_id) REFERENCES milestones(id) ON DELETE SET NULL;
 
@@ -32834,6 +32470,9 @@ ALTER TABLE ONLY users_star_projects
 ALTER TABLE ONLY alert_management_alerts
     ADD CONSTRAINT fk_2358b75436 FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE SET NULL;
 
+ALTER TABLE ONLY ci_stages
+    ADD CONSTRAINT fk_2360681d1d FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY import_failures
     ADD CONSTRAINT fk_24b824da43 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
 
@@ -32867,6 +32506,9 @@ ALTER TABLE ONLY agent_group_authorizations
 ALTER TABLE ONLY deployment_approvals
     ADD CONSTRAINT fk_2d060dfc73 FOREIGN KEY (deployment_id) REFERENCES deployments(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_freeze_periods
+    ADD CONSTRAINT fk_2e02bbd1a6 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY notes
     ADD CONSTRAINT fk_2e82291620 FOREIGN KEY (review_id) REFERENCES reviews(id) ON DELETE SET NULL;
 
@@ -32888,6 +32530,9 @@ ALTER TABLE ONLY approvals
 ALTER TABLE ONLY namespaces
     ADD CONSTRAINT fk_319256d87a FOREIGN KEY (file_template_project_id) REFERENCES projects(id) ON DELETE SET NULL;
 
+ALTER TABLE ONLY ci_group_variables
+    ADD CONSTRAINT fk_33ae4d58d8 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY namespaces
     ADD CONSTRAINT fk_3448c97865 FOREIGN KEY (push_rule_id) REFERENCES push_rules(id) ON DELETE SET NULL;
 
@@ -32927,9 +32572,6 @@ ALTER TABLE ONLY epics
 ALTER TABLE ONLY ci_pipelines
     ADD CONSTRAINT fk_3d34ab2e06 FOREIGN KEY (pipeline_schedule_id) REFERENCES ci_pipeline_schedules(id) ON DELETE SET NULL;
 
-ALTER TABLE ONLY merge_request_reviewers
-    ADD CONSTRAINT fk_3d674b9f23 FOREIGN KEY (updated_state_by_user_id) REFERENCES users(id) ON DELETE SET NULL;
-
 ALTER TABLE ONLY ci_pipeline_schedule_variables
     ADD CONSTRAINT fk_41c35fda51 FOREIGN KEY (pipeline_schedule_id) REFERENCES ci_pipeline_schedules(id) ON DELETE CASCADE;
 
@@ -32939,6 +32581,9 @@ ALTER TABLE ONLY geo_event_log
 ALTER TABLE ONLY incident_management_timeline_events
     ADD CONSTRAINT fk_4432fc4d78 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_runner_projects
+    ADD CONSTRAINT fk_4478a6f1e4 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY todos
     ADD CONSTRAINT fk_45054f9c45 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
@@ -32957,6 +32602,9 @@ ALTER TABLE ONLY alert_management_alerts
 ALTER TABLE ONLY path_locks
     ADD CONSTRAINT fk_5265c98f24 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY dast_site_profiles_pipelines
+    ADD CONSTRAINT fk_53849b0ad5 FOREIGN KEY (ci_pipeline_id) REFERENCES ci_pipelines(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY terraform_states
     ADD CONSTRAINT fk_558901b030 FOREIGN KEY (locked_by_user_id) REFERENCES users(id) ON DELETE SET NULL;
 
@@ -33005,8 +32653,8 @@ ALTER TABLE ONLY merge_requests
 ALTER TABLE ONLY ci_builds
     ADD CONSTRAINT fk_6661f4f0e8 FOREIGN KEY (resource_group_id) REFERENCES ci_resource_groups(id) ON DELETE SET NULL;
 
-ALTER TABLE ONLY routes
-    ADD CONSTRAINT fk_679ff8213d FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE SET NULL;
+ALTER TABLE ONLY project_pages_metadata
+    ADD CONSTRAINT fk_69366a119e FOREIGN KEY (artifacts_archive_id) REFERENCES ci_job_artifacts(id) ON DELETE SET NULL;
 
 ALTER TABLE ONLY application_settings
     ADD CONSTRAINT fk_693b8795e4 FOREIGN KEY (push_rule_id) REFERENCES push_rules(id) ON DELETE SET NULL;
@@ -33033,7 +32681,7 @@ ALTER TABLE ONLY protected_branch_push_access_levels
     ADD CONSTRAINT fk_7111b68cdb FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
 
 ALTER TABLE ONLY projects
-    ADD CONSTRAINT fk_71625606ac FOREIGN KEY (project_namespace_id) REFERENCES namespaces(id) ON DELETE SET NULL;
+    ADD CONSTRAINT fk_71625606ac FOREIGN KEY (project_namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
 
 ALTER TABLE ONLY integrations
     ADD CONSTRAINT fk_71cce407f9 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -33053,6 +32701,9 @@ ALTER TABLE ONLY vulnerabilities
 ALTER TABLE ONLY oauth_openid_requests
     ADD CONSTRAINT fk_77114b3b09 FOREIGN KEY (access_grant_id) REFERENCES oauth_access_grants(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_resource_groups
+    ADD CONSTRAINT fk_774722d144 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY users
     ADD CONSTRAINT fk_789cd90b35 FOREIGN KEY (accepted_term_id) REFERENCES application_setting_terms(id) ON DELETE CASCADE;
 
@@ -33065,6 +32716,9 @@ ALTER TABLE ONLY analytics_devops_adoption_snapshots
 ALTER TABLE ONLY lists
     ADD CONSTRAINT fk_7a5553d60f FOREIGN KEY (label_id) REFERENCES labels(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_unit_tests
+    ADD CONSTRAINT fk_7a8fabf0a8 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY protected_branches
     ADD CONSTRAINT fk_7a9c6d93e7 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
@@ -33107,6 +32761,9 @@ ALTER TABLE ONLY merge_request_diffs
 ALTER TABLE ONLY requirements
     ADD CONSTRAINT fk_85044baef0 FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_pipelines
+    ADD CONSTRAINT fk_86635dbd80 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY geo_event_log
     ADD CONSTRAINT fk_86c84214ec FOREIGN KEY (repository_renamed_event_id) REFERENCES geo_repository_renamed_events(id) ON DELETE CASCADE;
 
@@ -33140,6 +32797,9 @@ ALTER TABLE ONLY releases
 ALTER TABLE ONLY protected_tags
     ADD CONSTRAINT fk_8e4af87648 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_pipeline_schedules
+    ADD CONSTRAINT fk_8ead60fcc4 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY todos
     ADD CONSTRAINT fk_91d1f47b13 FOREIGN KEY (note_id) REFERENCES notes(id) ON DELETE CASCADE;
 
@@ -33194,6 +32854,9 @@ ALTER TABLE ONLY protected_environments
 ALTER TABLE ONLY alert_management_alerts
     ADD CONSTRAINT fk_9e49e5c2b7 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_pipeline_schedules
+    ADD CONSTRAINT fk_9ea99f58d2 FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE SET NULL;
+
 ALTER TABLE ONLY protected_branch_push_access_levels
     ADD CONSTRAINT fk_9ffc86a3d9 FOREIGN KEY (protected_branch_id) REFERENCES protected_branches(id) ON DELETE CASCADE;
 
@@ -33206,9 +32869,15 @@ ALTER TABLE ONLY issues
 ALTER TABLE ONLY ci_builds
     ADD CONSTRAINT fk_a2141b1522 FOREIGN KEY (auto_canceled_by_id) REFERENCES ci_pipelines(id) ON DELETE SET NULL;
 
+ALTER TABLE ONLY ci_pipelines
+    ADD CONSTRAINT fk_a23be95014 FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY todos
     ADD CONSTRAINT fk_a27c483435 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY dast_site_profiles_builds
+    ADD CONSTRAINT fk_a325505e99 FOREIGN KEY (ci_build_id) REFERENCES ci_builds(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY jira_connect_subscriptions
     ADD CONSTRAINT fk_a3c10bcf7d FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
 
@@ -33218,12 +32887,12 @@ ALTER TABLE ONLY bulk_import_entities
 ALTER TABLE ONLY users
     ADD CONSTRAINT fk_a4b8fefe3e FOREIGN KEY (managing_group_id) REFERENCES namespaces(id) ON DELETE SET NULL;
 
-ALTER TABLE ONLY security_orchestration_policy_configurations
-    ADD CONSTRAINT fk_a50430b375 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
-
 ALTER TABLE ONLY lfs_objects_projects
     ADD CONSTRAINT fk_a56e02279c FOREIGN KEY (lfs_object_id) REFERENCES lfs_objects(id) ON DELETE RESTRICT NOT VALID;
 
+ALTER TABLE ONLY dast_profiles_pipelines
+    ADD CONSTRAINT fk_a60cad829d FOREIGN KEY (ci_pipeline_id) REFERENCES ci_pipelines(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY merge_requests
     ADD CONSTRAINT fk_a6963e8447 FOREIGN KEY (target_project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
@@ -33233,9 +32902,6 @@ ALTER TABLE ONLY epics
 ALTER TABLE ONLY dast_profiles
     ADD CONSTRAINT fk_aa76ef30e9 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
-ALTER TABLE ONLY members
-    ADD CONSTRAINT fk_aa82dcc1c6 FOREIGN KEY (member_namespace_id) REFERENCES namespaces(id) ON DELETE SET NULL;
-
 ALTER TABLE ONLY alert_management_alerts
     ADD CONSTRAINT fk_aad61aedca FOREIGN KEY (environment_id) REFERENCES environments(id) ON DELETE SET NULL;
 
@@ -33248,18 +32914,21 @@ ALTER TABLE ONLY boards
 ALTER TABLE ONLY member_tasks
     ADD CONSTRAINT fk_ab636303dd FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_sources_pipelines
+    ADD CONSTRAINT fk_acd9737679 FOREIGN KEY (source_project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY merge_requests
     ADD CONSTRAINT fk_ad525e1f87 FOREIGN KEY (merge_user_id) REFERENCES users(id) ON DELETE SET NULL;
 
+ALTER TABLE ONLY ci_variables
+    ADD CONSTRAINT fk_ada5eb64b3 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY merge_request_metrics
     ADD CONSTRAINT fk_ae440388cc FOREIGN KEY (latest_closed_by_id) REFERENCES users(id) ON DELETE SET NULL;
 
 ALTER TABLE ONLY dast_profile_schedules
     ADD CONSTRAINT fk_aef03d62e5 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL;
 
-ALTER TABLE ONLY merge_request_assignees
-    ADD CONSTRAINT fk_af036e3261 FOREIGN KEY (updated_state_by_user_id) REFERENCES users(id) ON DELETE SET NULL;
-
 ALTER TABLE ONLY analytics_cycle_analytics_group_stages
     ADD CONSTRAINT fk_analytics_cycle_analytics_group_stages_group_value_stream_id FOREIGN KEY (group_value_stream_id) REFERENCES analytics_cycle_analytics_group_value_streams(id) ON DELETE CASCADE;
 
@@ -33323,6 +32992,9 @@ ALTER TABLE ONLY ci_sources_pipelines
 ALTER TABLE ONLY packages_maven_metadata
     ADD CONSTRAINT fk_be88aed360 FOREIGN KEY (package_id) REFERENCES packages_packages(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_builds
+    ADD CONSTRAINT fk_befce0568a FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY design_management_versions
     ADD CONSTRAINT fk_c1440b4896 FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE SET NULL;
 
@@ -33455,8 +33127,11 @@ ALTER TABLE ONLY ci_builds_metadata
 ALTER TABLE ONLY gitlab_subscriptions
     ADD CONSTRAINT fk_e2595d00a1 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
 
-ALTER TABLE ONLY ci_builds
-    ADD CONSTRAINT fk_e4ef9c2f27 FOREIGN KEY (runner_id) REFERENCES ci_runners(id) ON DELETE SET NULL NOT VALID;
+ALTER TABLE ONLY ci_triggers
+    ADD CONSTRAINT fk_e3e63f966e FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
+ALTER TABLE ONLY dast_scanner_profiles_builds
+    ADD CONSTRAINT fk_e4c49200f8 FOREIGN KEY (ci_build_id) REFERENCES ci_builds(id) ON DELETE CASCADE;
 
 ALTER TABLE ONLY merge_requests
     ADD CONSTRAINT fk_e719a85f8a FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE SET NULL;
@@ -33479,6 +33154,12 @@ ALTER TABLE ONLY sprints
 ALTER TABLE ONLY application_settings
     ADD CONSTRAINT fk_e8a145f3a7 FOREIGN KEY (instance_administrators_group_id) REFERENCES namespaces(id) ON DELETE SET NULL;
 
+ALTER TABLE ONLY vulnerability_statistics
+    ADD CONSTRAINT fk_e8b13c928f FOREIGN KEY (latest_pipeline_id) REFERENCES ci_pipelines(id) ON DELETE SET NULL;
+
+ALTER TABLE ONLY ci_triggers
+    ADD CONSTRAINT fk_e8e10d1964 FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY integrations
     ADD CONSTRAINT fk_e8fe908a34 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
 
@@ -33551,6 +33232,15 @@ ALTER TABLE ONLY system_note_metadata
 ALTER TABLE ONLY vulnerability_remediations
     ADD CONSTRAINT fk_fc61a535a0 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_daily_build_group_report_results
+    ADD CONSTRAINT fk_fd1858fefd FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
+ALTER TABLE ONLY merge_requests
+    ADD CONSTRAINT fk_fd82eae0b9 FOREIGN KEY (head_pipeline_id) REFERENCES ci_pipelines(id) ON DELETE SET NULL;
+
+ALTER TABLE ONLY ci_pending_builds
+    ADD CONSTRAINT fk_fdc0137e4a FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY project_import_data
     ADD CONSTRAINT fk_ffb9ee3a10 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
@@ -33605,6 +33295,15 @@ ALTER TABLE ONLY ip_restrictions
 ALTER TABLE ONLY terraform_state_versions
     ADD CONSTRAINT fk_rails_04f176e239 FOREIGN KEY (terraform_state_id) REFERENCES terraform_states(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_build_report_results
+    ADD CONSTRAINT fk_rails_056d298d48 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
+ALTER TABLE ONLY ci_daily_build_group_report_results
+    ADD CONSTRAINT fk_rails_0667f7608c FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
+ALTER TABLE ONLY ci_subscriptions_projects
+    ADD CONSTRAINT fk_rails_0818751483 FOREIGN KEY (downstream_project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY user_interacted_projects
     ADD CONSTRAINT fk_rails_0894651f08 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
 
@@ -33623,9 +33322,6 @@ ALTER TABLE ONLY packages_debian_group_distributions
 ALTER TABLE ONLY packages_conan_file_metadata
     ADD CONSTRAINT fk_rails_0afabd9328 FOREIGN KEY (package_file_id) REFERENCES packages_package_files(id) ON DELETE CASCADE;
 
-ALTER TABLE ONLY related_epic_links
-    ADD CONSTRAINT fk_rails_0b72027748 FOREIGN KEY (target_id) REFERENCES epics(id) ON DELETE CASCADE;
-
 ALTER TABLE ONLY ci_build_pending_states
     ADD CONSTRAINT fk_rails_0bbbfeaf9d FOREIGN KEY (build_id) REFERENCES ci_builds(id) ON DELETE CASCADE;
 
@@ -33692,9 +33388,6 @@ ALTER TABLE ONLY bulk_imports
 ALTER TABLE ONLY diff_note_positions
     ADD CONSTRAINT fk_rails_13c7212859 FOREIGN KEY (note_id) REFERENCES notes(id) ON DELETE CASCADE;
 
-ALTER TABLE ONLY analytics_cycle_analytics_aggregations
-    ADD CONSTRAINT fk_rails_13c8374c7a FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
-
 ALTER TABLE ONLY users_security_dashboard_projects
     ADD CONSTRAINT fk_rails_150cd5682c FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
@@ -33776,6 +33469,9 @@ ALTER TABLE ONLY boards_epic_lists
 ALTER TABLE ONLY approval_merge_request_rules_groups
     ADD CONSTRAINT fk_rails_2020a7124a FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY vulnerability_feedback
+    ADD CONSTRAINT fk_rails_20976e6fd9 FOREIGN KEY (pipeline_id) REFERENCES ci_pipelines(id) ON DELETE SET NULL;
+
 ALTER TABLE ONLY work_item_types
     ADD CONSTRAINT fk_rails_20f694a960 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
 
@@ -33794,6 +33490,9 @@ ALTER TABLE ONLY service_desk_settings
 ALTER TABLE ONLY saml_group_links
     ADD CONSTRAINT fk_rails_22e312c530 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY vulnerability_finding_evidence_responses
+    ADD CONSTRAINT fk_rails_2390a09723 FOREIGN KEY (vulnerability_finding_evidence_id) REFERENCES vulnerability_finding_evidences(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY dast_profiles
     ADD CONSTRAINT fk_rails_23cae5abe1 FOREIGN KEY (dast_scanner_profile_id) REFERENCES dast_scanner_profiles(id) ON DELETE CASCADE;
 
@@ -33893,8 +33592,8 @@ ALTER TABLE ONLY container_repositories
 ALTER TABLE ONLY clusters_applications_jupyter
     ADD CONSTRAINT fk_rails_331f0aff78 FOREIGN KEY (oauth_application_id) REFERENCES oauth_applications(id) ON DELETE SET NULL;
 
-ALTER TABLE ONLY alert_management_alert_metric_images
-    ADD CONSTRAINT fk_rails_338e55b408 FOREIGN KEY (alert_id) REFERENCES alert_management_alerts(id) ON DELETE CASCADE;
+ALTER TABLE ONLY merge_request_metrics
+    ADD CONSTRAINT fk_rails_33ae169d48 FOREIGN KEY (pipeline_id) REFERENCES ci_pipelines(id) ON DELETE CASCADE;
 
 ALTER TABLE ONLY suggestions
     ADD CONSTRAINT fk_rails_33b03a535c FOREIGN KEY (note_id) REFERENCES notes(id) ON DELETE CASCADE;
@@ -33905,12 +33604,12 @@ ALTER TABLE ONLY requirements
 ALTER TABLE ONLY metrics_dashboard_annotations
     ADD CONSTRAINT fk_rails_345ab51043 FOREIGN KEY (cluster_id) REFERENCES clusters(id) ON DELETE CASCADE;
 
-ALTER TABLE ONLY group_features
-    ADD CONSTRAINT fk_rails_356514082b FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
-
 ALTER TABLE ONLY wiki_page_slugs
     ADD CONSTRAINT fk_rails_358b46be14 FOREIGN KEY (wiki_page_meta_id) REFERENCES wiki_page_meta(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_job_token_project_scope_links
+    ADD CONSTRAINT fk_rails_35f7f506ce FOREIGN KEY (added_by_id) REFERENCES users(id) ON DELETE SET NULL;
+
 ALTER TABLE ONLY board_labels
     ADD CONSTRAINT fk_rails_362b0600a3 FOREIGN KEY (label_id) REFERENCES labels(id) ON DELETE CASCADE;
 
@@ -33986,6 +33685,9 @@ ALTER TABLE ONLY geo_node_namespace_links
 ALTER TABLE ONLY epic_issues
     ADD CONSTRAINT fk_rails_4209981af6 FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_refs
+    ADD CONSTRAINT fk_rails_4249db8cc3 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY ci_resources
     ADD CONSTRAINT fk_rails_430336af2d FOREIGN KEY (resource_group_id) REFERENCES ci_resource_groups(id) ON DELETE CASCADE;
 
@@ -34031,9 +33733,18 @@ ALTER TABLE ONLY vulnerability_feedback
 ALTER TABLE ONLY user_custom_attributes
     ADD CONSTRAINT fk_rails_47b91868a8 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_pending_builds
+    ADD CONSTRAINT fk_rails_480669c3b3 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY upcoming_reconciliations
     ADD CONSTRAINT fk_rails_497b4938ac FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_pipeline_artifacts
+    ADD CONSTRAINT fk_rails_4a70390ca6 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
+ALTER TABLE ONLY ci_job_token_project_scope_links
+    ADD CONSTRAINT fk_rails_4b2ee3290b FOREIGN KEY (source_project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY group_deletion_schedules
     ADD CONSTRAINT fk_rails_4b8c694a6c FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
 
@@ -34058,9 +33769,6 @@ ALTER TABLE ONLY scim_identities
 ALTER TABLE ONLY snippet_user_mentions
     ADD CONSTRAINT fk_rails_4d3f96b2cb FOREIGN KEY (note_id) REFERENCES notes(id) ON DELETE CASCADE;
 
-ALTER TABLE ONLY protected_environment_approval_rules
-    ADD CONSTRAINT fk_rails_4e554f96f5 FOREIGN KEY (protected_environment_id) REFERENCES protected_environments(id) ON DELETE CASCADE;
-
 ALTER TABLE ONLY deployment_clusters
     ADD CONSTRAINT fk_rails_4e6243e120 FOREIGN KEY (cluster_id) REFERENCES clusters(id) ON DELETE CASCADE;
 
@@ -34070,6 +33778,9 @@ ALTER TABLE ONLY geo_repository_renamed_events
 ALTER TABLE ONLY aws_roles
     ADD CONSTRAINT fk_rails_4ed56f4720 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY security_scans
+    ADD CONSTRAINT fk_rails_4ef1e6b4c6 FOREIGN KEY (build_id) REFERENCES ci_builds(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY packages_debian_publications
     ADD CONSTRAINT fk_rails_4fc8ebd03e FOREIGN KEY (distribution_id) REFERENCES packages_debian_project_distributions(id) ON DELETE CASCADE;
 
@@ -34082,6 +33793,9 @@ ALTER TABLE ONLY resource_iteration_events
 ALTER TABLE ONLY status_page_settings
     ADD CONSTRAINT fk_rails_506e5ba391 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_project_monthly_usages
+    ADD CONSTRAINT fk_rails_508bcd4aa6 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY project_repository_storage_moves
     ADD CONSTRAINT fk_rails_5106dbd44a FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
@@ -34193,6 +33907,9 @@ ALTER TABLE ONLY evidences
 ALTER TABLE ONLY jira_imports
     ADD CONSTRAINT fk_rails_63cbe52ada FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY vulnerability_occurrence_pipelines
+    ADD CONSTRAINT fk_rails_6421e35d7d FOREIGN KEY (pipeline_id) REFERENCES ci_pipelines(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY group_deploy_tokens
     ADD CONSTRAINT fk_rails_6477b01f6b FOREIGN KEY (deploy_token_id) REFERENCES deploy_tokens(id) ON DELETE CASCADE;
 
@@ -34202,6 +33919,9 @@ ALTER TABLE ONLY reviews
 ALTER TABLE ONLY operations_feature_flags
     ADD CONSTRAINT fk_rails_648e241be7 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_sources_projects
+    ADD CONSTRAINT fk_rails_64b6855cbc FOREIGN KEY (source_project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY board_group_recent_visits
     ADD CONSTRAINT fk_rails_64bfc19bc5 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
 
@@ -34238,9 +33958,15 @@ ALTER TABLE ONLY vulnerability_findings_remediations
 ALTER TABLE ONLY resource_iteration_events
     ADD CONSTRAINT fk_rails_6830c13ac1 FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY vulnerability_finding_evidence_headers
+    ADD CONSTRAINT fk_rails_683b8e000c FOREIGN KEY (vulnerability_finding_evidence_response_id) REFERENCES vulnerability_finding_evidence_responses(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY geo_hashed_storage_migrated_events
     ADD CONSTRAINT fk_rails_687ed7d7c5 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_job_token_project_scope_links
+    ADD CONSTRAINT fk_rails_6904b38465 FOREIGN KEY (target_project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY plan_limits
     ADD CONSTRAINT fk_rails_69f8b6184f FOREIGN KEY (plan_id) REFERENCES plans(id) ON DELETE CASCADE;
 
@@ -34256,6 +33982,9 @@ ALTER TABLE ONLY prometheus_alerts
 ALTER TABLE ONLY term_agreements
     ADD CONSTRAINT fk_rails_6ea6520e4a FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY vulnerability_finding_evidence_assets
+    ADD CONSTRAINT fk_rails_6edbbecba4 FOREIGN KEY (vulnerability_finding_evidence_id) REFERENCES vulnerability_finding_evidences(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY project_compliance_framework_settings
     ADD CONSTRAINT fk_rails_6f5294f16c FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
@@ -34289,6 +34018,9 @@ ALTER TABLE ONLY dast_scanner_profiles
 ALTER TABLE ONLY vulnerability_historical_statistics
     ADD CONSTRAINT fk_rails_72b73ed023 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY vulnerability_finding_evidence_requests
+    ADD CONSTRAINT fk_rails_72c87c8eb6 FOREIGN KEY (vulnerability_finding_evidence_id) REFERENCES vulnerability_finding_evidences(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY slack_integrations
     ADD CONSTRAINT fk_rails_73db19721a FOREIGN KEY (service_id) REFERENCES integrations(id) ON DELETE CASCADE;
 
@@ -34304,9 +34036,6 @@ ALTER TABLE ONLY dast_site_profiles
 ALTER TABLE ONLY merge_request_context_commit_diff_files
     ADD CONSTRAINT fk_rails_74a00a1787 FOREIGN KEY (merge_request_context_commit_id) REFERENCES merge_request_context_commits(id) ON DELETE CASCADE;
 
-ALTER TABLE ONLY group_crm_settings
-    ADD CONSTRAINT fk_rails_74fdf2f13d FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
-
 ALTER TABLE ONLY clusters_applications_ingress
     ADD CONSTRAINT fk_rails_753a7b41c1 FOREIGN KEY (cluster_id) REFERENCES clusters(id) ON DELETE CASCADE;
 
@@ -34337,12 +34066,18 @@ ALTER TABLE ONLY boards_epic_user_preferences
 ALTER TABLE ONLY packages_debian_group_distribution_keys
     ADD CONSTRAINT fk_rails_779438f163 FOREIGN KEY (distribution_id) REFERENCES packages_debian_group_distributions(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_subscriptions_projects
+    ADD CONSTRAINT fk_rails_7871f9a97b FOREIGN KEY (upstream_project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY terraform_states
     ADD CONSTRAINT fk_rails_78f54ca485 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
 ALTER TABLE ONLY analytics_cycle_analytics_project_stages
     ADD CONSTRAINT fk_rails_796a7dbc9c FOREIGN KEY (project_value_stream_id) REFERENCES analytics_cycle_analytics_project_value_streams(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY vulnerability_finding_evidence_supporting_messages
+    ADD CONSTRAINT fk_rails_79e77f6c5c FOREIGN KEY (vulnerability_finding_evidence_id) REFERENCES vulnerability_finding_evidences(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY software_license_policies
     ADD CONSTRAINT fk_rails_7a7a2a92de FOREIGN KEY (software_license_id) REFERENCES software_licenses(id) ON DELETE CASCADE;
 
@@ -34376,9 +34111,6 @@ ALTER TABLE ONLY required_code_owners_sections
 ALTER TABLE ONLY dast_site_profiles
     ADD CONSTRAINT fk_rails_83e309d69e FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
-ALTER TABLE ONLY security_trainings
-    ADD CONSTRAINT fk_rails_84c7951d72 FOREIGN KEY (provider_id) REFERENCES security_training_providers(id) ON DELETE CASCADE;
-
 ALTER TABLE ONLY zentao_tracker_data
     ADD CONSTRAINT fk_rails_84efda7be0 FOREIGN KEY (integration_id) REFERENCES integrations(id) ON DELETE CASCADE;
 
@@ -34475,12 +34207,12 @@ ALTER TABLE ONLY project_error_tracking_settings
 ALTER TABLE ONLY list_user_preferences
     ADD CONSTRAINT fk_rails_916d72cafd FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY vulnerability_finding_evidence_responses
+    ADD CONSTRAINT fk_rails_929041a499 FOREIGN KEY (vulnerability_finding_evidence_supporting_message_id) REFERENCES vulnerability_finding_evidence_supporting_messages(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY merge_request_cleanup_schedules
     ADD CONSTRAINT fk_rails_92dd0e705c FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
 
-ALTER TABLE ONLY project_build_artifacts_size_refreshes
-    ADD CONSTRAINT fk_rails_936db5fc44 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
-
 ALTER TABLE ONLY board_labels
     ADD CONSTRAINT fk_rails_9374a16edd FOREIGN KEY (board_id) REFERENCES boards(id) ON DELETE CASCADE;
 
@@ -34511,6 +34243,9 @@ ALTER TABLE ONLY group_repository_storage_moves
 ALTER TABLE ONLY resource_label_events
     ADD CONSTRAINT fk_rails_9851a00031 FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_job_artifacts
+    ADD CONSTRAINT fk_rails_9862d392f9 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY board_project_recent_visits
     ADD CONSTRAINT fk_rails_98f8843922 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
@@ -34616,9 +34351,6 @@ ALTER TABLE ONLY resource_milestone_events
 ALTER TABLE ONLY term_agreements
     ADD CONSTRAINT fk_rails_a88721bcdf FOREIGN KEY (term_id) REFERENCES application_setting_terms(id);
 
-ALTER TABLE ONLY saved_replies
-    ADD CONSTRAINT fk_rails_a8bf5bf111 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
-
 ALTER TABLE ONLY ci_pipeline_artifacts
     ADD CONSTRAINT fk_rails_a9e811a466 FOREIGN KEY (pipeline_id) REFERENCES ci_pipelines(id) ON DELETE CASCADE;
 
@@ -34724,6 +34456,9 @@ ALTER TABLE ONLY projects_sync_events
 ALTER TABLE ONLY approval_merge_request_rules_users
     ADD CONSTRAINT fk_rails_bc8972fa55 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY external_pull_requests
+    ADD CONSTRAINT fk_rails_bcae9b5c7b FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY elasticsearch_indexed_projects
     ADD CONSTRAINT fk_rails_bd13bbdc3d FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
@@ -34775,9 +34510,6 @@ ALTER TABLE ONLY group_deploy_keys_groups
 ALTER TABLE ONLY merge_request_user_mentions
     ADD CONSTRAINT fk_rails_c440b9ea31 FOREIGN KEY (note_id) REFERENCES notes(id) ON DELETE CASCADE;
 
-ALTER TABLE ONLY related_epic_links
-    ADD CONSTRAINT fk_rails_c464534def FOREIGN KEY (source_id) REFERENCES epics(id) ON DELETE CASCADE;
-
 ALTER TABLE ONLY boards_epic_board_recent_visits
     ADD CONSTRAINT fk_rails_c4dcba4a3e FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
 
@@ -34835,12 +34567,18 @@ ALTER TABLE ONLY operations_strategies_user_lists
 ALTER TABLE ONLY issue_tracker_data
     ADD CONSTRAINT fk_rails_ccc0840427 FOREIGN KEY (service_id) REFERENCES integrations(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY vulnerability_finding_evidence_headers
+    ADD CONSTRAINT fk_rails_ce7f121a03 FOREIGN KEY (vulnerability_finding_evidence_request_id) REFERENCES vulnerability_finding_evidence_requests(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY resource_milestone_events
     ADD CONSTRAINT fk_rails_cedf8cce4d FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL;
 
 ALTER TABLE ONLY resource_iteration_events
     ADD CONSTRAINT fk_rails_cee126f66c FOREIGN KEY (iteration_id) REFERENCES sprints(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY vulnerability_finding_evidence_requests
+    ADD CONSTRAINT fk_rails_cf0f278cb0 FOREIGN KEY (vulnerability_finding_evidence_supporting_message_id) REFERENCES vulnerability_finding_evidence_supporting_messages(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY upload_states
     ADD CONSTRAINT fk_rails_d00f153613 FOREIGN KEY (upload_id) REFERENCES uploads(id) ON DELETE CASCADE;
 
@@ -34895,6 +34633,9 @@ ALTER TABLE ONLY issues_prometheus_alert_events
 ALTER TABLE ONLY board_user_preferences
     ADD CONSTRAINT fk_rails_dbebdaa8fe FOREIGN KEY (board_id) REFERENCES boards(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_running_builds
+    ADD CONSTRAINT fk_rails_dc1d0801e8 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY vulnerability_occurrence_pipelines
     ADD CONSTRAINT fk_rails_dc3ae04693 FOREIGN KEY (occurrence_id) REFERENCES vulnerability_occurrences(id) ON DELETE CASCADE;
 
@@ -34922,6 +34663,9 @@ ALTER TABLE ONLY analytics_cycle_analytics_group_stages
 ALTER TABLE ONLY bulk_import_export_uploads
     ADD CONSTRAINT fk_rails_dfbfb45eca FOREIGN KEY (export_id) REFERENCES bulk_import_exports(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_minutes_additional_packs
+    ADD CONSTRAINT fk_rails_e0e0c4e4b1 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY label_priorities
     ADD CONSTRAINT fk_rails_e161058b0f FOREIGN KEY (label_id) REFERENCES labels(id) ON DELETE CASCADE;
 
@@ -34961,6 +34705,9 @@ ALTER TABLE ONLY approval_merge_request_rule_sources
 ALTER TABLE ONLY prometheus_alerts
     ADD CONSTRAINT fk_rails_e6351447ec FOREIGN KEY (prometheus_metric_id) REFERENCES prometheus_metrics(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY requirements_management_test_reports
+    ADD CONSTRAINT fk_rails_e67d085910 FOREIGN KEY (build_id) REFERENCES ci_builds(id) ON DELETE SET NULL;
+
 ALTER TABLE ONLY merge_request_metrics
     ADD CONSTRAINT fk_rails_e6d7c24d1b FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
 
@@ -34988,6 +34735,9 @@ ALTER TABLE ONLY vulnerability_issue_links
 ALTER TABLE ONLY merge_request_blocks
     ADD CONSTRAINT fk_rails_e9387863bc FOREIGN KEY (blocking_merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY vulnerability_finding_evidence_sources
+    ADD CONSTRAINT fk_rails_e9761bed4c FOREIGN KEY (vulnerability_finding_evidence_id) REFERENCES vulnerability_finding_evidences(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY protected_branch_unprotect_access_levels
     ADD CONSTRAINT fk_rails_e9eb8dc025 FOREIGN KEY (protected_branch_id) REFERENCES protected_branches(id) ON DELETE CASCADE;
 
@@ -35075,12 +34825,15 @@ ALTER TABLE ONLY internal_ids
 ALTER TABLE ONLY issues_self_managed_prometheus_alert_events
     ADD CONSTRAINT fk_rails_f7db2d72eb FOREIGN KEY (self_managed_prometheus_alert_event_id) REFERENCES self_managed_prometheus_alert_events(id) ON DELETE CASCADE;
 
-ALTER TABLE ONLY security_trainings
-    ADD CONSTRAINT fk_rails_f80240fae0 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
-
 ALTER TABLE ONLY merge_requests_closing_issues
     ADD CONSTRAINT fk_rails_f8540692be FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY merge_trains
+    ADD CONSTRAINT fk_rails_f90820cb08 FOREIGN KEY (pipeline_id) REFERENCES ci_pipelines(id) ON DELETE SET NULL;
+
+ALTER TABLE ONLY ci_runner_namespaces
+    ADD CONSTRAINT fk_rails_f9d9ed3308 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY banned_users
     ADD CONSTRAINT fk_rails_fa5bb598e5 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
 
@@ -35123,6 +34876,9 @@ ALTER TABLE ONLY resource_label_events
 ALTER TABLE ONLY pages_deployment_states
     ADD CONSTRAINT fk_rails_ff6ca551a4 FOREIGN KEY (pages_deployment_id) REFERENCES pages_deployments(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY ci_builds_metadata
+    ADD CONSTRAINT fk_rails_ffcf702a02 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY security_orchestration_policy_configurations
     ADD CONSTRAINT fk_security_policy_configurations_management_project_id FOREIGN KEY (security_policy_management_project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
diff --git a/db/migrate/20220314184009_init_schema.rb b/db/migrate/20211202041233_init_schema.rb
similarity index 100%
rename from db/migrate/20220314184009_init_schema.rb
rename to db/migrate/20211202041233_init_schema.rb
diff --git a/db/migrate/20211202094944_move_loose_fk_deleted_records_to_dynamic_schema.rb b/db/migrate/20211202094944_move_loose_fk_deleted_records_to_dynamic_schema.rb
new file mode 100644
index 0000000000000000000000000000000000000000..84bc551d2b530e4a49891e75617a9eab1c85eaa1
--- /dev/null
+++ b/db/migrate/20211202094944_move_loose_fk_deleted_records_to_dynamic_schema.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class MoveLooseFkDeletedRecordsToDynamicSchema < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def up
+    if table_exists?('gitlab_partitions_static.loose_foreign_keys_deleted_records_1')
+      execute 'ALTER TABLE gitlab_partitions_static.loose_foreign_keys_deleted_records_1 SET SCHEMA gitlab_partitions_dynamic'
+    end
+  end
+
+  def down
+    if table_exists?('gitlab_partitions_dynamic.loose_foreign_keys_deleted_records_1')
+      execute 'ALTER TABLE gitlab_partitions_dynamic.loose_foreign_keys_deleted_records_1 SET SCHEMA gitlab_partitions_static'
+    end
+  end
+end
diff --git a/db/migrate/20211202135508_add_index_on_packages_build_infos_package_id_pipeline_id.rb b/db/migrate/20211202135508_add_index_on_packages_build_infos_package_id_pipeline_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..47a155d40fad68e6aeda8b68e12047c169465806
--- /dev/null
+++ b/db/migrate/20211202135508_add_index_on_packages_build_infos_package_id_pipeline_id.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class AddIndexOnPackagesBuildInfosPackageIdPipelineId < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_packages_build_infos_package_id_pipeline_id'
+  OLD_INDEX_NAME = 'idx_packages_build_infos_on_package_id'
+
+  def up
+    add_concurrent_index :packages_build_infos, [:package_id, :pipeline_id], name: INDEX_NAME
+    remove_concurrent_index_by_name :packages_build_infos, OLD_INDEX_NAME
+  end
+
+  def down
+    add_concurrent_index :packages_build_infos, :package_id, name: OLD_INDEX_NAME
+    remove_concurrent_index :packages_build_infos, [:package_id, :pipeline_id], name: INDEX_NAME
+  end
+end
diff --git a/db/migrate/20211203160952_add_updated_state_by_user_id_to_merge_request_reviewers.rb b/db/migrate/20211203160952_add_updated_state_by_user_id_to_merge_request_reviewers.rb
new file mode 100644
index 0000000000000000000000000000000000000000..dafd2108b4389d729faa9ac1231bb9d0c238643f
--- /dev/null
+++ b/db/migrate/20211203160952_add_updated_state_by_user_id_to_merge_request_reviewers.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+# See https://docs.gitlab.com/ee/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class AddUpdatedStateByUserIdToMergeRequestReviewers < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def change
+    add_column :merge_request_reviewers, :updated_state_by_user_id, :bigint
+  end
+end
diff --git a/db/migrate/20211203161149_add_index_to_merge_request_reviewers_updated_state_by_user_id.rb b/db/migrate/20211203161149_add_index_to_merge_request_reviewers_updated_state_by_user_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6f4ee079015c1731446f4b4b35ecbc2546c0e6ca
--- /dev/null
+++ b/db/migrate/20211203161149_add_index_to_merge_request_reviewers_updated_state_by_user_id.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddIndexToMergeRequestReviewersUpdatedStateByUserId < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_on_merge_request_reviewers_updated_state_by_user_id'
+
+  def up
+    add_concurrent_index :merge_request_reviewers, :updated_state_by_user_id, name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :merge_request_reviewers, INDEX_NAME
+  end
+end
diff --git a/db/migrate/20211203161840_add_updated_state_by_user_id_to_merge_request_assignees.rb b/db/migrate/20211203161840_add_updated_state_by_user_id_to_merge_request_assignees.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1c9e71936308e9e4d3bef0c7c6863da2704e98a0
--- /dev/null
+++ b/db/migrate/20211203161840_add_updated_state_by_user_id_to_merge_request_assignees.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddUpdatedStateByUserIdToMergeRequestAssignees < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def change
+    add_column :merge_request_assignees, :updated_state_by_user_id, :bigint
+  end
+end
diff --git a/db/migrate/20211203161942_add_index_to_merge_request_assignees_updated_state_by_user_id.rb b/db/migrate/20211203161942_add_index_to_merge_request_assignees_updated_state_by_user_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d052ffdf4d605fddcd32ef1797cda3d3a1bf8d2e
--- /dev/null
+++ b/db/migrate/20211203161942_add_index_to_merge_request_assignees_updated_state_by_user_id.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddIndexToMergeRequestAssigneesUpdatedStateByUserId < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_on_merge_request_assignees_updated_state_by_user_id'
+
+  def up
+    add_concurrent_index :merge_request_assignees, :updated_state_by_user_id, name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :merge_request_assignees, INDEX_NAME
+  end
+end
diff --git a/db/migrate/20211204010826_add_index_snippets_on_project_id_and_title.rb b/db/migrate/20211204010826_add_index_snippets_on_project_id_and_title.rb
new file mode 100644
index 0000000000000000000000000000000000000000..35a3a98030aa0c9027065e1f46a306fd633e2fbc
--- /dev/null
+++ b/db/migrate/20211204010826_add_index_snippets_on_project_id_and_title.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddIndexSnippetsOnProjectIdAndTitle < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_snippets_on_project_id_and_title'
+
+  def up
+    add_concurrent_index :snippets, [:project_id, :title], name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :snippets, name: INDEX_NAME
+  end
+end
diff --git a/db/migrate/20211207154413_add_ci_runners_index_on_created_at_where_active_is_false.rb b/db/migrate/20211207154413_add_ci_runners_index_on_created_at_where_active_is_false.rb
new file mode 100644
index 0000000000000000000000000000000000000000..da391da33ec61c28cbac558ce7c0a30a0bee05a8
--- /dev/null
+++ b/db/migrate/20211207154413_add_ci_runners_index_on_created_at_where_active_is_false.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddCiRunnersIndexOnCreatedAtWhereActiveIsFalse < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'index_ci_runners_on_created_at_and_id_where_inactive'
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :ci_runners, [:created_at, :id], where: 'active = FALSE', order: { created_at: :desc, id: :desc }, name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :ci_runners, INDEX_NAME
+  end
+end
diff --git a/db/migrate/20211207154414_add_ci_runners_index_on_contacted_at_where_active_is_false.rb b/db/migrate/20211207154414_add_ci_runners_index_on_contacted_at_where_active_is_false.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e25d3c0dffad9a3bcc8bfa44b60da638aea973be
--- /dev/null
+++ b/db/migrate/20211207154414_add_ci_runners_index_on_contacted_at_where_active_is_false.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddCiRunnersIndexOnContactedAtWhereActiveIsFalse < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'index_ci_runners_on_contacted_at_and_id_where_inactive'
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :ci_runners, [:contacted_at, :id], where: 'active = FALSE', order: { contacted_at: :desc, id: :desc }, name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :ci_runners, INDEX_NAME
+  end
+end
diff --git a/db/migrate/20211207165508_add_protected_environments_required_approval_count_check_constraint.rb b/db/migrate/20211207165508_add_protected_environments_required_approval_count_check_constraint.rb
new file mode 100644
index 0000000000000000000000000000000000000000..fb1339cecfac73a2dc1739ca8151e577593e3fd0
--- /dev/null
+++ b/db/migrate/20211207165508_add_protected_environments_required_approval_count_check_constraint.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddProtectedEnvironmentsRequiredApprovalCountCheckConstraint < Gitlab::Database::Migration[1.0]
+  CONSTRAINT_NAME = 'protected_environments_required_approval_count_positive'
+
+  disable_ddl_transaction!
+
+  def up
+    add_check_constraint :protected_environments, 'required_approval_count >= 0', CONSTRAINT_NAME
+  end
+
+  def down
+    remove_check_constraint :protected_environments, CONSTRAINT_NAME
+  end
+end
diff --git a/db/migrate/20211208111425_add_executor_type_column_to_ci_runners.rb b/db/migrate/20211208111425_add_executor_type_column_to_ci_runners.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1e1fdbdb12235b65d0324729cd28e7daf6d8c6d9
--- /dev/null
+++ b/db/migrate/20211208111425_add_executor_type_column_to_ci_runners.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddExecutorTypeColumnToCiRunners < Gitlab::Database::Migration[1.0]
+  def change
+    add_column :ci_runners, :executor_type, :smallint, null: true
+  end
+end
diff --git a/db/migrate/20211209230042_add_status_to_cluster_agent_tokens.rb b/db/migrate/20211209230042_add_status_to_cluster_agent_tokens.rb
new file mode 100644
index 0000000000000000000000000000000000000000..596c82eb209827f6555c6bafa1e461c6289cf078
--- /dev/null
+++ b/db/migrate/20211209230042_add_status_to_cluster_agent_tokens.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddStatusToClusterAgentTokens < Gitlab::Database::Migration[1.0]
+  def change
+    add_column :cluster_agent_tokens, :status, :smallint, null: false, default: 0
+  end
+end
diff --git a/db/migrate/20211210025754_alter_constraint_of_phone.rb b/db/migrate/20211210025754_alter_constraint_of_phone.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1644fbe9000e50cf120d20841e970adfba9ef33c
--- /dev/null
+++ b/db/migrate/20211210025754_alter_constraint_of_phone.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AlterConstraintOfPhone < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    constraint_phone = check_constraint_name('verification_codes', 'phone', 'max_length')
+    remove_check_constraint(:verification_codes, constraint_phone)
+    add_check_constraint(:verification_codes, 'char_length(phone) <= 50', constraint_phone)
+  end
+
+  def down
+    constraint_phone = check_constraint_name('verification_codes', 'phone', 'max_length')
+    remove_check_constraint(:verification_codes, constraint_phone)
+    add_check_constraint(:verification_codes, 'char_length(phone) <= 32', constraint_phone)
+  end
+end
diff --git a/db/migrate/20211210031721_change_user_details_phone_text_limit.rb b/db/migrate/20211210031721_change_user_details_phone_text_limit.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5432f6d3d246edea73ce42af42940dd5412d3ec7
--- /dev/null
+++ b/db/migrate/20211210031721_change_user_details_phone_text_limit.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class ChangeUserDetailsPhoneTextLimit < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    remove_text_limit :user_details, :phone
+    add_text_limit :user_details, :phone, 50
+  end
+
+  def down
+    remove_text_limit :user_details, :phone
+    add_text_limit :user_details, :phone, 32
+  end
+end
diff --git a/db/migrate/20211213130324_update_timelogs_spent_at_default.rb b/db/migrate/20211213130324_update_timelogs_spent_at_default.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f90b19b5f68983707014baa65f0ad20eefe9fb11
--- /dev/null
+++ b/db/migrate/20211213130324_update_timelogs_spent_at_default.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class UpdateTimelogsSpentAtDefault < Gitlab::Database::Migration[1.0]
+  def change
+    change_column_default(:timelogs, :spent_at, from: nil, to: -> { 'NOW()' })
+  end
+end
diff --git a/db/migrate/20211213142344_add_settings_user_email_lookup_limit.rb b/db/migrate/20211213142344_add_settings_user_email_lookup_limit.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ac7027bf082d37ecd6193e780b09e903a2edf8c4
--- /dev/null
+++ b/db/migrate/20211213142344_add_settings_user_email_lookup_limit.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddSettingsUserEmailLookupLimit < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    add_column :application_settings, :user_email_lookup_limit, :integer, null: false, default: 60
+  end
+
+  def down
+    remove_column :application_settings, :user_email_lookup_limit
+  end
+end
diff --git a/db/migrate/20211213154259_add_status_to_packages_package_files.rb b/db/migrate/20211213154259_add_status_to_packages_package_files.rb
new file mode 100644
index 0000000000000000000000000000000000000000..38ea069a30bedc4a490f703559b15d4556929012
--- /dev/null
+++ b/db/migrate/20211213154259_add_status_to_packages_package_files.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddStatusToPackagesPackageFiles < Gitlab::Database::Migration[1.0]
+  def change
+    add_column :packages_package_files, :status, :smallint, default: 0, null: false
+  end
+end
diff --git a/db/migrate/20211213154704_add_status_index_to_packages_package_files.rb b/db/migrate/20211213154704_add_status_index_to_packages_package_files.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7067e3efa6cf3ee0966a5b9ba0df960b92bf9f39
--- /dev/null
+++ b/db/migrate/20211213154704_add_status_index_to_packages_package_files.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddStatusIndexToPackagesPackageFiles < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_packages_package_files_on_package_id_status_and_id'
+
+  def up
+    add_concurrent_index :packages_package_files, [:package_id, :status, :id], name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :packages_package_files, name: INDEX_NAME
+  end
+end
diff --git a/db/migrate/20211214110307_remove_temp_index_from_vulnerability_occurrences.rb b/db/migrate/20211214110307_remove_temp_index_from_vulnerability_occurrences.rb
new file mode 100644
index 0000000000000000000000000000000000000000..99f985d528c9b043577d325e224c48f116a01d52
--- /dev/null
+++ b/db/migrate/20211214110307_remove_temp_index_from_vulnerability_occurrences.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveTempIndexFromVulnerabilityOccurrences < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'vulnerability_occurrences_location_temp_index'
+
+  disable_ddl_transaction!
+
+  def up
+    remove_concurrent_index_by_name :vulnerability_occurrences, name: INDEX_NAME
+  end
+
+  def down
+    add_concurrent_index :vulnerability_occurrences, :id, where: 'location IS NULL', name: INDEX_NAME
+  end
+end
diff --git a/db/migrate/20211215182006_update_application_settings_protected_paths.rb b/db/migrate/20211215182006_update_application_settings_protected_paths.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f1c1dde55e004c5bd4bb0db987f926e00d142f51
--- /dev/null
+++ b/db/migrate/20211215182006_update_application_settings_protected_paths.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+class UpdateApplicationSettingsProtectedPaths < Gitlab::Database::Migration[1.0]
+  REMOVE_PROTECTED_PATHS = [
+    '/oauth/authorize',
+    '/oauth/token'
+  ].freeze
+
+  NEW_DEFAULT_PROTECTED_PATHS = [
+    '/users/password',
+    '/users/sign_in',
+    '/api/v3/session.json',
+    '/api/v3/session',
+    '/api/v4/session.json',
+    '/api/v4/session',
+    '/users',
+    '/users/confirmation',
+    '/unsubscribes/',
+    '/import/github/personal_access_token',
+    '/admin/session'
+  ].freeze
+
+  OLD_DEFAULT_PROTECTED_PATHS = (NEW_DEFAULT_PROTECTED_PATHS + REMOVE_PROTECTED_PATHS).freeze
+
+  class ApplicationSetting < ActiveRecord::Base
+    self.table_name = 'application_settings'
+  end
+
+  def up
+    change_column_default(:application_settings, :protected_paths, NEW_DEFAULT_PROTECTED_PATHS)
+
+    ApplicationSetting.reset_column_information
+
+    ApplicationSetting.where.not(protected_paths: nil).each do |application_setting|
+      paths_to_remove = application_setting.protected_paths & REMOVE_PROTECTED_PATHS
+
+      next if paths_to_remove.empty?
+
+      updated_protected_paths = application_setting.protected_paths - paths_to_remove
+      application_setting.update!(protected_paths: updated_protected_paths)
+    end
+  end
+
+  def down
+    change_column_default(:application_settings, :protected_paths, OLD_DEFAULT_PROTECTED_PATHS)
+
+    ApplicationSetting.reset_column_information
+
+    ApplicationSetting.where.not(protected_paths: nil).each do |application_setting|
+      paths_to_add = REMOVE_PROTECTED_PATHS - application_setting.protected_paths
+
+      next if paths_to_add.empty?
+
+      updated_protected_paths = application_setting.protected_paths + paths_to_add
+      application_setting.update!(protected_paths: updated_protected_paths)
+    end
+  end
+end
diff --git a/db/migrate/20211216133107_add_cluster_agent_id_to_vulnerability_reads.rb b/db/migrate/20211216133107_add_cluster_agent_id_to_vulnerability_reads.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0bbd5c25df4d5f70c7490374882c9f2158242810
--- /dev/null
+++ b/db/migrate/20211216133107_add_cluster_agent_id_to_vulnerability_reads.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+class AddClusterAgentIdToVulnerabilityReads < Gitlab::Database::Migration[1.0]
+  # rubocop:disable Migration/AddLimitToTextColumns
+  # limit is added in 20211216134134_add_text_limit_to_vulnerability_reads_cluster_agent_id.rb
+  def change
+    add_column :vulnerability_reads, :cluster_agent_id, :text
+  end
+  # rubocop:enable Migration/AddLimitToTextColumns
+end
diff --git a/db/migrate/20211216134134_add_text_limit_to_vulnerability_reads_cluster_agent_id.rb b/db/migrate/20211216134134_add_text_limit_to_vulnerability_reads_cluster_agent_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f4776ff10a41ba9eabef041a709831a51e1ba732
--- /dev/null
+++ b/db/migrate/20211216134134_add_text_limit_to_vulnerability_reads_cluster_agent_id.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddTextLimitToVulnerabilityReadsClusterAgentId < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    add_text_limit :vulnerability_reads, :cluster_agent_id, 10
+  end
+
+  def down
+    remove_text_limit :vulnerability_reads, :cluster_agent_id
+  end
+end
diff --git a/db/migrate/20211216135651_add_index_to_cluster_agent_id.rb b/db/migrate/20211216135651_add_index_to_cluster_agent_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..05928083823dec2ddab35f9f6b4066ae81334e3b
--- /dev/null
+++ b/db/migrate/20211216135651_add_index_to_cluster_agent_id.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class AddIndexToClusterAgentId < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = "index_vulnerability_reads_on_cluster_agent_id"
+  CLUSTER_IMAGE_SCANNING_REPORT_TYPE = 7
+
+  def up
+    add_concurrent_index :vulnerability_reads, :cluster_agent_id, where: "report_type = #{CLUSTER_IMAGE_SCANNING_REPORT_TYPE}", name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :vulnerability_reads, INDEX_NAME
+  end
+end
diff --git a/db/migrate/20211216220939_add_group_crm_settings.rb b/db/migrate/20211216220939_add_group_crm_settings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e931aa3709bef45500b44888030f01c4a4f8f253
--- /dev/null
+++ b/db/migrate/20211216220939_add_group_crm_settings.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddGroupCrmSettings < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def change
+    create_table :group_crm_settings, id: false do |t|
+      t.references :group, primary_key: true, foreign_key: { to_table: :namespaces, on_delete: :cascade }
+      t.timestamps_with_timezone
+      t.boolean :enabled, null: false, default: false
+    end
+  end
+end
diff --git a/db/migrate/20211217050753_remove_artifacts_archive_id_foreign_key_from_project_pages_metadata.rb b/db/migrate/20211217050753_remove_artifacts_archive_id_foreign_key_from_project_pages_metadata.rb
new file mode 100644
index 0000000000000000000000000000000000000000..fa81fa512aea75a065f1a0f7db0135081afc8ba5
--- /dev/null
+++ b/db/migrate/20211217050753_remove_artifacts_archive_id_foreign_key_from_project_pages_metadata.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveArtifactsArchiveIdForeignKeyFromProjectPagesMetadata < Gitlab::Database::Migration[1.0]
+  CONSTRAINT_NAME = 'fk_69366a119e'
+
+  disable_ddl_transaction!
+
+  def up
+    with_lock_retries do
+      execute('lock table ci_job_artifacts, project_pages_metadata in access exclusive mode')
+
+      remove_foreign_key :project_pages_metadata, to_table: :ci_job_artifacts, column: :artifacts_archive_id, on_delete: :nullify, name: CONSTRAINT_NAME
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key :project_pages_metadata, :ci_job_artifacts, column: :artifacts_archive_id, on_delete: :nullify, name: CONSTRAINT_NAME
+  end
+end
diff --git a/db/migrate/20211220174504_add_secure_scanning_actions_to_onboarding_progresses.rb b/db/migrate/20211220174504_add_secure_scanning_actions_to_onboarding_progresses.rb
new file mode 100644
index 0000000000000000000000000000000000000000..cf9f25111763a128ed3a456264412ffbe4e15abd
--- /dev/null
+++ b/db/migrate/20211220174504_add_secure_scanning_actions_to_onboarding_progresses.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddSecureScanningActionsToOnboardingProgresses < Gitlab::Database::Migration[1.0]
+  def change
+    change_table(:onboarding_progresses, bulk: true) do |t|
+      t.column :secure_dependency_scanning_run_at, :datetime_with_timezone
+      t.column :secure_container_scanning_run_at, :datetime_with_timezone
+      t.column :secure_dast_run_at, :datetime_with_timezone
+      t.column :secure_secret_detection_run_at, :datetime_with_timezone
+      t.column :secure_coverage_fuzzing_run_at, :datetime_with_timezone
+      t.column :secure_cluster_image_scanning_run_at, :datetime_with_timezone
+      t.column :secure_api_fuzzing_run_at, :datetime_with_timezone
+    end
+  end
+end
diff --git a/db/migrate/20211223125921_add_temp_index_to_members_state.rb b/db/migrate/20211223125921_add_temp_index_to_members_state.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7dd2ec1a8aa01183149f5593cbe09fcf9c504842
--- /dev/null
+++ b/db/migrate/20211223125921_add_temp_index_to_members_state.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class AddTempIndexToMembersState < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'tmp_index_members_on_state'
+
+  def up
+    # Temporary index to be removed in 14.9 https://gitlab.com/gitlab-org/gitlab/-/issues/349960
+    add_concurrent_index :members, :state, name: INDEX_NAME, where: 'state = 2'
+  end
+
+  def down
+    remove_concurrent_index_by_name :members, INDEX_NAME
+  end
+end
diff --git a/db/migrate/20211224112937_add_packages_cleanup_package_file_worker_capacity_to_application_settings.rb b/db/migrate/20211224112937_add_packages_cleanup_package_file_worker_capacity_to_application_settings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..cb58033361f4daad1b3b89804834ab7940d7f2ae
--- /dev/null
+++ b/db/migrate/20211224112937_add_packages_cleanup_package_file_worker_capacity_to_application_settings.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddPackagesCleanupPackageFileWorkerCapacityToApplicationSettings < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def change
+    add_column :application_settings,
+               :packages_cleanup_package_file_worker_capacity,
+               :smallint,
+               default: 2,
+               null: false
+  end
+end
diff --git a/db/migrate/20211224114539_add_packages_cleanup_package_file_worker_capacity_check_constraint_to_app_settings.rb b/db/migrate/20211224114539_add_packages_cleanup_package_file_worker_capacity_check_constraint_to_app_settings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3a40540a1e1095f7ba41e67bd887ed2bf0461cde
--- /dev/null
+++ b/db/migrate/20211224114539_add_packages_cleanup_package_file_worker_capacity_check_constraint_to_app_settings.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddPackagesCleanupPackageFileWorkerCapacityCheckConstraintToAppSettings < Gitlab::Database::Migration[1.0]
+  CONSTRAINT_NAME = 'app_settings_p_cleanup_package_file_worker_capacity_positive'
+
+  disable_ddl_transaction!
+
+  def up
+    add_check_constraint :application_settings, 'packages_cleanup_package_file_worker_capacity >= 0', CONSTRAINT_NAME
+  end
+
+  def down
+    remove_check_constraint :application_settings, CONSTRAINT_NAME
+  end
+end
diff --git a/db/migrate/20220104174445_add_ci_runners_index_on_active_state.rb b/db/migrate/20220104174445_add_ci_runners_index_on_active_state.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2cef570966b2a57b9a7ee7bd872d3ff0460c731e
--- /dev/null
+++ b/db/migrate/20220104174445_add_ci_runners_index_on_active_state.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddCiRunnersIndexOnActiveState < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_ci_runners_on_active'
+
+  def up
+    add_concurrent_index :ci_runners, [:active, :id], name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :ci_runners, INDEX_NAME
+  end
+end
diff --git a/db/migrate/20220105082217_add_verification_token_to_external_ae_destinations.rb b/db/migrate/20220105082217_add_verification_token_to_external_ae_destinations.rb
new file mode 100644
index 0000000000000000000000000000000000000000..046a628b8ae1c4ba26d8e3218bea0c3daaaf6f73
--- /dev/null
+++ b/db/migrate/20220105082217_add_verification_token_to_external_ae_destinations.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddVerificationTokenToExternalAeDestinations < Gitlab::Database::Migration[1.0]
+  def up
+    # rubocop:disable Migration/AddLimitToTextColumns
+    add_column :audit_events_external_audit_event_destinations, :verification_token, :text
+    # rubocop:enable Migration/AddLimitToTextColumns
+  end
+
+  def down
+    remove_column :audit_events_external_audit_event_destinations, :verification_token
+  end
+end
diff --git a/db/migrate/20220105121325_add_route_namespace_reference.rb b/db/migrate/20220105121325_add_route_namespace_reference.rb
new file mode 100644
index 0000000000000000000000000000000000000000..77bd0530b8a83b16930dd215d5408983e2babb93
--- /dev/null
+++ b/db/migrate/20220105121325_add_route_namespace_reference.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddRouteNamespaceReference < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def up
+    add_column :routes, :namespace_id, :bigint unless column_exists?(:routes, :namespace_id)
+  end
+
+  def down
+    remove_column :routes, :namespace_id if column_exists?(:routes, :namespace_id)
+  end
+end
diff --git a/db/migrate/20220105152547_add_foreign_key_to_updated_state_by_user_id_to_merge_request_assignees.rb b/db/migrate/20220105152547_add_foreign_key_to_updated_state_by_user_id_to_merge_request_assignees.rb
new file mode 100644
index 0000000000000000000000000000000000000000..58411c1dc0fa5a74d0810fabcd8c370eb7036c88
--- /dev/null
+++ b/db/migrate/20220105152547_add_foreign_key_to_updated_state_by_user_id_to_merge_request_assignees.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddForeignKeyToUpdatedStateByUserIdToMergeRequestAssignees < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_foreign_key :merge_request_assignees, :users, column: :updated_state_by_user_id, on_delete: :nullify
+  end
+
+  def down
+    with_lock_retries do
+      remove_foreign_key :merge_request_assignees, column: :updated_state_by_user_id
+    end
+  end
+end
diff --git a/db/migrate/20220105153149_add_foreign_key_to_updated_state_by_user_id_to_merge_request_reviewers.rb b/db/migrate/20220105153149_add_foreign_key_to_updated_state_by_user_id_to_merge_request_reviewers.rb
new file mode 100644
index 0000000000000000000000000000000000000000..13e375a5b979771598e76eb3fc9d77f4af373ab6
--- /dev/null
+++ b/db/migrate/20220105153149_add_foreign_key_to_updated_state_by_user_id_to_merge_request_reviewers.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddForeignKeyToUpdatedStateByUserIdToMergeRequestReviewers < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_foreign_key :merge_request_reviewers, :users, column: :updated_state_by_user_id, on_delete: :nullify
+  end
+
+  def down
+    with_lock_retries do
+      remove_foreign_key :merge_request_reviewers, column: :updated_state_by_user_id
+    end
+  end
+end
diff --git a/db/migrate/20220106111958_add_insert_or_update_vulnerability_reads_trigger.rb b/db/migrate/20220106111958_add_insert_or_update_vulnerability_reads_trigger.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0049f4e00a2e60f49f274d7a47e8b78d9bf2dbc0
--- /dev/null
+++ b/db/migrate/20220106111958_add_insert_or_update_vulnerability_reads_trigger.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+class AddInsertOrUpdateVulnerabilityReadsTrigger < Gitlab::Database::Migration[1.0]
+  include Gitlab::Database::SchemaHelpers
+
+  FUNCTION_NAME = 'insert_or_update_vulnerability_reads'
+  TRIGGER_NAME = 'trigger_insert_or_update_vulnerability_reads_from_occurrences'
+
+  def up
+    execute(<<~SQL)
+      CREATE OR REPLACE FUNCTION #{FUNCTION_NAME}()
+      RETURNS TRIGGER
+      LANGUAGE plpgsql
+      AS $$
+      DECLARE
+        severity smallint;
+        state smallint;
+        report_type smallint;
+        resolved_on_default_branch boolean;
+      BEGIN
+        IF (NEW.vulnerability_id IS NULL AND (TG_OP = 'INSERT' OR TG_OP = 'UPDATE')) THEN
+          RETURN NULL;
+        END IF;
+
+        IF (TG_OP = 'UPDATE' AND OLD.vulnerability_id IS NOT NULL AND NEW.vulnerability_id IS NOT NULL) THEN
+          RETURN NULL;
+        END IF;
+
+        SELECT
+          vulnerabilities.severity, vulnerabilities.state, vulnerabilities.report_type, vulnerabilities.resolved_on_default_branch
+        INTO
+          severity, state, report_type, resolved_on_default_branch
+        FROM
+           vulnerabilities
+        WHERE
+          vulnerabilities.id = NEW.vulnerability_id;
+
+        INSERT INTO vulnerability_reads (vulnerability_id, project_id, scanner_id, report_type, severity, state, resolved_on_default_branch, uuid, location_image, cluster_agent_id)
+          VALUES (NEW.vulnerability_id, NEW.project_id, NEW.scanner_id, report_type, severity, state, resolved_on_default_branch, NEW.uuid::uuid, NEW.location->>'image', NEW.location->'kubernetes_resource'->>'agent_id')
+          ON CONFLICT(vulnerability_id) DO NOTHING;
+        RETURN NULL;
+      END
+      $$;
+    SQL
+
+    execute(<<~SQL)
+      CREATE TRIGGER #{TRIGGER_NAME}
+      AFTER INSERT OR UPDATE ON vulnerability_occurrences
+      FOR EACH ROW
+      EXECUTE PROCEDURE #{FUNCTION_NAME}();
+    SQL
+  end
+
+  def down
+    drop_trigger(:vulnerability_occurrences, TRIGGER_NAME)
+    drop_function(FUNCTION_NAME)
+  end
+end
diff --git a/db/migrate/20220106112043_add_update_vulnerability_reads_trigger.rb b/db/migrate/20220106112043_add_update_vulnerability_reads_trigger.rb
new file mode 100644
index 0000000000000000000000000000000000000000..940ec638924483e1e2c6d7ab9863e99d2566e06d
--- /dev/null
+++ b/db/migrate/20220106112043_add_update_vulnerability_reads_trigger.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+class AddUpdateVulnerabilityReadsTrigger < Gitlab::Database::Migration[1.0]
+  include Gitlab::Database::SchemaHelpers
+
+  TRIGGER_NAME = 'trigger_update_vulnerability_reads_on_vulnerability_update'
+  FUNCTION_NAME = 'update_vulnerability_reads_from_vulnerability'
+
+  def up
+    create_trigger_function(FUNCTION_NAME, replace: true) do
+      <<~SQL
+        UPDATE
+          vulnerability_reads
+        SET
+          severity = NEW.severity,
+          state = NEW.state,
+          resolved_on_default_branch = NEW.resolved_on_default_branch
+        WHERE vulnerability_id = NEW.id;
+        RETURN NULL;
+      SQL
+    end
+
+    execute(<<~SQL)
+      CREATE TRIGGER #{TRIGGER_NAME}
+      AFTER UPDATE ON vulnerabilities
+      FOR EACH ROW
+      WHEN (
+        OLD.severity IS DISTINCT FROM NEW.severity OR
+        OLD.state IS DISTINCT FROM NEW.state OR
+        OLD.resolved_on_default_branch IS DISTINCT FROM NEW.resolved_on_default_branch
+      )
+      EXECUTE PROCEDURE #{FUNCTION_NAME}();
+    SQL
+  end
+
+  def down
+    drop_trigger(:vulnerabilities, TRIGGER_NAME)
+    drop_function(FUNCTION_NAME)
+  end
+end
diff --git a/db/migrate/20220106112085_add_update_vulnerability_reads_location_trigger.rb b/db/migrate/20220106112085_add_update_vulnerability_reads_location_trigger.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a863fe8b7b8c05b7261d2b8dde1736e4fb7265e5
--- /dev/null
+++ b/db/migrate/20220106112085_add_update_vulnerability_reads_location_trigger.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+class AddUpdateVulnerabilityReadsLocationTrigger < Gitlab::Database::Migration[1.0]
+  include Gitlab::Database::SchemaHelpers
+
+  TRIGGER_NAME = 'trigger_update_location_on_vulnerability_occurrences_update'
+  FUNCTION_NAME = 'update_location_from_vulnerability_occurrences'
+
+  def up
+    create_trigger_function(FUNCTION_NAME, replace: true) do
+      <<~SQL
+        UPDATE
+          vulnerability_reads
+        SET
+          location_image = NEW.location->>'image',
+          cluster_agent_id = NEW.location->'kubernetes_resource'->>'agent_id'
+        WHERE
+          vulnerability_id = NEW.vulnerability_id;
+        RETURN NULL;
+      SQL
+    end
+
+    execute(<<~SQL)
+      CREATE TRIGGER #{TRIGGER_NAME}
+      AFTER UPDATE ON vulnerability_occurrences
+      FOR EACH ROW
+      WHEN (
+        NEW.report_type IN (2, 7) AND (
+          OLD.location->>'image' IS DISTINCT FROM NEW.location->>'image' OR
+          OLD.location->'kubernetes_resource'->>'agent_id' IS DISTINCT FROM NEW.location->'kubernetes_resource'->>'agent_id'
+        )
+      )
+      EXECUTE PROCEDURE #{FUNCTION_NAME}();
+    SQL
+  end
+
+  def down
+    drop_trigger(:vulnerability_occurrences, TRIGGER_NAME)
+    drop_function(FUNCTION_NAME)
+  end
+end
diff --git a/db/migrate/20220106141756_remove_lock_version_indexes.rb b/db/migrate/20220106141756_remove_lock_version_indexes.rb
new file mode 100644
index 0000000000000000000000000000000000000000..382f20dfc73283491ca452035b40f20ba3022078
--- /dev/null
+++ b/db/migrate/20220106141756_remove_lock_version_indexes.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class RemoveLockVersionIndexes < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEXES = {
+    issues: 'index_issues_on_lock_version',
+    merge_requests: 'index_merge_requests_on_lock_version',
+    epics: 'index_epics_on_lock_version'
+  }
+
+  def up
+    INDEXES.each do |table, index_name|
+      remove_concurrent_index_by_name table, index_name
+    end
+  end
+
+  def down
+    INDEXES.each do |table, index_name|
+      add_concurrent_index table, :lock_version, where: "lock_version IS NULL", name: index_name
+    end
+  end
+end
diff --git a/db/migrate/20220106163326_add_has_issues_on_vulnerability_reads_trigger.rb b/db/migrate/20220106163326_add_has_issues_on_vulnerability_reads_trigger.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b3023a1f91594872e7261fa8116ebe7210efa747
--- /dev/null
+++ b/db/migrate/20220106163326_add_has_issues_on_vulnerability_reads_trigger.rb
@@ -0,0 +1,79 @@
+# frozen_string_literal: true
+
+class AddHasIssuesOnVulnerabilityReadsTrigger < Gitlab::Database::Migration[1.0]
+  include Gitlab::Database::SchemaHelpers
+
+  TRIGGER_ON_INSERT = 'trigger_update_has_issues_on_vulnerability_issue_links_update'
+  INSERT_FUNCTION_NAME = 'set_has_issues_on_vulnerability_reads'
+
+  TRIGGER_ON_DELETE = 'trigger_update_has_issues_on_vulnerability_issue_links_delete'
+  DELETE_FUNCTION_NAME = 'unset_has_issues_on_vulnerability_reads'
+
+  def up
+    create_trigger_function(INSERT_FUNCTION_NAME, replace: true) do
+      <<~SQL
+        UPDATE
+          vulnerability_reads
+        SET
+          has_issues = true
+        WHERE
+          vulnerability_id = NEW.vulnerability_id AND has_issues IS FALSE;
+        RETURN NULL;
+      SQL
+    end
+
+    execute(<<~SQL)
+      CREATE OR REPLACE FUNCTION #{DELETE_FUNCTION_NAME}()
+      RETURNS TRIGGER
+      LANGUAGE plpgsql
+      AS $$
+      DECLARE
+        has_issue_links integer;
+      BEGIN
+        PERFORM 1
+        FROM
+          vulnerability_reads
+        WHERE
+          vulnerability_id = OLD.vulnerability_id
+        FOR UPDATE;
+
+        SELECT 1 INTO has_issue_links FROM vulnerability_issue_links WHERE vulnerability_id = OLD.vulnerability_id LIMIT 1;
+
+        IF (has_issue_links = 1) THEN
+          RETURN NULL;
+        END IF;
+
+        UPDATE
+          vulnerability_reads
+        SET
+          has_issues = false
+        WHERE
+          vulnerability_id = OLD.vulnerability_id;
+
+        RETURN NULL;
+      END
+      $$;
+    SQL
+
+    execute(<<~SQL)
+      CREATE TRIGGER #{TRIGGER_ON_INSERT}
+      AFTER INSERT ON vulnerability_issue_links
+      FOR EACH ROW
+      EXECUTE FUNCTION #{INSERT_FUNCTION_NAME}();
+    SQL
+
+    execute(<<~SQL)
+      CREATE TRIGGER #{TRIGGER_ON_DELETE}
+      AFTER DELETE ON vulnerability_issue_links
+      FOR EACH ROW
+      EXECUTE FUNCTION #{DELETE_FUNCTION_NAME}();
+    SQL
+  end
+
+  def down
+    drop_trigger(:vulnerability_issue_links, TRIGGER_ON_INSERT)
+    drop_function(INSERT_FUNCTION_NAME)
+    drop_trigger(:vulnerability_issue_links, TRIGGER_ON_DELETE)
+    drop_function(DELETE_FUNCTION_NAME)
+  end
+end
diff --git a/db/migrate/20220106230629_add_registry_migration_application_settings.rb b/db/migrate/20220106230629_add_registry_migration_application_settings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..191443de6eb7a24adf8127bca19ca5f5caf38cc7
--- /dev/null
+++ b/db/migrate/20220106230629_add_registry_migration_application_settings.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddRegistryMigrationApplicationSettings < Gitlab::Database::Migration[1.0]
+  # rubocop:disable Migration/AddLimitToTextColumns
+  # limit is added in 20220118141950_add_text_limit_to_container_registry_import_target_plan.rb
+  def change
+    add_column :application_settings, :container_registry_import_max_tags_count, :integer, default: 100, null: false
+    add_column :application_settings, :container_registry_import_max_retries, :integer, default: 3, null: false
+    add_column :application_settings, :container_registry_import_start_max_retries, :integer, default: 50, null: false
+    add_column :application_settings, :container_registry_import_max_step_duration, :integer, default: 5.minutes, null: false
+    add_column :application_settings, :container_registry_import_target_plan, :text, default: 'free', null: false
+    add_column :application_settings, :container_registry_import_created_before, :datetime_with_timezone, default: '2022-01-23 00:00:00', null: false
+  end
+  # rubocop:enable Migration/AddLimitToTextColumns
+end
diff --git a/db/migrate/20220106230712_add_migration_columns_to_container_repositories.rb b/db/migrate/20220106230712_add_migration_columns_to_container_repositories.rb
new file mode 100644
index 0000000000000000000000000000000000000000..76dccbe785f1e60087e0be7764419c79d3ae3f65
--- /dev/null
+++ b/db/migrate/20220106230712_add_migration_columns_to_container_repositories.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddMigrationColumnsToContainerRepositories < Gitlab::Database::Migration[1.0]
+  # rubocop:disable Migration/AddLimitToTextColumns
+  # limit is added in 20220117225936_add_text_limits_to_container_repositories_migration_columns.rb
+  def change
+    add_column :container_repositories, :migration_pre_import_started_at, :datetime_with_timezone
+    add_column :container_repositories, :migration_pre_import_done_at, :datetime_with_timezone
+    add_column :container_repositories, :migration_import_started_at, :datetime_with_timezone
+    add_column :container_repositories, :migration_import_done_at, :datetime_with_timezone
+    add_column :container_repositories, :migration_aborted_at, :datetime_with_timezone
+    add_column :container_repositories, :migration_skipped_at, :datetime_with_timezone
+    add_column :container_repositories, :migration_retries_count, :integer, default: 0, null: false
+    add_column :container_repositories, :migration_skipped_reason, :smallint
+    add_column :container_repositories, :migration_state, :text, default: 'default', null: false
+    add_column :container_repositories, :migration_aborted_in_state, :text
+  end
+  # rubocop:enable Migration/AddLimitToTextColumns
+end
diff --git a/db/migrate/20220107091629_add_route_namespace_index.rb b/db/migrate/20220107091629_add_route_namespace_index.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bc1044a24da30b7f6a9830c8c89e6bed826c14a3
--- /dev/null
+++ b/db/migrate/20220107091629_add_route_namespace_index.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddRouteNamespaceIndex < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+  INDEX_NAME = 'index_routes_on_namespace_id'
+
+  def up
+    add_concurrent_index :routes, :namespace_id, unique: true, name: INDEX_NAME
+    add_concurrent_foreign_key :routes, :namespaces, column: :namespace_id, on_delete: :nullify, reverse_lock_order: true
+  end
+
+  def down
+    with_lock_retries do
+      remove_foreign_key_if_exists :routes, column: :namespace_id
+    end
+
+    remove_concurrent_index_by_name :routes, INDEX_NAME
+  end
+end
diff --git a/db/migrate/20220107165036_remove_note_id_index.rb b/db/migrate/20220107165036_remove_note_id_index.rb
new file mode 100644
index 0000000000000000000000000000000000000000..15b4a3caf788af5c9dc5076bb302ea9b286057d5
--- /dev/null
+++ b/db/migrate/20220107165036_remove_note_id_index.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class RemoveNoteIdIndex < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  TABLE = :suggestions
+  INDEX_NAME = 'index_suggestions_on_note_id'
+
+  def up
+    remove_concurrent_index_by_name TABLE, INDEX_NAME
+  end
+
+  def down
+    add_concurrent_index TABLE, :note_id, name: INDEX_NAME
+  end
+end
diff --git a/db/migrate/20220109133006_remove_ci_pipelines_lock_version_index.rb b/db/migrate/20220109133006_remove_ci_pipelines_lock_version_index.rb
new file mode 100644
index 0000000000000000000000000000000000000000..abbd54ff19bfdcccc6829411ab98d755337d6708
--- /dev/null
+++ b/db/migrate/20220109133006_remove_ci_pipelines_lock_version_index.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveCiPipelinesLockVersionIndex < Gitlab::Database::Migration[1.0]
+  TABLE = :ci_pipelines
+  INDEX_NAME = 'tmp_index_ci_pipelines_lock_version'
+  COLUMN = :id
+
+  disable_ddl_transaction!
+
+  def up
+    remove_concurrent_index TABLE, COLUMN, where: "lock_version IS NULL", name: INDEX_NAME
+  end
+
+  def down
+    add_concurrent_index TABLE, COLUMN, where: "lock_version IS NULL", name: INDEX_NAME
+  end
+end
diff --git a/db/migrate/20220110170953_create_ci_secure_files.rb b/db/migrate/20220110170953_create_ci_secure_files.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1498a2d0212daf81e9f8615054f047038fd30467
--- /dev/null
+++ b/db/migrate/20220110170953_create_ci_secure_files.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class CreateCiSecureFiles < Gitlab::Database::Migration[1.0]
+  def up
+    create_table :ci_secure_files do |t|
+      t.bigint :project_id, index: true, null: false
+      t.timestamps_with_timezone null: false
+      t.integer :file_store, limit: 2, null: false, default: 1
+      t.integer :permissions, null: false, default: 0, limit: 2
+      t.text :name, null: false, limit: 255
+      t.text :file, null: false, limit: 255
+      t.binary :checksum, null: false
+    end
+  end
+
+  def down
+    drop_table :ci_secure_files, if_exists: true
+  end
+end
diff --git a/db/migrate/20220111095006_add_maintainer_note_to_ci_runners.rb b/db/migrate/20220111095006_add_maintainer_note_to_ci_runners.rb
new file mode 100644
index 0000000000000000000000000000000000000000..969774983c45fa66a3272314044217a5cb49c37a
--- /dev/null
+++ b/db/migrate/20220111095006_add_maintainer_note_to_ci_runners.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+class AddMaintainerNoteToCiRunners < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def change
+    # rubocop:disable Migration/AddLimitToTextColumns
+    # limit is added in 20220111095007_add_text_limit_to_ci_runners_maintainer_note.rb
+    add_column :ci_runners, :maintainer_note, :text
+    # rubocop:enable Migration/AddLimitToTextColumns
+  end
+end
diff --git a/db/migrate/20220111095007_add_text_limit_to_ci_runners_maintainer_note.rb b/db/migrate/20220111095007_add_text_limit_to_ci_runners_maintainer_note.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0a0a41713065e463cfd0ee2a63fd176e62447d52
--- /dev/null
+++ b/db/migrate/20220111095007_add_text_limit_to_ci_runners_maintainer_note.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddTextLimitToCiRunnersMaintainerNote < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    add_text_limit :ci_runners, :maintainer_note, 255
+  end
+
+  def down
+    remove_text_limit :ci_runners, :maintainer_note
+  end
+end
diff --git a/db/migrate/20220111154950_add_token_expires_at_to_ci_runners.rb b/db/migrate/20220111154950_add_token_expires_at_to_ci_runners.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b4d7c63d24b04fbd47f704ea49a7a2d6e02ce69b
--- /dev/null
+++ b/db/migrate/20220111154950_add_token_expires_at_to_ci_runners.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddTokenExpiresAtToCiRunners < Gitlab::Database::Migration[1.0]
+  def change
+    add_column :ci_runners, :token_expires_at, :datetime_with_timezone
+  end
+end
diff --git a/db/migrate/20220111154951_add_index_to_ci_runners_token_expires_at.rb b/db/migrate/20220111154951_add_index_to_ci_runners_token_expires_at.rb
new file mode 100644
index 0000000000000000000000000000000000000000..53623198f5116d3d5a104ab7137655cb3f461b03
--- /dev/null
+++ b/db/migrate/20220111154951_add_index_to_ci_runners_token_expires_at.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddIndexToCiRunnersTokenExpiresAt < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :ci_runners, [:token_expires_at, :id], order: { token_expires_at: :asc, id: :desc }, name: 'index_ci_runners_on_token_expires_at_and_id_desc'
+    add_concurrent_index :ci_runners, [:token_expires_at, :id], order: { token_expires_at: :desc, id: :desc }, name: 'index_ci_runners_on_token_expires_at_desc_and_id_desc'
+  end
+
+  def down
+    remove_concurrent_index_by_name :ci_runners, 'index_ci_runners_on_token_expires_at_desc_and_id_desc'
+    remove_concurrent_index_by_name :ci_runners, 'index_ci_runners_on_token_expires_at_and_id_desc'
+  end
+end
diff --git a/db/migrate/20220111200254_remove_index_from_merge_requests.rb b/db/migrate/20220111200254_remove_index_from_merge_requests.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0ac6019ad5ee6d1d30a0beed4a946f090c83b950
--- /dev/null
+++ b/db/migrate/20220111200254_remove_index_from_merge_requests.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveIndexFromMergeRequests < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_merge_requests_on_title'
+
+  def up
+    remove_concurrent_index :merge_requests, :title, name: INDEX_NAME
+  end
+
+  def down
+    add_concurrent_index :merge_requests, :title, name: INDEX_NAME
+  end
+end
diff --git a/db/migrate/20220112115413_add_requires_verification_to_user_details.rb b/db/migrate/20220112115413_add_requires_verification_to_user_details.rb
new file mode 100644
index 0000000000000000000000000000000000000000..01fe4f1d5cff6d81d91fdfcd244a1791c3912fe5
--- /dev/null
+++ b/db/migrate/20220112115413_add_requires_verification_to_user_details.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddRequiresVerificationToUserDetails < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def change
+    add_column :user_details, :requires_credit_card_verification, :boolean, null: false, default: false
+  end
+end
diff --git a/db/migrate/20220112205111_create_security_training_providers.rb b/db/migrate/20220112205111_create_security_training_providers.rb
new file mode 100644
index 0000000000000000000000000000000000000000..afddec6a1349b5eaeb9fe6d4a71e4afcebe40e0c
--- /dev/null
+++ b/db/migrate/20220112205111_create_security_training_providers.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class CreateSecurityTrainingProviders < Gitlab::Database::Migration[1.0]
+  def change
+    create_table :security_training_providers do |t|
+      t.text :name, limit: 256, null: false
+      t.text :description, limit: 512
+      t.text :url, limit: 512, null: false
+      t.text :logo_url, limit: 512
+
+      t.timestamps_with_timezone null: false
+    end
+  end
+end
diff --git a/db/migrate/20220112232037_add_member_namespace_reference.rb b/db/migrate/20220112232037_add_member_namespace_reference.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d67ea09a78cb7d488e566125778809a39823d09c
--- /dev/null
+++ b/db/migrate/20220112232037_add_member_namespace_reference.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddMemberNamespaceReference < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def up
+    add_column :members, :member_namespace_id, :bigint unless column_exists?(:members, :member_namespace_id)
+  end
+
+  def down
+    remove_column :members, :member_namespace_id if column_exists?(:members, :member_namespace_id)
+  end
+end
diff --git a/db/migrate/20220112232605_add_member_namespace_index.rb b/db/migrate/20220112232605_add_member_namespace_index.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ba32df53ae75f1fe72d19f3d165fe672ed94dfc2
--- /dev/null
+++ b/db/migrate/20220112232605_add_member_namespace_index.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddMemberNamespaceIndex < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+  INDEX_NAME = 'index_members_on_member_namespace_id'
+
+  def up
+    add_concurrent_index :members, :member_namespace_id, unique: false, name: INDEX_NAME
+    add_concurrent_foreign_key :members, :namespaces, column: :member_namespace_id, on_delete: :nullify, reverse_lock_order: true
+  end
+
+  def down
+    with_lock_retries do
+      remove_foreign_key_if_exists :members, column: :member_namespace_id
+    end
+
+    remove_concurrent_index_by_name :members, INDEX_NAME
+  end
+end
diff --git a/db/migrate/20220113125401_create_security_trainings.rb b/db/migrate/20220113125401_create_security_trainings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6924c7bd18909b432a6dc455e07ea7975cac56a8
--- /dev/null
+++ b/db/migrate/20220113125401_create_security_trainings.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class CreateSecurityTrainings < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def change
+    create_table :security_trainings do |t|
+      t.references :project, null: false, foreign_key: { on_delete: :cascade }
+      t.references :provider, null: false, foreign_key: { to_table: :security_training_providers, on_delete: :cascade }
+      t.boolean :is_primary, default: false, null: false
+
+      t.timestamps_with_timezone null: false
+
+      # Guarantee that there will be only one primary per project
+      t.index :project_id, name: 'index_security_trainings_on_unique_project_id', unique: true, where: 'is_primary IS TRUE'
+    end
+  end
+end
diff --git a/db/migrate/20220113135449_add_package_files_limit_to_application_settings.rb b/db/migrate/20220113135449_add_package_files_limit_to_application_settings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6d3deacdda305bc4ace0624df33405f8a24c5618
--- /dev/null
+++ b/db/migrate/20220113135449_add_package_files_limit_to_application_settings.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddPackageFilesLimitToApplicationSettings < Gitlab::Database::Migration[1.0]
+  def change
+    add_column :application_settings, :max_package_files_for_package_destruction, :smallint, default: 100, null: false
+  end
+end
diff --git a/db/migrate/20220113135924_add_application_settings_package_files_limit_constraints.rb b/db/migrate/20220113135924_add_application_settings_package_files_limit_constraints.rb
new file mode 100644
index 0000000000000000000000000000000000000000..65fbccbd1ae8dfcddb8d45715212c2a14bdc6a8d
--- /dev/null
+++ b/db/migrate/20220113135924_add_application_settings_package_files_limit_constraints.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddApplicationSettingsPackageFilesLimitConstraints < Gitlab::Database::Migration[1.0]
+  CONSTRAINT_NAME = 'app_settings_max_package_files_for_package_destruction_positive'
+
+  disable_ddl_transaction!
+
+  def up
+    add_check_constraint :application_settings, 'max_package_files_for_package_destruction > 0', CONSTRAINT_NAME
+  end
+
+  def down
+    remove_check_constraint :application_settings, CONSTRAINT_NAME
+  end
+end
diff --git a/db/migrate/20220113164801_add_diffs_colors_to_user_preferences.rb b/db/migrate/20220113164801_add_diffs_colors_to_user_preferences.rb
new file mode 100644
index 0000000000000000000000000000000000000000..00e8e574722b494ac8f64bcc5ed192d67a51bfe4
--- /dev/null
+++ b/db/migrate/20220113164801_add_diffs_colors_to_user_preferences.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddDiffsColorsToUserPreferences < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  # rubocop:disable Migration/AddLimitToTextColumns
+  # limit is added in 20220113164901_add_text_limit_to_user_preferences_diffs_colors.rb
+  def change
+    add_column :user_preferences, :diffs_deletion_color, :text
+    add_column :user_preferences, :diffs_addition_color, :text
+  end
+  # rubocop:enable Migration/AddLimitToTextColumns
+end
diff --git a/db/migrate/20220113164901_add_text_limit_to_user_preferences_diffs_colors.rb b/db/migrate/20220113164901_add_text_limit_to_user_preferences_diffs_colors.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9ae1c87519451d4936ed3a8c50dacf8c7c99d3f2
--- /dev/null
+++ b/db/migrate/20220113164901_add_text_limit_to_user_preferences_diffs_colors.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddTextLimitToUserPreferencesDiffsColors < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    add_text_limit :user_preferences, :diffs_deletion_color, 7
+    add_text_limit :user_preferences, :diffs_addition_color, 7
+  end
+
+  def down
+    remove_text_limit :user_preferences, :diffs_addition_color
+    remove_text_limit :user_preferences, :diffs_deletion_color
+  end
+end
diff --git a/db/migrate/20220114131950_add_status_only_index_to_packages_package_files.rb b/db/migrate/20220114131950_add_status_only_index_to_packages_package_files.rb
new file mode 100644
index 0000000000000000000000000000000000000000..948edea1138750ebcbe4282c5992597bfe91402a
--- /dev/null
+++ b/db/migrate/20220114131950_add_status_only_index_to_packages_package_files.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddStatusOnlyIndexToPackagesPackageFiles < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_packages_package_files_on_status'
+
+  def up
+    add_concurrent_index :packages_package_files, :status, name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :packages_package_files, name: INDEX_NAME
+  end
+end
diff --git a/db/migrate/20220117082611_add_text_limit_to_exad_verification_tokens.rb b/db/migrate/20220117082611_add_text_limit_to_exad_verification_tokens.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9978e87a1e338fb1502ab2148825ecc1b0070a0d
--- /dev/null
+++ b/db/migrate/20220117082611_add_text_limit_to_exad_verification_tokens.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddTextLimitToExadVerificationTokens < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    add_text_limit :audit_events_external_audit_event_destinations, :verification_token, 24
+  end
+
+  def down
+    remove_text_limit :audit_events_external_audit_event_destinations, :verification_token
+  end
+end
diff --git a/db/migrate/20220117225936_add_text_limits_to_container_repositories_migration_columns.rb b/db/migrate/20220117225936_add_text_limits_to_container_repositories_migration_columns.rb
new file mode 100644
index 0000000000000000000000000000000000000000..91c0612716b8dd7d8eb9e41dba15ecb9ded30734
--- /dev/null
+++ b/db/migrate/20220117225936_add_text_limits_to_container_repositories_migration_columns.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddTextLimitsToContainerRepositoriesMigrationColumns < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    add_text_limit :container_repositories, :migration_state, 255
+    add_text_limit :container_repositories, :migration_aborted_in_state, 255
+  end
+
+  def down
+    remove_text_limit :container_repositories, :migration_state
+    remove_text_limit :container_repositories, :migration_aborted_in_state
+  end
+end
diff --git a/db/migrate/20220118015633_add_url_text_to_issuable_metric_images.rb b/db/migrate/20220118015633_add_url_text_to_issuable_metric_images.rb
new file mode 100644
index 0000000000000000000000000000000000000000..55d820c12567faf29e9648303f56da6fcfeb82d4
--- /dev/null
+++ b/db/migrate/20220118015633_add_url_text_to_issuable_metric_images.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+class AddUrlTextToIssuableMetricImages < Gitlab::Database::Migration[1.0]
+  # rubocop:disable Migration/AddLimitToTextColumns
+  # limit is added in 20220118020026_add_url_text_limit_to_issuable_metric_images
+  def change
+    add_column :issuable_metric_images, :url_text, :text
+  end
+  # rubocop:enable Migration/AddLimitToTextColumns
+end
diff --git a/db/migrate/20220118020026_add_url_text_limit_to_issuable_metric_images.rb b/db/migrate/20220118020026_add_url_text_limit_to_issuable_metric_images.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2f0f27681cdbb827b2dd4e09ce2dcc70fe18b565
--- /dev/null
+++ b/db/migrate/20220118020026_add_url_text_limit_to_issuable_metric_images.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddUrlTextLimitToIssuableMetricImages < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    add_text_limit :issuable_metric_images, :url_text, 128
+  end
+
+  def down
+    remove_text_limit :issuable_metric_images, :url_text
+  end
+end
diff --git a/db/migrate/20220118141950_add_text_limit_to_container_registry_import_target_plan.rb b/db/migrate/20220118141950_add_text_limit_to_container_registry_import_target_plan.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c7247d03423016b557c896a9580b9d4ab5faf0b4
--- /dev/null
+++ b/db/migrate/20220118141950_add_text_limit_to_container_registry_import_target_plan.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddTextLimitToContainerRegistryImportTargetPlan < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    add_text_limit :application_settings, :container_registry_import_target_plan, 255
+  end
+
+  def down
+    remove_text_limit :application_settings, :container_registry_import_target_plan
+  end
+end
diff --git a/db/migrate/20220118155846_add_runner_token_expiration_interval_settings_to_application_settings.rb b/db/migrate/20220118155846_add_runner_token_expiration_interval_settings_to_application_settings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..32ca8a5fb12cfa4087605ffaa367e100b0ff1bae
--- /dev/null
+++ b/db/migrate/20220118155846_add_runner_token_expiration_interval_settings_to_application_settings.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddRunnerTokenExpirationIntervalSettingsToApplicationSettings < Gitlab::Database::Migration[1.0]
+  def change
+    [:runner_token_expiration_interval, :group_runner_token_expiration_interval, :project_runner_token_expiration_interval].each do |field|
+      add_column :application_settings, field, :integer
+    end
+  end
+end
diff --git a/db/migrate/20220118155847_add_runner_token_expiration_interval_settings_to_namespace_settings.rb b/db/migrate/20220118155847_add_runner_token_expiration_interval_settings_to_namespace_settings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7b83cb2dd554f395936dcf8cbe5664a1651da3d8
--- /dev/null
+++ b/db/migrate/20220118155847_add_runner_token_expiration_interval_settings_to_namespace_settings.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class AddRunnerTokenExpirationIntervalSettingsToNamespaceSettings < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def change
+    [:runner_token_expiration_interval, :subgroup_runner_token_expiration_interval, :project_runner_token_expiration_interval].each do |field|
+      add_column :namespace_settings, field, :integer
+    end
+  end
+end
diff --git a/db/migrate/20220118155848_add_runner_token_expiration_interval_settings_to_project_settings.rb b/db/migrate/20220118155848_add_runner_token_expiration_interval_settings_to_project_settings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ef9591718283c28832ecffb3843d948a199a403d
--- /dev/null
+++ b/db/migrate/20220118155848_add_runner_token_expiration_interval_settings_to_project_settings.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddRunnerTokenExpirationIntervalSettingsToProjectSettings < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def change
+    add_column :project_ci_cd_settings, :runner_token_expiration_interval, :integer
+  end
+end
diff --git a/db/migrate/20220119094023_add_unique_index_to_aed_verification_token.rb b/db/migrate/20220119094023_add_unique_index_to_aed_verification_token.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bd40fe2203e703ce7b80743376fb366de594ad2e
--- /dev/null
+++ b/db/migrate/20220119094023_add_unique_index_to_aed_verification_token.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddUniqueIndexToAedVerificationToken < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_audit_events_external_audit_on_verification_token'
+
+  def up
+    add_concurrent_index :audit_events_external_audit_event_destinations, :verification_token, unique: true, name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :audit_events_external_audit_event_destinations, INDEX_NAME
+  end
+end
diff --git a/db/migrate/20220119141407_add_dependency_proxy_size_to_namespace_statistics.rb b/db/migrate/20220119141407_add_dependency_proxy_size_to_namespace_statistics.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d8107ad8e214b049a579575844002eaa72f1bf66
--- /dev/null
+++ b/db/migrate/20220119141407_add_dependency_proxy_size_to_namespace_statistics.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddDependencyProxySizeToNamespaceStatistics < Gitlab::Database::Migration[1.0]
+  def change
+    add_column :namespace_statistics, :dependency_proxy_size, :bigint, default: 0, null: false
+  end
+end
diff --git a/db/migrate/20220119144253_add_dependency_proxy_size_to_namespace_root_storage_statistics.rb b/db/migrate/20220119144253_add_dependency_proxy_size_to_namespace_root_storage_statistics.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8218f869ce6f4f64d9d34ad0062d6febb29fd760
--- /dev/null
+++ b/db/migrate/20220119144253_add_dependency_proxy_size_to_namespace_root_storage_statistics.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddDependencyProxySizeToNamespaceRootStorageStatistics < Gitlab::Database::Migration[1.0]
+  def change
+    add_column :namespace_root_storage_statistics, :dependency_proxy_size, :bigint, default: 0, null: false
+  end
+end
diff --git a/db/migrate/20220119170426_remove_temporary_vulnerability_occurrences_deduplication_index.rb b/db/migrate/20220119170426_remove_temporary_vulnerability_occurrences_deduplication_index.rb
new file mode 100644
index 0000000000000000000000000000000000000000..26859beb671d88216a827c3be890af0fb6e9ed98
--- /dev/null
+++ b/db/migrate/20220119170426_remove_temporary_vulnerability_occurrences_deduplication_index.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class RemoveTemporaryVulnerabilityOccurrencesDeduplicationIndex < Gitlab::Database::Migration[1.0]
+  MIGRATION = 'RecalculateVulnerabilitiesOccurrencesUuid'
+  INDEX_NAME = 'tmp_idx_deduplicate_vulnerability_occurrences'
+
+  disable_ddl_transaction!
+
+  def up
+    finalize_background_migration(MIGRATION)
+
+    remove_concurrent_index_by_name(:vulnerability_occurrences, INDEX_NAME)
+  end
+
+  def down
+    add_concurrent_index :vulnerability_occurrences,
+      %i[project_id report_type location_fingerprint primary_identifier_id id],
+      name: INDEX_NAME
+  end
+end
diff --git a/db/migrate/20220119220620_add_scan_method_to_dast_site_profile.rb b/db/migrate/20220119220620_add_scan_method_to_dast_site_profile.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f7b7580d673f8553ad70fbea239ce7ea1488bdd6
--- /dev/null
+++ b/db/migrate/20220119220620_add_scan_method_to_dast_site_profile.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class AddScanMethodToDastSiteProfile < Gitlab::Database::Migration[1.0]
+  def up
+    add_column :dast_site_profiles, :scan_method, :integer, limit: 2, default: 0, null: false
+  end
+
+  def down
+    remove_column :dast_site_profiles, :scan_method
+  end
+end
diff --git a/db/migrate/20220120033115_create_alert_management_alert_metric_images.rb b/db/migrate/20220120033115_create_alert_management_alert_metric_images.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e98392190f4de39a402b3e8715074a7d26635ca9
--- /dev/null
+++ b/db/migrate/20220120033115_create_alert_management_alert_metric_images.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class CreateAlertManagementAlertMetricImages < Gitlab::Database::Migration[1.0]
+  def up
+    create_table :alert_management_alert_metric_images do |t|
+      t.references :alert, null: false, index: true, foreign_key: { to_table: :alert_management_alerts, on_delete: :cascade }
+      t.timestamps_with_timezone
+      t.integer :file_store, limit: 2
+      t.text :file, limit: 255, null: false
+      t.text :url, limit: 255
+      t.text :url_text, limit: 128
+    end
+  end
+
+  def down
+    drop_table :alert_management_alert_metric_images, if_exists: true
+  end
+end
diff --git a/db/migrate/20220120085655_add_ci_runner_project_index_to_runner_id_and_project_id.rb b/db/migrate/20220120085655_add_ci_runner_project_index_to_runner_id_and_project_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bcf32d2abd0b355e92ed4f27791a33a02a74f88c
--- /dev/null
+++ b/db/migrate/20220120085655_add_ci_runner_project_index_to_runner_id_and_project_id.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddCiRunnerProjectIndexToRunnerIdAndProjectId < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  OLD_INDEX_NAME = 'index_ci_runner_projects_on_runner_id'
+  NEW_INDEX_NAME = 'index_ci_runner_projects_on_runner_id_and_project_id'
+  TABLE_NAME = :ci_runner_projects
+
+  def up
+    add_concurrent_index(TABLE_NAME, [:runner_id, :project_id], name: NEW_INDEX_NAME)
+    remove_concurrent_index_by_name(TABLE_NAME, OLD_INDEX_NAME)
+  end
+
+  def down
+    add_concurrent_index(TABLE_NAME, :runner_id, name: OLD_INDEX_NAME)
+    remove_concurrent_index_by_name(TABLE_NAME, NEW_INDEX_NAME)
+  end
+end
diff --git a/db/migrate/20220120160625_remove_temp_index_on_id_from_vulnerability_occurrences.rb b/db/migrate/20220120160625_remove_temp_index_on_id_from_vulnerability_occurrences.rb
new file mode 100644
index 0000000000000000000000000000000000000000..747cabcd865f7c2d7d921ed39b80178262454bc0
--- /dev/null
+++ b/db/migrate/20220120160625_remove_temp_index_on_id_from_vulnerability_occurrences.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveTempIndexOnIdFromVulnerabilityOccurrences < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'tmp_idx_vulnerability_occurrences_on_id_where_report_type_7_99'
+
+  disable_ddl_transaction!
+
+  def up
+    remove_concurrent_index_by_name :vulnerability_occurrences, name: INDEX_NAME
+  end
+
+  def down
+    add_concurrent_index :vulnerability_occurrences, :id, where: 'report_type IN (7, 99)', name: INDEX_NAME
+  end
+end
diff --git a/db/migrate/20220120211831_temp_index_for_group_namespace_member_backfill.rb b/db/migrate/20220120211831_temp_index_for_group_namespace_member_backfill.rb
new file mode 100644
index 0000000000000000000000000000000000000000..527d8783a0f827b07918550881560bef441114c6
--- /dev/null
+++ b/db/migrate/20220120211831_temp_index_for_group_namespace_member_backfill.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class TempIndexForGroupNamespaceMemberBackfill < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'tmp_index_for_namespace_id_migration_on_group_members'
+
+  disable_ddl_transaction!
+
+  def up
+    # Temporary index to be removed in 14.10
+    # https://gitlab.com/gitlab-org/gitlab/-/issues/353538
+    add_concurrent_index :members, :id, where: "members.member_namespace_id IS NULL and members.type = 'GroupMember'", name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :members, INDEX_NAME
+  end
+end
diff --git a/db/migrate/20220124200927_add_index_to_issues.rb b/db/migrate/20220124200927_add_index_to_issues.rb
new file mode 100644
index 0000000000000000000000000000000000000000..03cdc3ade2caa30dbfbdc95ba41bb58b3c20588c
--- /dev/null
+++ b/db/migrate/20220124200927_add_index_to_issues.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddIndexToIssues < Gitlab::Database::Migration[1.0]
+  DOWNTIME = false
+
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_issues_on_id_and_weight'
+
+  def up
+    add_concurrent_index :issues, [:id, :weight], name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :issues, INDEX_NAME
+  end
+end
diff --git a/db/migrate/20220125084127_add_cleanup_attempts_to_loose_foreign_keys_deleted_records.rb b/db/migrate/20220125084127_add_cleanup_attempts_to_loose_foreign_keys_deleted_records.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e0c80ad79e5890bad7b46fa400d023d365040443
--- /dev/null
+++ b/db/migrate/20220125084127_add_cleanup_attempts_to_loose_foreign_keys_deleted_records.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddCleanupAttemptsToLooseForeignKeysDeletedRecords < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def up
+    add_column :loose_foreign_keys_deleted_records, :cleanup_attempts, :smallint, default: 0
+  end
+
+  def down
+    remove_column :loose_foreign_keys_deleted_records, :cleanup_attempts
+  end
+end
diff --git a/db/migrate/20220125122228_add_topics_non_private_projects_count.rb b/db/migrate/20220125122228_add_topics_non_private_projects_count.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8c7b750d5ffc1c633fb8000f85e2306d782c15e4
--- /dev/null
+++ b/db/migrate/20220125122228_add_topics_non_private_projects_count.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class AddTopicsNonPrivateProjectsCount < Gitlab::Database::Migration[1.0]
+  def up
+    add_column :topics, :non_private_projects_count, :bigint, null: false, default: 0
+  end
+
+  def down
+    remove_column :topics, :non_private_projects_count
+  end
+end
diff --git a/db/migrate/20220125122725_add_topics_non_private_projects_count_index.rb b/db/migrate/20220125122725_add_topics_non_private_projects_count_index.rb
new file mode 100644
index 0000000000000000000000000000000000000000..46b4d298a2e8c5e548baf66753191aa22685545d
--- /dev/null
+++ b/db/migrate/20220125122725_add_topics_non_private_projects_count_index.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddTopicsNonPrivateProjectsCountIndex < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'index_topics_non_private_projects_count'
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :topics, [:non_private_projects_count, :id], order: { non_private_projects_count: :desc }, name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :topics, INDEX_NAME
+  end
+end
diff --git a/db/migrate/20220125230538_add_compound_index_on_project_id_and_id_for_vulnerabilities.rb b/db/migrate/20220125230538_add_compound_index_on_project_id_and_id_for_vulnerabilities.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c745fa51328e2d9427b3dc0d92d714bbca9f47c3
--- /dev/null
+++ b/db/migrate/20220125230538_add_compound_index_on_project_id_and_id_for_vulnerabilities.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddCompoundIndexOnProjectIdAndIdForVulnerabilities < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'index_vulnerabilities_on_project_id_and_id'
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :vulnerabilities, [:project_id, :id], name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index :vulnerabilities, [:project_id, :id], name: INDEX_NAME
+  end
+end
diff --git a/db/migrate/20220126191624_add_scan_file_path_to_dast_site_profile.rb b/db/migrate/20220126191624_add_scan_file_path_to_dast_site_profile.rb
new file mode 100644
index 0000000000000000000000000000000000000000..eab02663e26fff1d7fbbe6b27b955e7c9bc752d0
--- /dev/null
+++ b/db/migrate/20220126191624_add_scan_file_path_to_dast_site_profile.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class AddScanFilePathToDastSiteProfile < Gitlab::Database::Migration[2.0]
+  # rubocop:disable Migration/AddLimitToTextColumns
+  # limit is added in 20221012135524_add_scan_file_path_limit_for_dast_site_profile
+  def up
+    add_column :dast_site_profiles, :scan_file_path, :text
+  end
+  # rubocop:enable Migration/AddLimitToTextColumns
+
+  def down
+    remove_column :dast_site_profiles, :scan_file_path, :text
+  end
+end
diff --git a/db/migrate/20220128093756_add_ecdsa_sk_and_ed25519_sk_key_restrictions_to_application_settings.rb b/db/migrate/20220128093756_add_ecdsa_sk_and_ed25519_sk_key_restrictions_to_application_settings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1acd9599da452999edd6320ae4b13561c1cee0e2
--- /dev/null
+++ b/db/migrate/20220128093756_add_ecdsa_sk_and_ed25519_sk_key_restrictions_to_application_settings.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+class AddEcdsaSkAndEd25519SkKeyRestrictionsToApplicationSettings < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def change
+    add_column :application_settings, :ecdsa_sk_key_restriction, :integer, default: 0, null: false
+    add_column :application_settings, :ed25519_sk_key_restriction, :integer, default: 0, null: false
+  end
+end
diff --git a/db/migrate/20220128194722_add_index_on_migration_state_and_import_done_at_to_container_repositories.rb b/db/migrate/20220128194722_add_index_on_migration_state_and_import_done_at_to_container_repositories.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6c9fb20bbbda416a5121822e1ce28d799b556179
--- /dev/null
+++ b/db/migrate/20220128194722_add_index_on_migration_state_and_import_done_at_to_container_repositories.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class AddIndexOnMigrationStateAndImportDoneAtToContainerRepositories < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'index_container_repositories_on_migration_state_import_done_at'
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :container_repositories, [:migration_state, :migration_import_done_at], name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :container_repositories, INDEX_NAME
+  end
+end
diff --git a/db/migrate/20220131135725_add_severity_level_to_merge_requests_compliance_violations.rb b/db/migrate/20220131135725_add_severity_level_to_merge_requests_compliance_violations.rb
new file mode 100644
index 0000000000000000000000000000000000000000..50aa012105551915198c70540a865ee9d95c94c0
--- /dev/null
+++ b/db/migrate/20220131135725_add_severity_level_to_merge_requests_compliance_violations.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddSeverityLevelToMergeRequestsComplianceViolations < Gitlab::Database::Migration[1.0]
+  def change
+    add_column :merge_requests_compliance_violations, :severity_level, :integer, limit: 2, null: false, default: 0
+  end
+end
diff --git a/db/migrate/20220131192643_add_show_diff_preview_in_email_to_project_settings.rb b/db/migrate/20220131192643_add_show_diff_preview_in_email_to_project_settings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1811bf04ee499e66e673ea69d6f95c572e12f868
--- /dev/null
+++ b/db/migrate/20220131192643_add_show_diff_preview_in_email_to_project_settings.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddShowDiffPreviewInEmailToProjectSettings < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def change
+    add_column :project_settings, :show_diff_preview_in_email, :boolean, default: true, null: false
+  end
+end
diff --git a/db/migrate/20220201205300_remove_index_for_vulnerability_occurrences.rb b/db/migrate/20220201205300_remove_index_for_vulnerability_occurrences.rb
new file mode 100644
index 0000000000000000000000000000000000000000..89591d14aae552c6cd3e785c6c345d1b2d4fb788
--- /dev/null
+++ b/db/migrate/20220201205300_remove_index_for_vulnerability_occurrences.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveIndexForVulnerabilityOccurrences < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'index_vulnerability_occurrences_on_unique_keys'
+
+  disable_ddl_transaction!
+
+  def up
+    remove_concurrent_index_by_name :vulnerability_occurrences, INDEX_NAME
+  end
+
+  def down
+    # no-op
+
+    # The index is UNIQUE so we cannot add it back again
+  end
+end
diff --git a/db/migrate/20220202034409_add_tmp_index_on_id_and_migration_state_to_container_repositories.rb b/db/migrate/20220202034409_add_tmp_index_on_id_and_migration_state_to_container_repositories.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b999c871a3ef7875b046fb72bbc072e5ec6b184e
--- /dev/null
+++ b/db/migrate/20220202034409_add_tmp_index_on_id_and_migration_state_to_container_repositories.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class AddTmpIndexOnIdAndMigrationStateToContainerRepositories < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'tmp_index_container_repositories_on_id_migration_state'
+
+  disable_ddl_transaction!
+
+  # Temporary index to be removed https://gitlab.com/gitlab-org/gitlab/-/issues/351783
+  def up
+    add_concurrent_index :container_repositories, [:id, :migration_state], name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :container_repositories, INDEX_NAME
+  end
+end
diff --git a/db/migrate/20220202115350_add_migration_indexes_to_container_repositories.rb b/db/migrate/20220202115350_add_migration_indexes_to_container_repositories.rb
new file mode 100644
index 0000000000000000000000000000000000000000..673d066e3c014e6b94520ab7bb72da6e0bde6842
--- /dev/null
+++ b/db/migrate/20220202115350_add_migration_indexes_to_container_repositories.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+class AddMigrationIndexesToContainerRepositories < Gitlab::Database::Migration[1.0]
+  PRE_IMPORTING_INDEX = 'idx_container_repos_on_pre_import_started_at_when_pre_importing'
+  PRE_IMPORT_DONE_INDEX = 'idx_container_repos_on_pre_import_done_at_when_pre_import_done'
+  IMPORTING_INDEX = 'idx_container_repos_on_import_started_at_when_importing'
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :container_repositories, :migration_pre_import_started_at, name: PRE_IMPORTING_INDEX, where: "migration_state = 'pre_importing'"
+    add_concurrent_index :container_repositories, :migration_pre_import_done_at, name: PRE_IMPORT_DONE_INDEX, where: "migration_state = 'pre_import_done'"
+    add_concurrent_index :container_repositories, :migration_import_started_at, name: IMPORTING_INDEX, where: "migration_state = 'importing'"
+  end
+
+  def down
+    remove_concurrent_index_by_name :container_repositories, IMPORTING_INDEX
+    remove_concurrent_index_by_name :container_repositories, PRE_IMPORT_DONE_INDEX
+    remove_concurrent_index_by_name :container_repositories, PRE_IMPORTING_INDEX
+  end
+end
diff --git a/db/migrate/20220203074916_add_topics_lower_name_index.rb b/db/migrate/20220203074916_add_topics_lower_name_index.rb
new file mode 100644
index 0000000000000000000000000000000000000000..721abf66c6742e4fcbb0eea4fd125d5300d8346d
--- /dev/null
+++ b/db/migrate/20220203074916_add_topics_lower_name_index.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddTopicsLowerNameIndex < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'index_topics_on_lower_name'
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :topics, 'lower(name)', name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :topics, INDEX_NAME
+  end
+end
diff --git a/db/migrate/20220203091304_fix_unique_packages_index_excluding_pending_destruction_status.rb b/db/migrate/20220203091304_fix_unique_packages_index_excluding_pending_destruction_status.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c30d8de23db3dd3a52138a6db71959eb85ed878d
--- /dev/null
+++ b/db/migrate/20220203091304_fix_unique_packages_index_excluding_pending_destruction_status.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+class FixUniquePackagesIndexExcludingPendingDestructionStatus < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  GO_UNIQUE_INDEX_NAME = 'index_packages_on_project_id_name_version_unique_when_golang'
+  GENERIC_UNIQUE_INDEX_NAME = 'index_packages_on_project_id_name_version_unique_when_generic'
+  HELM_UNIQUE_INDEX_NAME = 'index_packages_on_project_id_name_version_unique_when_helm'
+
+  NEW_GO_UNIQUE_INDEX_NAME = 'idx_packages_on_project_id_name_version_unique_when_golang'
+  NEW_GENERIC_UNIQUE_INDEX_NAME = 'idx_packages_on_project_id_name_version_unique_when_generic'
+  NEW_HELM_UNIQUE_INDEX_NAME = 'idx_packages_on_project_id_name_version_unique_when_helm'
+
+  def up
+    add_concurrent_index :packages_packages, [:project_id, :name, :version], unique: true, name: NEW_GO_UNIQUE_INDEX_NAME, where: 'package_type = 8 AND status != 4'
+    add_concurrent_index :packages_packages, [:project_id, :name, :version], unique: true, name: NEW_GENERIC_UNIQUE_INDEX_NAME, where: 'package_type = 7 AND status != 4'
+    add_concurrent_index :packages_packages, [:project_id, :name, :version], unique: true, name: NEW_HELM_UNIQUE_INDEX_NAME, where: 'package_type = 11 AND status != 4'
+
+    remove_concurrent_index_by_name :packages_packages, GO_UNIQUE_INDEX_NAME
+    remove_concurrent_index_by_name :packages_packages, GENERIC_UNIQUE_INDEX_NAME
+    remove_concurrent_index_by_name :packages_packages, HELM_UNIQUE_INDEX_NAME
+  end
+
+  def down
+    # no-op
+    # We can't guarantee that the old index can be recreated since it targets a set larger that the new index.
+  end
+end
diff --git a/db/migrate/20220203123333_add_batched_migration_max_batch.rb b/db/migrate/20220203123333_add_batched_migration_max_batch.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d16c6dd41107781b085f2d7d639035a1c51a6545
--- /dev/null
+++ b/db/migrate/20220203123333_add_batched_migration_max_batch.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddBatchedMigrationMaxBatch < Gitlab::Database::Migration[1.0]
+  def change
+    add_column :batched_background_migrations, :max_batch_size, :integer
+  end
+end
diff --git a/db/migrate/20220203133652_add_legacy_open_source_license_available_to_project_settings.rb b/db/migrate/20220203133652_add_legacy_open_source_license_available_to_project_settings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..47f92fae496f7f303b4889e98b79aa78975fb035
--- /dev/null
+++ b/db/migrate/20220203133652_add_legacy_open_source_license_available_to_project_settings.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddLegacyOpenSourceLicenseAvailableToProjectSettings < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def change
+    add_column :project_settings, :legacy_open_source_license_available, :boolean, default: true, null: false
+  end
+end
diff --git a/db/migrate/20220203134942_add_hidden_to_projects.rb b/db/migrate/20220203134942_add_hidden_to_projects.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7046d641289319efd428cc21295f49a6bb38e6d0
--- /dev/null
+++ b/db/migrate/20220203134942_add_hidden_to_projects.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class AddHiddenToProjects < Gitlab::Database::Migration[1.0]
+  DOWNTIME = false
+
+  enable_lock_retries!
+
+  def change
+    add_column :projects, :hidden, :boolean, default: false, null: false # rubocop: disable Migration/AddColumnsToWideTables
+  end
+end
diff --git a/db/migrate/20220204093120_create_analytics_cycle_analytics_aggregations.rb b/db/migrate/20220204093120_create_analytics_cycle_analytics_aggregations.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0339e16a85bddac13af0c3207d3fdb2801ecd40a
--- /dev/null
+++ b/db/migrate/20220204093120_create_analytics_cycle_analytics_aggregations.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+class CreateAnalyticsCycleAnalyticsAggregations < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def up
+    create_table :analytics_cycle_analytics_aggregations, id: false do |t|
+      t.references :group, index: false, null: false, foreign_key: { to_table: :namespaces, on_delete: :cascade }
+      t.integer :incremental_runtimes_in_seconds, array: true, default: [], null: false
+      t.integer :incremental_processed_records, array: true, default: [], null: false
+      t.integer :last_full_run_runtimes_in_seconds, array: true, default: [], null: false
+      t.integer :last_full_run_processed_records, array: true, default: [], null: false
+      t.integer :last_incremental_issues_id
+      t.integer :last_incremental_merge_requests_id
+      t.integer :last_full_run_issues_id
+      t.integer :last_full_run_merge_requests_id
+
+      t.datetime_with_timezone :last_incremental_run_at
+      t.datetime_with_timezone :last_incremental_issues_updated_at
+      t.datetime_with_timezone :last_incremental_merge_requests_updated_at
+      t.datetime_with_timezone :last_full_run_at
+      t.datetime_with_timezone :last_full_run_issues_updated_at
+      t.datetime_with_timezone :last_full_run_mrs_updated_at
+      t.datetime_with_timezone :last_consistency_check_updated_at
+
+      t.boolean :enabled, default: true, null: false
+
+      t.index :last_incremental_run_at, where: 'enabled IS TRUE', name: 'ca_aggregations_last_incremental_run_at', order: { last_incremental_run_at: 'ASC NULLS FIRST' }
+      t.index :last_full_run_at, where: 'enabled IS TRUE', name: 'ca_aggregations_last_full_run_at', order: { last_full_run_at: 'ASC NULLS FIRST' }
+      t.index :last_consistency_check_updated_at, where: 'enabled IS TRUE', name: 'ca_aggregations_last_consistency_check_updated_at', order: { last_consistency_check_updated_at: 'ASC NULLS FIRST' }
+
+      t.check_constraint 'CARDINALITY(incremental_runtimes_in_seconds) <= 10'
+      t.check_constraint 'CARDINALITY(incremental_processed_records) <= 10'
+      t.check_constraint 'CARDINALITY(last_full_run_runtimes_in_seconds) <= 10'
+      t.check_constraint 'CARDINALITY(last_full_run_processed_records) <= 10'
+    end
+
+    execute("ALTER TABLE analytics_cycle_analytics_aggregations ADD PRIMARY KEY (group_id)")
+  end
+
+  def down
+    drop_table :analytics_cycle_analytics_aggregations
+  end
+end
diff --git a/db/migrate/20220204154220_add_index_on_greatest_done_at_to_container_repositories.rb b/db/migrate/20220204154220_add_index_on_greatest_done_at_to_container_repositories.rb
new file mode 100644
index 0000000000000000000000000000000000000000..455a8478cc40d46c2611b5841e38f6e68e646b46
--- /dev/null
+++ b/db/migrate/20220204154220_add_index_on_greatest_done_at_to_container_repositories.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddIndexOnGreatestDoneAtToContainerRepositories < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'index_container_repositories_on_greatest_done_at'
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :container_repositories,
+                         'GREATEST(migration_pre_import_done_at, migration_import_done_at, migration_aborted_at)',
+                         where: "migration_state IN ('import_done', 'pre_import_done', 'import_aborted')",
+                         name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :container_repositories, INDEX_NAME
+  end
+end
diff --git a/db/migrate/20220204193000_add_integrations_encrypted_properties.rb b/db/migrate/20220204193000_add_integrations_encrypted_properties.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7df88b68657f3e69edbcbb04e57b4fa02ec728f6
--- /dev/null
+++ b/db/migrate/20220204193000_add_integrations_encrypted_properties.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+class AddIntegrationsEncryptedProperties < Gitlab::Database::Migration[1.0]
+  def change
+    add_column :integrations, :encrypted_properties, :binary
+    add_column :integrations, :encrypted_properties_iv, :binary
+  end
+end
diff --git a/db/migrate/20220207083129_add_users_get_by_id_limit_to_application_setting.rb b/db/migrate/20220207083129_add_users_get_by_id_limit_to_application_setting.rb
new file mode 100644
index 0000000000000000000000000000000000000000..cdf2aced2130a76e8898f55bfa4e42e0e6fa5ba3
--- /dev/null
+++ b/db/migrate/20220207083129_add_users_get_by_id_limit_to_application_setting.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddUsersGetByIdLimitToApplicationSetting < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def up
+    add_column :application_settings, :users_get_by_id_limit, :integer, null: false, default: 300
+    add_column :application_settings, :users_get_by_id_limit_allowlist, :text, array: true, limit: 255, null: false, default: []
+  end
+
+  def down
+    remove_column :application_settings, :users_get_by_id_limit
+    remove_column :application_settings, :users_get_by_id_limit_allowlist
+  end
+end
diff --git a/db/migrate/20220208170445_add_not_valid_foreign_key_to_ci_builds_runner_id.rb b/db/migrate/20220208170445_add_not_valid_foreign_key_to_ci_builds_runner_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9b2ba17e0683b4e38530f2a09526658ebaeb223e
--- /dev/null
+++ b/db/migrate/20220208170445_add_not_valid_foreign_key_to_ci_builds_runner_id.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddNotValidForeignKeyToCiBuildsRunnerId < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_foreign_key :ci_builds, :ci_runners, column: :runner_id, on_delete: :nullify, validate: false
+  end
+
+  def down
+    with_lock_retries do
+      remove_foreign_key_if_exists :ci_builds, column: :runner_id
+    end
+  end
+end
diff --git a/db/migrate/20220208171826_update_default_scan_method_of_dast_site_profile.rb b/db/migrate/20220208171826_update_default_scan_method_of_dast_site_profile.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b01dbe642e223883b2459b37a434c114940a9111
--- /dev/null
+++ b/db/migrate/20220208171826_update_default_scan_method_of_dast_site_profile.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+# See https://docs.gitlab.com/ee/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class UpdateDefaultScanMethodOfDastSiteProfile < Gitlab::Database::Migration[1.0]
+  BATCH_SIZE = 500
+
+  disable_ddl_transaction!
+
+  def up
+    each_batch_range('dast_site_profiles', scope: ->(table) { table.where(target_type: 1) }, of: BATCH_SIZE) do |min, max|
+      execute <<~SQL
+        UPDATE dast_site_profiles
+        SET scan_method = 1
+        WHERE id BETWEEN #{min} AND #{max}
+      SQL
+    end
+  end
+
+  def down
+    # noop
+  end
+end
diff --git a/db/migrate/20220211090920_cleanup_populate_topics_non_private_projects_count.rb b/db/migrate/20220211090920_cleanup_populate_topics_non_private_projects_count.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5ab8feb2195125aa108d02a69348c112ee5c37cc
--- /dev/null
+++ b/db/migrate/20220211090920_cleanup_populate_topics_non_private_projects_count.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class CleanupPopulateTopicsNonPrivateProjectsCount < Gitlab::Database::Migration[1.0]
+  MIGRATION = 'PopulateTopicsNonPrivateProjectsCount'
+
+  disable_ddl_transaction!
+
+  def up
+    finalize_background_migration(MIGRATION)
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/migrate/20220211125954_create_related_epic_links.rb b/db/migrate/20220211125954_create_related_epic_links.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c06a68a9dd2a12ff7a1a43729e4ab4f43aab490e
--- /dev/null
+++ b/db/migrate/20220211125954_create_related_epic_links.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class CreateRelatedEpicLinks < Gitlab::Database::Migration[1.0]
+  def up
+    create_table :related_epic_links do |t|
+      t.references :source, index: true, foreign_key: { to_table: :epics, on_delete: :cascade }, null: false
+      t.references :target, index: true, foreign_key: { to_table: :epics, on_delete: :cascade }, null: false
+      t.timestamps_with_timezone null: false
+      t.integer :link_type, null: false, default: 0, limit: 2
+
+      t.index [:source_id, :target_id], unique: true
+    end
+  end
+
+  def down
+    drop_table :related_epic_links
+  end
+end
diff --git a/db/migrate/20220211214605_update_integrations_trigger_type_new_on_insert_null_safe.rb b/db/migrate/20220211214605_update_integrations_trigger_type_new_on_insert_null_safe.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7a60ea48f402528f476adb76141a60703d807eb9
--- /dev/null
+++ b/db/migrate/20220211214605_update_integrations_trigger_type_new_on_insert_null_safe.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+class UpdateIntegrationsTriggerTypeNewOnInsertNullSafe < Gitlab::Database::Migration[1.0]
+  include Gitlab::Database::SchemaHelpers
+
+  FUNCTION_NAME = 'integrations_set_type_new'
+
+  def up
+    # Update `type_new` dynamically based on `type`, if `type_new` is null
+    # and `type` dynamically based on `type_new`, if `type` is null.
+    #
+    # The old class names are in the format `AbcService`, and the new ones `Integrations::Abc`.
+    create_trigger_function(FUNCTION_NAME, replace: true) do
+      <<~SQL.squish
+        UPDATE integrations
+           SET type_new = COALESCE(NEW.type_new, regexp_replace(NEW.type, '\\A(.+)Service\\Z', 'Integrations::\\1'))
+             , type     = COALESCE(NEW.type, regexp_replace(NEW.type_new, '\\AIntegrations::(.+)\\Z', '\\1Service'))
+        WHERE integrations.id = NEW.id;
+        RETURN NULL;
+      SQL
+    end
+  end
+
+  def down
+    # Update `type_new` dynamically based on `type`.
+    #
+    # The old class names are in the format `AbcService`, and the new ones `Integrations::Abc`.
+    create_trigger_function(FUNCTION_NAME, replace: true) do
+      <<~SQL
+        UPDATE integrations SET type_new = regexp_replace(NEW.type, '\\A(.+)Service\\Z', 'Integrations::\\1')
+        WHERE integrations.id = NEW.id;
+        RETURN NULL;
+      SQL
+    end
+  end
+end
diff --git a/db/migrate/20220213100000_remove_integration_type_triggers.rb b/db/migrate/20220213100000_remove_integration_type_triggers.rb
new file mode 100644
index 0000000000000000000000000000000000000000..137e5648125945d8b6ac70bab1909af79beb7177
--- /dev/null
+++ b/db/migrate/20220213100000_remove_integration_type_triggers.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+class RemoveIntegrationTypeTriggers < Gitlab::Database::Migration[1.0]
+  include Gitlab::Database::SchemaHelpers
+
+  FUNCTION_NAME = 'integrations_set_type_new'
+  TRIGGER_ON_INSERT_NAME = 'trigger_type_new_on_insert'
+
+  def up
+    drop_trigger(:integrations, TRIGGER_ON_INSERT_NAME)
+    drop_function(FUNCTION_NAME)
+  end
+
+  def down
+    create_trigger_function(FUNCTION_NAME, replace: true) do
+      <<~SQL.squish
+        UPDATE integrations
+           SET type_new = COALESCE(NEW.type_new, regexp_replace(NEW.type, '\\A(.+)Service\\Z', 'Integrations::\\1'))
+             , type     = COALESCE(NEW.type, regexp_replace(NEW.type_new, '\\AIntegrations::(.+)\\Z', '\\1Service'))
+        WHERE integrations.id = NEW.id;
+        RETURN NULL;
+      SQL
+    end
+
+    execute(<<~SQL)
+      CREATE TRIGGER #{TRIGGER_ON_INSERT_NAME}
+      AFTER INSERT ON integrations
+      FOR EACH ROW
+      EXECUTE FUNCTION #{FUNCTION_NAME}();
+    SQL
+  end
+end
diff --git a/db/migrate/20220215164709_update_application_settings_container_registry_exp_pol_worker_capacity_default.rb b/db/migrate/20220215164709_update_application_settings_container_registry_exp_pol_worker_capacity_default.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4b743f84c4d775cf448ccb7ef57287c6dd473d0d
--- /dev/null
+++ b/db/migrate/20220215164709_update_application_settings_container_registry_exp_pol_worker_capacity_default.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+class UpdateApplicationSettingsContainerRegistryExpPolWorkerCapacityDefault < Gitlab::Database::Migration[1.0]
+  class Settings < ActiveRecord::Base
+    self.table_name = 'application_settings'
+  end
+
+  def up
+    change_column_default(:application_settings, :container_registry_expiration_policies_worker_capacity, from: 0, to: 4)
+
+    current_settings = Settings.first
+
+    if current_settings&.container_registry_expiration_policies_worker_capacity == 0
+      current_settings.update!(container_registry_expiration_policies_worker_capacity: 4)
+    end
+  end
+
+  def down
+    change_column_default(:application_settings, :container_registry_expiration_policies_worker_capacity, from: 4, to: 0)
+  end
+end
diff --git a/db/migrate/20220216110023_create_saved_replies.rb b/db/migrate/20220216110023_create_saved_replies.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e4b6c039dee81dd2ca014008b2af271e82f94bc0
--- /dev/null
+++ b/db/migrate/20220216110023_create_saved_replies.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class CreateSavedReplies < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def up
+    create_table :saved_replies do |t|
+      t.references :user, index: false, null: false, foreign_key: { on_delete: :cascade }
+      t.timestamps_with_timezone null: false
+      t.text :name, null: false, limit: 255
+      t.text :content, null: false, limit: 10000
+
+      t.index [:user_id, :name], name: 'index_saved_replies_on_name_text_pattern_ops', unique: true, opclass: { name: :text_pattern_ops }
+    end
+  end
+
+  def down
+    drop_table :saved_replies, if_exists: true
+  end
+end
diff --git a/db/migrate/20220217100008_add_container_registry_expiration_policies_caching_to_application_settings.rb b/db/migrate/20220217100008_add_container_registry_expiration_policies_caching_to_application_settings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bd5b13ffa1c6631bda6754c9279417499b0624a6
--- /dev/null
+++ b/db/migrate/20220217100008_add_container_registry_expiration_policies_caching_to_application_settings.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddContainerRegistryExpirationPoliciesCachingToApplicationSettings < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def up
+    add_column :application_settings, :container_registry_expiration_policies_caching, :boolean, null: false, default: true
+  end
+
+  def down
+    remove_column :application_settings, :container_registry_expiration_policies_caching
+  end
+end
diff --git a/db/migrate/20220217113058_add_status_to_status_check_responses.rb b/db/migrate/20220217113058_add_status_to_status_check_responses.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2f1186778836cc870ebfaf775f34d2178f54cc6d
--- /dev/null
+++ b/db/migrate/20220217113058_add_status_to_status_check_responses.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddStatusToStatusCheckResponses < Gitlab::Database::Migration[1.0]
+  def change
+    add_column :status_check_responses, :status, :integer, default: 0, null: false, limit: 2
+  end
+end
diff --git a/db/migrate/20220221102333_change_maintainer_note_limit_in_ci_runner.rb b/db/migrate/20220221102333_change_maintainer_note_limit_in_ci_runner.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a3d71a060b86d4fb79e3626a3e5da671fa0ca985
--- /dev/null
+++ b/db/migrate/20220221102333_change_maintainer_note_limit_in_ci_runner.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class ChangeMaintainerNoteLimitInCiRunner < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    add_text_limit(
+      :ci_runners,
+      :maintainer_note,
+      1024,
+      constraint_name: check_constraint_name(:ci_runners, :maintainer_note, 'max_length_1MB')
+    )
+
+    remove_text_limit(
+      :ci_runners,
+      :maintainer_note,
+      constraint_name: check_constraint_name(:ci_runners, :maintainer_note, 'max_length')
+    )
+  end
+
+  def down
+    # no-op: Danger of failing if there are records with length(maintainer_note) > 255
+  end
+end
diff --git a/db/migrate/20220222072536_add_target_access_levels_to_broadcast_messages.rb b/db/migrate/20220222072536_add_target_access_levels_to_broadcast_messages.rb
new file mode 100644
index 0000000000000000000000000000000000000000..fd353843878e0c65cb330dee658077e838eedd70
--- /dev/null
+++ b/db/migrate/20220222072536_add_target_access_levels_to_broadcast_messages.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class AddTargetAccessLevelsToBroadcastMessages < Gitlab::Database::Migration[1.0]
+  def up
+    add_column :broadcast_messages, :target_access_levels, :integer, if_not_exists: true, array: true, null: false, default: []
+  end
+
+  def down
+    remove_column :broadcast_messages, :target_access_levels, if_exists: true
+  end
+end
diff --git a/db/migrate/20220301002101_add_security_orchestration_policy_configuration_namespace_reference.rb b/db/migrate/20220301002101_add_security_orchestration_policy_configuration_namespace_reference.rb
new file mode 100644
index 0000000000000000000000000000000000000000..42828086310e350ff8de1886b7baf16de211ba68
--- /dev/null
+++ b/db/migrate/20220301002101_add_security_orchestration_policy_configuration_namespace_reference.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class AddSecurityOrchestrationPolicyConfigurationNamespaceReference < Gitlab::Database::Migration[1.0]
+  def up
+    add_column :security_orchestration_policy_configurations, :namespace_id, :bigint
+  end
+
+  def down
+    remove_column :security_orchestration_policy_configurations, :namespace_id
+  end
+end
diff --git a/db/migrate/20220301003502_add_security_orchestration_policy_configuration_namespace_index.rb b/db/migrate/20220301003502_add_security_orchestration_policy_configuration_namespace_index.rb
new file mode 100644
index 0000000000000000000000000000000000000000..de6b36faa6588a045daf5f7f27e7b5dfc82f2b22
--- /dev/null
+++ b/db/migrate/20220301003502_add_security_orchestration_policy_configuration_namespace_index.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class AddSecurityOrchestrationPolicyConfigurationNamespaceIndex < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+  INDEX_NAME = 'partial_index_sop_configs_on_namespace_id'
+
+  def up
+    add_concurrent_index :security_orchestration_policy_configurations, :namespace_id, unique: true, name: INDEX_NAME, where: 'namespace_id IS NOT NULL'
+    add_concurrent_foreign_key :security_orchestration_policy_configurations, :namespaces, column: :namespace_id, on_delete: :cascade, reverse_lock_order: true
+
+    add_check_constraint :security_orchestration_policy_configurations,
+      "((project_id IS NULL) != (namespace_id IS NULL))",
+      :cop_configs_project_or_namespace_existence
+  end
+
+  def down
+    exec_query 'DELETE FROM security_orchestration_policy_configurations WHERE namespace_id IS NOT NULL'
+
+    remove_check_constraint :security_orchestration_policy_configurations, :cop_configs_project_or_namespace_existence
+
+    with_lock_retries do
+      remove_foreign_key_if_exists :security_orchestration_policy_configurations, column: :namespace_id
+    end
+
+    remove_concurrent_index_by_name :security_orchestration_policy_configurations, INDEX_NAME
+  end
+end
diff --git a/db/migrate/20220301091503_add_not_null_constraint_to_security_policy_configurations.rb b/db/migrate/20220301091503_add_not_null_constraint_to_security_policy_configurations.rb
new file mode 100644
index 0000000000000000000000000000000000000000..79ffcb2cbb32866dde03d34acb35aa327a1d340a
--- /dev/null
+++ b/db/migrate/20220301091503_add_not_null_constraint_to_security_policy_configurations.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class AddNotNullConstraintToSecurityPolicyConfigurations < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    change_column_null :security_orchestration_policy_configurations, :project_id, true
+  end
+
+  def down
+    exec_query 'DELETE FROM security_orchestration_policy_configurations WHERE project_id IS NULL'
+    change_column_null :security_orchestration_policy_configurations, :project_id, false
+  end
+end
diff --git a/db/migrate/20220301175104_change_security_orchestration_policy_configuration_project_index.rb b/db/migrate/20220301175104_change_security_orchestration_policy_configuration_project_index.rb
new file mode 100644
index 0000000000000000000000000000000000000000..53706d46979c8d7df7c4924a0e04a3b431babe7d
--- /dev/null
+++ b/db/migrate/20220301175104_change_security_orchestration_policy_configuration_project_index.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class ChangeSecurityOrchestrationPolicyConfigurationProjectIndex < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+  OLD_INDEX_NAME = 'index_sop_configs_on_project_id'
+  NEW_INDEX_NAME = 'partial_index_sop_configs_on_project_id'
+
+  def up
+    add_concurrent_index :security_orchestration_policy_configurations, :project_id, unique: true, name: NEW_INDEX_NAME, where: 'project_id IS NOT NULL'
+    remove_concurrent_index_by_name :security_orchestration_policy_configurations, OLD_INDEX_NAME
+  end
+
+  def down
+    add_concurrent_index :security_orchestration_policy_configurations, :project_id, unique: true, name: OLD_INDEX_NAME
+    remove_concurrent_index_by_name :security_orchestration_policy_configurations, NEW_INDEX_NAME
+  end
+end
diff --git a/db/migrate/20220301175426_create_project_build_artifacts_size_refresh.rb b/db/migrate/20220301175426_create_project_build_artifacts_size_refresh.rb
new file mode 100644
index 0000000000000000000000000000000000000000..fd01437d0454f1a8863732af5ca7b13a1ea70ca4
--- /dev/null
+++ b/db/migrate/20220301175426_create_project_build_artifacts_size_refresh.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class CreateProjectBuildArtifactsSizeRefresh < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  CREATED_STATE = 1
+
+  def change
+    create_table :project_build_artifacts_size_refreshes do |t|
+      t.references :project, index: { unique: true }, foreign_key: { on_delete: :cascade }, null: false
+      t.bigint :last_job_artifact_id, null: true
+      t.integer :state, null: false, default: CREATED_STATE, limit: 1
+      t.datetime_with_timezone :refresh_started_at, null: true
+      t.timestamps_with_timezone null: false
+
+      # We will use this index for 2 purposes:
+      # - for finding rows with state = :waiting
+      # - for finding rows with state = :running and updated_at < x.days.ago
+      #   which we can use to find jobs that were not able to complete and considered
+      #   stale so we can retry
+      t.index [:state, :updated_at], name: 'idx_build_artifacts_size_refreshes_state_updated_at'
+    end
+  end
+end
diff --git a/db/migrate/20220302110724_add_group_features_table.rb b/db/migrate/20220302110724_add_group_features_table.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9d9204afec2bd56bc642c83ac9d2e7fd7d220019
--- /dev/null
+++ b/db/migrate/20220302110724_add_group_features_table.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddGroupFeaturesTable < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def up
+    create_table :group_features, id: false do |t|
+      t.references :group, index: false, foreign_key: { to_table: :namespaces, on_delete: :cascade }, null: false
+      t.timestamps_with_timezone null: false
+      t.integer :wiki_access_level, default: Featurable::ENABLED, null: false, limit: 2
+    end
+
+    execute('ALTER TABLE group_features ADD PRIMARY KEY (group_id)')
+  end
+
+  def down
+    drop_table :group_features
+  end
+end
diff --git a/db/migrate/20220303190555_add_comment_to_deployment_approvals.rb b/db/migrate/20220303190555_add_comment_to_deployment_approvals.rb
new file mode 100644
index 0000000000000000000000000000000000000000..56b873c009acb595d84378e08ca9e4d4b7f59c51
--- /dev/null
+++ b/db/migrate/20220303190555_add_comment_to_deployment_approvals.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+class AddCommentToDeploymentApprovals < Gitlab::Database::Migration[1.0]
+  # rubocop:disable Migration/AddLimitToTextColumns
+  # limit is added in 20220303191047_add_text_limit_to_deployment_approvals_comment
+  def change
+    add_column :deployment_approvals, :comment, :text
+  end
+  # rubocop:enable Migration/AddLimitToTextColumns
+end
diff --git a/db/migrate/20220303191047_add_text_limit_to_deployment_approvals_comment.rb b/db/migrate/20220303191047_add_text_limit_to_deployment_approvals_comment.rb
new file mode 100644
index 0000000000000000000000000000000000000000..70c7f5f3a7bda440c419beed4901ad3f76a3340a
--- /dev/null
+++ b/db/migrate/20220303191047_add_text_limit_to_deployment_approvals_comment.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddTextLimitToDeploymentApprovalsComment < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    add_text_limit :deployment_approvals, :comment, 255
+  end
+
+  def down
+    remove_text_limit :deployment_approvals, :comment
+  end
+end
diff --git a/db/migrate/20220304052335_remove_not_null_contraint_on_title_from_sprints.rb b/db/migrate/20220304052335_remove_not_null_contraint_on_title_from_sprints.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f429303ab835fdcd75102b47e841225833d70608
--- /dev/null
+++ b/db/migrate/20220304052335_remove_not_null_contraint_on_title_from_sprints.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveNotNullContraintOnTitleFromSprints < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def up
+    change_column_null :sprints, :title, true
+  end
+
+  def down
+    execute <<~SQL
+      UPDATE sprints SET title = id WHERE title IS NULL
+    SQL
+
+    change_column_null :sprints, :title, false
+  end
+end
diff --git a/db/migrate/20220304061631_remove_unique_index_for_sprints_on_iterations_cadence_id_and_title.rb b/db/migrate/20220304061631_remove_unique_index_for_sprints_on_iterations_cadence_id_and_title.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8c223bbce01794f6d2d7049880466abf0517f461
--- /dev/null
+++ b/db/migrate/20220304061631_remove_unique_index_for_sprints_on_iterations_cadence_id_and_title.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveUniqueIndexForSprintsOnIterationsCadenceIdAndTitle < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_sprints_on_iterations_cadence_id_and_title'
+
+  def up
+    remove_concurrent_index_by_name :sprints, INDEX_NAME
+  end
+
+  def down
+    add_concurrent_index :sprints, [:iterations_cadence_id, :title], name: INDEX_NAME, unique: true
+  end
+end
diff --git a/db/migrate/20220304062107_remove_unique_index_for_sprints_on_project_id_and_title.rb b/db/migrate/20220304062107_remove_unique_index_for_sprints_on_project_id_and_title.rb
new file mode 100644
index 0000000000000000000000000000000000000000..34a357bdc5c13a41e1d7b054a27881c4fa7d7b95
--- /dev/null
+++ b/db/migrate/20220304062107_remove_unique_index_for_sprints_on_project_id_and_title.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveUniqueIndexForSprintsOnProjectIdAndTitle < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_sprints_on_project_id_and_title'
+
+  def up
+    remove_concurrent_index_by_name :sprints, INDEX_NAME
+  end
+
+  def down
+    add_concurrent_index :sprints, [:project_id, :title], where: "project_id IS NOT NULL", name: INDEX_NAME, unique: true
+  end
+end
diff --git a/db/migrate/20220304152729_add_default_to_required_python_on_packages_pypi_metadata.rb b/db/migrate/20220304152729_add_default_to_required_python_on_packages_pypi_metadata.rb
new file mode 100644
index 0000000000000000000000000000000000000000..56297565cb46a47a51106d39c74135944cc47489
--- /dev/null
+++ b/db/migrate/20220304152729_add_default_to_required_python_on_packages_pypi_metadata.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class AddDefaultToRequiredPythonOnPackagesPypiMetadata < Gitlab::Database::Migration[1.0]
+  def up
+    change_column_default(:packages_pypi_metadata, :required_python, '')
+  end
+
+  def down
+    change_column_default(:packages_pypi_metadata, :required_python, nil)
+  end
+end
diff --git a/db/migrate/20220307203458_rename_user_email_lookup_limit_setting_to_search_settings.rb b/db/migrate/20220307203458_rename_user_email_lookup_limit_setting_to_search_settings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..62fe55b22f288b015e76acdb9f71a47b61557a8e
--- /dev/null
+++ b/db/migrate/20220307203458_rename_user_email_lookup_limit_setting_to_search_settings.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class RenameUserEmailLookupLimitSettingToSearchSettings < Gitlab::Database::Migration[1.0]
+  def up
+    add_column :application_settings, :search_rate_limit, :integer, null: false, default: 30
+    add_column :application_settings, :search_rate_limit_unauthenticated, :integer, null: false, default: 10
+  end
+
+  def down
+    remove_column :application_settings, :search_rate_limit
+    remove_column :application_settings, :search_rate_limit_unauthenticated
+  end
+end
diff --git a/db/migrate/20220309100648_add_time_to_restore_service_dora_metric.rb b/db/migrate/20220309100648_add_time_to_restore_service_dora_metric.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5cb49a9899aa51c770ea7b3cf9d3cdbcdaaddb2b
--- /dev/null
+++ b/db/migrate/20220309100648_add_time_to_restore_service_dora_metric.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddTimeToRestoreServiceDoraMetric < Gitlab::Database::Migration[1.0]
+  def change
+    add_column :dora_daily_metrics, :time_to_restore_service_in_seconds, :integer
+  end
+end
diff --git a/db/migrate/20220310011530_add_database_grafana_config_to_application_settings.rb b/db/migrate/20220310011530_add_database_grafana_config_to_application_settings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7752fbba12ffac16ed2a8e494977fae58333670a
--- /dev/null
+++ b/db/migrate/20220310011530_add_database_grafana_config_to_application_settings.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddDatabaseGrafanaConfigToApplicationSettings < Gitlab::Database::Migration[1.0]
+  # rubocop:disable Migration/AddLimitToTextColumns
+  # limit is added in 20220307002607_add_text_limit_to_db_reindexing_grafana_application_settings
+  def change
+    add_column :application_settings, :encrypted_database_grafana_api_key, :binary
+    add_column :application_settings, :encrypted_database_grafana_api_key_iv, :binary
+    add_column :application_settings, :database_grafana_api_url, :text
+    add_column :application_settings, :database_grafana_tag, :text
+  end
+  # rubocop:enable Migration/AddLimitToTextColumns
+end
diff --git a/db/migrate/20220310011613_add_text_limit_to_database_grafana_application_settings.rb b/db/migrate/20220310011613_add_text_limit_to_database_grafana_application_settings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..72bcf493d6e4f56f5d1551a374e37701cefb3aa8
--- /dev/null
+++ b/db/migrate/20220310011613_add_text_limit_to_database_grafana_application_settings.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddTextLimitToDatabaseGrafanaApplicationSettings < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    add_text_limit :application_settings, :database_grafana_api_url, 255
+    add_text_limit :application_settings, :database_grafana_tag, 255
+  end
+
+  def down
+    remove_text_limit :application_settings, :database_grafana_tag
+    remove_text_limit :application_settings, :database_grafana_api_url
+  end
+end
diff --git a/db/migrate/20220310101118_update_holder_name_limit.rb b/db/migrate/20220310101118_update_holder_name_limit.rb
new file mode 100644
index 0000000000000000000000000000000000000000..55eb8f75d701fd7ee5a174a44a4d6d529a608993
--- /dev/null
+++ b/db/migrate/20220310101118_update_holder_name_limit.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+# See https://docs.gitlab.com/ee/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class UpdateHolderNameLimit < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    add_text_limit :user_credit_card_validations, :holder_name, 50, constraint_name: new_constraint_name
+    remove_text_limit :user_credit_card_validations, :holder_name, constraint_name: old_constraint_name
+  end
+
+  def down
+    add_text_limit :user_credit_card_validations, :holder_name, 26, validate: false, constraint_name: old_constraint_name
+    remove_text_limit :user_credit_card_validations, :holder_name, constraint_name: new_constraint_name
+  end
+
+  private
+
+  def old_constraint_name
+    check_constraint_name(:user_credit_card_validations, :holder_name, 'max_length')
+  end
+
+  def new_constraint_name
+    check_constraint_name(:user_credit_card_validations, :holder_name, 'max_length_50')
+  end
+end
diff --git a/db/migrate/20220314094841_add_package_registry_access_level_into_project_features.rb b/db/migrate/20220314094841_add_package_registry_access_level_into_project_features.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4effdfa6a5e9b4a570bea7fe635dca86b54451cd
--- /dev/null
+++ b/db/migrate/20220314094841_add_package_registry_access_level_into_project_features.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddPackageRegistryAccessLevelIntoProjectFeatures < Gitlab::Database::Migration[1.0]
+  DISABLED = 0 # ProjectFeature::DISABLED
+
+  def up
+    add_column :project_features, :package_registry_access_level, :integer, default: DISABLED, null: false
+  end
+
+  def down
+    remove_column :project_features, :package_registry_access_level
+  end
+end
diff --git a/db/migrate/20220314184009_create_protected_environment_approval_rules.rb b/db/migrate/20220314184009_create_protected_environment_approval_rules.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f0db2c004ed8f5eece1b3230af1b1e1f1b08c562
--- /dev/null
+++ b/db/migrate/20220314184009_create_protected_environment_approval_rules.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+class CreateProtectedEnvironmentApprovalRules < Gitlab::Database::Migration[1.0]
+  def up
+    create_table :protected_environment_approval_rules do |t|
+      t.references :protected_environment,
+                   index: { name: :index_approval_rule_on_protected_environment_id },
+                   foreign_key: { to_table: :protected_environments, on_delete: :cascade },
+                   null: false
+
+      t.bigint :user_id
+      t.bigint :group_id
+      t.timestamps_with_timezone null: false
+      t.integer :access_level, limit: 2
+      t.integer :required_approvals, null: false, limit: 2
+
+      t.index :user_id
+      t.index :group_id
+
+      t.check_constraint "((access_level IS NOT NULL) AND (group_id IS NULL) AND (user_id IS NULL)) OR " \
+                         "((user_id IS NOT NULL) AND (access_level IS NULL) AND (group_id IS NULL)) OR " \
+                         "((group_id IS NOT NULL) AND (user_id IS NULL) AND (access_level IS NULL))"
+      t.check_constraint "required_approvals > 0"
+    end
+  end
+
+  def down
+    drop_table :protected_environment_approval_rules
+  end
+end
diff --git a/db/post_migrate/20211202145237_add_todos_project_and_id_index.rb b/db/post_migrate/20211202145237_add_todos_project_and_id_index.rb
new file mode 100644
index 0000000000000000000000000000000000000000..69f7822c05799699751a63923cb44ff188a63805
--- /dev/null
+++ b/db/post_migrate/20211202145237_add_todos_project_and_id_index.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+# See https://docs.gitlab.com/ee/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class AddTodosProjectAndIdIndex < Gitlab::Database::Migration[1.0]
+  # When using the methods "add_concurrent_index" or "remove_concurrent_index"
+  # you must disable the use of transactions
+  # as these methods can not run in an existing transaction.
+  # When using "add_concurrent_index" or "remove_concurrent_index" methods make sure
+  # that either of them is the _only_ method called in the migration,
+  # any other changes should go in a separate migration.
+  # This ensures that upon failure _only_ the index creation or removing fails
+  # and can be retried or reverted easily.
+  #
+  # To disable transactions uncomment the following line and remove these
+  # comments:
+  disable_ddl_transaction!
+
+  NEW_INDEX_NAME = 'index_todos_on_project_id_and_id'
+  OLD_INDEX_NAME = 'index_todos_on_project_id'
+
+  def up
+    add_concurrent_index :todos, [:project_id, :id], name: NEW_INDEX_NAME
+    remove_concurrent_index_by_name :todos, OLD_INDEX_NAME
+  end
+
+  def down
+    add_concurrent_index :todos, :project_id, name: OLD_INDEX_NAME
+    remove_concurrent_index_by_name :todos, NEW_INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20211203091642_add_index_to_projects_on_marked_for_deletion_at.rb b/db/post_migrate/20211203091642_add_index_to_projects_on_marked_for_deletion_at.rb
new file mode 100644
index 0000000000000000000000000000000000000000..56b0df1f39300c6d0dea0ff5a50ded1a53d2a5d4
--- /dev/null
+++ b/db/post_migrate/20211203091642_add_index_to_projects_on_marked_for_deletion_at.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddIndexToProjectsOnMarkedForDeletionAt < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_projects_not_aimed_for_deletion'
+
+  def up
+    add_concurrent_index :projects, :id, where: 'marked_for_deletion_at IS NULL', name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index :projects, :id, name: INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20211206073851_create_calendar_events_index_synchronously.rb b/db/post_migrate/20211206073851_create_calendar_events_index_synchronously.rb
new file mode 100644
index 0000000000000000000000000000000000000000..020dceac0049093ebb0357eb603e8bc226af5be0
--- /dev/null
+++ b/db/post_migrate/20211206073851_create_calendar_events_index_synchronously.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class CreateCalendarEventsIndexSynchronously < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_events_author_id_project_id_action_target_type_created_at'
+
+  def up
+    add_concurrent_index :events, [:author_id, :project_id, :action, :target_type, :created_at], name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :events, INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20211206074547_remove_old_calendar_events_index.rb b/db/post_migrate/20211206074547_remove_old_calendar_events_index.rb
new file mode 100644
index 0000000000000000000000000000000000000000..51460a9dc95f13b4390236de113f3e998b02d11e
--- /dev/null
+++ b/db/post_migrate/20211206074547_remove_old_calendar_events_index.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+# See https://docs.gitlab.com/ee/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class RemoveOldCalendarEventsIndex < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  OLD_INDEX_NAME = 'index_events_on_author_id_and_project_id'
+
+  def up
+    remove_concurrent_index_by_name :events, OLD_INDEX_NAME
+  end
+
+  def down
+    add_concurrent_index :events, [:author_id, :project_id], name: OLD_INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20211206161271_add_indexes_for_primary_email_cleanup_migration.rb b/db/post_migrate/20211206161271_add_indexes_for_primary_email_cleanup_migration.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0e370dfc5f83a9027d94f2e325b4ccaa40b8f78a
--- /dev/null
+++ b/db/post_migrate/20211206161271_add_indexes_for_primary_email_cleanup_migration.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+class AddIndexesForPrimaryEmailCleanupMigration < Gitlab::Database::Migration[1.0]
+  USERS_INDEX = :index_users_on_id_for_primary_email_migration
+  EMAIL_INDEX = :index_emails_on_email_user_id
+
+  disable_ddl_transaction!
+
+  def up
+    unless index_exists_by_name?(:users, USERS_INDEX)
+
+      disable_statement_timeout do
+        execute <<~SQL
+        CREATE INDEX CONCURRENTLY #{USERS_INDEX}
+        ON users (id) INCLUDE (email, confirmed_at)
+        WHERE confirmed_at IS NOT NULL
+        SQL
+      end
+    end
+
+    add_concurrent_index :emails, [:email, :user_id], name: EMAIL_INDEX
+  end
+
+  def down
+    remove_concurrent_index_by_name :users, USERS_INDEX
+    remove_concurrent_index_by_name :emails, EMAIL_INDEX
+  end
+end
diff --git a/db/post_migrate/20211207081708_add_index_ci_job_artifacts_project_id_file_type.rb b/db/post_migrate/20211207081708_add_index_ci_job_artifacts_project_id_file_type.rb
new file mode 100644
index 0000000000000000000000000000000000000000..959bf61a6cc41fc8b3f6d170c65c5d289b5c64d3
--- /dev/null
+++ b/db/post_migrate/20211207081708_add_index_ci_job_artifacts_project_id_file_type.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddIndexCiJobArtifactsProjectIdFileType < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_ci_job_artifacts_on_id_project_id_and_file_type'
+
+  def up
+    add_concurrent_index :ci_job_artifacts, [:project_id, :file_type, :id], name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :ci_job_artifacts, INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20211207090503_cleanup_first_mentioned_in_commit_jobs.rb b/db/post_migrate/20211207090503_cleanup_first_mentioned_in_commit_jobs.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3788a680fb68db1fc38b675f5c8a0419c2123958
--- /dev/null
+++ b/db/post_migrate/20211207090503_cleanup_first_mentioned_in_commit_jobs.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class CleanupFirstMentionedInCommitJobs < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  MIGRATION = 'FixFirstMentionedInCommitAt'
+  INDEX_NAME = 'index_issue_metrics_first_mentioned_in_commit'
+
+  def up
+    finalize_background_migration(MIGRATION)
+
+    remove_concurrent_index_by_name :issue_metrics, name: INDEX_NAME
+  end
+
+  def down
+    # Handles reported schema inconsistencies (column with or without timezone)
+    # We did the same in db/post_migrate/20211004110500_add_temporary_index_to_issue_metrics.rb
+    condition = Gitlab::BackgroundMigration::FixFirstMentionedInCommitAt::TmpIssueMetrics
+      .first_mentioned_in_commit_at_condition
+    add_concurrent_index :issue_metrics, :issue_id, where: condition, name: INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid.rb b/db/post_migrate/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid.rb
new file mode 100644
index 0000000000000000000000000000000000000000..cc37f2dc65d7a7964a344b341e250312f23e3657
--- /dev/null
+++ b/db/post_migrate/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class RemoveJobsForRecalculateVulnerabilitiesOccurrencesUuid < Gitlab::Database::Migration[1.0]
+  MIGRATION_NAME = 'RecalculateVulnerabilitiesOccurrencesUuid'
+
+  def up
+    delete_job_tracking(
+      MIGRATION_NAME,
+      status: %w[pending succeeded]
+    )
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4.rb b/db/post_migrate/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4.rb
new file mode 100644
index 0000000000000000000000000000000000000000..13abf8b5540d91caa76064335bb3b9caa8e8e821
--- /dev/null
+++ b/db/post_migrate/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+class ScheduleRecalculateUuidOnVulnerabilitiesOccurrences4 < Gitlab::Database::Migration[1.0]
+  MIGRATION = 'RecalculateVulnerabilitiesOccurrencesUuid'
+  DELAY_INTERVAL = 2.minutes.to_i
+  BATCH_SIZE = 2_500
+
+  disable_ddl_transaction!
+
+  def up
+    # Make sure the migration removing Findings with attributes for which UUID would be identical
+    # has finished
+    # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74008
+    Gitlab::BackgroundMigration.steal('RemoveOccurrencePipelinesAndDuplicateVulnerabilitiesFindings')
+
+    queue_background_migration_jobs_by_range_at_intervals(
+      define_batchable_model('vulnerability_occurrences'),
+      MIGRATION,
+      DELAY_INTERVAL,
+      batch_size: BATCH_SIZE,
+      track_jobs: true
+    )
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20211207173510_remove_extra_finding_evidence_tables_foreign_keys.rb b/db/post_migrate/20211207173510_remove_extra_finding_evidence_tables_foreign_keys.rb
new file mode 100644
index 0000000000000000000000000000000000000000..eaf07abe29d1198aa613c7e77eb22cafcc1519b8
--- /dev/null
+++ b/db/post_migrate/20211207173510_remove_extra_finding_evidence_tables_foreign_keys.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+class RemoveExtraFindingEvidenceTablesForeignKeys < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    with_lock_retries do
+      remove_foreign_key :vulnerability_finding_evidence_assets, :vulnerability_finding_evidences
+      remove_foreign_key :vulnerability_finding_evidence_headers, :vulnerability_finding_evidence_requests
+      remove_foreign_key :vulnerability_finding_evidence_headers, :vulnerability_finding_evidence_responses
+      remove_foreign_key :vulnerability_finding_evidence_requests, :vulnerability_finding_evidences
+      remove_foreign_key :vulnerability_finding_evidence_requests, :vulnerability_finding_evidence_supporting_messages
+      remove_foreign_key :vulnerability_finding_evidence_responses, :vulnerability_finding_evidences
+      remove_foreign_key :vulnerability_finding_evidence_responses, :vulnerability_finding_evidence_supporting_messages
+      remove_foreign_key :vulnerability_finding_evidence_sources, :vulnerability_finding_evidences
+      remove_foreign_key :vulnerability_finding_evidence_supporting_messages, :vulnerability_finding_evidences
+    end
+  end
+
+  def down
+    with_lock_retries do
+      add_foreign_key :vulnerability_finding_evidence_assets, :vulnerability_finding_evidences, on_delete: :cascade
+    end
+
+    with_lock_retries do
+      add_foreign_key :vulnerability_finding_evidence_headers, :vulnerability_finding_evidence_requests, on_delete: :cascade
+    end
+
+    with_lock_retries do
+      add_foreign_key :vulnerability_finding_evidence_headers, :vulnerability_finding_evidence_responses, on_delete: :cascade
+    end
+
+    with_lock_retries do
+      add_foreign_key :vulnerability_finding_evidence_requests, :vulnerability_finding_evidences, on_delete: :cascade
+    end
+
+    with_lock_retries do
+      add_foreign_key :vulnerability_finding_evidence_requests, :vulnerability_finding_evidence_supporting_messages, on_delete: :cascade
+    end
+
+    with_lock_retries do
+      add_foreign_key :vulnerability_finding_evidence_responses, :vulnerability_finding_evidences, on_delete: :cascade
+    end
+
+    with_lock_retries do
+      add_foreign_key :vulnerability_finding_evidence_responses, :vulnerability_finding_evidence_supporting_messages, on_delete: :cascade
+    end
+
+    with_lock_retries do
+      add_foreign_key :vulnerability_finding_evidence_sources, :vulnerability_finding_evidences, on_delete: :cascade
+    end
+
+    with_lock_retries do
+      add_foreign_key :vulnerability_finding_evidence_supporting_messages, :vulnerability_finding_evidences, on_delete: :cascade
+    end
+  end
+end
diff --git a/db/post_migrate/20211207173511_remove_extra_finding_evidence_tables.rb b/db/post_migrate/20211207173511_remove_extra_finding_evidence_tables.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9a246a8c707d4bef8e5c529344c4daad4a76ff22
--- /dev/null
+++ b/db/post_migrate/20211207173511_remove_extra_finding_evidence_tables.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+class RemoveExtraFindingEvidenceTables < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    with_lock_retries do
+      drop_table :vulnerability_finding_evidence_assets, if_exists: true
+      drop_table :vulnerability_finding_evidence_headers, if_exists: true
+      drop_table :vulnerability_finding_evidence_requests, if_exists: true
+      drop_table :vulnerability_finding_evidence_responses, if_exists: true
+      drop_table :vulnerability_finding_evidence_sources, if_exists: true
+      drop_table :vulnerability_finding_evidence_supporting_messages, if_exists: true
+    end
+  end
+
+  def down
+    create_table :vulnerability_finding_evidence_assets, if_not_exists: true do |t|
+      t.timestamps_with_timezone null: false
+
+      t.references :vulnerability_finding_evidence, index: { name: 'finding_evidence_assets_on_finding_evidence_id' }, null: false
+      t.text :type, limit: 2048
+      t.text :name, limit: 2048
+      t.text :url, limit: 2048
+    end
+
+    create_table :vulnerability_finding_evidence_sources, if_not_exists: true do |t|
+      t.timestamps_with_timezone null: false
+
+      t.references :vulnerability_finding_evidence, index: { name: 'finding_evidence_sources_on_finding_evidence_id' }, null: false
+      t.text :name, limit: 2048
+      t.text :url, limit: 2048
+    end
+
+    create_table :vulnerability_finding_evidence_supporting_messages, if_not_exists: true do |t|
+      t.timestamps_with_timezone null: false
+
+      t.references :vulnerability_finding_evidence, index: { name: 'finding_evidence_supporting_messages_on_finding_evidence_id' }, null: false
+      t.text :name, limit: 2048
+    end
+
+    create_table :vulnerability_finding_evidence_requests, if_not_exists: true do |t|
+      t.timestamps_with_timezone null: false
+
+      t.references :vulnerability_finding_evidence, index: { name: 'finding_evidence_requests_on_finding_evidence_id' }, null: true
+      t.text :method, limit: 32
+      t.text :url, limit: 2048
+      t.text :body, limit: 2048
+      t.references :vulnerability_finding_evidence_supporting_message, index: { name: 'finding_evidence_requests_on_supporting_evidence_id' }, null: true
+    end
+
+    create_table :vulnerability_finding_evidence_responses, if_not_exists: true do |t|
+      t.timestamps_with_timezone null: false
+
+      t.references :vulnerability_finding_evidence, index: { name: 'finding_evidence_responses_on_finding_evidences_id' }, null: true
+      t.integer :status_code
+      t.text :reason_phrase, limit: 2048
+      t.text :body, limit: 2048
+      t.references :vulnerability_finding_evidence_supporting_message, index: { name: 'finding_evidence_responses_on_supporting_evidence_id' }, null: true
+    end
+
+    create_table :vulnerability_finding_evidence_headers, if_not_exists: true do |t|
+      t.timestamps_with_timezone null: false
+
+      t.references :vulnerability_finding_evidence_request, index: { name: 'finding_evidence_header_on_finding_evidence_request_id' }, null: true
+      t.references :vulnerability_finding_evidence_response, index: { name: 'finding_evidence_header_on_finding_evidence_response_id' }, null: true
+      t.text :name, null: false, limit: 255
+      t.text :value, null: false, limit: 8192
+    end
+  end
+end
diff --git a/db/post_migrate/20211208122200_schedule_backfill_ci_namespace_mirrors.rb b/db/post_migrate/20211208122200_schedule_backfill_ci_namespace_mirrors.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e42b74748d7daf2599da331f5d39fbf96a3a827d
--- /dev/null
+++ b/db/post_migrate/20211208122200_schedule_backfill_ci_namespace_mirrors.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class ScheduleBackfillCiNamespaceMirrors < Gitlab::Database::Migration[1.0]
+  def up
+    # no-op
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20211208122201_schedule_backfill_ci_project_mirrors.rb b/db/post_migrate/20211208122201_schedule_backfill_ci_project_mirrors.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2a58eda040e2ae3344bf602913bdbb9d1ad04397
--- /dev/null
+++ b/db/post_migrate/20211208122201_schedule_backfill_ci_project_mirrors.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class ScheduleBackfillCiProjectMirrors < Gitlab::Database::Migration[1.0]
+  def up
+    # no-op
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20211208171402_reschedule_recalculate_vulnerability_finding_signatures_for_findings.rb b/db/post_migrate/20211208171402_reschedule_recalculate_vulnerability_finding_signatures_for_findings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8eee082809b8e320920ec104367536b0b9f92f3d
--- /dev/null
+++ b/db/post_migrate/20211208171402_reschedule_recalculate_vulnerability_finding_signatures_for_findings.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class RescheduleRecalculateVulnerabilityFindingSignaturesForFindings < Gitlab::Database::Migration[1.0]
+  MIGRATION = 'RecalculateVulnerabilityFindingSignaturesForFindings'
+  BATCH_SIZE = 1_000
+  DELAY_INTERVAL = 2.minutes
+
+  disable_ddl_transaction!
+
+  # Due to production incident previous migration was orphaned and must be rescheduled,
+  # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72919#note_741188600
+  def up
+    return unless Gitlab.ee?
+
+    delete_queued_jobs(MIGRATION)
+
+    requeue_background_migration_jobs_by_range_at_intervals(
+      MIGRATION,
+      DELAY_INTERVAL,
+      batch_size: BATCH_SIZE
+    )
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20211209093636_track_ci_job_artifacts_deletes.rb b/db/post_migrate/20211209093636_track_ci_job_artifacts_deletes.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8c95c76d1fef41d55790271ad3bcb405550fc6cd
--- /dev/null
+++ b/db/post_migrate/20211209093636_track_ci_job_artifacts_deletes.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class TrackCiJobArtifactsDeletes < Gitlab::Database::Migration[1.0]
+  include Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers
+
+  enable_lock_retries!
+
+  def up
+    track_record_deletions(:ci_job_artifacts)
+  end
+
+  def down
+    untrack_record_deletions(:ci_job_artifacts)
+  end
+end
diff --git a/db/post_migrate/20211209093828_track_users_deletes.rb b/db/post_migrate/20211209093828_track_users_deletes.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e25a8a36cb2b34497d291cf0509a9a0b91cfeaf0
--- /dev/null
+++ b/db/post_migrate/20211209093828_track_users_deletes.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class TrackUsersDeletes < Gitlab::Database::Migration[1.0]
+  include Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers
+
+  enable_lock_retries!
+
+  def up
+    track_record_deletions(:users)
+  end
+
+  def down
+    untrack_record_deletions(:users)
+  end
+end
diff --git a/db/post_migrate/20211209093923_track_external_pull_requests_deletes.rb b/db/post_migrate/20211209093923_track_external_pull_requests_deletes.rb
new file mode 100644
index 0000000000000000000000000000000000000000..cd8a6baf407507577718550e47e6aa0dc77a43ce
--- /dev/null
+++ b/db/post_migrate/20211209093923_track_external_pull_requests_deletes.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class TrackExternalPullRequestsDeletes < Gitlab::Database::Migration[1.0]
+  include Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers
+
+  enable_lock_retries!
+
+  def up
+    track_record_deletions(:external_pull_requests)
+  end
+
+  def down
+    untrack_record_deletions(:external_pull_requests)
+  end
+end
diff --git a/db/post_migrate/20211209094222_track_merge_requests_deletes.rb b/db/post_migrate/20211209094222_track_merge_requests_deletes.rb
new file mode 100644
index 0000000000000000000000000000000000000000..51007082e9ee5bb368a8037338a261e0847fc285
--- /dev/null
+++ b/db/post_migrate/20211209094222_track_merge_requests_deletes.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class TrackMergeRequestsDeletes < Gitlab::Database::Migration[1.0]
+  include Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers
+
+  enable_lock_retries!
+
+  def up
+    track_record_deletions(:merge_requests)
+  end
+
+  def down
+    untrack_record_deletions(:merge_requests)
+  end
+end
diff --git a/db/post_migrate/20211209103048_backfill_project_namespaces_for_group.rb b/db/post_migrate/20211209103048_backfill_project_namespaces_for_group.rb
new file mode 100644
index 0000000000000000000000000000000000000000..44dffc798d3817cc2f111bd6d72740a2b8389323
--- /dev/null
+++ b/db/post_migrate/20211209103048_backfill_project_namespaces_for_group.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+class BackfillProjectNamespacesForGroup < Gitlab::Database::Migration[1.0]
+  MIGRATION = 'ProjectNamespaces::BackfillProjectNamespaces'
+  DELAY_INTERVAL = 2.minutes
+  GROUP_ID = 9970 # picking gitlab-org group.
+
+  disable_ddl_transaction!
+
+  def up
+    return unless Gitlab.com? || Gitlab.staging?
+
+    projects_table = ::Gitlab::BackgroundMigration::ProjectNamespaces::Models::Project.arel_table
+    hierarchy_cte_sql = Arel.sql(::Gitlab::BackgroundMigration::ProjectNamespaces::BackfillProjectNamespaces.hierarchy_cte(GROUP_ID))
+    group_projects = ::Gitlab::BackgroundMigration::ProjectNamespaces::Models::Project.where(projects_table[:namespace_id].in(hierarchy_cte_sql))
+
+    min_id = group_projects.minimum(:id)
+    max_id = group_projects.maximum(:id)
+
+    return if min_id.blank? || max_id.blank?
+
+    queue_batched_background_migration(
+      MIGRATION,
+      :projects,
+      :id,
+      GROUP_ID,
+      'up',
+      job_interval: DELAY_INTERVAL,
+      batch_min_value: min_id,
+      batch_max_value: max_id,
+      sub_batch_size: 25,
+      batch_class_name: 'BackfillProjectNamespacePerGroupBatchingStrategy'
+    )
+  end
+
+  def down
+    return unless Gitlab.com? || Gitlab.staging?
+
+    delete_batched_background_migration(MIGRATION, :projects, :id, [GROUP_ID, 'up'])
+  end
+end
diff --git a/db/post_migrate/20211209203820_add_tmp_index_on_report_type.rb b/db/post_migrate/20211209203820_add_tmp_index_on_report_type.rb
new file mode 100644
index 0000000000000000000000000000000000000000..07a2c079511b558b677b037aa36cabafa920368b
--- /dev/null
+++ b/db/post_migrate/20211209203820_add_tmp_index_on_report_type.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+class AddTmpIndexOnReportType < Gitlab::Database::Migration[1.0]
+  # Temporary index to perform migration fixing invalid vulnerability_occurrences.raw_metadata rows
+  # Will be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/349605
+  INDEX_NAME = 'tmp_idx_vulnerability_occurrences_on_id_where_report_type_7_99'
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :vulnerability_occurrences, :id, where: 'report_type IN (7, 99)', name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :vulnerability_occurrences, INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20211209203821_convert_stringified_raw_metadata_hash_to_json.rb b/db/post_migrate/20211209203821_convert_stringified_raw_metadata_hash_to_json.rb
new file mode 100644
index 0000000000000000000000000000000000000000..757cbf60d4d911ef103ffe34fc9a22788b76a3cf
--- /dev/null
+++ b/db/post_migrate/20211209203821_convert_stringified_raw_metadata_hash_to_json.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+class ConvertStringifiedRawMetadataHashToJson < Gitlab::Database::Migration[1.0]
+  MIGRATION_CLASS = Gitlab::BackgroundMigration::FixVulnerabilityOccurrencesWithHashesAsRawMetadata
+  MODEL_CLASS = MIGRATION_CLASS::Finding
+  DELAY_INTERVAL = 2.minutes
+  BATCH_SIZE = 500
+
+  disable_ddl_transaction!
+
+  def up
+    queue_background_migration_jobs_by_range_at_intervals(
+      MODEL_CLASS.by_api_report_types,
+      MIGRATION_CLASS,
+      DELAY_INTERVAL,
+      batch_size: BATCH_SIZE
+    )
+  end
+
+  def down
+    # no-op
+
+    # up fixes invalid data by updating columns in-place.
+    # It is a backwards-compatible change, and reversing it in a downgrade would not be desirable.
+  end
+end
diff --git a/db/post_migrate/20211210140000_add_temporary_static_object_token_index.rb b/db/post_migrate/20211210140000_add_temporary_static_object_token_index.rb
new file mode 100644
index 0000000000000000000000000000000000000000..54997dc4cc4b492f44efa819889e76f9dc658f43
--- /dev/null
+++ b/db/post_migrate/20211210140000_add_temporary_static_object_token_index.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddTemporaryStaticObjectTokenIndex < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_users_with_static_object_token'
+
+  def up
+    add_concurrent_index :users, :id, where: "static_object_token IS NOT NULL AND static_object_token_encrypted IS NULL", name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index :users, :id, name: INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20211210140629_encrypt_static_object_token.rb b/db/post_migrate/20211210140629_encrypt_static_object_token.rb
new file mode 100644
index 0000000000000000000000000000000000000000..fe4db9fc14ce58a6e45430ebddec84eb97f62cf4
--- /dev/null
+++ b/db/post_migrate/20211210140629_encrypt_static_object_token.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class EncryptStaticObjectToken < Gitlab::Database::Migration[1.0]
+  BATCH_SIZE = 10_000
+  MIGRATION = 'EncryptStaticObjectToken'
+
+  disable_ddl_transaction!
+
+  def up
+    queue_background_migration_jobs_by_range_at_intervals(
+      define_batchable_model('users').where.not(static_object_token: nil).where(static_object_token_encrypted: nil),
+      MIGRATION,
+      2.minutes,
+      batch_size: BATCH_SIZE,
+      track_jobs: true
+    )
+  end
+
+  def down
+    # no ops
+  end
+end
diff --git a/db/post_migrate/20211210173137_remove_vulnerability_finding_links_again.rb b/db/post_migrate/20211210173137_remove_vulnerability_finding_links_again.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ffe8bf0d794f8ab922f04d03aef0169f67254b03
--- /dev/null
+++ b/db/post_migrate/20211210173137_remove_vulnerability_finding_links_again.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class RemoveVulnerabilityFindingLinksAgain < Gitlab::Database::Migration[1.0]
+  # This migration has been moved to a TRUNCATE in db/post_migrate/20220201193033_add_unique_index_to_vulnerability_finding_links_with_truncate.rb
+  # Previously, this was causing an bug where there was a conflict between the table cleanup and the index creation.
+
+  def up
+    # no op
+  end
+
+  def down
+    # no op
+  end
+end
diff --git a/db/post_migrate/20211213064821_add_agent_id_location_index_to_vulnerability_occurrences.rb b/db/post_migrate/20211213064821_add_agent_id_location_index_to_vulnerability_occurrences.rb
new file mode 100644
index 0000000000000000000000000000000000000000..92b5a1b085c79634a3ce41d7560d025dcff7c24c
--- /dev/null
+++ b/db/post_migrate/20211213064821_add_agent_id_location_index_to_vulnerability_occurrences.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class AddAgentIdLocationIndexToVulnerabilityOccurrences < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_vulnerability_occurrences_on_location_agent_id'
+
+  def up
+    add_concurrent_index :vulnerability_occurrences, "(location -> 'agent_id')",
+                         using: 'GIN',
+                         where: 'report_type = 7',
+                         name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :vulnerability_occurrences, INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20211213102111_drop_ci_pipelines_mr_metrics_fk.rb b/db/post_migrate/20211213102111_drop_ci_pipelines_mr_metrics_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..49f498c911d981dcca340e6d6ffc866bdd921077
--- /dev/null
+++ b/db/post_migrate/20211213102111_drop_ci_pipelines_mr_metrics_fk.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class DropCiPipelinesMrMetricsFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    with_lock_retries do
+      remove_foreign_key_if_exists(:merge_request_metrics, :ci_pipelines, name: "fk_rails_33ae169d48")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:merge_request_metrics, :ci_pipelines, name: "fk_rails_33ae169d48", column: :pipeline_id, target_column: :id, on_delete: "cascade")
+  end
+end
diff --git a/db/post_migrate/20211214012507_backfill_incident_issue_escalation_statuses.rb b/db/post_migrate/20211214012507_backfill_incident_issue_escalation_statuses.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f8239b6e0cd2ce1b56fe146007a38f6b8d6feb9f
--- /dev/null
+++ b/db/post_migrate/20211214012507_backfill_incident_issue_escalation_statuses.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class BackfillIncidentIssueEscalationStatuses < Gitlab::Database::Migration[1.0]
+  # Removed in favor of creating records for existing incidents
+  # as-needed. See db/migrate/20220321234317_remove_all_issuable_escalation_statuses.rb.
+  def change
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20211215090620_schedule_update_timelogs_null_spent_at.rb b/db/post_migrate/20211215090620_schedule_update_timelogs_null_spent_at.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5876d3f8a9ad68a30b036415c564c2488d403c10
--- /dev/null
+++ b/db/post_migrate/20211215090620_schedule_update_timelogs_null_spent_at.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class ScheduleUpdateTimelogsNullSpentAt < Gitlab::Database::Migration[1.0]
+  DOWNTIME = false
+  BATCH_SIZE = 5_000
+  DELAY_INTERVAL = 2.minutes
+  MIGRATION = 'UpdateTimelogsNullSpentAt'
+
+  disable_ddl_transaction!
+
+  def up
+    queue_background_migration_jobs_by_range_at_intervals(
+      define_batchable_model('timelogs').where(spent_at: nil),
+      MIGRATION,
+      DELAY_INTERVAL,
+      batch_size: BATCH_SIZE
+    )
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20211217120000_modify_kubernetes_resource_location_index_to_vulnerability_occurrences.rb b/db/post_migrate/20211217120000_modify_kubernetes_resource_location_index_to_vulnerability_occurrences.rb
new file mode 100644
index 0000000000000000000000000000000000000000..310a49a667e11464e35a3cd573fdbb29d06e1ba0
--- /dev/null
+++ b/db/post_migrate/20211217120000_modify_kubernetes_resource_location_index_to_vulnerability_occurrences.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+class ModifyKubernetesResourceLocationIndexToVulnerabilityOccurrences < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  OLD_CLUSTER_ID_INDEX_NAME = 'index_vulnerability_occurrences_on_location_cluster_id'
+  OLD_AGENT_ID_INDEX_NAME = 'index_vulnerability_occurrences_on_location_agent_id'
+
+  NEW_CLUSTER_ID_INDEX_NAME = 'index_vulnerability_occurrences_on_location_k8s_cluster_id'
+  NEW_AGENT_ID_INDEX_NAME = 'index_vulnerability_occurrences_on_location_k8s_agent_id'
+
+  def up
+    add_concurrent_index :vulnerability_occurrences, "(location -> 'kubernetes_resource' -> 'cluster_id')",
+                         using: 'GIN',
+                         where: 'report_type = 7',
+                         name: NEW_CLUSTER_ID_INDEX_NAME
+
+    add_concurrent_index :vulnerability_occurrences, "(location -> 'kubernetes_resource' -> 'agent_id')",
+                         using: 'GIN',
+                         where: 'report_type = 7',
+                         name: NEW_AGENT_ID_INDEX_NAME
+
+    remove_concurrent_index_by_name :vulnerability_occurrences, OLD_CLUSTER_ID_INDEX_NAME
+    remove_concurrent_index_by_name :vulnerability_occurrences, OLD_AGENT_ID_INDEX_NAME
+  end
+
+  def down
+    add_concurrent_index :vulnerability_occurrences, "(location -> 'cluster_id')",
+                         using: 'GIN',
+                         where: 'report_type = 7',
+                         name: OLD_CLUSTER_ID_INDEX_NAME
+
+    add_concurrent_index :vulnerability_occurrences, "(location -> 'agent_id')",
+                         using: 'GIN',
+                         where: 'report_type = 7',
+                         name: OLD_AGENT_ID_INDEX_NAME
+
+    remove_concurrent_index_by_name :vulnerability_occurrences, NEW_CLUSTER_ID_INDEX_NAME
+    remove_concurrent_index_by_name :vulnerability_occurrences, NEW_AGENT_ID_INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20211217145923_add_index_to_events_on_author_id_and_action_and_id.rb b/db/post_migrate/20211217145923_add_index_to_events_on_author_id_and_action_and_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a05d68279c3fdb37704ef395fe6dfc0444da8378
--- /dev/null
+++ b/db/post_migrate/20211217145923_add_index_to_events_on_author_id_and_action_and_id.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class AddIndexToEventsOnAuthorIdAndActionAndId < Gitlab::Database::Migration[1.0]
+  # no-op
+  # see: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77436
+
+  def up
+    # no-op
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20211217174331_mark_recalculate_finding_signatures_as_completed.rb b/db/post_migrate/20211217174331_mark_recalculate_finding_signatures_as_completed.rb
new file mode 100644
index 0000000000000000000000000000000000000000..316209ae1f4dd2368dfcfa1992f8a142fb0e8bd8
--- /dev/null
+++ b/db/post_migrate/20211217174331_mark_recalculate_finding_signatures_as_completed.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class MarkRecalculateFindingSignaturesAsCompleted < Gitlab::Database::Migration[1.0]
+  MIGRATION = 'RecalculateVulnerabilitiesOccurrencesUuid'
+
+  def up
+    # Only run migration for Gitlab.com
+    return unless ::Gitlab.com?
+
+    # In previous migration marking jobs as successful was missed
+    Gitlab::Database::BackgroundMigrationJob
+      .for_migration_class(MIGRATION)
+      .pending
+      .update_all(status: :succeeded)
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20211220064757_drop_temporary_indexes_for_primary_email_migration.rb b/db/post_migrate/20211220064757_drop_temporary_indexes_for_primary_email_migration.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1d61aec401eaaf64e0ac611e62c61d51261aae41
--- /dev/null
+++ b/db/post_migrate/20211220064757_drop_temporary_indexes_for_primary_email_migration.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+class DropTemporaryIndexesForPrimaryEmailMigration < Gitlab::Database::Migration[1.0]
+  USERS_INDEX = :index_users_on_id_for_primary_email_migration
+  EMAIL_INDEX = :index_emails_on_email_user_id
+
+  disable_ddl_transaction!
+
+  def up
+    remove_concurrent_index_by_name :users, USERS_INDEX
+    remove_concurrent_index_by_name :emails, EMAIL_INDEX
+  end
+
+  def down
+    unless index_exists_by_name?(:users, USERS_INDEX)
+
+      disable_statement_timeout do
+        execute <<~SQL
+        CREATE INDEX CONCURRENTLY #{USERS_INDEX}
+        ON users (id) INCLUDE (email, confirmed_at)
+        WHERE confirmed_at IS NOT NULL
+        SQL
+      end
+    end
+
+    add_concurrent_index :emails, [:email, :user_id], name: EMAIL_INDEX
+  end
+end
diff --git a/db/post_migrate/20211220120402_add_index_on_ci_pipelines_user_id_id_failure_reason.rb b/db/post_migrate/20211220120402_add_index_on_ci_pipelines_user_id_id_failure_reason.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c98d3d05f2f9c0e24423b4fc081abba6f39c4768
--- /dev/null
+++ b/db/post_migrate/20211220120402_add_index_on_ci_pipelines_user_id_id_failure_reason.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddIndexOnCiPipelinesUserIdIdFailureReason < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_ci_pipelines_on_user_id_and_id_desc_and_user_not_verified'
+
+  def up
+    add_concurrent_index :ci_pipelines, [:user_id, :id], order: { id: :desc }, where: 'failure_reason = 3', name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :ci_pipelines, INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20211220123956_update_invalid_member_states.rb b/db/post_migrate/20211220123956_update_invalid_member_states.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5da100f0ec29fd254a1a507de192c0f9fea49463
--- /dev/null
+++ b/db/post_migrate/20211220123956_update_invalid_member_states.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+class UpdateInvalidMemberStates < Gitlab::Database::Migration[1.0]
+  class Member < ActiveRecord::Base
+    include EachBatch
+
+    self.table_name = 'members'
+
+    scope :in_invalid_state, -> { where(state: 2) }
+  end
+
+  def up
+    Member.in_invalid_state.each_batch do |relation|
+      relation.update_all(state: 0)
+    end
+  end
+
+  def down
+    # no-op as we don't need to revert any changed records
+  end
+end
diff --git a/db/post_migrate/20211229023654_add_async_index_ci_job_artifacts_project_id_file_type.rb b/db/post_migrate/20211229023654_add_async_index_ci_job_artifacts_project_id_file_type.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5338cab38714f25057146e6f3f113b3c6c8590f3
--- /dev/null
+++ b/db/post_migrate/20211229023654_add_async_index_ci_job_artifacts_project_id_file_type.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddAsyncIndexCiJobArtifactsProjectIdFileType < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_ci_job_artifacts_on_id_project_id_and_file_type'
+
+  def up
+    prepare_async_index :ci_job_artifacts, [:project_id, :file_type, :id], name: INDEX_NAME
+  end
+
+  def down
+    unprepare_async_index_by_name :ci_job_artifacts, INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20211230112517_remove_index_events_on_author_id_and_action_and_id.rb b/db/post_migrate/20211230112517_remove_index_events_on_author_id_and_action_and_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2215a49e28665e314123793179a5c098819eefa8
--- /dev/null
+++ b/db/post_migrate/20211230112517_remove_index_events_on_author_id_and_action_and_id.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveIndexEventsOnAuthorIdAndActionAndId < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'index_events_on_author_id_and_action_and_id'
+
+  disable_ddl_transaction!
+
+  def up
+    remove_concurrent_index_by_name :events, name: INDEX_NAME
+  end
+
+  def down
+    # no-op
+    # The index had been added in the same milestone.
+    # Adding back the index takes a long time and should not be needed.
+  end
+end
diff --git a/db/post_migrate/20211230113031_add_index_to_events_on_author_id_and_id.rb b/db/post_migrate/20211230113031_add_index_to_events_on_author_id_and_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e4cdc9add398c9490f2c4a0b06b2848a8ae9a09d
--- /dev/null
+++ b/db/post_migrate/20211230113031_add_index_to_events_on_author_id_and_id.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddIndexToEventsOnAuthorIdAndId < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'index_events_on_author_id_and_id'
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :events, [:author_id, :id], name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :events, INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220104060049_remove_foreign_key_ci_group_variables_group_id.rb b/db/post_migrate/20220104060049_remove_foreign_key_ci_group_variables_group_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9be81e00b5000b767e372d35bcfbb2f09f57770e
--- /dev/null
+++ b/db/post_migrate/20220104060049_remove_foreign_key_ci_group_variables_group_id.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveForeignKeyCiGroupVariablesGroupId < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  CONSTRAINT_NAME = 'fk_33ae4d58d8'
+
+  def up
+    with_lock_retries do
+      remove_foreign_key_if_exists(:ci_group_variables, :namespaces, name: CONSTRAINT_NAME)
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key :ci_group_variables, :namespaces, column: :group_id, on_delete: :cascade, name: CONSTRAINT_NAME
+  end
+end
diff --git a/db/post_migrate/20220105020514_remove_ci_minutes_additional_packs_namespace_id_foreign_key_constraint.rb b/db/post_migrate/20220105020514_remove_ci_minutes_additional_packs_namespace_id_foreign_key_constraint.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b072d5616f54c8314bf412ba1b9f4d728d83af05
--- /dev/null
+++ b/db/post_migrate/20220105020514_remove_ci_minutes_additional_packs_namespace_id_foreign_key_constraint.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveCiMinutesAdditionalPacksNamespaceIdForeignKeyConstraint < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  CONSTRAINT_NAME = 'fk_rails_e0e0c4e4b1'
+
+  def up
+    with_lock_retries do
+      remove_foreign_key_if_exists(:ci_minutes_additional_packs, :namespaces, name: CONSTRAINT_NAME)
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key :ci_minutes_additional_packs, :namespaces, column: :namespace_id, on_delete: :cascade, name: CONSTRAINT_NAME
+  end
+end
diff --git a/db/post_migrate/20220106185033_remove_finding_evidence_summary.rb b/db/post_migrate/20220106185033_remove_finding_evidence_summary.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d28e8bb81f67f698cc99d847f5e5fe7e7ffc69c5
--- /dev/null
+++ b/db/post_migrate/20220106185033_remove_finding_evidence_summary.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveFindingEvidenceSummary < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    remove_column :vulnerability_finding_evidences, :summary, :text
+  end
+
+  def down
+    add_column :vulnerability_finding_evidences, :summary, :text
+
+    add_text_limit :vulnerability_finding_evidences, :summary, 8_000_000
+  end
+end
diff --git a/db/post_migrate/20220106231518_remove_foreign_key_ci_daily_build_group_report_results_group_id.rb b/db/post_migrate/20220106231518_remove_foreign_key_ci_daily_build_group_report_results_group_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ece20f8095d1839ee72c8b8d92fcdeeab1fa835c
--- /dev/null
+++ b/db/post_migrate/20220106231518_remove_foreign_key_ci_daily_build_group_report_results_group_id.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveForeignKeyCiDailyBuildGroupReportResultsGroupId < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  CONSTRAINT_NAME = 'fk_fd1858fefd'
+
+  def up
+    with_lock_retries do
+      remove_foreign_key_if_exists(:ci_daily_build_group_report_results, :namespaces, name: CONSTRAINT_NAME)
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key :ci_daily_build_group_report_results, :namespaces, column: :group_id, on_delete: :cascade, name: CONSTRAINT_NAME
+  end
+end
diff --git a/db/post_migrate/20220106233459_remove_foreign_key_ci_pending_builds_namespace_id.rb b/db/post_migrate/20220106233459_remove_foreign_key_ci_pending_builds_namespace_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1304f19708ec1fc314d623197aa7010ba7de6eb8
--- /dev/null
+++ b/db/post_migrate/20220106233459_remove_foreign_key_ci_pending_builds_namespace_id.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveForeignKeyCiPendingBuildsNamespaceId < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  CONSTRAINT_NAME = 'fk_fdc0137e4a'
+
+  def up
+    with_lock_retries do
+      remove_foreign_key_if_exists(:ci_pending_builds, :namespaces, name: CONSTRAINT_NAME)
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key :ci_pending_builds, :namespaces, column: :namespace_id, on_delete: :cascade, name: CONSTRAINT_NAME
+  end
+end
diff --git a/db/post_migrate/20220106235626_remove_foreign_key_ci_runner_namespaces_namespace_id.rb b/db/post_migrate/20220106235626_remove_foreign_key_ci_runner_namespaces_namespace_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..61ca066401e43b7687b814ee0adc9a04c99df342
--- /dev/null
+++ b/db/post_migrate/20220106235626_remove_foreign_key_ci_runner_namespaces_namespace_id.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveForeignKeyCiRunnerNamespacesNamespaceId < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  CONSTRAINT_NAME = 'fk_rails_f9d9ed3308'
+
+  def up
+    with_lock_retries do
+      remove_foreign_key_if_exists(:ci_runner_namespaces, :namespaces, name: CONSTRAINT_NAME)
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key :ci_runner_namespaces, :namespaces, column: :namespace_id, on_delete: :cascade, name: CONSTRAINT_NAME
+  end
+end
diff --git a/db/post_migrate/20220107064845_populate_vulnerability_reads.rb b/db/post_migrate/20220107064845_populate_vulnerability_reads.rb
new file mode 100644
index 0000000000000000000000000000000000000000..58826c5f929569a4dab8e6f8d6734562b3ddf913
--- /dev/null
+++ b/db/post_migrate/20220107064845_populate_vulnerability_reads.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+class PopulateVulnerabilityReads < Gitlab::Database::Migration[1.0]
+  BATCH_SIZE = 10_000
+  DELAY_INTERVAL = 2.minutes
+  MIGRATION_NAME = 'PopulateVulnerabilityReads'
+  SUB_BATCH_SIZE = 1_000
+
+  disable_ddl_transaction!
+
+  def up
+    queue_background_migration_jobs_by_range_at_intervals(
+      define_batchable_model('vulnerabilities'),
+      MIGRATION_NAME,
+      DELAY_INTERVAL,
+      batch_size: BATCH_SIZE,
+      track_jobs: true,
+      other_job_arguments: [SUB_BATCH_SIZE]
+    )
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20220109134455_add_idx_vulnerability_occurrences_dedup_again.rb b/db/post_migrate/20220109134455_add_idx_vulnerability_occurrences_dedup_again.rb
new file mode 100644
index 0000000000000000000000000000000000000000..06be8edd7074cef6ae4a1175b34db57161e84a0c
--- /dev/null
+++ b/db/post_migrate/20220109134455_add_idx_vulnerability_occurrences_dedup_again.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddIdxVulnerabilityOccurrencesDedupAgain < Gitlab::Database::Migration[1.0]
+  TABLE = :vulnerability_occurrences
+  INDEX_NAME = 'index_vulnerability_occurrences_deduplication'
+  COLUMNS = %i[project_id report_type project_fingerprint]
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index TABLE, COLUMNS, name: INDEX_NAME
+  end
+
+  def down
+    # nothing to do here
+  end
+end
diff --git a/db/post_migrate/20220110171049_schedule_populate_test_reports_issue_id.rb b/db/post_migrate/20220110171049_schedule_populate_test_reports_issue_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..dae93e1636dfc76ad90447af665603d4b0babd01
--- /dev/null
+++ b/db/post_migrate/20220110171049_schedule_populate_test_reports_issue_id.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class SchedulePopulateTestReportsIssueId < Gitlab::Database::Migration[1.0]
+  MIGRATION = 'PopulateTestReportsIssueId'
+  DELAY_INTERVAL = 2.minutes.to_i
+  BATCH_SIZE = 30
+
+  disable_ddl_transaction!
+
+  def up
+    queue_background_migration_jobs_by_range_at_intervals(
+      define_batchable_model('requirements_management_test_reports').where(issue_id: nil),
+      MIGRATION,
+      DELAY_INTERVAL,
+      batch_size: BATCH_SIZE,
+      track_jobs: true
+    )
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20220110224913_remove_dast_scanner_profiles_builds_ci_build_id_fk.rb b/db/post_migrate/20220110224913_remove_dast_scanner_profiles_builds_ci_build_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d91cd3b43ef60f15a5aec3f5270bb9b8ee54ffde
--- /dev/null
+++ b/db/post_migrate/20220110224913_remove_dast_scanner_profiles_builds_ci_build_id_fk.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class RemoveDastScannerProfilesBuildsCiBuildIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  CONSTRAINT_NAME = 'fk_e4c49200f8'
+
+  def up
+    with_lock_retries do
+      execute('LOCK ci_builds, dast_scanner_profiles_builds IN ACCESS EXCLUSIVE MODE')
+      remove_foreign_key_if_exists(:dast_scanner_profiles_builds, :ci_builds, name: CONSTRAINT_NAME)
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:dast_scanner_profiles_builds, :ci_builds, column: :ci_build_id, on_delete: :cascade, name: CONSTRAINT_NAME)
+  end
+end
diff --git a/db/post_migrate/20220110231420_remove_requirements_management_test_reports_build_id_fk.rb b/db/post_migrate/20220110231420_remove_requirements_management_test_reports_build_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..dd8c6de4aafc1f93ee1c6d975d781c6da072e570
--- /dev/null
+++ b/db/post_migrate/20220110231420_remove_requirements_management_test_reports_build_id_fk.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class RemoveRequirementsManagementTestReportsBuildIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  CONSTRAINT_NAME = 'fk_rails_e67d085910'
+
+  def up
+    with_lock_retries do
+      execute('LOCK ci_builds, requirements_management_test_reports IN ACCESS EXCLUSIVE MODE')
+      remove_foreign_key_if_exists(:requirements_management_test_reports, :ci_builds, name: CONSTRAINT_NAME)
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:requirements_management_test_reports, :ci_builds, column: :build_id, on_delete: :nullify, name: CONSTRAINT_NAME)
+  end
+end
diff --git a/db/post_migrate/20220110233155_remove_dast_site_profiles_builds_ci_build_id_fk.rb b/db/post_migrate/20220110233155_remove_dast_site_profiles_builds_ci_build_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..00d8a39216bcc6e0f73245e2a6520bdd6e4d7e2f
--- /dev/null
+++ b/db/post_migrate/20220110233155_remove_dast_site_profiles_builds_ci_build_id_fk.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class RemoveDastSiteProfilesBuildsCiBuildIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  CONSTRAINT_NAME = 'fk_a325505e99'
+
+  def up
+    with_lock_retries do
+      execute('LOCK ci_builds, dast_site_profiles_builds IN ACCESS EXCLUSIVE MODE')
+      remove_foreign_key_if_exists(:dast_site_profiles_builds, :ci_builds, name: CONSTRAINT_NAME)
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:dast_site_profiles_builds, :ci_builds, column: :ci_build_id, on_delete: :cascade, name: CONSTRAINT_NAME)
+  end
+end
diff --git a/db/post_migrate/20220111002756_remove_security_scans_build_id_fk.rb b/db/post_migrate/20220111002756_remove_security_scans_build_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..20782664f633e8f33dad8a302f09e9359aa2eabd
--- /dev/null
+++ b/db/post_migrate/20220111002756_remove_security_scans_build_id_fk.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class RemoveSecurityScansBuildIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  CONSTRAINT_NAME = 'fk_rails_4ef1e6b4c6'
+
+  def up
+    with_lock_retries do
+      execute('LOCK ci_builds, security_scans IN ACCESS EXCLUSIVE MODE')
+      remove_foreign_key_if_exists(:security_scans, :ci_builds, name: CONSTRAINT_NAME)
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:security_scans, :ci_builds, column: :build_id, on_delete: :cascade, name: CONSTRAINT_NAME)
+  end
+end
diff --git a/db/post_migrate/20220111023852_index_cluster_agent_tokens_on_status.rb b/db/post_migrate/20220111023852_index_cluster_agent_tokens_on_status.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6de0f9424e8a0c6220ae97d7792aeab970396d37
--- /dev/null
+++ b/db/post_migrate/20220111023852_index_cluster_agent_tokens_on_status.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class IndexClusterAgentTokensOnStatus < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_cluster_agent_tokens_on_agent_id_status_last_used_at'
+
+  def up
+    add_concurrent_index :cluster_agent_tokens, 'agent_id, status, last_used_at DESC NULLS LAST', name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :cluster_agent_tokens, INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220111093534_remove_index_on_auto_stop_in.rb b/db/post_migrate/20220111093534_remove_index_on_auto_stop_in.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bcb78b283765123c5749c96655478f5eac8358cf
--- /dev/null
+++ b/db/post_migrate/20220111093534_remove_index_on_auto_stop_in.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveIndexOnAutoStopIn < Gitlab::Database::Migration[1.0]
+  TABLE = :environments
+  INDEX_NAME = 'index_environments_on_auto_stop_at'
+  COLUMN = :auto_stop_at
+
+  disable_ddl_transaction!
+
+  def up
+    remove_concurrent_index TABLE, COLUMN, where: 'auto_stop_at IS NOT NULL', name: INDEX_NAME
+  end
+
+  def down
+    add_concurrent_index TABLE, COLUMN, where: 'auto_stop_at IS NOT NULL', name: INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220111101421_remove_index_on_merge_request_id.rb b/db/post_migrate/20220111101421_remove_index_on_merge_request_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..38cc259312dc8f1dc963c0c8e91c995c9cba34ae
--- /dev/null
+++ b/db/post_migrate/20220111101421_remove_index_on_merge_request_id.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveIndexOnMergeRequestId < Gitlab::Database::Migration[1.0]
+  TABLE = :merge_request_context_commits
+  INDEX_NAME = 'index_merge_request_context_commits_on_merge_request_id'
+  COLUMN = :merge_request_id
+
+  disable_ddl_transaction!
+
+  def up
+    remove_concurrent_index TABLE, COLUMN, name: INDEX_NAME
+  end
+
+  def down
+    add_concurrent_index TABLE, COLUMN, name: INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220111102314_truncate_ci_mirror_tables.rb b/db/post_migrate/20220111102314_truncate_ci_mirror_tables.rb
new file mode 100644
index 0000000000000000000000000000000000000000..795ec24f3bdb501606f3d5904f1bb33de2e131b9
--- /dev/null
+++ b/db/post_migrate/20220111102314_truncate_ci_mirror_tables.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class TruncateCiMirrorTables < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    execute('TRUNCATE TABLE ci_namespace_mirrors')
+    execute('TRUNCATE TABLE ci_project_mirrors')
+  end
+
+  def down
+    # noop
+  end
+end
diff --git a/db/post_migrate/20220111221516_remove_projects_ci_pending_builds_fk.rb b/db/post_migrate/20220111221516_remove_projects_ci_pending_builds_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bc17c125ba72ffd02bbfd4ce680efd83c223d05f
--- /dev/null
+++ b/db/post_migrate/20220111221516_remove_projects_ci_pending_builds_fk.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiPendingBuildsFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    with_lock_retries do
+      remove_foreign_key_if_exists(:ci_pending_builds, :projects, name: "fk_rails_480669c3b3")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_pending_builds, :projects, name: "fk_rails_480669c3b3", column: :project_id, target_column: :id, on_delete: "cascade")
+  end
+end
diff --git a/db/post_migrate/20220112015940_remove_projects_ci_running_builds_fk.rb b/db/post_migrate/20220112015940_remove_projects_ci_running_builds_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..79d864e2c2af2ccf06a4bf5c37cc9fd3b59528a0
--- /dev/null
+++ b/db/post_migrate/20220112015940_remove_projects_ci_running_builds_fk.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiRunningBuildsFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    with_lock_retries do
+      execute('LOCK projects, ci_running_builds IN ACCESS EXCLUSIVE MODE')
+
+      remove_foreign_key_if_exists(:ci_running_builds, :projects, name: "fk_rails_dc1d0801e8")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_running_builds, :projects, name: "fk_rails_dc1d0801e8", column: :project_id, target_column: :id, on_delete: "cascade")
+  end
+end
diff --git a/db/post_migrate/20220112090556_remove_cascade_delete_from_project_namespace_foreign_key.rb b/db/post_migrate/20220112090556_remove_cascade_delete_from_project_namespace_foreign_key.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d786c9d846a37a76d686a4e93f8f45ebea50b365
--- /dev/null
+++ b/db/post_migrate/20220112090556_remove_cascade_delete_from_project_namespace_foreign_key.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class RemoveCascadeDeleteFromProjectNamespaceForeignKey < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  TARGET_COLUMN = :project_namespace_id
+
+  def up
+    with_lock_retries do
+      remove_foreign_key_if_exists(:projects, column: TARGET_COLUMN)
+    end
+
+    add_concurrent_foreign_key(:projects, :namespaces, column: TARGET_COLUMN, on_delete: :nullify)
+  end
+
+  def down
+    with_lock_retries do
+      remove_foreign_key_if_exists(:projects, column: TARGET_COLUMN)
+    end
+
+    add_concurrent_foreign_key(:projects, :namespaces, column: TARGET_COLUMN, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220112230642_remove_projects_ci_unit_tests_project_id_fk.rb b/db/post_migrate/20220112230642_remove_projects_ci_unit_tests_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9ad90a3a7a07e8031b6b47d46e70445ff0d83493
--- /dev/null
+++ b/db/post_migrate/20220112230642_remove_projects_ci_unit_tests_project_id_fk.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiUnitTestsProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    with_lock_retries do
+      remove_foreign_key_if_exists(:ci_unit_tests, :projects, name: "fk_7a8fabf0a8")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_unit_tests, :projects, name: "fk_7a8fabf0a8", column: :project_id, target_column: :id, on_delete: "cascade")
+  end
+end
diff --git a/db/post_migrate/20220112232723_remove_projects_ci_daily_build_group_report_results_project_id_fk.rb b/db/post_migrate/20220112232723_remove_projects_ci_daily_build_group_report_results_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ad7cf2a20c9f016f1aabde805ff15db0da9a4f29
--- /dev/null
+++ b/db/post_migrate/20220112232723_remove_projects_ci_daily_build_group_report_results_project_id_fk.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiDailyBuildGroupReportResultsProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    with_lock_retries do
+      execute('LOCK projects, ci_daily_build_group_report_results IN ACCESS EXCLUSIVE MODE')
+      remove_foreign_key_if_exists(:ci_daily_build_group_report_results, :projects, name: "fk_rails_0667f7608c")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_daily_build_group_report_results, :projects, name: "fk_rails_0667f7608c", column: :project_id, target_column: :id, on_delete: "cascade")
+  end
+end
diff --git a/db/post_migrate/20220113013319_remove_projects_ci_freeze_periods_project_id_fk.rb b/db/post_migrate/20220113013319_remove_projects_ci_freeze_periods_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..13cfacdc22301b05e569a7aa2bb07597fc5c7cf8
--- /dev/null
+++ b/db/post_migrate/20220113013319_remove_projects_ci_freeze_periods_project_id_fk.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiFreezePeriodsProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    with_lock_retries do
+      remove_foreign_key_if_exists(:ci_freeze_periods, :projects, name: "fk_2e02bbd1a6")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_freeze_periods, :projects, name: "fk_2e02bbd1a6", column: :project_id, target_column: :id, on_delete: "cascade")
+  end
+end
diff --git a/db/post_migrate/20220113014438_remove_projects_ci_resource_groups_project_id_fk.rb b/db/post_migrate/20220113014438_remove_projects_ci_resource_groups_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e86dd015493245910e04be48820a17e8eb438835
--- /dev/null
+++ b/db/post_migrate/20220113014438_remove_projects_ci_resource_groups_project_id_fk.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiResourceGroupsProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    with_lock_retries do
+      remove_foreign_key_if_exists(:ci_resource_groups, :projects, name: "fk_774722d144")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_resource_groups, :projects, name: "fk_774722d144", column: :project_id, target_column: :id, on_delete: "cascade")
+  end
+end
diff --git a/db/post_migrate/20220113015830_remove_projects_ci_build_report_results_project_id_fk.rb b/db/post_migrate/20220113015830_remove_projects_ci_build_report_results_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3d2753bf9bfdcb0d41a0c5a296b8efabce8243f2
--- /dev/null
+++ b/db/post_migrate/20220113015830_remove_projects_ci_build_report_results_project_id_fk.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiBuildReportResultsProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    with_lock_retries do
+      remove_foreign_key_if_exists(:ci_build_report_results, :projects, name: "fk_rails_056d298d48")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_build_report_results, :projects, name: "fk_rails_056d298d48", column: :project_id, target_column: :id, on_delete: "cascade")
+  end
+end
diff --git a/db/post_migrate/20220113035519_remove_users_ci_job_token_project_scope_links_added_by_id_fk.rb b/db/post_migrate/20220113035519_remove_users_ci_job_token_project_scope_links_added_by_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..966286a6730910694541ed10d6c2ad20f3aec084
--- /dev/null
+++ b/db/post_migrate/20220113035519_remove_users_ci_job_token_project_scope_links_added_by_id_fk.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveUsersCiJobTokenProjectScopeLinksAddedByIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    with_lock_retries do
+      remove_foreign_key_if_exists(:ci_job_token_project_scope_links, :users, name: "fk_rails_35f7f506ce")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_job_token_project_scope_links, :users, name: "fk_rails_35f7f506ce", column: :added_by_id, target_column: :id, on_delete: :nullify)
+  end
+end
diff --git a/db/post_migrate/20220113040447_remove_users_ci_pipeline_schedules_owner_id_fk.rb b/db/post_migrate/20220113040447_remove_users_ci_pipeline_schedules_owner_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2e5d4cfd22e1feadbfe3649729b9fa0840525f4d
--- /dev/null
+++ b/db/post_migrate/20220113040447_remove_users_ci_pipeline_schedules_owner_id_fk.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveUsersCiPipelineSchedulesOwnerIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    with_lock_retries do
+      remove_foreign_key_if_exists(:ci_pipeline_schedules, :users, name: "fk_9ea99f58d2")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_pipeline_schedules, :users, name: "fk_9ea99f58d2", column: :owner_id, target_column: :id, on_delete: :nullify)
+  end
+end
diff --git a/db/post_migrate/20220113111440_schedule_fix_incorrect_max_seats_used.rb b/db/post_migrate/20220113111440_schedule_fix_incorrect_max_seats_used.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f39b026bd7701e6467047acc655b38a535177009
--- /dev/null
+++ b/db/post_migrate/20220113111440_schedule_fix_incorrect_max_seats_used.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class ScheduleFixIncorrectMaxSeatsUsed < Gitlab::Database::Migration[1.0]
+  DOWNTIME = false
+  TMP_IDX_NAME = 'tmp_gitlab_subscriptions_max_seats_used_migration'
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :gitlab_subscriptions, :id, where: "start_date >= '2021-08-02' AND start_date <= '2021-11-20' AND max_seats_used != 0 AND max_seats_used > seats_in_use AND max_seats_used > seats", name: TMP_IDX_NAME
+
+    return unless Gitlab.com?
+
+    migrate_in(1.hour, 'FixIncorrectMaxSeatsUsed')
+  end
+
+  def down
+    remove_concurrent_index_by_name :gitlab_subscriptions, TMP_IDX_NAME
+  end
+end
diff --git a/db/post_migrate/20220114105525_add_index_on_projects_path.rb b/db/post_migrate/20220114105525_add_index_on_projects_path.rb
new file mode 100644
index 0000000000000000000000000000000000000000..cef38f91b214dffc97465cbcdb73451ce813d294
--- /dev/null
+++ b/db/post_migrate/20220114105525_add_index_on_projects_path.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddIndexOnProjectsPath < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  TABLE = :projects
+  INDEX_NAME = 'index_on_projects_path'
+  COLUMN = :path
+
+  def up
+    add_concurrent_index TABLE, COLUMN, name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index TABLE, COLUMN, name: INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220116175851_add_author_index_to_design_management_versions.rb b/db/post_migrate/20220116175851_add_author_index_to_design_management_versions.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1ea89609926ef045507ec94a7b34537388ba2f4f
--- /dev/null
+++ b/db/post_migrate/20220116175851_add_author_index_to_design_management_versions.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class AddAuthorIndexToDesignManagementVersions < Gitlab::Database::Migration[1.0]
+  TABLE = :design_management_versions
+  INDEX_NAME = 'index_design_management_versions_on_author_id'
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index TABLE, :author_id, where: 'author_id IS NOT NULL', name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index TABLE, :author_id, name: INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220117034056_remove_index_cluster_agent_tokens_on_agent_id_and_last_used_at.rb b/db/post_migrate/20220117034056_remove_index_cluster_agent_tokens_on_agent_id_and_last_used_at.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5e306be016a35735b24d6c841913bb7a1a485438
--- /dev/null
+++ b/db/post_migrate/20220117034056_remove_index_cluster_agent_tokens_on_agent_id_and_last_used_at.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveIndexClusterAgentTokensOnAgentIdAndLastUsedAt < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX = 'index_cluster_agent_tokens_on_agent_id_and_last_used_at'
+
+  def up
+    remove_concurrent_index_by_name :cluster_agent_tokens, name: INDEX
+  end
+
+  def down
+    add_concurrent_index :cluster_agent_tokens, 'agent_id, last_used_at DESC NULLS LAST', name: INDEX
+  end
+end
diff --git a/db/post_migrate/20220118204039_self_managed_reschedule_recalculate_vulnerability_finding_signatures_for_findings.rb b/db/post_migrate/20220118204039_self_managed_reschedule_recalculate_vulnerability_finding_signatures_for_findings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..18f68150e4595d7338b1615c98718196f781494f
--- /dev/null
+++ b/db/post_migrate/20220118204039_self_managed_reschedule_recalculate_vulnerability_finding_signatures_for_findings.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+class SelfManagedRescheduleRecalculateVulnerabilityFindingSignaturesForFindings < Gitlab::Database::Migration[1.0]
+  MIGRATION = 'RecalculateVulnerabilityFindingSignaturesForFindings'
+  BATCH_SIZE = 1_000
+  DELAY_INTERVAL = 2.minutes
+
+  disable_ddl_transaction!
+
+  def up
+    # Only run migration for self-managed
+    return if ::Gitlab.com?
+
+    # Vulnerability Finding Signatures is an EE only feature
+    return unless Gitlab.ee?
+
+    delete_queued_jobs(MIGRATION)
+
+    requeue_background_migration_jobs_by_range_at_intervals(
+      MIGRATION,
+      DELAY_INTERVAL,
+      batch_size: BATCH_SIZE
+    )
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20220119094503_populate_audit_event_streaming_verification_token.rb b/db/post_migrate/20220119094503_populate_audit_event_streaming_verification_token.rb
new file mode 100644
index 0000000000000000000000000000000000000000..482f873739a9cdb81c9ec24e5d12eedf620393c8
--- /dev/null
+++ b/db/post_migrate/20220119094503_populate_audit_event_streaming_verification_token.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class PopulateAuditEventStreamingVerificationToken < Gitlab::Database::Migration[1.0]
+  class ExternalAuditEventDestination < ActiveRecord::Base
+    self.table_name = 'audit_events_external_audit_event_destinations'
+
+    def regenerate_verification_token
+      update!(verification_token: SecureRandom.base58(24))
+    end
+  end
+
+  def up
+    ExternalAuditEventDestination.all.each { |destination| destination.regenerate_verification_token }
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20220119141736_remove_projects_ci_pipeline_artifacts_project_id_fk.rb b/db/post_migrate/20220119141736_remove_projects_ci_pipeline_artifacts_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..59a003c8f8d299c00748499647f4822c7e632d87
--- /dev/null
+++ b/db/post_migrate/20220119141736_remove_projects_ci_pipeline_artifacts_project_id_fk.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiPipelineArtifactsProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    with_lock_retries do
+      execute('LOCK projects, ci_pipeline_artifacts IN ACCESS EXCLUSIVE MODE')
+
+      remove_foreign_key_if_exists(:ci_pipeline_artifacts, :projects, name: "fk_rails_4a70390ca6")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_pipeline_artifacts, :projects, name: "fk_rails_4a70390ca6", column: :project_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220119143130_remove_projects_ci_sources_pipelines_source_project_id_fk.rb b/db/post_migrate/20220119143130_remove_projects_ci_sources_pipelines_source_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7fe9f1c856bed095cee6d2445c60bf432d9bb6c1
--- /dev/null
+++ b/db/post_migrate/20220119143130_remove_projects_ci_sources_pipelines_source_project_id_fk.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiSourcesPipelinesSourceProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    with_lock_retries do
+      execute('LOCK projects, ci_sources_pipelines IN ACCESS EXCLUSIVE MODE')
+
+      remove_foreign_key_if_exists(:ci_sources_pipelines, :projects, name: "fk_acd9737679")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_sources_pipelines, :projects, name: "fk_acd9737679", column: :source_project_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220119144458_remove_users_ci_triggers_owner_id_fk.rb b/db/post_migrate/20220119144458_remove_users_ci_triggers_owner_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9acf53a6ea210c2912c2994591d4bab48db6b927
--- /dev/null
+++ b/db/post_migrate/20220119144458_remove_users_ci_triggers_owner_id_fk.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveUsersCiTriggersOwnerIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    with_lock_retries do
+      execute('LOCK users, ci_triggers IN ACCESS EXCLUSIVE MODE')
+
+      remove_foreign_key_if_exists(:ci_triggers, :users, name: "fk_e8e10d1964")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_triggers, :users, name: "fk_e8e10d1964", column: :owner_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220119151221_remove_merge_requests_ci_pipelines_merge_request_id_fk.rb b/db/post_migrate/20220119151221_remove_merge_requests_ci_pipelines_merge_request_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c7ced0ae3b7251fbe1ed2973544a2c452053c02d
--- /dev/null
+++ b/db/post_migrate/20220119151221_remove_merge_requests_ci_pipelines_merge_request_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveMergeRequestsCiPipelinesMergeRequestIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless foreign_key_exists?(:ci_pipelines, :merge_requests, name: "fk_a23be95014")
+
+    with_lock_retries do
+      execute('LOCK merge_requests, ci_pipelines IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_pipelines, :merge_requests, name: "fk_a23be95014")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_pipelines, :merge_requests, name: "fk_a23be95014", column: :merge_request_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220119153706_remove_ci_pipelines_merge_trains_pipeline_id_fk.rb b/db/post_migrate/20220119153706_remove_ci_pipelines_merge_trains_pipeline_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..92d68ff4fbb1451f177d048e4d2b5bafda85bc26
--- /dev/null
+++ b/db/post_migrate/20220119153706_remove_ci_pipelines_merge_trains_pipeline_id_fk.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveCiPipelinesMergeTrainsPipelineIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    with_lock_retries do
+      execute('LOCK ci_pipelines, merge_trains IN ACCESS EXCLUSIVE MODE')
+
+      remove_foreign_key_if_exists(:merge_trains, :ci_pipelines, name: "fk_rails_f90820cb08")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:merge_trains, :ci_pipelines, name: "fk_rails_f90820cb08", column: :pipeline_id, target_column: :id, on_delete: :nullify)
+  end
+end
diff --git a/db/post_migrate/20220119154442_remove_ci_pipelines_merge_requests_head_pipeline_id_fk.rb b/db/post_migrate/20220119154442_remove_ci_pipelines_merge_requests_head_pipeline_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6a978ce2ab1d3af609df45206fec730675a1822a
--- /dev/null
+++ b/db/post_migrate/20220119154442_remove_ci_pipelines_merge_requests_head_pipeline_id_fk.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveCiPipelinesMergeRequestsHeadPipelineIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    with_lock_retries do
+      execute('LOCK ci_pipelines, merge_requests IN ACCESS EXCLUSIVE MODE')
+
+      remove_foreign_key_if_exists(:merge_requests, :ci_pipelines, name: "fk_fd82eae0b9")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:merge_requests, :ci_pipelines, name: "fk_fd82eae0b9", column: :head_pipeline_id, target_column: :id, on_delete: :nullify)
+  end
+end
diff --git a/db/post_migrate/20220119193130_remove_ci_pipelines_dast_profiles_pipelines_ci_pipeline_id_fk.rb b/db/post_migrate/20220119193130_remove_ci_pipelines_dast_profiles_pipelines_ci_pipeline_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f4eedd0fa706188bb180c7778408e68a99a0af51
--- /dev/null
+++ b/db/post_migrate/20220119193130_remove_ci_pipelines_dast_profiles_pipelines_ci_pipeline_id_fk.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveCiPipelinesDastProfilesPipelinesCiPipelineIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    with_lock_retries do
+      execute('LOCK ci_pipelines, dast_profiles_pipelines IN ACCESS EXCLUSIVE MODE')
+
+      remove_foreign_key_if_exists(:dast_profiles_pipelines, :ci_pipelines, name: "fk_a60cad829d")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:dast_profiles_pipelines, :ci_pipelines, name: "fk_a60cad829d", column: :ci_pipeline_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220119201340_remove_ci_pipelines_vulnerability_statistics_latest_pipeline_id_fk.rb b/db/post_migrate/20220119201340_remove_ci_pipelines_vulnerability_statistics_latest_pipeline_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bd80767cf6afbb15df1e315f1f240354b9ca6e12
--- /dev/null
+++ b/db/post_migrate/20220119201340_remove_ci_pipelines_vulnerability_statistics_latest_pipeline_id_fk.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveCiPipelinesVulnerabilityStatisticsLatestPipelineIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    with_lock_retries do
+      execute('LOCK ci_pipelines, vulnerability_statistics IN ACCESS EXCLUSIVE MODE')
+
+      remove_foreign_key_if_exists(:vulnerability_statistics, :ci_pipelines, name: "fk_e8b13c928f")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:vulnerability_statistics, :ci_pipelines, name: "fk_e8b13c928f", column: :latest_pipeline_id, target_column: :id, on_delete: :nullify)
+  end
+end
diff --git a/db/post_migrate/20220119203119_remove_ci_pipelines_vulnerability_occurrence_pipelines_pipeline_id_fk.rb b/db/post_migrate/20220119203119_remove_ci_pipelines_vulnerability_occurrence_pipelines_pipeline_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b6397486dd04687adae2309f25954efc1b91f125
--- /dev/null
+++ b/db/post_migrate/20220119203119_remove_ci_pipelines_vulnerability_occurrence_pipelines_pipeline_id_fk.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveCiPipelinesVulnerabilityOccurrencePipelinesPipelineIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    with_lock_retries do
+      execute('LOCK ci_pipelines, vulnerability_occurrence_pipelines IN ACCESS EXCLUSIVE MODE')
+
+      remove_foreign_key_if_exists(:vulnerability_occurrence_pipelines, :ci_pipelines, name: "fk_rails_6421e35d7d")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:vulnerability_occurrence_pipelines, :ci_pipelines, name: "fk_rails_6421e35d7d", column: :pipeline_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220120094340_drop_position_from_security_findings.rb b/db/post_migrate/20220120094340_drop_position_from_security_findings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..56af346ad1bd332af1bcc0fccc8216888ffadc60
--- /dev/null
+++ b/db/post_migrate/20220120094340_drop_position_from_security_findings.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class DropPositionFromSecurityFindings < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def change
+    remove_column :security_findings, :position, :integer
+  end
+end
diff --git a/db/post_migrate/20220120123700_add_tmp_index_routes_id_for_namespaces.rb b/db/post_migrate/20220120123700_add_tmp_index_routes_id_for_namespaces.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2b8cecd0e570e66428091ee94a6afd80cd734216
--- /dev/null
+++ b/db/post_migrate/20220120123700_add_tmp_index_routes_id_for_namespaces.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddTmpIndexRoutesIdForNamespaces < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'tmp_index_for_namespace_id_migration_on_routes'
+
+  disable_ddl_transaction!
+
+  def up
+    # Temporary index to be removed in 14.9
+    # https://gitlab.com/gitlab-org/gitlab/-/issues/352353
+    add_concurrent_index :routes, :id, where: "routes.namespace_id is null and routes.source_type = 'Namespace'", name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :routes, INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220120123800_backfill_namespace_id_for_namespace_routes.rb b/db/post_migrate/20220120123800_backfill_namespace_id_for_namespace_routes.rb
new file mode 100644
index 0000000000000000000000000000000000000000..68279456ddd2bf94d843f2c5b3f06d33f63b803f
--- /dev/null
+++ b/db/post_migrate/20220120123800_backfill_namespace_id_for_namespace_routes.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class BackfillNamespaceIdForNamespaceRoutes < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  MIGRATION = 'BackfillNamespaceIdForNamespaceRoute'
+  INTERVAL = 2.minutes
+  BATCH_SIZE = 1_000
+  MAX_BATCH_SIZE = 10_000
+  SUB_BATCH_SIZE = 200
+
+  def up
+    queue_batched_background_migration(
+      MIGRATION,
+      :routes,
+      :id,
+      job_interval: INTERVAL,
+      batch_size: BATCH_SIZE,
+      max_batch_size: MAX_BATCH_SIZE,
+      sub_batch_size: SUB_BATCH_SIZE
+    )
+  end
+
+  def down
+    delete_batched_background_migration(MIGRATION, :routes, :id, [])
+  end
+end
diff --git a/db/post_migrate/20220120211832_backfill_member_namespace_id_for_group_members.rb b/db/post_migrate/20220120211832_backfill_member_namespace_id_for_group_members.rb
new file mode 100644
index 0000000000000000000000000000000000000000..279084e0fc5bb128392f87e1871957931b1f707c
--- /dev/null
+++ b/db/post_migrate/20220120211832_backfill_member_namespace_id_for_group_members.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class BackfillMemberNamespaceIdForGroupMembers < Gitlab::Database::Migration[1.0]
+  MIGRATION = 'BackfillMemberNamespaceForGroupMembers'
+  INTERVAL = 2.minutes
+  BATCH_SIZE = 1_000
+  MAX_BATCH_SIZE = 2_000
+  SUB_BATCH_SIZE = 100
+
+  disable_ddl_transaction!
+
+  def up
+    queue_batched_background_migration(
+      MIGRATION,
+      :members,
+      :id,
+      job_interval: INTERVAL,
+      batch_size: BATCH_SIZE,
+      max_batch_size: MAX_BATCH_SIZE,
+      sub_batch_size: SUB_BATCH_SIZE
+    )
+  end
+
+  def down
+    delete_batched_background_migration(MIGRATION, :members, :id, [])
+  end
+end
diff --git a/db/post_migrate/20220121214752_remove_projects_ci_stages_project_id_fk.rb b/db/post_migrate/20220121214752_remove_projects_ci_stages_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..93f0b30571ab370715915f1968c11c355f1b8210
--- /dev/null
+++ b/db/post_migrate/20220121214752_remove_projects_ci_stages_project_id_fk.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiStagesProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return if Gitlab.com? # unsafe migration, skip on GitLab.com due to https://gitlab.com/groups/gitlab-org/-/epics/7249#note_819625526
+    return unless foreign_key_exists?(:ci_stages, :projects, name: "fk_2360681d1d")
+
+    with_lock_retries do
+      execute('LOCK projects, ci_stages IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_stages, :projects, name: "fk_2360681d1d")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_stages, :projects, name: "fk_2360681d1d", column: :project_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220121214753_re_remove_projects_ci_stages_project_id_fk.rb b/db/post_migrate/20220121214753_re_remove_projects_ci_stages_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..45dec15a5a7340062a6a73a840953cc5233e9736
--- /dev/null
+++ b/db/post_migrate/20220121214753_re_remove_projects_ci_stages_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class ReRemoveProjectsCiStagesProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless foreign_key_exists?(:ci_stages, :projects, name: "fk_2360681d1d")
+
+    with_lock_retries do
+      execute('LOCK projects, ci_stages IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_stages, :projects, name: "fk_2360681d1d")
+    end
+  end
+
+  def down
+    # no-op, since the FK will be added via rollback by prior-migration
+  end
+end
diff --git a/db/post_migrate/20220121221651_remove_projects_ci_variables_project_id_fk.rb b/db/post_migrate/20220121221651_remove_projects_ci_variables_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f647d4376ac1f214b2ce864cfb857d1c04c7a0e7
--- /dev/null
+++ b/db/post_migrate/20220121221651_remove_projects_ci_variables_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiVariablesProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless foreign_key_exists?(:ci_variables, :projects, name: "fk_ada5eb64b3")
+
+    with_lock_retries do
+      execute('LOCK projects, ci_variables IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_variables, :projects, name: "fk_ada5eb64b3")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_variables, :projects, name: "fk_ada5eb64b3", column: :project_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220124130028_dedup_runner_projects.rb b/db/post_migrate/20220124130028_dedup_runner_projects.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1a4c895f1c49581dd3122607d2765515f7ce23c3
--- /dev/null
+++ b/db/post_migrate/20220124130028_dedup_runner_projects.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+class DedupRunnerProjects < Gitlab::Database::Migration[1.0]
+  TABLE_NAME = :ci_runner_projects
+  TMP_INDEX_NAME = 'tmp_unique_ci_runner_projects_by_runner_id_and_project_id'
+  OLD_INDEX_NAME = 'index_ci_runner_projects_on_runner_id_and_project_id'
+  INDEX_NAME = 'index_unique_ci_runner_projects_on_runner_id_and_project_id'
+  BATCH_SIZE = 5000
+
+  disable_ddl_transaction!
+
+  module Ci
+    class RunnerProject < ActiveRecord::Base
+      include EachBatch
+
+      self.table_name = 'ci_runner_projects'
+    end
+  end
+
+  def up
+    last_runner_project_record_id = Ci::RunnerProject.maximum(:id) || 0
+
+    # This index will disallow further duplicates while we're deduplicating the data.
+    add_concurrent_index(TABLE_NAME, [:runner_id, :project_id], where: "id > #{Integer(last_runner_project_record_id)}", unique: true, name: TMP_INDEX_NAME)
+
+    Ci::RunnerProject.each_batch(of: BATCH_SIZE) do |relation|
+      duplicated_runner_projects = Ci::RunnerProject
+        .select('COUNT(*)', :runner_id, :project_id)
+        .where('(runner_id, project_id) IN (?)', relation.select(:runner_id, :project_id))
+        .group(:runner_id, :project_id)
+        .having('COUNT(*) > 1')
+
+      duplicated_runner_projects.each do |runner_project|
+        deduplicate_item(runner_project)
+      end
+    end
+
+    add_concurrent_index(TABLE_NAME, [:runner_id, :project_id], unique: true, name: INDEX_NAME)
+    remove_concurrent_index_by_name(TABLE_NAME, TMP_INDEX_NAME)
+    remove_concurrent_index_by_name(TABLE_NAME, OLD_INDEX_NAME)
+  end
+
+  def down
+    add_concurrent_index(TABLE_NAME, [:runner_id, :project_id], name: OLD_INDEX_NAME)
+    remove_concurrent_index_by_name(TABLE_NAME, TMP_INDEX_NAME)
+    remove_concurrent_index_by_name(TABLE_NAME, INDEX_NAME)
+  end
+
+  private
+
+  def deduplicate_item(runner_project)
+    runner_projects_records = Ci::RunnerProject
+      .where(project_id: runner_project.project_id, runner_id: runner_project.runner_id)
+      .order(updated_at: :asc)
+      .to_a
+
+    attributes = {}
+    runner_projects_records.each do |runner_projects_record|
+      params = runner_projects_record.attributes.except('id')
+      attributes.merge!(params.compact)
+    end
+
+    ApplicationRecord.transaction do
+      record_to_keep = runner_projects_records.pop
+      records_to_delete = runner_projects_records
+
+      Ci::RunnerProject.where(id: records_to_delete.map(&:id)).delete_all
+      record_to_keep.update!(attributes)
+    end
+  end
+end
diff --git a/db/post_migrate/20220124145019_remove_projects_external_pull_requests_project_id_fk.rb b/db/post_migrate/20220124145019_remove_projects_external_pull_requests_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b16234fc8124b10b511e1fdb3dac0bedb5a0867b
--- /dev/null
+++ b/db/post_migrate/20220124145019_remove_projects_external_pull_requests_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveProjectsExternalPullRequestsProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless foreign_key_exists?(:external_pull_requests, :projects, name: "fk_rails_bcae9b5c7b")
+
+    with_lock_retries do
+      execute('LOCK projects, external_pull_requests IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:external_pull_requests, :projects, name: "fk_rails_bcae9b5c7b")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:external_pull_requests, :projects, name: "fk_rails_bcae9b5c7b", column: :project_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220124151456_remove_projects_ci_triggers_project_id_fk.rb b/db/post_migrate/20220124151456_remove_projects_ci_triggers_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..684d363eb96181e350c3554c4d7d151e5fd71cb1
--- /dev/null
+++ b/db/post_migrate/20220124151456_remove_projects_ci_triggers_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiTriggersProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless foreign_key_exists?(:ci_triggers, :projects, name: "fk_e3e63f966e")
+
+    with_lock_retries do
+      execute('LOCK projects, ci_triggers IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_triggers, :projects, name: "fk_e3e63f966e")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_triggers, :projects, name: "fk_e3e63f966e", column: :project_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220124151949_remove_projects_ci_runner_projects_project_id_fk.rb b/db/post_migrate/20220124151949_remove_projects_ci_runner_projects_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..de8feb96a06c945f1646e1cade4e4de5cbfe1aab
--- /dev/null
+++ b/db/post_migrate/20220124151949_remove_projects_ci_runner_projects_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiRunnerProjectsProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless foreign_key_exists?(:ci_runner_projects, :projects, name: "fk_4478a6f1e4")
+
+    with_lock_retries do
+      execute('LOCK projects, ci_runner_projects IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_runner_projects, :projects, name: "fk_4478a6f1e4")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_runner_projects, :projects, name: "fk_4478a6f1e4", column: :project_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220124152824_remove_projects_ci_subscriptions_projects_downstream_project_id_fk.rb b/db/post_migrate/20220124152824_remove_projects_ci_subscriptions_projects_downstream_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8596b1f14ba395692e2e6fc633b7111446ed0d5a
--- /dev/null
+++ b/db/post_migrate/20220124152824_remove_projects_ci_subscriptions_projects_downstream_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiSubscriptionsProjectsDownstreamProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless foreign_key_exists?(:ci_subscriptions_projects, :projects, name: "fk_rails_0818751483")
+
+    with_lock_retries do
+      execute('LOCK projects, ci_subscriptions_projects IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_subscriptions_projects, :projects, name: "fk_rails_0818751483")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_subscriptions_projects, :projects, name: "fk_rails_0818751483", column: :downstream_project_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220124153233_remove_projects_ci_job_artifacts_project_id_fk.rb b/db/post_migrate/20220124153233_remove_projects_ci_job_artifacts_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1948a78916def30c6fe2f2af0033d765453b448a
--- /dev/null
+++ b/db/post_migrate/20220124153233_remove_projects_ci_job_artifacts_project_id_fk.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiJobArtifactsProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return if Gitlab.com? # unsafe migration, skip on GitLab.com due to https://gitlab.com/groups/gitlab-org/-/epics/7249#note_819625526
+    return unless foreign_key_exists?(:ci_job_artifacts, :projects, name: "fk_rails_9862d392f9")
+
+    with_lock_retries do
+      execute('LOCK projects, ci_job_artifacts IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_job_artifacts, :projects, name: "fk_rails_9862d392f9")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_job_artifacts, :projects, name: "fk_rails_9862d392f9", column: :project_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220124153234_re_remove_projects_ci_job_artifacts_project_id_fk.rb b/db/post_migrate/20220124153234_re_remove_projects_ci_job_artifacts_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bb59134b92744912c2ebb4a2865b5d2f66be7fa8
--- /dev/null
+++ b/db/post_migrate/20220124153234_re_remove_projects_ci_job_artifacts_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class ReRemoveProjectsCiJobArtifactsProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless foreign_key_exists?(:ci_job_artifacts, :projects, name: "fk_rails_9862d392f9")
+
+    with_lock_retries do
+      execute('LOCK projects, ci_job_artifacts IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_job_artifacts, :projects, name: "fk_rails_9862d392f9")
+    end
+  end
+
+  def down
+    # no-op, since the FK will be added via rollback by prior-migration
+  end
+end
diff --git a/db/post_migrate/20220124180704_remove_projects_ci_builds_metadata_project_id_fk.rb b/db/post_migrate/20220124180704_remove_projects_ci_builds_metadata_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..fc9dc2cc6dc8cb78d7481ed4212fd8d403ee775c
--- /dev/null
+++ b/db/post_migrate/20220124180704_remove_projects_ci_builds_metadata_project_id_fk.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiBuildsMetadataProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return if Gitlab.com? # unsafe migration, skip on GitLab.com due to https://gitlab.com/groups/gitlab-org/-/epics/7249#note_819625526
+    return unless foreign_key_exists?(:ci_builds_metadata, :projects, name: "fk_rails_ffcf702a02")
+
+    with_lock_retries do
+      execute('LOCK projects, ci_builds_metadata IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_builds_metadata, :projects, name: "fk_rails_ffcf702a02")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_builds_metadata, :projects, name: "fk_rails_ffcf702a02", column: :project_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220124180705_re_remove_projects_ci_builds_metadata_project_id_fk.rb b/db/post_migrate/20220124180705_re_remove_projects_ci_builds_metadata_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6483b8e06437b0379e02cb5f292b402384b7ad2f
--- /dev/null
+++ b/db/post_migrate/20220124180705_re_remove_projects_ci_builds_metadata_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class ReRemoveProjectsCiBuildsMetadataProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless foreign_key_exists?(:ci_builds_metadata, :projects, name: "fk_rails_ffcf702a02")
+
+    with_lock_retries do
+      execute('LOCK projects, ci_builds_metadata IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_builds_metadata, :projects, name: "fk_rails_ffcf702a02")
+    end
+  end
+
+  def down
+    # no-op, since the FK will be added via rollback by prior-migration
+  end
+end
diff --git a/db/post_migrate/20220124184338_remove_projects_ci_subscriptions_projects_upstream_project_id_fk.rb b/db/post_migrate/20220124184338_remove_projects_ci_subscriptions_projects_upstream_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..50448f4a8844f001095e2008b20bdc11519a736d
--- /dev/null
+++ b/db/post_migrate/20220124184338_remove_projects_ci_subscriptions_projects_upstream_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiSubscriptionsProjectsUpstreamProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless foreign_key_exists?(:ci_subscriptions_projects, :projects, name: "fk_rails_7871f9a97b")
+
+    with_lock_retries do
+      execute('LOCK projects, ci_subscriptions_projects IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_subscriptions_projects, :projects, name: "fk_rails_7871f9a97b")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_subscriptions_projects, :projects, name: "fk_rails_7871f9a97b", column: :upstream_project_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220124204046_remove_projects_ci_sources_pipelines_project_id_fk.rb b/db/post_migrate/20220124204046_remove_projects_ci_sources_pipelines_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e15d337045e0ce67818fde4291d860cda0a7ce57
--- /dev/null
+++ b/db/post_migrate/20220124204046_remove_projects_ci_sources_pipelines_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiSourcesPipelinesProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless foreign_key_exists?(:ci_sources_pipelines, :projects, name: "fk_1e53c97c0a")
+
+    with_lock_retries do
+      execute('LOCK projects, ci_sources_pipelines IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_sources_pipelines, :projects, name: "fk_1e53c97c0a")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_sources_pipelines, :projects, name: "fk_1e53c97c0a", column: :project_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220124214131_remove_projects_ci_refs_project_id_fk.rb b/db/post_migrate/20220124214131_remove_projects_ci_refs_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f90d477673a930ba3af30380641b7a45e6e53b43
--- /dev/null
+++ b/db/post_migrate/20220124214131_remove_projects_ci_refs_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiRefsProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless foreign_key_exists?(:ci_refs, :projects, name: "fk_rails_4249db8cc3")
+
+    with_lock_retries do
+      execute('LOCK projects, ci_refs IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_refs, :projects, name: "fk_rails_4249db8cc3")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_refs, :projects, name: "fk_rails_4249db8cc3", column: :project_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220124215857_remove_projects_ci_job_token_project_scope_links_source_project_id_fk.rb b/db/post_migrate/20220124215857_remove_projects_ci_job_token_project_scope_links_source_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8bfe9586a5095838bbabd83d8062906db3ff4dfb
--- /dev/null
+++ b/db/post_migrate/20220124215857_remove_projects_ci_job_token_project_scope_links_source_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiJobTokenProjectScopeLinksSourceProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless foreign_key_exists?(:ci_job_token_project_scope_links, :projects, name: "fk_rails_4b2ee3290b")
+
+    with_lock_retries do
+      execute('LOCK projects, ci_job_token_project_scope_links IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_job_token_project_scope_links, :projects, name: "fk_rails_4b2ee3290b")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_job_token_project_scope_links, :projects, name: "fk_rails_4b2ee3290b", column: :source_project_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220124221521_remove_projects_ci_project_monthly_usages_project_id_fk.rb b/db/post_migrate/20220124221521_remove_projects_ci_project_monthly_usages_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..cff78342d21e462869f651bb74a99ecda399522b
--- /dev/null
+++ b/db/post_migrate/20220124221521_remove_projects_ci_project_monthly_usages_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiProjectMonthlyUsagesProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless foreign_key_exists?(:ci_project_monthly_usages, :projects, name: "fk_rails_508bcd4aa6")
+
+    with_lock_retries do
+      execute('LOCK projects, ci_project_monthly_usages IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_project_monthly_usages, :projects, name: "fk_rails_508bcd4aa6")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_project_monthly_usages, :projects, name: "fk_rails_508bcd4aa6", column: :project_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220125083520_remove_ci_pipelines_dast_site_profiles_pipelines_ci_pipeline_id_fk.rb b/db/post_migrate/20220125083520_remove_ci_pipelines_dast_site_profiles_pipelines_ci_pipeline_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b111b95fccfbdc03a798d7af9d76ad3fa1c3aeec
--- /dev/null
+++ b/db/post_migrate/20220125083520_remove_ci_pipelines_dast_site_profiles_pipelines_ci_pipeline_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveCiPipelinesDastSiteProfilesPipelinesCiPipelineIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless foreign_key_exists?(:dast_site_profiles_pipelines, :ci_pipelines, name: "fk_53849b0ad5")
+
+    with_lock_retries do
+      execute('LOCK ci_pipelines, dast_site_profiles_pipelines IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:dast_site_profiles_pipelines, :ci_pipelines, name: "fk_53849b0ad5")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:dast_site_profiles_pipelines, :ci_pipelines, name: "fk_53849b0ad5", column: :ci_pipeline_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220125084348_remove_ci_pipelines_vulnerability_feedback_pipeline_id_fk.rb b/db/post_migrate/20220125084348_remove_ci_pipelines_vulnerability_feedback_pipeline_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1b932d084bbe8538dfdb36caa7e52dba4a412216
--- /dev/null
+++ b/db/post_migrate/20220125084348_remove_ci_pipelines_vulnerability_feedback_pipeline_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveCiPipelinesVulnerabilityFeedbackPipelineIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless foreign_key_exists?(:vulnerability_feedback, :ci_pipelines, name: "fk_rails_20976e6fd9")
+
+    with_lock_retries do
+      execute('LOCK ci_pipelines, vulnerability_feedback IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:vulnerability_feedback, :ci_pipelines, name: "fk_rails_20976e6fd9")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:vulnerability_feedback, :ci_pipelines, name: "fk_rails_20976e6fd9", column: :pipeline_id, target_column: :id, on_delete: :nullify)
+  end
+end
diff --git a/db/post_migrate/20220125122640_schedule_populate_topics_non_private_projects_count.rb b/db/post_migrate/20220125122640_schedule_populate_topics_non_private_projects_count.rb
new file mode 100644
index 0000000000000000000000000000000000000000..dee86a705539a9d4029995e098aefd02b82d0baa
--- /dev/null
+++ b/db/post_migrate/20220125122640_schedule_populate_topics_non_private_projects_count.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class SchedulePopulateTopicsNonPrivateProjectsCount < Gitlab::Database::Migration[1.0]
+  MIGRATION = 'PopulateTopicsNonPrivateProjectsCount'
+  BATCH_SIZE = 10_000
+  DELAY_INTERVAL = 2.minutes
+
+  disable_ddl_transaction!
+
+  def up
+    queue_background_migration_jobs_by_range_at_intervals(
+      define_batchable_model('topics'),
+      MIGRATION,
+      DELAY_INTERVAL,
+      batch_size: BATCH_SIZE,
+      track_jobs: true
+    )
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20220126201752_remove_projects_ci_job_token_project_scope_links_target_project_id_fk.rb b/db/post_migrate/20220126201752_remove_projects_ci_job_token_project_scope_links_target_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a33e02f2408c75454efa9b7c95176007caa6a667
--- /dev/null
+++ b/db/post_migrate/20220126201752_remove_projects_ci_job_token_project_scope_links_target_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiJobTokenProjectScopeLinksTargetProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless foreign_key_exists?(:ci_job_token_project_scope_links, :projects, name: "fk_rails_6904b38465")
+
+    with_lock_retries do
+      execute('LOCK projects, ci_job_token_project_scope_links IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_job_token_project_scope_links, :projects, name: "fk_rails_6904b38465")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_job_token_project_scope_links, :projects, name: "fk_rails_6904b38465", column: :target_project_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220126202654_remove_projects_ci_sources_projects_source_project_id_fk.rb b/db/post_migrate/20220126202654_remove_projects_ci_sources_projects_source_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a69cd43b92121680ec694607ce16089c2a7e6888
--- /dev/null
+++ b/db/post_migrate/20220126202654_remove_projects_ci_sources_projects_source_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiSourcesProjectsSourceProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless foreign_key_exists?(:ci_sources_projects, :projects, name: "fk_rails_64b6855cbc")
+
+    with_lock_retries do
+      execute('LOCK projects, ci_sources_projects IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_sources_projects, :projects, name: "fk_rails_64b6855cbc")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_sources_projects, :projects, name: "fk_rails_64b6855cbc", column: :source_project_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220126203421_remove_projects_ci_pipeline_schedules_project_id_fk.rb b/db/post_migrate/20220126203421_remove_projects_ci_pipeline_schedules_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..870127ab1687540055329640309a2ea4bd5a2aea
--- /dev/null
+++ b/db/post_migrate/20220126203421_remove_projects_ci_pipeline_schedules_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiPipelineSchedulesProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless foreign_key_exists?(:ci_pipeline_schedules, :projects, name: "fk_8ead60fcc4")
+
+    with_lock_retries do
+      execute('LOCK projects, ci_pipeline_schedules IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_pipeline_schedules, :projects, name: "fk_8ead60fcc4")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_pipeline_schedules, :projects, name: "fk_8ead60fcc4", column: :project_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220126210021_remove_projects_ci_builds_project_id_fk.rb b/db/post_migrate/20220126210021_remove_projects_ci_builds_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8caa6db750779d26883a4e2422a2f3702c1d4f9e
--- /dev/null
+++ b/db/post_migrate/20220126210021_remove_projects_ci_builds_project_id_fk.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiBuildsProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return if Gitlab.com? # unsafe migration, skip on GitLab.com due to https://gitlab.com/groups/gitlab-org/-/epics/7249#note_819625526
+    return unless foreign_key_exists?(:ci_builds, :projects, name: "fk_befce0568a")
+
+    with_lock_retries do
+      execute('LOCK projects, ci_builds IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_builds, :projects, name: "fk_befce0568a")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_builds, :projects, name: "fk_befce0568a", column: :project_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220126210022_re_remove_projects_ci_builds_project_id_fk.rb b/db/post_migrate/20220126210022_re_remove_projects_ci_builds_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2a026388bbf5a4bec7e19874fe8351d2669fddd6
--- /dev/null
+++ b/db/post_migrate/20220126210022_re_remove_projects_ci_builds_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class ReRemoveProjectsCiBuildsProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless foreign_key_exists?(:ci_builds, :projects, name: "fk_befce0568a")
+
+    with_lock_retries do
+      execute('LOCK projects, ci_builds IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_builds, :projects, name: "fk_befce0568a")
+    end
+  end
+
+  def down
+    # no-op, since the FK will be added via rollback by prior-migration
+  end
+end
diff --git a/db/post_migrate/20220126210657_remove_projects_ci_pipelines_project_id_fk.rb b/db/post_migrate/20220126210657_remove_projects_ci_pipelines_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6867cf720f3b5109bfdb1fd0a2e75da0e9d3b93c
--- /dev/null
+++ b/db/post_migrate/20220126210657_remove_projects_ci_pipelines_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiPipelinesProjectIdFk < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless foreign_key_exists?(:ci_pipelines, :projects, name: "fk_86635dbd80")
+
+    with_lock_retries do
+      execute('LOCK projects, ci_pipelines IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+      remove_foreign_key_if_exists(:ci_pipelines, :projects, name: "fk_86635dbd80")
+    end
+  end
+
+  def down
+    add_concurrent_foreign_key(:ci_pipelines, :projects, name: "fk_86635dbd80", column: :project_id, target_column: :id, on_delete: :cascade)
+  end
+end
diff --git a/db/post_migrate/20220127112243_add_index_to_merge_request_assignees_state.rb b/db/post_migrate/20220127112243_add_index_to_merge_request_assignees_state.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e6bb43af760da3f6a3ddda7b956b1a1cb81e09eb
--- /dev/null
+++ b/db/post_migrate/20220127112243_add_index_to_merge_request_assignees_state.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddIndexToMergeRequestAssigneesState < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_on_merge_request_assignees_state'
+
+  def up
+    add_concurrent_index :merge_request_assignees, :state, where: 'state = 2', name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :merge_request_assignees, INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220127112412_add_index_to_merge_request_reviewers_state.rb b/db/post_migrate/20220127112412_add_index_to_merge_request_reviewers_state.rb
new file mode 100644
index 0000000000000000000000000000000000000000..13f4e05c15b516f68fc36dbf6bc4a860439719bb
--- /dev/null
+++ b/db/post_migrate/20220127112412_add_index_to_merge_request_reviewers_state.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddIndexToMergeRequestReviewersState < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_on_merge_request_reviewers_state'
+
+  def up
+    add_concurrent_index :merge_request_reviewers, :state, where: 'state = 2', name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :merge_request_reviewers, INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220127132200_cleanup_backfill_ci_namespace_mirrors.rb b/db/post_migrate/20220127132200_cleanup_backfill_ci_namespace_mirrors.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a6775251d4235caf54a62dcaff26414e14bcc434
--- /dev/null
+++ b/db/post_migrate/20220127132200_cleanup_backfill_ci_namespace_mirrors.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class CleanupBackfillCiNamespaceMirrors < Gitlab::Database::Migration[1.0]
+  def up
+    # no-op
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20220127132201_cleanup_backfill_ci_project_mirrors.rb b/db/post_migrate/20220127132201_cleanup_backfill_ci_project_mirrors.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c0cdb74c595a656bfc15089d9d3f48c86a002ef4
--- /dev/null
+++ b/db/post_migrate/20220127132201_cleanup_backfill_ci_project_mirrors.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class CleanupBackfillCiProjectMirrors < Gitlab::Database::Migration[1.0]
+  def up
+    # no-op
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20220128103042_schedule_delete_invalid_epic_issues_revised.rb b/db/post_migrate/20220128103042_schedule_delete_invalid_epic_issues_revised.rb
new file mode 100644
index 0000000000000000000000000000000000000000..642bf012ce0edd6dadc429af7fedd8a3f309e591
--- /dev/null
+++ b/db/post_migrate/20220128103042_schedule_delete_invalid_epic_issues_revised.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class ScheduleDeleteInvalidEpicIssuesRevised < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  MIGRATION = 'DeleteInvalidEpicIssues'
+  INTERVAL = 2.minutes
+  BATCH_SIZE = 1_000
+  MAX_BATCH_SIZE = 2_000
+  SUB_BATCH_SIZE = 50
+
+  def up
+    queue_batched_background_migration(
+      MIGRATION,
+      :epics,
+      :id,
+      job_interval: INTERVAL,
+      batch_size: BATCH_SIZE,
+      max_batch_size: MAX_BATCH_SIZE,
+      sub_batch_size: SUB_BATCH_SIZE
+    )
+  end
+
+  def down
+    delete_batched_background_migration(MIGRATION, :epics, :id, [])
+  end
+end
diff --git a/db/post_migrate/20220128155251_remove_dangling_running_builds.rb b/db/post_migrate/20220128155251_remove_dangling_running_builds.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f86a21ced008b20dc20849b12ccff28dc7e1ee44
--- /dev/null
+++ b/db/post_migrate/20220128155251_remove_dangling_running_builds.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+class RemoveDanglingRunningBuilds < Gitlab::Database::Migration[1.0]
+  BATCH_SIZE = 100
+
+  disable_ddl_transaction!
+
+  def up
+    each_batch_range('ci_running_builds', of: BATCH_SIZE) do |min, max|
+      execute <<~SQL
+        DELETE FROM ci_running_builds
+          USING ci_builds
+          WHERE ci_builds.id = ci_running_builds.build_id
+            AND ci_builds.status = 'failed'
+            AND ci_builds.type = 'Ci::Build'
+            AND ci_running_builds.id BETWEEN #{min} AND #{max}
+      SQL
+    end
+  end
+
+  def down
+    # no-op
+    # This migration deletes data and it can not be reversed
+  end
+end
diff --git a/db/post_migrate/20220128155814_fix_approval_rules_code_owners_rule_type_index.rb b/db/post_migrate/20220128155814_fix_approval_rules_code_owners_rule_type_index.rb
new file mode 100644
index 0000000000000000000000000000000000000000..eccfab2512615d7517558ad809bfdcdf972940a6
--- /dev/null
+++ b/db/post_migrate/20220128155814_fix_approval_rules_code_owners_rule_type_index.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class FixApprovalRulesCodeOwnersRuleTypeIndex < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'index_approval_rules_code_owners_rule_type'
+  OLD_INDEX_NAME = 'index_approval_rules_code_owners_rule_type_old'
+  TABLE = :approval_merge_request_rules
+  COLUMN = :merge_request_id
+  WHERE_CONDITION = 'rule_type = 2'
+
+  disable_ddl_transaction!
+
+  def up
+    rename_index TABLE, INDEX_NAME, OLD_INDEX_NAME if index_exists_by_name?(TABLE, INDEX_NAME) && !index_exists_by_name?(TABLE, OLD_INDEX_NAME)
+
+    add_concurrent_index TABLE, COLUMN, where: WHERE_CONDITION, name: INDEX_NAME
+
+    remove_concurrent_index_by_name TABLE, OLD_INDEX_NAME
+  end
+
+  def down
+    # No-op
+  end
+end
diff --git a/db/post_migrate/20220131000000_index_job_artifacts_on_trace_type_and_expire_at.rb b/db/post_migrate/20220131000000_index_job_artifacts_on_trace_type_and_expire_at.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f47c04dd2ef2a49ac5e0310989327094f10ebabc
--- /dev/null
+++ b/db/post_migrate/20220131000000_index_job_artifacts_on_trace_type_and_expire_at.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class IndexJobArtifactsOnTraceTypeAndExpireAt < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'tmp_index_ci_job_artifacts_on_id_where_trace_and_expire_at'
+  TIMESTAMPS = "'2021-04-22 00:00:00', '2021-05-22 00:00:00', '2021-06-22 00:00:00', '2022-01-22 00:00:00', '2022-02-22 00:00:00', '2022-03-22 00:00:00', '2022-04-22 00:00:00'"
+
+  def up
+    add_concurrent_index :ci_job_artifacts, :id, where: "file_type = 3 AND expire_at IN (#{TIMESTAMPS})", name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :ci_job_artifacts, INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220131000001_schedule_trace_expiry_removal.rb b/db/post_migrate/20220131000001_schedule_trace_expiry_removal.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8e282a9b8c2f416b8d1a8e6e15a3077f54be8247
--- /dev/null
+++ b/db/post_migrate/20220131000001_schedule_trace_expiry_removal.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+class ScheduleTraceExpiryRemoval < Gitlab::Database::Migration[1.0]
+  MIGRATION = 'RemoveAllTraceExpirationDates'
+  BATCH_SIZE = 100_000
+  DELAY_INTERVAL = 4.minutes
+
+  disable_ddl_transaction!
+
+  # Stubbed class to connect to the CI database
+  # connects_to has to be called in abstract classes.
+  class MultiDbAdaptableClass < ActiveRecord::Base
+    self.abstract_class = true
+
+    if Gitlab::Database.has_config?(:ci)
+      connects_to database: { writing: :ci, reading: :ci }
+    end
+  end
+
+  # Stubbed class to access the ci_job_artifacts table
+  class JobArtifact < MultiDbAdaptableClass
+    include EachBatch
+
+    self.table_name = 'ci_job_artifacts'
+
+    TARGET_TIMESTAMPS = [
+      Date.new(2021, 04, 22).midnight.utc,
+      Date.new(2021, 05, 22).midnight.utc,
+      Date.new(2021, 06, 22).midnight.utc,
+      Date.new(2022, 01, 22).midnight.utc,
+      Date.new(2022, 02, 22).midnight.utc,
+      Date.new(2022, 03, 22).midnight.utc,
+      Date.new(2022, 04, 22).midnight.utc
+    ].freeze
+
+    scope :in_targeted_timestamps, -> { where(expire_at: TARGET_TIMESTAMPS) }
+    scope :traces, -> { where(file_type: 3) }
+  end
+
+  def up
+    return unless Gitlab.com?
+
+    queue_background_migration_jobs_by_range_at_intervals(
+      JobArtifact.traces.in_targeted_timestamps,
+      MIGRATION,
+      DELAY_INTERVAL,
+      batch_size: BATCH_SIZE,
+      track_jobs: true
+    )
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20220201034731_remove_index_clusters_kubernetes_namespaces_on_cluster_id.rb b/db/post_migrate/20220201034731_remove_index_clusters_kubernetes_namespaces_on_cluster_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0e2ef3b33244e1083feecff4d9d551311e183953
--- /dev/null
+++ b/db/post_migrate/20220201034731_remove_index_clusters_kubernetes_namespaces_on_cluster_id.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveIndexClustersKubernetesNamespacesOnClusterId < Gitlab::Database::Migration[1.0]
+  INDEX = 'index_clusters_kubernetes_namespaces_on_cluster_id'
+
+  disable_ddl_transaction!
+
+  def up
+    remove_concurrent_index_by_name :clusters_kubernetes_namespaces, INDEX
+  end
+
+  def down
+    add_concurrent_index :clusters_kubernetes_namespaces, :cluster_id, name: INDEX
+  end
+end
diff --git a/db/post_migrate/20220201141705_cleanup_background_migration_populate_test_reports_issue_id.rb b/db/post_migrate/20220201141705_cleanup_background_migration_populate_test_reports_issue_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..252b4a01d04fa7d00cd3bb3136edff1965fb34df
--- /dev/null
+++ b/db/post_migrate/20220201141705_cleanup_background_migration_populate_test_reports_issue_id.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class CleanupBackgroundMigrationPopulateTestReportsIssueId < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  MIGRATION = 'PopulateTestReportsIssueId'
+
+  def up
+    finalize_background_migration(MIGRATION)
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20220201173212_add_user_details_provisioning_index.rb b/db/post_migrate/20220201173212_add_user_details_provisioning_index.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a864ec7e3951c60d334fa52a78353709787e9c83
--- /dev/null
+++ b/db/post_migrate/20220201173212_add_user_details_provisioning_index.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class AddUserDetailsProvisioningIndex < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'idx_user_details_on_provisioned_by_group_id_user_id'
+  OLD_INDEX_NAME = 'index_user_details_on_provisioned_by_group_id'
+
+  def up
+    add_concurrent_index :user_details, [:provisioned_by_group_id, :user_id], name: INDEX_NAME
+    remove_concurrent_index_by_name :user_details, OLD_INDEX_NAME
+  end
+
+  def down
+    add_concurrent_index :user_details, :provisioned_by_group_id, name: OLD_INDEX_NAME
+    remove_concurrent_index_by_name :user_details, INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220201193033_add_unique_index_to_vulnerability_finding_links_with_truncate.rb b/db/post_migrate/20220201193033_add_unique_index_to_vulnerability_finding_links_with_truncate.rb
new file mode 100644
index 0000000000000000000000000000000000000000..cc9dabdf6248c9ed2a09ba33ea3beab513808364
--- /dev/null
+++ b/db/post_migrate/20220201193033_add_unique_index_to_vulnerability_finding_links_with_truncate.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class AddUniqueIndexToVulnerabilityFindingLinksWithTruncate < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  NAME_URL_INDEX_NAME = 'finding_link_name_url_idx'
+  URL_INDEX_NAME = 'finding_link_url_idx'
+
+  def up
+    execute('TRUNCATE TABLE vulnerability_finding_links')
+
+    add_concurrent_index :vulnerability_finding_links, [:vulnerability_occurrence_id, :name, :url], unique: true, name: NAME_URL_INDEX_NAME
+    add_concurrent_index :vulnerability_finding_links, [:vulnerability_occurrence_id, :url], unique: true, where: 'name is null', name: URL_INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index :vulnerability_finding_links, [:vulnerability_occurrence_id, :name, :url], name: NAME_URL_INDEX_NAME
+    remove_concurrent_index :vulnerability_finding_links, [:vulnerability_occurrence_id, :url], name: URL_INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220202105733_delete_service_template_records.rb b/db/post_migrate/20220202105733_delete_service_template_records.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e1697f235888fc49cbaacdcbeb6cbc20dd983508
--- /dev/null
+++ b/db/post_migrate/20220202105733_delete_service_template_records.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class DeleteServiceTemplateRecords < Gitlab::Database::Migration[1.0]
+  class Integration < ActiveRecord::Base
+    # Disable single-table inheritance
+    self.inheritance_column = :_type_disabled
+  end
+
+  def up
+    Integration.where(template: true).delete_all
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20220204053655_remove_index_epic_issues_on_epic_id.rb b/db/post_migrate/20220204053655_remove_index_epic_issues_on_epic_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7815829d36a9c1e4cca0532a5b29cf4d44a2a440
--- /dev/null
+++ b/db/post_migrate/20220204053655_remove_index_epic_issues_on_epic_id.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveIndexEpicIssuesOnEpicId < Gitlab::Database::Migration[1.0]
+  INDEX = 'index_epic_issues_on_epic_id'
+
+  disable_ddl_transaction!
+
+  def up
+    remove_concurrent_index_by_name :epic_issues, name: INDEX
+  end
+
+  def down
+    add_concurrent_index :epic_issues, :epic_id, name: INDEX
+  end
+end
diff --git a/db/post_migrate/20220204095121_backfill_namespace_statistics_with_dependency_proxy_size.rb b/db/post_migrate/20220204095121_backfill_namespace_statistics_with_dependency_proxy_size.rb
new file mode 100644
index 0000000000000000000000000000000000000000..49c9efc497caf8ca4c0966c11ab97916758e692b
--- /dev/null
+++ b/db/post_migrate/20220204095121_backfill_namespace_statistics_with_dependency_proxy_size.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+class BackfillNamespaceStatisticsWithDependencyProxySize < Gitlab::Database::Migration[1.0]
+  DELAY_INTERVAL = 2.minutes.to_i
+  BATCH_SIZE = 500
+  MIGRATION = 'PopulateNamespaceStatistics'
+
+  disable_ddl_transaction!
+
+  def up
+    groups = exec_query <<~SQL
+      SELECT dependency_proxy_manifests.group_id FROM dependency_proxy_manifests
+      UNION
+      SELECT dependency_proxy_blobs.group_id from dependency_proxy_blobs
+    SQL
+
+    groups.rows.flatten.in_groups_of(BATCH_SIZE, false).each_with_index do |group_ids, index|
+      migrate_in(index * DELAY_INTERVAL, MIGRATION, [group_ids, [:dependency_proxy_size]])
+    end
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20220204110725_backfill_cycle_analytics_aggregations.rb b/db/post_migrate/20220204110725_backfill_cycle_analytics_aggregations.rb
new file mode 100644
index 0000000000000000000000000000000000000000..933ad747c5c8abecf9f6d88b3011e65604469ebc
--- /dev/null
+++ b/db/post_migrate/20220204110725_backfill_cycle_analytics_aggregations.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+class BackfillCycleAnalyticsAggregations < Gitlab::Database::Migration[1.0]
+  BATCH_SIZE = 50
+
+  def up
+    model = define_batchable_model('analytics_cycle_analytics_group_value_streams')
+
+    model.each_batch(of: BATCH_SIZE) do |relation|
+      execute <<~SQL
+      WITH records_to_be_inserted AS #{Gitlab::Database::AsWithMaterialized.materialized_if_supported} (
+        SELECT root_ancestor.id AS group_id
+        FROM (#{relation.select(:group_id).to_sql}) as value_streams,
+        LATERAL (
+          WITH RECURSIVE "base_and_ancestors" AS (
+            (SELECT "namespaces"."id", "namespaces"."parent_id"  FROM "namespaces" WHERE "namespaces"."id" = value_streams.group_id)
+          UNION
+            (SELECT "namespaces"."id", "namespaces"."parent_id" FROM "namespaces", "base_and_ancestors" WHERE "namespaces"."id" = "base_and_ancestors"."parent_id")
+          )
+          SELECT "namespaces"."id" FROM "base_and_ancestors" as "namespaces" WHERE parent_id IS NULL LIMIT 1
+        ) as root_ancestor
+      )
+      INSERT INTO "analytics_cycle_analytics_aggregations"
+      SELECT * FROM "records_to_be_inserted"
+      ON CONFLICT DO NOTHING
+      SQL
+    end
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20220204194347_encrypt_integration_properties.rb b/db/post_migrate/20220204194347_encrypt_integration_properties.rb
new file mode 100644
index 0000000000000000000000000000000000000000..82dd3a05e1d0950f7202108dbbab574f8c248eeb
--- /dev/null
+++ b/db/post_migrate/20220204194347_encrypt_integration_properties.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class EncryptIntegrationProperties < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+  MIGRATION = 'EncryptIntegrationProperties'
+  BATCH_SIZE = 1_000
+  INTERVAL = 2.minutes.to_i
+
+  def up
+    queue_background_migration_jobs_by_range_at_intervals(
+      define_batchable_model('integrations').all,
+      MIGRATION,
+      INTERVAL,
+      track_jobs: true,
+      batch_size: BATCH_SIZE
+    )
+  end
+
+  def down
+    # this migration is not reversible
+  end
+end
diff --git a/db/post_migrate/20220207080758_update_api_indexes_for_projects.rb b/db/post_migrate/20220207080758_update_api_indexes_for_projects.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3275912b0abff743fa8681c3944fa2c348029880
--- /dev/null
+++ b/db/post_migrate/20220207080758_update_api_indexes_for_projects.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+class UpdateApiIndexesForProjects < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  ARCHIVED_INDEX_NAME = 'idx_projects_api_created_at_id_for_archived'
+  OLD_ARCHIVED_INDEX_NAME = 'index_projects_api_created_at_id_for_archived'
+  PUBLIC_AND_ARCHIVED_INDEX_NAME = 'idx_projects_api_created_at_id_for_archived_vis20'
+  OLD_PUBLIC_AND_ARCHIVED_INDEX_NAME = 'index_projects_api_created_at_id_for_archived_vis20'
+  INTERNAL_PROJECTS_INDEX_NAME = 'idx_projects_api_created_at_id_for_vis10'
+  OLD_INTERNAL_PROJECTS_INDEX_NAME = 'index_projects_api_created_at_id_for_vis10'
+
+  def up
+    add_concurrent_index :projects, [:created_at, :id],
+                         where: "archived = true AND pending_delete = false AND hidden = false",
+                         name: ARCHIVED_INDEX_NAME
+
+    add_concurrent_index :projects, [:created_at, :id],
+                         where: "archived = true AND visibility_level = 20 AND pending_delete = false AND hidden = false",
+                         name: PUBLIC_AND_ARCHIVED_INDEX_NAME
+
+    add_concurrent_index :projects, [:created_at, :id],
+                         where: "visibility_level = 10 AND pending_delete = false AND hidden = false",
+                         name: INTERNAL_PROJECTS_INDEX_NAME
+
+    remove_concurrent_index_by_name :projects, OLD_ARCHIVED_INDEX_NAME
+    remove_concurrent_index_by_name :projects, OLD_PUBLIC_AND_ARCHIVED_INDEX_NAME
+    remove_concurrent_index_by_name :projects, OLD_INTERNAL_PROJECTS_INDEX_NAME
+  end
+
+  def down
+    add_concurrent_index :projects, [:created_at, :id],
+                         where: "archived = true AND pending_delete = false",
+                         name: OLD_ARCHIVED_INDEX_NAME
+
+    add_concurrent_index :projects, [:created_at, :id],
+                         where: "archived = true AND visibility_level = 20 AND pending_delete = false",
+                         name: OLD_PUBLIC_AND_ARCHIVED_INDEX_NAME
+
+    add_concurrent_index :projects, [:created_at, :id],
+                         where: "visibility_level = 10 AND pending_delete = false",
+                         name: OLD_INTERNAL_PROJECTS_INDEX_NAME
+
+    remove_concurrent_index_by_name :projects, ARCHIVED_INDEX_NAME
+    remove_concurrent_index_by_name :projects, PUBLIC_AND_ARCHIVED_INDEX_NAME
+    remove_concurrent_index_by_name :projects, INTERNAL_PROJECTS_INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220208080921_schedule_migrate_personal_namespace_project_maintainer_to_owner.rb b/db/post_migrate/20220208080921_schedule_migrate_personal_namespace_project_maintainer_to_owner.rb
new file mode 100644
index 0000000000000000000000000000000000000000..633570aeaa0551e25cb8133a2c16a5fa228c678f
--- /dev/null
+++ b/db/post_migrate/20220208080921_schedule_migrate_personal_namespace_project_maintainer_to_owner.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+class ScheduleMigratePersonalNamespaceProjectMaintainerToOwner < Gitlab::Database::Migration[1.0]
+  MIGRATION = 'MigratePersonalNamespaceProjectMaintainerToOwner'
+  INTERVAL = 2.minutes
+  BATCH_SIZE = 1_000
+  SUB_BATCH_SIZE = 200
+
+  disable_ddl_transaction!
+
+  def up
+    queue_batched_background_migration(
+      MIGRATION,
+      :members,
+      :id,
+      job_interval: INTERVAL,
+      batch_size: BATCH_SIZE,
+      sub_batch_size: SUB_BATCH_SIZE
+    )
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20220208115439_start_backfill_ci_queuing_tables.rb b/db/post_migrate/20220208115439_start_backfill_ci_queuing_tables.rb
new file mode 100644
index 0000000000000000000000000000000000000000..82e361742904293afbcfa808fa1c8dd4042220e6
--- /dev/null
+++ b/db/post_migrate/20220208115439_start_backfill_ci_queuing_tables.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class StartBackfillCiQueuingTables < Gitlab::Database::Migration[1.0]
+  MIGRATION = 'BackfillCiQueuingTables'
+  BATCH_SIZE = 500
+  DELAY_INTERVAL = 2.minutes
+
+  disable_ddl_transaction!
+
+  def up
+    return if Gitlab.com?
+
+    queue_background_migration_jobs_by_range_at_intervals(
+      Gitlab::BackgroundMigration::BackfillCiQueuingTables::Ci::Build.pending,
+      MIGRATION,
+      DELAY_INTERVAL,
+      batch_size: BATCH_SIZE,
+      track_jobs: true)
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20220209111007_add_partial_index_for_batching_active_cluster_image_scanning_vulnerabilities.rb b/db/post_migrate/20220209111007_add_partial_index_for_batching_active_cluster_image_scanning_vulnerabilities.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d38509ed8c26742f2d0ce782a5d5d52079da5695
--- /dev/null
+++ b/db/post_migrate/20220209111007_add_partial_index_for_batching_active_cluster_image_scanning_vulnerabilities.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class AddPartialIndexForBatchingActiveClusterImageScanningVulnerabilities < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'index_vulnerabilities_on_project_id_and_id_active_cis'
+  INDEX_FILTER_CONDITION = 'report_type = 7 AND state = ANY(ARRAY[1, 4])'
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :vulnerabilities, [:project_id, :id], where: INDEX_FILTER_CONDITION, name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index :vulnerabilities, [:project_id, :id], name: INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220212120735_schedule_fix_incorrect_max_seats_used2.rb b/db/post_migrate/20220212120735_schedule_fix_incorrect_max_seats_used2.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c8a6bd0a15d28c37a495346c97bc428f58940690
--- /dev/null
+++ b/db/post_migrate/20220212120735_schedule_fix_incorrect_max_seats_used2.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class ScheduleFixIncorrectMaxSeatsUsed2 < Gitlab::Database::Migration[1.0]
+  MIGRATION = 'FixIncorrectMaxSeatsUsed'
+  TMP_IDX_NAME = 'tmp_gitlab_subscriptions_max_seats_used_migration_2'
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :gitlab_subscriptions, :id, where: "start_date < '2021-08-02' AND max_seats_used != 0 AND max_seats_used > seats_in_use AND max_seats_used > seats", name: TMP_IDX_NAME
+
+    return unless Gitlab.com?
+
+    migrate_in(1.hour, MIGRATION, ['batch_2_for_start_date_before_02_aug_2021'])
+  end
+
+  def down
+    remove_concurrent_index_by_name :gitlab_subscriptions, TMP_IDX_NAME
+  end
+end
diff --git a/db/post_migrate/20220213103859_remove_integrations_type.rb b/db/post_migrate/20220213103859_remove_integrations_type.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3c420760a2db768a1412ee36b46e39c079ac9cc3
--- /dev/null
+++ b/db/post_migrate/20220213103859_remove_integrations_type.rb
@@ -0,0 +1,132 @@
+# frozen_string_literal: true
+
+class RemoveIntegrationsType < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  MIGRATION = 'BackfillIntegrationsTypeNew'
+  BATCH_SIZE = 50
+  TABLE_NAME = :integrations
+  COLUMN = :type
+
+  # see db/post_migrate/20220213104531_create_indexes_on_integration_type_new.rb
+  def indices
+    [
+      {
+        name: "index_integrations_on_project_and_#{COLUMN}_where_inherit_null",
+        columns: [:project_id, COLUMN],
+        where: 'inherit_from_id IS NULL'
+      },
+      {
+        name: "index_integrations_on_project_id_and_#{COLUMN}_unique",
+        columns: [:project_id, COLUMN],
+        unique: true
+      },
+      {
+        name: "index_integrations_on_#{COLUMN}",
+        columns: [COLUMN]
+      },
+      {
+        name: "index_integrations_on_#{COLUMN}_and_instance_partial",
+        columns: [COLUMN, :instance],
+        where: 'instance = true',
+        unique: true
+      },
+      {
+        name: 'index_integrations_on_type_id_when_active_and_project_id_not_nu',
+        columns: [COLUMN, :id],
+        where: '((active = true) AND (project_id IS NOT NULL))'
+      },
+      {
+        name: "index_integrations_on_unique_group_id_and_#{COLUMN}",
+        columns: [:group_id, COLUMN],
+        unique: true
+      }
+    ]
+  end
+
+  def up
+    ensure_batched_background_migration_is_finished(
+      job_class_name: MIGRATION,
+      table_name: TABLE_NAME,
+      column_name: :id,
+      job_arguments: [])
+
+    cleanup_unmigrated_rows!
+
+    remove_column :integrations, :type, :text
+  end
+
+  # WARNING: this migration is not really safe to be reverted, since doing so
+  # will leave the type column empty. If this migration is reverted, we will
+  # need to backfill it from type_new
+  def down
+    add_column :integrations, :type, 'character varying'
+
+    indices.each do |index|
+      add_concurrent_index TABLE_NAME, index[:columns], index.except(:columns)
+    end
+  end
+
+  # Convert any remaining unmigrated rows
+  def cleanup_unmigrated_rows!
+    tmp_index_name = 'tmp_idx_integrations_unmigrated_type_new'
+    add_concurrent_index :integrations, :id, where: 'type_new is null', name: tmp_index_name
+
+    define_batchable_model(:integrations).where(type_new: nil).each_batch do |batch|
+      min_id, max_id = batch.pick(Arel.sql('MIN(id), MAX(id)'))
+
+      connection.execute(<<~SQL)
+          WITH mapping(old_type, new_type) AS (VALUES
+            ('AsanaService',                   'Integrations::Asana'),
+            ('AssemblaService',                'Integrations::Assembla'),
+            ('BambooService',                  'Integrations::Bamboo'),
+            ('BugzillaService',                'Integrations::Bugzilla'),
+            ('BuildkiteService',               'Integrations::Buildkite'),
+            ('CampfireService',                'Integrations::Campfire'),
+            ('ConfluenceService',              'Integrations::Confluence'),
+            ('CustomIssueTrackerService',      'Integrations::CustomIssueTracker'),
+            ('DatadogService',                 'Integrations::Datadog'),
+            ('DiscordService',                 'Integrations::Discord'),
+            ('DroneCiService',                 'Integrations::DroneCi'),
+            ('EmailsOnPushService',            'Integrations::EmailsOnPush'),
+            ('EwmService',                     'Integrations::Ewm'),
+            ('ExternalWikiService',            'Integrations::ExternalWiki'),
+            ('FlowdockService',                'Integrations::Flowdock'),
+            ('HangoutsChatService',            'Integrations::HangoutsChat'),
+            ('IrkerService',                   'Integrations::Irker'),
+            ('JenkinsService',                 'Integrations::Jenkins'),
+            ('JiraService',                    'Integrations::Jira'),
+            ('MattermostService',              'Integrations::Mattermost'),
+            ('MattermostSlashCommandsService', 'Integrations::MattermostSlashCommands'),
+            ('MicrosoftTeamsService',          'Integrations::MicrosoftTeams'),
+            ('MockCiService',                  'Integrations::MockCi'),
+            ('MockMonitoringService',          'Integrations::MockMonitoring'),
+            ('PackagistService',               'Integrations::Packagist'),
+            ('PipelinesEmailService',          'Integrations::PipelinesEmail'),
+            ('PivotaltrackerService',          'Integrations::Pivotaltracker'),
+            ('PrometheusService',              'Integrations::Prometheus'),
+            ('PushoverService',                'Integrations::Pushover'),
+            ('RedmineService',                 'Integrations::Redmine'),
+            ('SlackService',                   'Integrations::Slack'),
+            ('SlackSlashCommandsService',      'Integrations::SlackSlashCommands'),
+            ('TeamcityService',                'Integrations::Teamcity'),
+            ('UnifyCircuitService',            'Integrations::UnifyCircuit'),
+            ('WebexTeamsService',              'Integrations::WebexTeams'),
+            ('YoutrackService',                'Integrations::Youtrack'),
+
+            -- EE-only integrations
+            ('GithubService',                  'Integrations::Github'),
+            ('GitlabSlackApplicationService',  'Integrations::GitlabSlackApplication')
+          )
+
+          UPDATE integrations SET type_new = mapping.new_type
+          FROM mapping
+            WHERE integrations.type_new IS NULL
+            AND integrations.id BETWEEN #{min_id} AND #{max_id}
+            AND integrations.type = mapping.old_type
+      SQL
+    end
+  ensure
+    remove_concurrent_index_by_name(:integrations, tmp_index_name)
+  end
+end
diff --git a/db/post_migrate/20220213104531_create_indexes_on_integration_type_new.rb b/db/post_migrate/20220213104531_create_indexes_on_integration_type_new.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3a9f48dec4445883d40ec7e20162cfc2b75d715e
--- /dev/null
+++ b/db/post_migrate/20220213104531_create_indexes_on_integration_type_new.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+# Reproduce the indices on integrations.type on integrations.type_new
+class CreateIndexesOnIntegrationTypeNew < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  TABLE_NAME = :integrations
+  COLUMN = :type_new
+
+  def indices
+    [
+      {
+        name: "index_integrations_on_project_and_#{COLUMN}_where_inherit_null",
+        columns: [:project_id, COLUMN],
+        where: 'inherit_from_id IS NULL'
+      },
+      {
+        name: "index_integrations_on_project_id_and_#{COLUMN}_unique",
+        columns: [:project_id, COLUMN],
+        unique: true
+      },
+      {
+        name: "index_integrations_on_#{COLUMN}",
+        columns: [COLUMN]
+      },
+      {
+        name: "index_integrations_on_#{COLUMN}_and_instance_partial",
+        columns: [COLUMN, :instance],
+        where: 'instance = true'
+      },
+      {
+        name: "index_integrations_on_#{COLUMN}_and_template_partial",
+        columns: [COLUMN, :template],
+        where: 'template = true'
+      },
+      {
+        # column names are limited to 63 characters, so this one is re-worded for clarity
+        name: "index_integrations_on_#{COLUMN}_id_when_active_and_has_project",
+        columns: [COLUMN, :id],
+        where: '((active = true) AND (project_id IS NOT NULL))'
+      },
+      {
+        name: "index_integrations_on_unique_group_id_and_#{COLUMN}",
+        columns: [:group_id, COLUMN]
+      }
+    ]
+  end
+
+  def up
+    indices.each do |index|
+      add_concurrent_index TABLE_NAME, index[:columns], index.except(:columns)
+    end
+  end
+
+  def down
+    indices.each do |index|
+      remove_concurrent_index_by_name TABLE_NAME, index[:name]
+    end
+  end
+end
diff --git a/db/post_migrate/20220215190020_rerun_convert_stringified_raw_metadata_hash_to_json.rb b/db/post_migrate/20220215190020_rerun_convert_stringified_raw_metadata_hash_to_json.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1f36132c57853ade204a87ecbec219a7fc73803a
--- /dev/null
+++ b/db/post_migrate/20220215190020_rerun_convert_stringified_raw_metadata_hash_to_json.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class RerunConvertStringifiedRawMetadataHashToJson < Gitlab::Database::Migration[1.0]
+  MIGRATION_CLASS = Gitlab::BackgroundMigration::FixVulnerabilityOccurrencesWithHashesAsRawMetadata
+  MODEL_CLASS = MIGRATION_CLASS::Finding
+  DELAY_INTERVAL = 2.minutes
+  BATCH_SIZE = 500
+
+  disable_ddl_transaction!
+
+  def up
+    queue_background_migration_jobs_by_range_at_intervals(
+      MODEL_CLASS.by_api_report_types,
+      MIGRATION_CLASS.name.demodulize,
+      DELAY_INTERVAL,
+      batch_size: BATCH_SIZE,
+      track_jobs: true
+    )
+  end
+
+  def down
+    # no-op
+
+    # up fixes invalid data by updating columns in-place.
+    # It is a backwards-compatible change, and reversing it in a downgrade would not be desirable.
+  end
+end
diff --git a/db/post_migrate/20220216201949_remove_package_files_limit_from_application_settings.rb b/db/post_migrate/20220216201949_remove_package_files_limit_from_application_settings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..589b75dd91883e4cbb0b397708ef61323986d7bb
--- /dev/null
+++ b/db/post_migrate/20220216201949_remove_package_files_limit_from_application_settings.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class RemovePackageFilesLimitFromApplicationSettings < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    return unless column_exists?(:application_settings, :max_package_files_for_package_destruction)
+
+    remove_column :application_settings, :max_package_files_for_package_destruction, :smallint
+  end
+
+  def down
+    add_column :application_settings, :max_package_files_for_package_destruction, :smallint, default: 100, null: false
+    add_check_constraint :application_settings,
+                         'max_package_files_for_package_destruction > 0',
+                         'app_settings_max_package_files_for_package_destruction_positive'
+  end
+end
diff --git a/db/post_migrate/20220217135229_validate_not_null_constraint_on_security_findings_uuid.rb b/db/post_migrate/20220217135229_validate_not_null_constraint_on_security_findings_uuid.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9cc04cef757804f5c8c7804b3e836ae8a9477b54
--- /dev/null
+++ b/db/post_migrate/20220217135229_validate_not_null_constraint_on_security_findings_uuid.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class ValidateNotNullConstraintOnSecurityFindingsUuid < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    validate_not_null_constraint(:security_findings, :uuid)
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20220221214928_remove_show_diff_preview_in_email_column.rb b/db/post_migrate/20220221214928_remove_show_diff_preview_in_email_column.rb
new file mode 100644
index 0000000000000000000000000000000000000000..41cd3446c7aa06221172b1da7bef253c7203bb1f
--- /dev/null
+++ b/db/post_migrate/20220221214928_remove_show_diff_preview_in_email_column.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class RemoveShowDiffPreviewInEmailColumn < Gitlab::Database::Migration[1.0]
+  enable_lock_retries!
+
+  def up
+    remove_column :project_settings, :show_diff_preview_in_email, :boolean
+  end
+
+  def down
+    add_column :project_settings, :show_diff_preview_in_email, :boolean, default: true, null: false
+  end
+end
diff --git a/db/post_migrate/20220222191845_remove_not_null_constraint_for_security_scan_succeeded.rb b/db/post_migrate/20220222191845_remove_not_null_constraint_for_security_scan_succeeded.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4d4a20b83b3b0ed136c6c6616f9f95d509c155e2
--- /dev/null
+++ b/db/post_migrate/20220222191845_remove_not_null_constraint_for_security_scan_succeeded.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class RemoveNotNullConstraintForSecurityScanSucceeded < Gitlab::Database::Migration[1.0]
+  def up
+    change_column_null :analytics_devops_adoption_snapshots, :security_scan_succeeded, true
+  end
+
+  def down
+    # There may now be nulls in the table, so we cannot re-add the constraint here.
+  end
+end
diff --git a/db/post_migrate/20220222192524_create_not_null_constraint_releases_tag.rb b/db/post_migrate/20220222192524_create_not_null_constraint_releases_tag.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2bb5ba187433d17f148baa4a52a1385f63f4c6a5
--- /dev/null
+++ b/db/post_migrate/20220222192524_create_not_null_constraint_releases_tag.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class CreateNotNullConstraintReleasesTag < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    add_not_null_constraint :releases, :tag, constraint_name: 'releases_not_null_tag', validate: false
+  end
+
+  def down
+    remove_not_null_constraint :releases, :tag, constraint_name: 'releases_not_null_tag'
+  end
+end
diff --git a/db/post_migrate/20220222192525_remove_null_releases.rb b/db/post_migrate/20220222192525_remove_null_releases.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4efd5393122edc18ecf33b78329a233ff2115740
--- /dev/null
+++ b/db/post_migrate/20220222192525_remove_null_releases.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class RemoveNullReleases < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  class Release < ActiveRecord::Base
+    include EachBatch
+
+    self.table_name = 'releases'
+  end
+
+  def up
+    Release.all.each_batch(of: 25000) do |rel|
+      rel.where(tag: nil).delete_all
+    end
+  end
+
+  def down
+    # no-op
+    #
+    # releases with the same tag within a project have been removed
+    # and therefore the duplicate release data is no longer available
+  end
+end
diff --git a/db/post_migrate/20220223112304_schedule_nullify_orphan_runner_id_on_ci_builds.rb b/db/post_migrate/20220223112304_schedule_nullify_orphan_runner_id_on_ci_builds.rb
new file mode 100644
index 0000000000000000000000000000000000000000..10b6ab8204d289396f2b285460d8263b72b7c892
--- /dev/null
+++ b/db/post_migrate/20220223112304_schedule_nullify_orphan_runner_id_on_ci_builds.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class ScheduleNullifyOrphanRunnerIdOnCiBuilds < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  MIGRATION = 'NullifyOrphanRunnerIdOnCiBuilds'
+  INTERVAL = 2.minutes
+  BATCH_SIZE = 50_000
+  MAX_BATCH_SIZE = 150_000
+  SUB_BATCH_SIZE = 500
+
+  def up
+    queue_batched_background_migration(
+      MIGRATION,
+      :ci_builds,
+      :id,
+      job_interval: INTERVAL,
+      batch_size: BATCH_SIZE,
+      max_batch_size: MAX_BATCH_SIZE,
+      sub_batch_size: SUB_BATCH_SIZE
+    )
+  end
+
+  def down
+    delete_batched_background_migration(MIGRATION, :ci_builds, :id, [])
+  end
+end
diff --git a/db/post_migrate/20220223124428_schedule_merge_topics_with_same_name.rb b/db/post_migrate/20220223124428_schedule_merge_topics_with_same_name.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7e79c89203a669ccf325ef238e07e1d8e19059d9
--- /dev/null
+++ b/db/post_migrate/20220223124428_schedule_merge_topics_with_same_name.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class ScheduleMergeTopicsWithSameName < Gitlab::Database::Migration[1.0]
+  MIGRATION = 'MergeTopicsWithSameName'
+  BATCH_SIZE = 100
+
+  disable_ddl_transaction!
+
+  class Topic < ActiveRecord::Base
+    self.table_name = 'topics'
+  end
+
+  def up
+    Topic.select('LOWER(name) as name').group('LOWER(name)').having('COUNT(*) > 1').order('LOWER(name)')
+    .in_groups_of(BATCH_SIZE, false).each_with_index do |group, i|
+      migrate_in((i + 1) * 2.minutes, MIGRATION, [group.map(&:name)])
+    end
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20220224000000_async_build_trace_expire_at_index.rb b/db/post_migrate/20220224000000_async_build_trace_expire_at_index.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b22f3e7996f8bdf905fd8f42376404e4d7ff69fd
--- /dev/null
+++ b/db/post_migrate/20220224000000_async_build_trace_expire_at_index.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class AsyncBuildTraceExpireAtIndex < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'tmp_index_ci_job_artifacts_on_id_where_trace_and_expire_at'
+  TIMESTAMPS = "'2021-04-22 00:00:00', '2021-05-22 00:00:00', '2021-06-22 00:00:00', '2022-01-22 00:00:00', '2022-02-22 00:00:00', '2022-03-22 00:00:00', '2022-04-22 00:00:00'"
+
+  def up
+    prepare_async_index :ci_job_artifacts, :id, where: "file_type = 3 AND expire_at IN (#{TIMESTAMPS})", name: INDEX_NAME
+  end
+
+  def down
+    unprepare_async_index :ci_builds, :id, name: INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220224204415_recreate_index_security_ci_builds_on_name_and_id_parser_with_new_features.rb b/db/post_migrate/20220224204415_recreate_index_security_ci_builds_on_name_and_id_parser_with_new_features.rb
new file mode 100644
index 0000000000000000000000000000000000000000..feb0f2c83abf8ddbd76ac76f8329de5f9896eb6b
--- /dev/null
+++ b/db/post_migrate/20220224204415_recreate_index_security_ci_builds_on_name_and_id_parser_with_new_features.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+class RecreateIndexSecurityCiBuildsOnNameAndIdParserWithNewFeatures < Gitlab::Database::Migration[1.0]
+  TABLE = "ci_builds"
+  OLD_INDEX_NAME = "index_security_ci_builds_on_name_and_id_parser_features"
+  NEW_INDEX_NAME = "index_security_ci_builds_on_name_and_id_parser_features_old"
+  COLUMNS = %i[name id]
+  CONSTRAINTS = "(name::text = ANY (ARRAY['container_scanning'::character varying::text,
+                                         'dast'::character varying::text,
+                                         'dependency_scanning'::character varying::text,
+                                         'license_management'::character varying::text,
+                                         'sast'::character varying::text,
+                                         'secret_detection'::character varying::text,
+                                         'coverage_fuzzing'::character varying::text,
+                                         'license_scanning'::character varying::text,
+                                         'apifuzzer_fuzz'::character varying::text,
+                                         'apifuzzer_fuzz_dnd'::character varying::text])
+                ) AND type::text = 'Ci::Build'::text"
+
+  enable_lock_retries!
+
+  def up
+    rename_index(TABLE, OLD_INDEX_NAME, NEW_INDEX_NAME)
+    prepare_async_index TABLE, COLUMNS, name: OLD_INDEX_NAME, where: CONSTRAINTS
+  end
+
+  def down
+    unprepare_async_index TABLE, COLUMNS, name: OLD_INDEX_NAME
+    rename_index(TABLE, NEW_INDEX_NAME, OLD_INDEX_NAME)
+  end
+end
diff --git a/db/post_migrate/20220225133705_cleanup_backfill_ci_queuing_tables.rb b/db/post_migrate/20220225133705_cleanup_backfill_ci_queuing_tables.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4fcf8a287277af0b38dbb01f668074a81fec5bc1
--- /dev/null
+++ b/db/post_migrate/20220225133705_cleanup_backfill_ci_queuing_tables.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class CleanupBackfillCiQueuingTables < Gitlab::Database::Migration[1.0]
+  MIGRATION = 'BackfillCiQueuingTables'
+
+  disable_ddl_transaction!
+
+  def up
+    finalize_background_migration(MIGRATION)
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20220301093434_backfill_all_project_namespaces.rb b/db/post_migrate/20220301093434_backfill_all_project_namespaces.rb
new file mode 100644
index 0000000000000000000000000000000000000000..607161004cfc3fb7c5a194eaa10fff5d3255a5ed
--- /dev/null
+++ b/db/post_migrate/20220301093434_backfill_all_project_namespaces.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+class BackfillAllProjectNamespaces < Gitlab::Database::Migration[1.0]
+  MIGRATION = 'ProjectNamespaces::BackfillProjectNamespaces'
+  DELAY_INTERVAL = 2.minutes
+  BATCH_SIZE = 1_000
+  MAX_BATCH_SIZE = 5_000
+  SUB_BATCH_SIZE = 10
+
+  disable_ddl_transaction!
+
+  def up
+    queue_batched_background_migration(
+      MIGRATION,
+      :projects,
+      :id,
+      nil,
+      'up',
+      job_interval: DELAY_INTERVAL,
+      batch_size: BATCH_SIZE,
+      max_batch_size: MAX_BATCH_SIZE,
+      sub_batch_size: SUB_BATCH_SIZE
+    )
+  end
+
+  def down
+    delete_batched_background_migration(MIGRATION, :projects, :id, [nil, 'up'])
+  end
+end
diff --git a/db/post_migrate/20220302114046_backfill_group_features.rb b/db/post_migrate/20220302114046_backfill_group_features.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5e0ff9095a38bd0d4203ce21f7dbb1263b4b3080
--- /dev/null
+++ b/db/post_migrate/20220302114046_backfill_group_features.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class BackfillGroupFeatures < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  MIGRATION = 'BackfillGroupFeatures'
+  INTERVAL = 2.minutes
+  BATCH_SIZE = 10_000
+  SUB_BATCH_SIZE = 1_000
+
+  def up
+    queue_batched_background_migration(
+      MIGRATION,
+      :namespaces,
+      :id,
+      BATCH_SIZE,
+      job_interval: INTERVAL,
+      batch_size: BATCH_SIZE,
+      max_batch_size: BATCH_SIZE,
+      sub_batch_size: SUB_BATCH_SIZE
+    )
+  end
+
+  def down
+    delete_batched_background_migration(MIGRATION, :namespaces, :id, [BATCH_SIZE])
+  end
+end
diff --git a/db/post_migrate/20220302203410_create_index_security_ci_builds_on_name_and_id_parser_with_new_features.rb b/db/post_migrate/20220302203410_create_index_security_ci_builds_on_name_and_id_parser_with_new_features.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5be6bb002693371e4cfa319cef29a02f3e7c3510
--- /dev/null
+++ b/db/post_migrate/20220302203410_create_index_security_ci_builds_on_name_and_id_parser_with_new_features.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+class CreateIndexSecurityCiBuildsOnNameAndIdParserWithNewFeatures < Gitlab::Database::Migration[1.0]
+  TABLE = "ci_builds"
+  COLUMNS = %i[name id]
+  INDEX_NAME = "index_security_ci_builds_on_name_and_id_parser_features"
+  CONSTRAINTS = "(name::text = ANY (ARRAY['container_scanning'::character varying::text,
+                                         'dast'::character varying::text,
+                                         'dependency_scanning'::character varying::text,
+                                         'license_management'::character varying::text,
+                                         'sast'::character varying::text,
+                                         'secret_detection'::character varying::text,
+                                         'coverage_fuzzing'::character varying::text,
+                                         'license_scanning'::character varying::text,
+                                         'apifuzzer_fuzz'::character varying::text,
+                                         'apifuzzer_fuzz_dnd'::character varying::text])
+                ) AND type::text = 'Ci::Build'::text"
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index(TABLE, COLUMNS, name: INDEX_NAME, where: CONSTRAINTS)
+  end
+
+  def down
+    remove_concurrent_index(TABLE, COLUMNS, name: INDEX_NAME, where: CONSTRAINTS)
+  end
+end
diff --git a/db/post_migrate/20220304165107_drop_partitioned_foreign_keys.rb b/db/post_migrate/20220304165107_drop_partitioned_foreign_keys.rb
new file mode 100644
index 0000000000000000000000000000000000000000..43f89b05fa483af030501733ddd35d3ecbbdff27
--- /dev/null
+++ b/db/post_migrate/20220304165107_drop_partitioned_foreign_keys.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class DropPartitionedForeignKeys < Gitlab::Database::Migration[1.0]
+  def up
+    drop_table :partitioned_foreign_keys
+  end
+
+  def down
+    create_table :partitioned_foreign_keys do |t|
+      t.boolean :cascade_delete, null: false, default: true
+      t.text :from_table, null: false, limit: 63
+      t.text :from_column, null: false, limit: 63
+      t.text :to_table, null: false, limit: 63
+      t.text :to_column, null: false, limit: 63
+
+      t.index [:to_table, :from_table, :from_column], unique: true, name: :index_partitioned_foreign_keys_unique_index
+    end
+  end
+end
diff --git a/db/post_migrate/20220304201847_add_unique_index_on_security_training_providers.rb b/db/post_migrate/20220304201847_add_unique_index_on_security_training_providers.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e78b8fd48cae5ef98004b7395c46935c7c2855ba
--- /dev/null
+++ b/db/post_migrate/20220304201847_add_unique_index_on_security_training_providers.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddUniqueIndexOnSecurityTrainingProviders < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'index_security_training_providers_on_unique_name'
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :security_training_providers, :name, unique: true, name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :security_training_providers, INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220305223212_add_security_training_providers.rb b/db/post_migrate/20220305223212_add_security_training_providers.rb
new file mode 100644
index 0000000000000000000000000000000000000000..fbddee0ae9993320483bf265b18b8a1354141170
--- /dev/null
+++ b/db/post_migrate/20220305223212_add_security_training_providers.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+class AddSecurityTrainingProviders < Gitlab::Database::Migration[1.0]
+  KONTRA_DATA = {
+    name: 'Kontra',
+    description: "Kontra Application Security provides interactive developer security education that
+                  enables engineers to quickly learn security best practices
+                  and fix issues in their code by analysing real-world software security vulnerabilities.",
+    url: "https://application.security/api/webhook/gitlab/exercises/search"
+  }
+
+  SCW_DATA = {
+    name: 'Secure Code Warrior',
+    description: "Resolve vulnerabilities faster and confidently with highly relevant and bite-sized secure coding learning.",
+    url: "https://integration-api.securecodewarrior.com/api/v1/trial"
+  }
+
+  module Security
+    class TrainingProvider < ActiveRecord::Base
+      self.table_name = 'security_training_providers'
+    end
+  end
+
+  def up
+    current_time = Time.current
+    timestamps = { created_at: current_time, updated_at: current_time }
+
+    Security::TrainingProvider.reset_column_information
+
+    # upsert providers
+    Security::TrainingProvider.upsert_all([KONTRA_DATA.merge(timestamps), SCW_DATA.merge(timestamps)])
+  end
+
+  def down
+    Security::TrainingProvider.reset_column_information
+
+    Security::TrainingProvider.find_by(name: KONTRA_DATA[:name])&.destroy
+    Security::TrainingProvider.find_by(name: SCW_DATA[:name])&.destroy
+  end
+end
diff --git a/db/post_migrate/20220307192534_create_index_for_remove_duplicate_project_tag_releases.rb b/db/post_migrate/20220307192534_create_index_for_remove_duplicate_project_tag_releases.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3e580c013c3035f257e697f9ccb7ac4b5c3d2074
--- /dev/null
+++ b/db/post_migrate/20220307192534_create_index_for_remove_duplicate_project_tag_releases.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class CreateIndexForRemoveDuplicateProjectTagReleases < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'index_releases_on_id_project_id_tag'
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :releases,
+                         %i[project_id tag id],
+                         name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :releases, name: INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220307192610_remove_duplicate_project_tag_releases.rb b/db/post_migrate/20220307192610_remove_duplicate_project_tag_releases.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d8b9938082524b2662de05f16e5994c60cbe39e9
--- /dev/null
+++ b/db/post_migrate/20220307192610_remove_duplicate_project_tag_releases.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class RemoveDuplicateProjectTagReleases < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  class Release < ActiveRecord::Base
+    include EachBatch
+
+    self.table_name = 'releases'
+  end
+
+  def up
+    Release.each_batch(of: 5000) do |relation|
+      relation
+        .where('exists (select 1 from releases r2 where r2.project_id = releases.project_id and r2.tag = releases.tag and r2.id > releases.id)')
+        .delete_all
+    end
+  end
+
+  def down
+    # no-op
+    #
+    # releases with the same tag within a project have been removed
+    # and therefore the duplicate release data is no longer available
+  end
+end
diff --git a/db/post_migrate/20220307192645_remove_index_for_remove_duplicate_project_tag_releases.rb b/db/post_migrate/20220307192645_remove_index_for_remove_duplicate_project_tag_releases.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8efb24daff96f1fee12c0dd40cf553e88419e348
--- /dev/null
+++ b/db/post_migrate/20220307192645_remove_index_for_remove_duplicate_project_tag_releases.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveIndexForRemoveDuplicateProjectTagReleases < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'index_releases_on_id_project_id_tag'
+
+  disable_ddl_transaction!
+
+  def up
+    remove_concurrent_index_by_name :releases, name: INDEX_NAME
+  end
+
+  def down
+    add_concurrent_index :releases,
+                         %i[project_id tag id],
+                         name: INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220307192725_create_unique_index_release_tag_project.rb b/db/post_migrate/20220307192725_create_unique_index_release_tag_project.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8540f19f0796fbe48edc15e0d51f63690296a0ea
--- /dev/null
+++ b/db/post_migrate/20220307192725_create_unique_index_release_tag_project.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class CreateUniqueIndexReleaseTagProject < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'index_releases_on_project_tag_unique'
+  OLD_INDEX_NAME = 'index_releases_on_project_id_and_tag'
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :releases,
+                         %i[project_id tag],
+                         unique: true,
+                         name: INDEX_NAME
+    remove_concurrent_index_by_name :releases, name: OLD_INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :releases, name: INDEX_NAME
+    add_concurrent_index :releases,
+                         %i[project_id tag],
+                         name: OLD_INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220307203459_rename_user_email_lookup_limit_setting_to_search_settings_cleanup.rb b/db/post_migrate/20220307203459_rename_user_email_lookup_limit_setting_to_search_settings_cleanup.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2d01374780d326581a66e44029fe197c037527d7
--- /dev/null
+++ b/db/post_migrate/20220307203459_rename_user_email_lookup_limit_setting_to_search_settings_cleanup.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RenameUserEmailLookupLimitSettingToSearchSettingsCleanup < Gitlab::Database::Migration[1.0]
+  class ApplicationSetting < ActiveRecord::Base
+    self.table_name = :application_settings
+  end
+
+  def up
+    ApplicationSetting.update_all 'search_rate_limit=user_email_lookup_limit'
+  end
+
+  def down
+    ApplicationSetting.update_all 'user_email_lookup_limit=search_rate_limit'
+  end
+end
diff --git a/db/post_migrate/20220308000205_drop_old_index_security_ci_builds_on_name_and_id_parser_features.rb b/db/post_migrate/20220308000205_drop_old_index_security_ci_builds_on_name_and_id_parser_features.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4b895c291d890652e9f93764afc896e30e9ec45b
--- /dev/null
+++ b/db/post_migrate/20220308000205_drop_old_index_security_ci_builds_on_name_and_id_parser_features.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class DropOldIndexSecurityCiBuildsOnNameAndIdParserFeatures < Gitlab::Database::Migration[1.0]
+  TABLE = "ci_builds"
+  COLUMNS = %i[name id]
+  INDEX_NAME = "index_security_ci_builds_on_name_and_id_parser_features_old"
+  CONSTRAINTS = "(name::text = ANY (ARRAY['container_scanning'::character varying::text,
+                                         'dast'::character varying::text,
+                                         'dependency_scanning'::character varying::text,
+                                         'license_management'::character varying::text,
+                                         'sast'::character varying::text,
+                                         'secret_detection'::character varying::text,
+                                         'coverage_fuzzing'::character varying::text,
+                                         'license_scanning'::character varying::text])
+                ) AND type::text = 'Ci::Build'::text"
+
+  disable_ddl_transaction!
+
+  def up
+    remove_concurrent_index(TABLE, COLUMNS, name: INDEX_NAME, where: CONSTRAINTS)
+  end
+
+  def down
+    add_concurrent_index(TABLE, COLUMNS, name: INDEX_NAME, where: CONSTRAINTS)
+  end
+end
diff --git a/db/post_migrate/20220308115219_schedule_reset_duplicate_ci_runners_token_encrypted_values_on_projects.rb b/db/post_migrate/20220308115219_schedule_reset_duplicate_ci_runners_token_encrypted_values_on_projects.rb
new file mode 100644
index 0000000000000000000000000000000000000000..27e7af9a550d17a4f3f38602f5b3b67d2df5e6c3
--- /dev/null
+++ b/db/post_migrate/20220308115219_schedule_reset_duplicate_ci_runners_token_encrypted_values_on_projects.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class ScheduleResetDuplicateCiRunnersTokenEncryptedValuesOnProjects < Gitlab::Database::Migration[1.0]
+  MIGRATION = 'ResetDuplicateCiRunnersTokenEncryptedValuesOnProjects'
+  TOKEN_COLUMN_NAME = :runners_token_encrypted
+  TEMP_INDEX_NAME = "tmp_index_projects_on_id_and_#{TOKEN_COLUMN_NAME}"
+  BATCH_SIZE = 10_000
+  DELAY_INTERVAL = 2.minutes
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :projects, [:id, TOKEN_COLUMN_NAME], where: "#{TOKEN_COLUMN_NAME} IS NOT NULL", unique: false, name: TEMP_INDEX_NAME
+
+    queue_background_migration_jobs_by_range_at_intervals(
+      Gitlab::BackgroundMigration::ResetDuplicateCiRunnersTokenEncryptedValuesOnProjects::Project.base_query,
+      MIGRATION,
+      DELAY_INTERVAL,
+      batch_size: BATCH_SIZE,
+      track_jobs: true
+    )
+  end
+
+  def down
+    remove_concurrent_index_by_name(:projects, name: TEMP_INDEX_NAME)
+  end
+end
diff --git a/db/post_migrate/20220308115502_schedule_reset_duplicate_ci_runners_token_values_on_projects.rb b/db/post_migrate/20220308115502_schedule_reset_duplicate_ci_runners_token_values_on_projects.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f076b0a740e6662eea6242596da326baca1b2916
--- /dev/null
+++ b/db/post_migrate/20220308115502_schedule_reset_duplicate_ci_runners_token_values_on_projects.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class ScheduleResetDuplicateCiRunnersTokenValuesOnProjects < Gitlab::Database::Migration[1.0]
+  MIGRATION = 'ResetDuplicateCiRunnersTokenValuesOnProjects'
+  TOKEN_COLUMN_NAME = :runners_token
+  TEMP_INDEX_NAME = "tmp_index_projects_on_id_and_#{TOKEN_COLUMN_NAME}"
+  BATCH_SIZE = 10_000
+  DELAY_INTERVAL = 2.minutes
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :projects, [:id, TOKEN_COLUMN_NAME], where: "#{TOKEN_COLUMN_NAME} IS NOT NULL", unique: false, name: TEMP_INDEX_NAME
+
+    queue_background_migration_jobs_by_range_at_intervals(
+      Gitlab::BackgroundMigration::ResetDuplicateCiRunnersTokenValuesOnProjects::Project.base_query,
+      MIGRATION,
+      DELAY_INTERVAL,
+      batch_size: BATCH_SIZE,
+      track_jobs: true
+    )
+  end
+
+  def down
+    remove_concurrent_index_by_name(:projects, name: TEMP_INDEX_NAME)
+  end
+end
diff --git a/db/post_migrate/20220309084838_remove_external_pull_request_tracking.rb b/db/post_migrate/20220309084838_remove_external_pull_request_tracking.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6159f9d68220bd41b01e377e4a068ea8efe5f5cd
--- /dev/null
+++ b/db/post_migrate/20220309084838_remove_external_pull_request_tracking.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveExternalPullRequestTracking < Gitlab::Database::Migration[1.0]
+  include Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers
+
+  enable_lock_retries!
+
+  def up
+    untrack_record_deletions(:external_pull_requests)
+  end
+
+  def down
+    track_record_deletions(:external_pull_requests)
+  end
+end
diff --git a/db/post_migrate/20220309084954_remove_leftover_external_pull_request_deletions.rb b/db/post_migrate/20220309084954_remove_leftover_external_pull_request_deletions.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ea9fd6b28c2b70316aa922901a7bf3fd90eb3c1e
--- /dev/null
+++ b/db/post_migrate/20220309084954_remove_leftover_external_pull_request_deletions.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+class RemoveLeftoverExternalPullRequestDeletions < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    # Delete all pending record deletions in the public.external_pull_requests until
+    # there are no more rows left.
+    loop do
+      result = execute <<~SQL
+      DELETE FROM "loose_foreign_keys_deleted_records"
+      WHERE
+      ("loose_foreign_keys_deleted_records"."partition", "loose_foreign_keys_deleted_records"."id") IN (
+        SELECT "loose_foreign_keys_deleted_records"."partition", "loose_foreign_keys_deleted_records"."id"
+        FROM "loose_foreign_keys_deleted_records"
+        WHERE
+        "loose_foreign_keys_deleted_records"."fully_qualified_table_name" = 'public.external_pull_requests' AND
+        "loose_foreign_keys_deleted_records"."status" = 1
+        LIMIT 100
+      )
+      SQL
+
+      break if result.cmd_tuples == 0
+    end
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20220309154855_add_index_on_issues_closed_incidents.rb b/db/post_migrate/20220309154855_add_index_on_issues_closed_incidents.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e9a2c1c85f27073ff30c706f739128b99866ab52
--- /dev/null
+++ b/db/post_migrate/20220309154855_add_index_on_issues_closed_incidents.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddIndexOnIssuesClosedIncidents < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_on_issues_closed_incidents_by_project_id_and_closed_at'
+
+  def up
+    add_concurrent_index :issues, [:project_id, :closed_at], where: "issue_type = 1 AND state_id = 2", name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :issues, INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220310095341_add_async_index_ci_job_artifacts_project_id_created_at.rb b/db/post_migrate/20220310095341_add_async_index_ci_job_artifacts_project_id_created_at.rb
new file mode 100644
index 0000000000000000000000000000000000000000..919e834a78374d697f6aa17da9e83f67a358a929
--- /dev/null
+++ b/db/post_migrate/20220310095341_add_async_index_ci_job_artifacts_project_id_created_at.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+# See https://docs.gitlab.com/ee/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class AddAsyncIndexCiJobArtifactsProjectIdCreatedAt < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'index_ci_job_artifacts_on_id_project_id_and_created_at'
+
+  def up
+    prepare_async_index :ci_job_artifacts, [:project_id, :created_at, :id], name: INDEX_NAME
+  end
+
+  def down
+    unprepare_async_index_by_name :ci_job_artifacts, INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220310134207_add_index_project_id_and_released_at_and_id_on_releases.rb b/db/post_migrate/20220310134207_add_index_project_id_and_released_at_and_id_on_releases.rb
new file mode 100644
index 0000000000000000000000000000000000000000..da928f3ec8fb57fee3145f2c8215a9e9a95701b8
--- /dev/null
+++ b/db/post_migrate/20220310134207_add_index_project_id_and_released_at_and_id_on_releases.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class AddIndexProjectIdAndReleasedAtAndIdOnReleases < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'index_releases_on_project_id_and_released_at_and_id'
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :releases, [:project_id, :released_at, :id],
+      name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :releases, INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220310141349_remove_dependency_list_usage_data_from_redis.rb b/db/post_migrate/20220310141349_remove_dependency_list_usage_data_from_redis.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3c1e671452917379593b7fd67694f4b7b587e85a
--- /dev/null
+++ b/db/post_migrate/20220310141349_remove_dependency_list_usage_data_from_redis.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class RemoveDependencyListUsageDataFromRedis < Gitlab::Database::Migration[1.0]
+  disable_ddl_transaction!
+
+  def up
+    Gitlab::Redis::SharedState.with { |r| r.del("DEPENDENCY_LIST_USAGE_COUNTER") }
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20220311010352_create_scan_id_and_id_index_on_security_findings.rb b/db/post_migrate/20220311010352_create_scan_id_and_id_index_on_security_findings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1b72c4b0a7882a407b7d1f3f2f022ac4a523d44d
--- /dev/null
+++ b/db/post_migrate/20220311010352_create_scan_id_and_id_index_on_security_findings.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class CreateScanIdAndIdIndexOnSecurityFindings < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'index_security_findings_on_scan_id_and_id'
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :security_findings, [:scan_id, :id], name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :security_findings, INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20220314154235_migrate_vulnerability_approval_rules.rb b/db/post_migrate/20220314154235_migrate_vulnerability_approval_rules.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f9ad2ba4f0caced819760105a4640a62a2f44179
--- /dev/null
+++ b/db/post_migrate/20220314154235_migrate_vulnerability_approval_rules.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+# See https://docs.gitlab.com/ee/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class MigrateVulnerabilityApprovalRules < Gitlab::Database::Migration[2.0]
+  restrict_gitlab_migration gitlab_schema: :gitlab_main
+
+  def up
+    # no-op
+  end
+
+  def down
+    # no-op
+    # Vulnerability-Check feature has been removed as part of 15.0
+  end
+end
diff --git a/db/post_migrate/20220314162342_add_index_ci_job_artifacts_project_id_created_at.rb b/db/post_migrate/20220314162342_add_index_ci_job_artifacts_project_id_created_at.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7241fd54cb3a226ddc4f98f23e86e686ac8c7cb4
--- /dev/null
+++ b/db/post_migrate/20220314162342_add_index_ci_job_artifacts_project_id_created_at.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddIndexCiJobArtifactsProjectIdCreatedAt < Gitlab::Database::Migration[1.0]
+  INDEX_NAME = 'index_ci_job_artifacts_on_id_project_id_and_created_at'
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :ci_job_artifacts, [:project_id, :created_at, :id], name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :ci_job_artifacts, INDEX_NAME
+  end
+end
diff --git a/db/schema_migrations/20211202041233 b/db/schema_migrations/20211202041233
new file mode 100644
index 0000000000000000000000000000000000000000..fb19264fbd584e85aa38410f844caa1428867811
--- /dev/null
+++ b/db/schema_migrations/20211202041233
@@ -0,0 +1 @@
+61c949b42338b248a0950cfafc82d58816c3fec44a2bf41c4ecb4cf09340a424
\ No newline at end of file
diff --git a/db/schema_migrations/20211202094944 b/db/schema_migrations/20211202094944
new file mode 100644
index 0000000000000000000000000000000000000000..b917cca67faf70ee1a0d977a84d846c604893611
--- /dev/null
+++ b/db/schema_migrations/20211202094944
@@ -0,0 +1 @@
+2bca61880005c9303b2ff71747cde64d3418b6ef8ad2a9f114d584f4149e386b
\ No newline at end of file
diff --git a/db/schema_migrations/20211202135508 b/db/schema_migrations/20211202135508
new file mode 100644
index 0000000000000000000000000000000000000000..6ca4701268db3b35e3393e8415a5f9ee47490e72
--- /dev/null
+++ b/db/schema_migrations/20211202135508
@@ -0,0 +1 @@
+b565abbbb43f04ba4a6b77154ecb24b30328ac6d964f4be9fc5f9d05144606f0
\ No newline at end of file
diff --git a/db/schema_migrations/20211202145237 b/db/schema_migrations/20211202145237
new file mode 100644
index 0000000000000000000000000000000000000000..f5b91a189c87b915db5fa15017d10794037eeb5f
--- /dev/null
+++ b/db/schema_migrations/20211202145237
@@ -0,0 +1 @@
+d109142aa838faedcd307f6cd235c969ca265813493eef50d63cbc2fe5d203b3
\ No newline at end of file
diff --git a/db/schema_migrations/20211203091642 b/db/schema_migrations/20211203091642
new file mode 100644
index 0000000000000000000000000000000000000000..ef53b1d2ed9db840835ba6d3f2166aecf4926ae9
--- /dev/null
+++ b/db/schema_migrations/20211203091642
@@ -0,0 +1 @@
+9954fb041a3f284f53cc9c5c68b1a9dff36513a1851e663c221eccd40736fb16
\ No newline at end of file
diff --git a/db/schema_migrations/20211203160952 b/db/schema_migrations/20211203160952
new file mode 100644
index 0000000000000000000000000000000000000000..10d033ef2008cd4b8159e54344f3ac0dd0afdf19
--- /dev/null
+++ b/db/schema_migrations/20211203160952
@@ -0,0 +1 @@
+f25c65dfcb5b7b4a663cc4c792ffd985f6afd3156036485a5a43a791ee799e7b
\ No newline at end of file
diff --git a/db/schema_migrations/20211203161149 b/db/schema_migrations/20211203161149
new file mode 100644
index 0000000000000000000000000000000000000000..3f58490a89c5b9bb594a7ab2e898fcfce3bf8f4d
--- /dev/null
+++ b/db/schema_migrations/20211203161149
@@ -0,0 +1 @@
+01482a299a7dac9d3f786f0dbe4650c686911bf788467146d3e9a91eafd0fc32
\ No newline at end of file
diff --git a/db/schema_migrations/20211203161840 b/db/schema_migrations/20211203161840
new file mode 100644
index 0000000000000000000000000000000000000000..347bd0f7691d0b4d6de9f2c2ac809d0420ec84c9
--- /dev/null
+++ b/db/schema_migrations/20211203161840
@@ -0,0 +1 @@
+1b895e979ba2f1696559179c46c000e349da2d1ab94c968dd95103f188425103
\ No newline at end of file
diff --git a/db/schema_migrations/20211203161942 b/db/schema_migrations/20211203161942
new file mode 100644
index 0000000000000000000000000000000000000000..f43c37333923ccacf62c0d14284f356408bac638
--- /dev/null
+++ b/db/schema_migrations/20211203161942
@@ -0,0 +1 @@
+62432b2679cafa381671c9555f503867c254a7b3734e10cf634b34998d5fb5a3
\ No newline at end of file
diff --git a/db/schema_migrations/20211204010826 b/db/schema_migrations/20211204010826
new file mode 100644
index 0000000000000000000000000000000000000000..11311e66ad0ff42f0c486844e1e645e01974088c
--- /dev/null
+++ b/db/schema_migrations/20211204010826
@@ -0,0 +1 @@
+6a3591e70ddd6573ad68360c1a8774ef61e7812ce831c75066baec5754e2bd76
\ No newline at end of file
diff --git a/db/schema_migrations/20211206073851 b/db/schema_migrations/20211206073851
new file mode 100644
index 0000000000000000000000000000000000000000..bfd8140b10966b85c07f08e651a219747115815f
--- /dev/null
+++ b/db/schema_migrations/20211206073851
@@ -0,0 +1 @@
+403592fda1d82ed3c3fb8d5315593b67954a4ecbc368d9bcd5eedc75bb3c9821
\ No newline at end of file
diff --git a/db/schema_migrations/20211206074547 b/db/schema_migrations/20211206074547
new file mode 100644
index 0000000000000000000000000000000000000000..dd84a987827bcec23114d0c3aa85e1d3ccf52c14
--- /dev/null
+++ b/db/schema_migrations/20211206074547
@@ -0,0 +1 @@
+ba1c0d20e21ef51278109d0eaeb23f1c541eb5eb9aeb9a92583ee6de83c68918
\ No newline at end of file
diff --git a/db/schema_migrations/20211206161271 b/db/schema_migrations/20211206161271
new file mode 100644
index 0000000000000000000000000000000000000000..8a2561eec24aef7faeb7fbc48dc6eab7e3cf50d0
--- /dev/null
+++ b/db/schema_migrations/20211206161271
@@ -0,0 +1 @@
+fa4a39c3bea70d31e8144f8830ef0353f22a7a663a891d9043e79f362058fbde
\ No newline at end of file
diff --git a/db/schema_migrations/20211207081708 b/db/schema_migrations/20211207081708
new file mode 100644
index 0000000000000000000000000000000000000000..b2fbb704451dfc15b34897c53d7c941ee445c8f6
--- /dev/null
+++ b/db/schema_migrations/20211207081708
@@ -0,0 +1 @@
+e26065e63eca51e4138b6e9f07e9ec1ee45838afa82c5832849e360375beeae2
\ No newline at end of file
diff --git a/db/schema_migrations/20211207090503 b/db/schema_migrations/20211207090503
new file mode 100644
index 0000000000000000000000000000000000000000..13daa5c81e67cdd4f1cc2c445ea20e9af995a84d
--- /dev/null
+++ b/db/schema_migrations/20211207090503
@@ -0,0 +1 @@
+c30656c3f079e789f386b5b607710a7d4df6d2eb20bd457bab3a2e8d9eeb051b
\ No newline at end of file
diff --git a/db/schema_migrations/20211207125331 b/db/schema_migrations/20211207125331
new file mode 100644
index 0000000000000000000000000000000000000000..833d5d0a3833bda6f23f9bd3bf173704645af146
--- /dev/null
+++ b/db/schema_migrations/20211207125331
@@ -0,0 +1 @@
+5ead867b7609248f702771078849c48c0558f5fe9a3021fbb32e4f9174af653a
\ No newline at end of file
diff --git a/db/schema_migrations/20211207135331 b/db/schema_migrations/20211207135331
new file mode 100644
index 0000000000000000000000000000000000000000..b4085490cc839781e0ffb924832ce91e03276331
--- /dev/null
+++ b/db/schema_migrations/20211207135331
@@ -0,0 +1 @@
+3d9dcab49ee409da8c1ab398101041092e566b06a7bb2764db49a9201a0e5f0c
\ No newline at end of file
diff --git a/db/schema_migrations/20211207154413 b/db/schema_migrations/20211207154413
new file mode 100644
index 0000000000000000000000000000000000000000..26bc9a4763241ea35477ede03c2010d0278d0d62
--- /dev/null
+++ b/db/schema_migrations/20211207154413
@@ -0,0 +1 @@
+98098b41864158fc4de3b8fe42603b2c0c5c2fbc664397c431712311bdaa3621
\ No newline at end of file
diff --git a/db/schema_migrations/20211207154414 b/db/schema_migrations/20211207154414
new file mode 100644
index 0000000000000000000000000000000000000000..c7e1f8de4d1bacdb78f2518f1a92687a9b1cc96a
--- /dev/null
+++ b/db/schema_migrations/20211207154414
@@ -0,0 +1 @@
+278907a15d04b455aa852eb9d17000c6b353be6ef78a8dcc2e71a9772a6e43ea
\ No newline at end of file
diff --git a/db/schema_migrations/20211207165508 b/db/schema_migrations/20211207165508
new file mode 100644
index 0000000000000000000000000000000000000000..df0c91bad7da911014cc4ef4a148dc28cd325a1e
--- /dev/null
+++ b/db/schema_migrations/20211207165508
@@ -0,0 +1 @@
+d1ed3ddf51c0bcebbac2a8dee05aa168daa35129110a463ac296ff2e640b0dbd
\ No newline at end of file
diff --git a/db/schema_migrations/20211207173510 b/db/schema_migrations/20211207173510
new file mode 100644
index 0000000000000000000000000000000000000000..09474e1c6439b23e058ea6eb62d11cfc5bbe86e9
--- /dev/null
+++ b/db/schema_migrations/20211207173510
@@ -0,0 +1 @@
+0a4ac9de84b8351f39e549904d9e661648b496e6e3183c4ff5eb22b70d5ba7e9
\ No newline at end of file
diff --git a/db/schema_migrations/20211207173511 b/db/schema_migrations/20211207173511
new file mode 100644
index 0000000000000000000000000000000000000000..93b44c20390af845711cae0fe405ef8867edf6c0
--- /dev/null
+++ b/db/schema_migrations/20211207173511
@@ -0,0 +1 @@
+8f41f45c5ef23eafae2e67951497b5752f4b30ecf73ae3c08f61febfa4fb17be
\ No newline at end of file
diff --git a/db/schema_migrations/20211208111425 b/db/schema_migrations/20211208111425
new file mode 100644
index 0000000000000000000000000000000000000000..0b1aa9199b6b01f125e8b0238ee176d8eb1c2a6c
--- /dev/null
+++ b/db/schema_migrations/20211208111425
@@ -0,0 +1 @@
+1e3f29ed1a820588da9fe135fbdd0feaa960038b99397dbd7921d4804dce1e1f
\ No newline at end of file
diff --git a/db/schema_migrations/20211208122200 b/db/schema_migrations/20211208122200
new file mode 100644
index 0000000000000000000000000000000000000000..1e4910d3a3cd6effbdf98aaef2193a2c0923f9f7
--- /dev/null
+++ b/db/schema_migrations/20211208122200
@@ -0,0 +1 @@
+8dec4379f34773e979cf6b33ba608185827c37b1a95c74d6472b7562c16d6110
\ No newline at end of file
diff --git a/db/schema_migrations/20211208122201 b/db/schema_migrations/20211208122201
new file mode 100644
index 0000000000000000000000000000000000000000..fb770a6d5fdb73cd73da780b801b0eb01a240f9d
--- /dev/null
+++ b/db/schema_migrations/20211208122201
@@ -0,0 +1 @@
+f58ccb07fa67ede2a50fa5ff6bddbe4bb89a622e84786fc4bfb404c11b9dbab4
\ No newline at end of file
diff --git a/db/schema_migrations/20211208171402 b/db/schema_migrations/20211208171402
new file mode 100644
index 0000000000000000000000000000000000000000..a563797dea5b599dfd5b41bb0902e1a7845ba7ae
--- /dev/null
+++ b/db/schema_migrations/20211208171402
@@ -0,0 +1 @@
+09a9e7fc042aab19bf768a79401f33b6e7408acff303fc0ee68360dfd7605101
\ No newline at end of file
diff --git a/db/schema_migrations/20211209093636 b/db/schema_migrations/20211209093636
new file mode 100644
index 0000000000000000000000000000000000000000..2d2601ff51cecc5f051680576d48473518c2b977
--- /dev/null
+++ b/db/schema_migrations/20211209093636
@@ -0,0 +1 @@
+e544953376948489daf4840d4a6228b18dc6e18d071a1025dab24c3559640489
\ No newline at end of file
diff --git a/db/schema_migrations/20211209093828 b/db/schema_migrations/20211209093828
new file mode 100644
index 0000000000000000000000000000000000000000..7f6b5a0c4421840ca70053214625d0ed22aed4cc
--- /dev/null
+++ b/db/schema_migrations/20211209093828
@@ -0,0 +1 @@
+583ee4809560fec645e6f0942b332f9ab2630d06b0a422b360c5bb546d0aad93
\ No newline at end of file
diff --git a/db/schema_migrations/20211209093923 b/db/schema_migrations/20211209093923
new file mode 100644
index 0000000000000000000000000000000000000000..654d4b3967ec916c26fb30b1860e09e0369953ad
--- /dev/null
+++ b/db/schema_migrations/20211209093923
@@ -0,0 +1 @@
+8ec578ddc956b2648bcdd8a2ce1728723e2b0eef1a0a4845f4cb0deb19c417ec
\ No newline at end of file
diff --git a/db/schema_migrations/20211209094222 b/db/schema_migrations/20211209094222
new file mode 100644
index 0000000000000000000000000000000000000000..29156e38fe99914a9304f93f7e7415949b1c24e8
--- /dev/null
+++ b/db/schema_migrations/20211209094222
@@ -0,0 +1 @@
+1b461efe52d55ba9dca05e64efaae411c3de01612cbc55f9525e522e9b181b3d
\ No newline at end of file
diff --git a/db/schema_migrations/20211209103048 b/db/schema_migrations/20211209103048
new file mode 100644
index 0000000000000000000000000000000000000000..133d5fc1ed4d5a35e913f5cbfef191d3ca2863cb
--- /dev/null
+++ b/db/schema_migrations/20211209103048
@@ -0,0 +1 @@
+d2d270a335b3a2441a20673bf19d47553f607533d4503e3a01bc3d6d108bcdb3
\ No newline at end of file
diff --git a/db/schema_migrations/20211209203820 b/db/schema_migrations/20211209203820
new file mode 100644
index 0000000000000000000000000000000000000000..cdff024b59723172f2d82130a648df77639fed53
--- /dev/null
+++ b/db/schema_migrations/20211209203820
@@ -0,0 +1 @@
+c501bc857cef21a8657508e9a286feb3c6f5db873247707e051a8702b1e80e79
\ No newline at end of file
diff --git a/db/schema_migrations/20211209203821 b/db/schema_migrations/20211209203821
new file mode 100644
index 0000000000000000000000000000000000000000..890d3db0b3a190cb7593b922fa7accc904c554cb
--- /dev/null
+++ b/db/schema_migrations/20211209203821
@@ -0,0 +1 @@
+4e8e0917bcfcadf288425e82eeb3747d775bb301017a9b320b694cd43ed0d60a
\ No newline at end of file
diff --git a/db/schema_migrations/20211209230042 b/db/schema_migrations/20211209230042
new file mode 100644
index 0000000000000000000000000000000000000000..818734c1330e7f27b30747f601de1ef9be8250ea
--- /dev/null
+++ b/db/schema_migrations/20211209230042
@@ -0,0 +1 @@
+907fafc18fa515fff8f716f6464263ccc8a9b6e5ead36f30b05089100fd71b6b
\ No newline at end of file
diff --git a/db/schema_migrations/20211210025754 b/db/schema_migrations/20211210025754
new file mode 100644
index 0000000000000000000000000000000000000000..f2fd6e506b8067bb0e46a63c4aa7f10b92cbf9df
--- /dev/null
+++ b/db/schema_migrations/20211210025754
@@ -0,0 +1 @@
+d39b46bfd4bdf81cd4969190d08dce2260b4f476564a2e6c3e05d69b87c1c6df
\ No newline at end of file
diff --git a/db/schema_migrations/20211210031721 b/db/schema_migrations/20211210031721
new file mode 100644
index 0000000000000000000000000000000000000000..57bbcccd347a9cad0a1dbdb9cfed9b84bba592dd
--- /dev/null
+++ b/db/schema_migrations/20211210031721
@@ -0,0 +1 @@
+6d62200480e46b356fe07eeb2c99b0fb441dadd00faf30079722c617facab7cc
\ No newline at end of file
diff --git a/db/schema_migrations/20211210140000 b/db/schema_migrations/20211210140000
new file mode 100644
index 0000000000000000000000000000000000000000..b64d8251d69993aa45a10ca0de4078c39c53cd6a
--- /dev/null
+++ b/db/schema_migrations/20211210140000
@@ -0,0 +1 @@
+f02c1b7412d2bb6d8a20639704ad55cdbcc14bfccf0509b659c3ef9614bcfa2b
\ No newline at end of file
diff --git a/db/schema_migrations/20211210140629 b/db/schema_migrations/20211210140629
new file mode 100644
index 0000000000000000000000000000000000000000..ad631461d87701676069453c45bcc93c7420cf86
--- /dev/null
+++ b/db/schema_migrations/20211210140629
@@ -0,0 +1 @@
+7940b0f692b62bcabbe98440082e2245fd28caba2c9e052e85e82acea0a98d23
\ No newline at end of file
diff --git a/db/schema_migrations/20211210173137 b/db/schema_migrations/20211210173137
new file mode 100644
index 0000000000000000000000000000000000000000..3dfcb177167d2c99d7c4cdcb7fe0824e8b3546a7
--- /dev/null
+++ b/db/schema_migrations/20211210173137
@@ -0,0 +1 @@
+9bbd4c3e396e0de130418e705a370ce629ca507c82fa2ff5bbf085cdf01c2ff3
\ No newline at end of file
diff --git a/db/schema_migrations/20211213064821 b/db/schema_migrations/20211213064821
new file mode 100644
index 0000000000000000000000000000000000000000..119805a99b7b03199686aef7a02dbb1891a7585f
--- /dev/null
+++ b/db/schema_migrations/20211213064821
@@ -0,0 +1 @@
+9d7e85ac7c9ee2b9505c479b878cb07888cf089c04d34bdeb834fbb0c5111931
\ No newline at end of file
diff --git a/db/schema_migrations/20211213102111 b/db/schema_migrations/20211213102111
new file mode 100644
index 0000000000000000000000000000000000000000..214d061f265b618ca4061f59057fc7bff3bf8a19
--- /dev/null
+++ b/db/schema_migrations/20211213102111
@@ -0,0 +1 @@
+3d011cc67fc6ac661788f2d0e3766e51d624a4248ac9dbd861a4db810d396091
\ No newline at end of file
diff --git a/db/schema_migrations/20211213130324 b/db/schema_migrations/20211213130324
new file mode 100644
index 0000000000000000000000000000000000000000..529fe91ab5f0dcda545ec8a1de96e2b0a77b6015
--- /dev/null
+++ b/db/schema_migrations/20211213130324
@@ -0,0 +1 @@
+2267855b2f12747b1f31f392677fac4d4f82ee234d7c54fd209b8bad417c8c75
\ No newline at end of file
diff --git a/db/schema_migrations/20211213142344 b/db/schema_migrations/20211213142344
new file mode 100644
index 0000000000000000000000000000000000000000..2bcbb15c2186ab0dc216d7b551a5f1baac7dd92f
--- /dev/null
+++ b/db/schema_migrations/20211213142344
@@ -0,0 +1 @@
+837539e12be12830d388bc6142622412b40ac061c397504eac03033a08f01e72
\ No newline at end of file
diff --git a/db/schema_migrations/20211213154259 b/db/schema_migrations/20211213154259
new file mode 100644
index 0000000000000000000000000000000000000000..0555d0c660060f9b77031f3fa7488f937d16c16e
--- /dev/null
+++ b/db/schema_migrations/20211213154259
@@ -0,0 +1 @@
+fccb1d6c7ac4e31cecaf7bc2e23f13f6c8147a3820cbd996a545a5b01cc03865
\ No newline at end of file
diff --git a/db/schema_migrations/20211213154704 b/db/schema_migrations/20211213154704
new file mode 100644
index 0000000000000000000000000000000000000000..0d9ba6457baa15e5daec552c0e4abbd4f21ea233
--- /dev/null
+++ b/db/schema_migrations/20211213154704
@@ -0,0 +1 @@
+deec24bae35829454a09d4e97478c0b57d5f80e3271f96b2554b1ab10dc84d7f
\ No newline at end of file
diff --git a/db/schema_migrations/20211214012507 b/db/schema_migrations/20211214012507
new file mode 100644
index 0000000000000000000000000000000000000000..7bac6c6d8c597f9c2158390a4c5c1399e1d1cf0f
--- /dev/null
+++ b/db/schema_migrations/20211214012507
@@ -0,0 +1 @@
+a7aa1ffccce785d365720309e3773f167075a9d06805eea941e6cd47bc918471
\ No newline at end of file
diff --git a/db/schema_migrations/20211214110307 b/db/schema_migrations/20211214110307
new file mode 100644
index 0000000000000000000000000000000000000000..6e3101bbe59e33197a8ed712e94e99fe9be20369
--- /dev/null
+++ b/db/schema_migrations/20211214110307
@@ -0,0 +1 @@
+a1a6e3c5b4a8f959c55edbb084b37ba555b3977e450a549925de47605638f66e
\ No newline at end of file
diff --git a/db/schema_migrations/20211215090620 b/db/schema_migrations/20211215090620
new file mode 100644
index 0000000000000000000000000000000000000000..9393ffee22e092c8542e9c4500ae5add2ef3a5a4
--- /dev/null
+++ b/db/schema_migrations/20211215090620
@@ -0,0 +1 @@
+43ae6290e11e3944b23ce2865b5c466a29c9ba3cfd2e0b58bd834568414b5bf2
\ No newline at end of file
diff --git a/db/schema_migrations/20211215182006 b/db/schema_migrations/20211215182006
new file mode 100644
index 0000000000000000000000000000000000000000..480a1e2369b6eb3c394a7c0e7f86eecd51b6772d
--- /dev/null
+++ b/db/schema_migrations/20211215182006
@@ -0,0 +1 @@
+ead2a1b13438514bb97bea3f1656f9bac352a8c733d9f808b2405685bce91e00
\ No newline at end of file
diff --git a/db/schema_migrations/20211216133107 b/db/schema_migrations/20211216133107
new file mode 100644
index 0000000000000000000000000000000000000000..c841207fffc88d346a2a8d618ae6472b28956a72
--- /dev/null
+++ b/db/schema_migrations/20211216133107
@@ -0,0 +1 @@
+a0c3a9746250aa67ffa8d05486fb6997c8d839b8bce7e870c0415c25600c5434
\ No newline at end of file
diff --git a/db/schema_migrations/20211216134134 b/db/schema_migrations/20211216134134
new file mode 100644
index 0000000000000000000000000000000000000000..09c3a59cc9885136b8f2fa48798e1181e6e0b4bd
--- /dev/null
+++ b/db/schema_migrations/20211216134134
@@ -0,0 +1 @@
+c53a1e4405187620929b8fc6877786cb713d13218f7385d1b9b3daaf6072fa05
\ No newline at end of file
diff --git a/db/schema_migrations/20211216135651 b/db/schema_migrations/20211216135651
new file mode 100644
index 0000000000000000000000000000000000000000..a94bdb329f1ac70c7a74222a4dc852be226026ca
--- /dev/null
+++ b/db/schema_migrations/20211216135651
@@ -0,0 +1 @@
+9b733363587957b4044bc6806dfbb9632ec7f5f6ffc8c82280e025012b8acb5a
\ No newline at end of file
diff --git a/db/schema_migrations/20211216220939 b/db/schema_migrations/20211216220939
new file mode 100644
index 0000000000000000000000000000000000000000..3fe48da6ca2b9b96c6bb80abca3ec653c18e00b6
--- /dev/null
+++ b/db/schema_migrations/20211216220939
@@ -0,0 +1 @@
+649cf0eb794904457b230c1240d2bea8a6e80b00dbf6b2d25b95c66247460aa4
\ No newline at end of file
diff --git a/db/schema_migrations/20211217050753 b/db/schema_migrations/20211217050753
new file mode 100644
index 0000000000000000000000000000000000000000..bfc571acab1e18ca7c17073680b50d9d5016a6b6
--- /dev/null
+++ b/db/schema_migrations/20211217050753
@@ -0,0 +1 @@
+fe5cbf928d45d506132078678cf70264f01190cfe581628a5038d77f68a52961
\ No newline at end of file
diff --git a/db/schema_migrations/20211217120000 b/db/schema_migrations/20211217120000
new file mode 100644
index 0000000000000000000000000000000000000000..d4efb66b98522efa679854ef8e8bb03060918005
--- /dev/null
+++ b/db/schema_migrations/20211217120000
@@ -0,0 +1 @@
+d4360d6057602ec1f5e6e9d11c93cfbb16d878e9ecd4d5bfb1bed1c01e14c7a3
\ No newline at end of file
diff --git a/db/schema_migrations/20211217145923 b/db/schema_migrations/20211217145923
new file mode 100644
index 0000000000000000000000000000000000000000..8a94da00fc8a46f9f51560c35978dcc4b5f4a32d
--- /dev/null
+++ b/db/schema_migrations/20211217145923
@@ -0,0 +1 @@
+2e35347592530f2a73e1cd75871438e29d277a206f621989e2c897fc587b6f5d
\ No newline at end of file
diff --git a/db/schema_migrations/20211217174331 b/db/schema_migrations/20211217174331
new file mode 100644
index 0000000000000000000000000000000000000000..32657e28f962bd4c8500f28d3db8eec111d4bcc9
--- /dev/null
+++ b/db/schema_migrations/20211217174331
@@ -0,0 +1 @@
+649360f4069aac4784f4d039015f8dda3f4bae28e8132f841e25b48f034a392e
\ No newline at end of file
diff --git a/db/schema_migrations/20211220064757 b/db/schema_migrations/20211220064757
new file mode 100644
index 0000000000000000000000000000000000000000..675596f1ce68fc0e8679cc31abb9c4f2c9484ee4
--- /dev/null
+++ b/db/schema_migrations/20211220064757
@@ -0,0 +1 @@
+34bfe07fff59a415540ca2c5c96b33dc9030c15b2ffbb30cb7deedeb939ae132
\ No newline at end of file
diff --git a/db/schema_migrations/20211220120402 b/db/schema_migrations/20211220120402
new file mode 100644
index 0000000000000000000000000000000000000000..c2bb4f8da7ef717dfbbe9f8e01e669acc4ce8389
--- /dev/null
+++ b/db/schema_migrations/20211220120402
@@ -0,0 +1 @@
+157128732c321577b7fa7a1b3d252ff70a2a62b34cd1e6edea59da4e632a1755
\ No newline at end of file
diff --git a/db/schema_migrations/20211220123956 b/db/schema_migrations/20211220123956
new file mode 100644
index 0000000000000000000000000000000000000000..291fdc306b50c31e743c3b87911500698213dc55
--- /dev/null
+++ b/db/schema_migrations/20211220123956
@@ -0,0 +1 @@
+088d17a1f55522c48e69ec78717b39b8c7538474a9263621bba1fa0280a27ad7
\ No newline at end of file
diff --git a/db/schema_migrations/20211220174504 b/db/schema_migrations/20211220174504
new file mode 100644
index 0000000000000000000000000000000000000000..ed8f5f35efc7adba39512ffc78fc957e2e90f6d5
--- /dev/null
+++ b/db/schema_migrations/20211220174504
@@ -0,0 +1 @@
+80c1ad5815ef68ab1a7d63566d478683b3f9a5169ed15ecd6f44f7f542d40dc8
\ No newline at end of file
diff --git a/db/schema_migrations/20211223125921 b/db/schema_migrations/20211223125921
new file mode 100644
index 0000000000000000000000000000000000000000..b4e3a1583dff320d52da112ad998c467b0b8dd99
--- /dev/null
+++ b/db/schema_migrations/20211223125921
@@ -0,0 +1 @@
+e08c1634376ed78b78c4a54d874bed66c1ce40c7c509b67cfda00d1a8657f127
\ No newline at end of file
diff --git a/db/schema_migrations/20211224112937 b/db/schema_migrations/20211224112937
new file mode 100644
index 0000000000000000000000000000000000000000..98296f9a27072f37863a4f90a68f8ae3349f0b5f
--- /dev/null
+++ b/db/schema_migrations/20211224112937
@@ -0,0 +1 @@
+3709c5c229e45ff0f594d6291d0b2b9a167b3bf4f5b29158b9abdac333a638b8
\ No newline at end of file
diff --git a/db/schema_migrations/20211224114539 b/db/schema_migrations/20211224114539
new file mode 100644
index 0000000000000000000000000000000000000000..2d7494e42912b79946025680c38937a0159db123
--- /dev/null
+++ b/db/schema_migrations/20211224114539
@@ -0,0 +1 @@
+f4ac776ec4213d6fcd07ccfa913f51e1386ff212bf47d27817b24b501a78443b
\ No newline at end of file
diff --git a/db/schema_migrations/20211229023654 b/db/schema_migrations/20211229023654
new file mode 100644
index 0000000000000000000000000000000000000000..f34b188c5d30293c69b64f8247d4a254ee33ed44
--- /dev/null
+++ b/db/schema_migrations/20211229023654
@@ -0,0 +1 @@
+8019915a00f62c137ee48c860c888e9d43f7253a5ea1a684ba2abe8bbe8016df
\ No newline at end of file
diff --git a/db/schema_migrations/20211230112517 b/db/schema_migrations/20211230112517
new file mode 100644
index 0000000000000000000000000000000000000000..bd22204d82dc58358b795030ac1468677ec61abe
--- /dev/null
+++ b/db/schema_migrations/20211230112517
@@ -0,0 +1 @@
+32c4b0ad5b52b8990b4c0ab6e832d503be6fc802a30aa2de20c7d3ced7f04c36
\ No newline at end of file
diff --git a/db/schema_migrations/20211230113031 b/db/schema_migrations/20211230113031
new file mode 100644
index 0000000000000000000000000000000000000000..2f5b81768c8ecc005c458e711af285c52059940f
--- /dev/null
+++ b/db/schema_migrations/20211230113031
@@ -0,0 +1 @@
+54201f4273226ed92ff0ed991fdba09c1108fccb764e6b9903e9f01e6acced1a
\ No newline at end of file
diff --git a/db/schema_migrations/20220104060049 b/db/schema_migrations/20220104060049
new file mode 100644
index 0000000000000000000000000000000000000000..83c36018d73936efe985eca1f7d4cc4b10dd5233
--- /dev/null
+++ b/db/schema_migrations/20220104060049
@@ -0,0 +1 @@
+fa87b087b576d320f94028444a082b920870a2554209808849f9f3f42ead83c4
\ No newline at end of file
diff --git a/db/schema_migrations/20220104174445 b/db/schema_migrations/20220104174445
new file mode 100644
index 0000000000000000000000000000000000000000..fffb27113e23ba210cb3ed8f6b4f3a740c36c2fe
--- /dev/null
+++ b/db/schema_migrations/20220104174445
@@ -0,0 +1 @@
+5e5e41ee4c8dc9c3fe791470862d15b8d213fcc931ef8b80937bdb5f5db20aed
\ No newline at end of file
diff --git a/db/schema_migrations/20220105020514 b/db/schema_migrations/20220105020514
new file mode 100644
index 0000000000000000000000000000000000000000..4ad9266c7c0b6f76c1b5045b6749d0cdf96c9123
--- /dev/null
+++ b/db/schema_migrations/20220105020514
@@ -0,0 +1 @@
+301c2f09f48aa3e34c2f679628a9542b4babc589e3d20e9ccf84a9209f5841ee
\ No newline at end of file
diff --git a/db/schema_migrations/20220105082217 b/db/schema_migrations/20220105082217
new file mode 100644
index 0000000000000000000000000000000000000000..a6232406be6d642418527a2c224857f0ec09ba1c
--- /dev/null
+++ b/db/schema_migrations/20220105082217
@@ -0,0 +1 @@
+448481ec9f7dd58d267e3660a49161c0e14baca35e640c59b27f2ebc4367b62a
\ No newline at end of file
diff --git a/db/schema_migrations/20220105121325 b/db/schema_migrations/20220105121325
new file mode 100644
index 0000000000000000000000000000000000000000..384616aba7f6f54acdb9436545fa2a152255cc26
--- /dev/null
+++ b/db/schema_migrations/20220105121325
@@ -0,0 +1 @@
+27ca3977a7569e98271eeb2bd224be1cfe5452ab3778665325b89bf966e07942
\ No newline at end of file
diff --git a/db/schema_migrations/20220105152547 b/db/schema_migrations/20220105152547
new file mode 100644
index 0000000000000000000000000000000000000000..d8c425da73677883e93c85a1e2e4e4e7a76ed93b
--- /dev/null
+++ b/db/schema_migrations/20220105152547
@@ -0,0 +1 @@
+0f1ea41fae57710e0e05c9b71a14800394c4c57e37a39e92be49c50120d7d2ee
\ No newline at end of file
diff --git a/db/schema_migrations/20220105153149 b/db/schema_migrations/20220105153149
new file mode 100644
index 0000000000000000000000000000000000000000..11b71946bc8e57e3a5414e4c5bf772fe7b222016
--- /dev/null
+++ b/db/schema_migrations/20220105153149
@@ -0,0 +1 @@
+8194c695a809f2eb29e5033f089c1d20874f61731a4289026f2d550854e7097d
\ No newline at end of file
diff --git a/db/schema_migrations/20220106111958 b/db/schema_migrations/20220106111958
new file mode 100644
index 0000000000000000000000000000000000000000..954db53295082733716673369c6dbafe52911293
--- /dev/null
+++ b/db/schema_migrations/20220106111958
@@ -0,0 +1 @@
+c1af9546bdfa0f32c3c2faf362062cd300800514e5b1efd1fa8a1770753d00e5
\ No newline at end of file
diff --git a/db/schema_migrations/20220106112043 b/db/schema_migrations/20220106112043
new file mode 100644
index 0000000000000000000000000000000000000000..34c8c5152da5cf7dc10559a96a7882c748a2b8a3
--- /dev/null
+++ b/db/schema_migrations/20220106112043
@@ -0,0 +1 @@
+8b51ae2b13066a56d2131efb7ea746335513031e751fb231e43121552d6f2b1d
\ No newline at end of file
diff --git a/db/schema_migrations/20220106112085 b/db/schema_migrations/20220106112085
new file mode 100644
index 0000000000000000000000000000000000000000..171f893a0abdbd658961ca9c49e4c373f8ef04be
--- /dev/null
+++ b/db/schema_migrations/20220106112085
@@ -0,0 +1 @@
+f385631d0317630661d487011a228501a6cbc71de25ca457d75e6a815c598045
\ No newline at end of file
diff --git a/db/schema_migrations/20220106141756 b/db/schema_migrations/20220106141756
new file mode 100644
index 0000000000000000000000000000000000000000..7718a41500bd33ea36371db4ca636185258a0950
--- /dev/null
+++ b/db/schema_migrations/20220106141756
@@ -0,0 +1 @@
+cedca81a6dc1562cf0ed5f17217c52420a1cb9a74acece8d67eb1bcb948a7181
\ No newline at end of file
diff --git a/db/schema_migrations/20220106163326 b/db/schema_migrations/20220106163326
new file mode 100644
index 0000000000000000000000000000000000000000..dbfb9079dc171627f5821b2ee7cc17581fe0814d
--- /dev/null
+++ b/db/schema_migrations/20220106163326
@@ -0,0 +1 @@
+4726d84ff42e64b1c47c5ba454ff5be05f434a86bb2af4bbe27dd00e5e3da5cb
\ No newline at end of file
diff --git a/db/schema_migrations/20220106185033 b/db/schema_migrations/20220106185033
new file mode 100644
index 0000000000000000000000000000000000000000..be45c8bab6f22577e223a16fe7efd87372ebc871
--- /dev/null
+++ b/db/schema_migrations/20220106185033
@@ -0,0 +1 @@
+5304bc3dada6794c8f6e1082861e12fdfb059effdcd5a17e11af5300e67708bd
\ No newline at end of file
diff --git a/db/schema_migrations/20220106230629 b/db/schema_migrations/20220106230629
new file mode 100644
index 0000000000000000000000000000000000000000..e8751a6616cfcf846ac70b7f7380cde9ecf7e508
--- /dev/null
+++ b/db/schema_migrations/20220106230629
@@ -0,0 +1 @@
+675d8f7bf77ddb860e707c25811d4eaaac1173c9fe62ce96c2708f0bbd0f4d48
\ No newline at end of file
diff --git a/db/schema_migrations/20220106230712 b/db/schema_migrations/20220106230712
new file mode 100644
index 0000000000000000000000000000000000000000..589b65d423c568b1d70c5e71060717f6ac222afc
--- /dev/null
+++ b/db/schema_migrations/20220106230712
@@ -0,0 +1 @@
+672b51ca014d208f971efe698edb8a8b32f541bf9d21a7f555c53f749ee936a4
\ No newline at end of file
diff --git a/db/schema_migrations/20220106231518 b/db/schema_migrations/20220106231518
new file mode 100644
index 0000000000000000000000000000000000000000..f7deaaa68b686376b35538056af294f4b666cb9b
--- /dev/null
+++ b/db/schema_migrations/20220106231518
@@ -0,0 +1 @@
+aafb52337688e8b57712872f6f7e8e67da132406b244df5e11a736b01e23354f
\ No newline at end of file
diff --git a/db/schema_migrations/20220106233459 b/db/schema_migrations/20220106233459
new file mode 100644
index 0000000000000000000000000000000000000000..2911e79d843307261890fa714de99e444d737faf
--- /dev/null
+++ b/db/schema_migrations/20220106233459
@@ -0,0 +1 @@
+fc44084057c5fd30f0e7918b4f856a60409f08ad1eb5c3fbc2d8ad5bad7f1ffd
\ No newline at end of file
diff --git a/db/schema_migrations/20220106235626 b/db/schema_migrations/20220106235626
new file mode 100644
index 0000000000000000000000000000000000000000..d8d8e3b20d75ead97591996d7913db61f7f5e28d
--- /dev/null
+++ b/db/schema_migrations/20220106235626
@@ -0,0 +1 @@
+34f966723cae63e831f7fc9d965cda90f1fd7bca522fc58e78a0de4b959a47a2
\ No newline at end of file
diff --git a/db/schema_migrations/20220107064845 b/db/schema_migrations/20220107064845
new file mode 100644
index 0000000000000000000000000000000000000000..bd63da8835567f48c23293387d81d24fc2555a6d
--- /dev/null
+++ b/db/schema_migrations/20220107064845
@@ -0,0 +1 @@
+c7c645787aadc95c77df6420f437f78aed4e7e862ea2b66e7824766b1d9f3cb5
\ No newline at end of file
diff --git a/db/schema_migrations/20220107091629 b/db/schema_migrations/20220107091629
new file mode 100644
index 0000000000000000000000000000000000000000..a14f97d77ebad04310f052f6581178b782f4963c
--- /dev/null
+++ b/db/schema_migrations/20220107091629
@@ -0,0 +1 @@
+ef1a7c5f7b10640a0ddc669528dcdb02fd2525d716562f928578e8902a07a832
\ No newline at end of file
diff --git a/db/schema_migrations/20220107165036 b/db/schema_migrations/20220107165036
new file mode 100644
index 0000000000000000000000000000000000000000..bab28284d04720516cef4cc08e2b429484fe13cf
--- /dev/null
+++ b/db/schema_migrations/20220107165036
@@ -0,0 +1 @@
+72639ba84675a6687864ef4cb6f02d0429124d7deb9ce9f3c8e255591e2f0a8d
\ No newline at end of file
diff --git a/db/schema_migrations/20220109133006 b/db/schema_migrations/20220109133006
new file mode 100644
index 0000000000000000000000000000000000000000..e74845e22542e407cc037b083f8a7ceea4689bfe
--- /dev/null
+++ b/db/schema_migrations/20220109133006
@@ -0,0 +1 @@
+192fc0b934c7d52e431a0ce7524a51beb24fa004a940e6b0675e36b0da143891
\ No newline at end of file
diff --git a/db/schema_migrations/20220109134455 b/db/schema_migrations/20220109134455
new file mode 100644
index 0000000000000000000000000000000000000000..7a4762e240e93fb37988b8ed1d26c313a301bf34
--- /dev/null
+++ b/db/schema_migrations/20220109134455
@@ -0,0 +1 @@
+fee092680e22e579ea51f776d11bbfd6a49b936e4ab776760a153ce613e7a0cd
\ No newline at end of file
diff --git a/db/schema_migrations/20220110170953 b/db/schema_migrations/20220110170953
new file mode 100644
index 0000000000000000000000000000000000000000..d4c2aa5fcf26e510b48ade6ef44be7554faa0db8
--- /dev/null
+++ b/db/schema_migrations/20220110170953
@@ -0,0 +1 @@
+da1c6f2db7cee1e4cb8b477d1892fa7206a95157a84864ad3d6022ab6cffbd1f
\ No newline at end of file
diff --git a/db/schema_migrations/20220110171049 b/db/schema_migrations/20220110171049
new file mode 100644
index 0000000000000000000000000000000000000000..ab39a1afb2535e41319c6ba70491c68056ef5044
--- /dev/null
+++ b/db/schema_migrations/20220110171049
@@ -0,0 +1 @@
+55ad00b1cf70f5d1a3f033efccf64c2c273ad03f65823a2281869849571ab35b
\ No newline at end of file
diff --git a/db/schema_migrations/20220110224913 b/db/schema_migrations/20220110224913
new file mode 100644
index 0000000000000000000000000000000000000000..653324d1060cef9a05ca5b5272ff4a556d94823a
--- /dev/null
+++ b/db/schema_migrations/20220110224913
@@ -0,0 +1 @@
+d8b206e26f6dd7e9d5f2b2d8cc5ce2e2bbe2d8d33317948f8cf110fe41872a5d
\ No newline at end of file
diff --git a/db/schema_migrations/20220110231420 b/db/schema_migrations/20220110231420
new file mode 100644
index 0000000000000000000000000000000000000000..b46bcdfd8020230e0e4630006e3f45e2753475bc
--- /dev/null
+++ b/db/schema_migrations/20220110231420
@@ -0,0 +1 @@
+768f97a38c0b741f7de99082ce7c8efb1578ac6600c3af4b30019bc987968bc9
\ No newline at end of file
diff --git a/db/schema_migrations/20220110233155 b/db/schema_migrations/20220110233155
new file mode 100644
index 0000000000000000000000000000000000000000..9301c7a2a7aeab7591b137a1f9fcdab877eb567e
--- /dev/null
+++ b/db/schema_migrations/20220110233155
@@ -0,0 +1 @@
+e7d9d79ffb8989ab39fe719217f22736244df70c2b1461ef5a1a3f1e74e43870
\ No newline at end of file
diff --git a/db/schema_migrations/20220111002756 b/db/schema_migrations/20220111002756
new file mode 100644
index 0000000000000000000000000000000000000000..ca619e3eaf41153b466e3c79bff9299d2f7a15a9
--- /dev/null
+++ b/db/schema_migrations/20220111002756
@@ -0,0 +1 @@
+34759cbf09171f6057b87af791f5e9f3045ac5e06558147436ba32e276f40a19
\ No newline at end of file
diff --git a/db/schema_migrations/20220111023852 b/db/schema_migrations/20220111023852
new file mode 100644
index 0000000000000000000000000000000000000000..15ab047066291946b2b2797b8eff83bf91162d48
--- /dev/null
+++ b/db/schema_migrations/20220111023852
@@ -0,0 +1 @@
+fdb6e193748f9933aa3ae60fab41960e06d4edf271048fc5f6c9c465d30a8334
\ No newline at end of file
diff --git a/db/schema_migrations/20220111093534 b/db/schema_migrations/20220111093534
new file mode 100644
index 0000000000000000000000000000000000000000..5999dbdf49aa2eeab31a23c3968dd603ed0cd467
--- /dev/null
+++ b/db/schema_migrations/20220111093534
@@ -0,0 +1 @@
+ff0127967c3ee6e4f4af528b84024a6a838f8dbeb19cf78d7d913d4fc8e155e7
\ No newline at end of file
diff --git a/db/schema_migrations/20220111095006 b/db/schema_migrations/20220111095006
new file mode 100644
index 0000000000000000000000000000000000000000..b5fed6279f150f8a18ce6f1293f24c9631b5b3a6
--- /dev/null
+++ b/db/schema_migrations/20220111095006
@@ -0,0 +1 @@
+0bc00cc8a5fa7cafa665ec113a4d0d1384c5acde37dfdf53ab1f5a2e1d6acb02
\ No newline at end of file
diff --git a/db/schema_migrations/20220111095007 b/db/schema_migrations/20220111095007
new file mode 100644
index 0000000000000000000000000000000000000000..77c70f8bccf804324f6fb4035d91d3cee9cf2a0b
--- /dev/null
+++ b/db/schema_migrations/20220111095007
@@ -0,0 +1 @@
+65259b0e71c1883b81c61354325cfeeade0013b55af8901bf707f2a94ee3a46a
\ No newline at end of file
diff --git a/db/schema_migrations/20220111101421 b/db/schema_migrations/20220111101421
new file mode 100644
index 0000000000000000000000000000000000000000..16d47665734722b39eca2a392237413cfc287cf4
--- /dev/null
+++ b/db/schema_migrations/20220111101421
@@ -0,0 +1 @@
+abbba4ccacebb825c3f9cb5b0463d457fd4a7b4396a2184a995e496aebaf4521
\ No newline at end of file
diff --git a/db/schema_migrations/20220111102314 b/db/schema_migrations/20220111102314
new file mode 100644
index 0000000000000000000000000000000000000000..95c172c3587a7e2d217f6db25913b6a0587292bd
--- /dev/null
+++ b/db/schema_migrations/20220111102314
@@ -0,0 +1 @@
+69c20daf6a23346288e516df3e70120819d76dcb5fe2b1b51af416349311820b
\ No newline at end of file
diff --git a/db/schema_migrations/20220111154950 b/db/schema_migrations/20220111154950
new file mode 100644
index 0000000000000000000000000000000000000000..6070beb76e9af0eaa610a986985ed514b6fdd626
--- /dev/null
+++ b/db/schema_migrations/20220111154950
@@ -0,0 +1 @@
+4719c533acaac3234ac0e131c70be49d0f98642e29e7d2e31519cc6c372056bc
\ No newline at end of file
diff --git a/db/schema_migrations/20220111154951 b/db/schema_migrations/20220111154951
new file mode 100644
index 0000000000000000000000000000000000000000..9d18e4c4d44cd5abe854ae47aee8bc31ed77e966
--- /dev/null
+++ b/db/schema_migrations/20220111154951
@@ -0,0 +1 @@
+48d6eaa68912f702be2bd38609bea4fa807eab7131f7c5e2261416820df9836a
\ No newline at end of file
diff --git a/db/schema_migrations/20220111200254 b/db/schema_migrations/20220111200254
new file mode 100644
index 0000000000000000000000000000000000000000..36ce3ad56f00a99be3d848a2334e97b2325b9790
--- /dev/null
+++ b/db/schema_migrations/20220111200254
@@ -0,0 +1 @@
+72c7e04b1a34154c894f93da800c15c717c3340d34729577538d539881d2e8ca
\ No newline at end of file
diff --git a/db/schema_migrations/20220111221516 b/db/schema_migrations/20220111221516
new file mode 100644
index 0000000000000000000000000000000000000000..b0c747f8e8a978ab5dd999167561dc82d5d2cd3a
--- /dev/null
+++ b/db/schema_migrations/20220111221516
@@ -0,0 +1 @@
+0cb120b0036b3f472edb57fcb8a52877d399edf8ff1f416ce76497d6aa8265d7
\ No newline at end of file
diff --git a/db/schema_migrations/20220112015940 b/db/schema_migrations/20220112015940
new file mode 100644
index 0000000000000000000000000000000000000000..0d012793ba0f5db332d2f2e4203c6a0ef2edae73
--- /dev/null
+++ b/db/schema_migrations/20220112015940
@@ -0,0 +1 @@
+e4417c3367115d6adba023e18657d8aecd476b8d1c4227c73e06f97d05af07ad
\ No newline at end of file
diff --git a/db/schema_migrations/20220112090556 b/db/schema_migrations/20220112090556
new file mode 100644
index 0000000000000000000000000000000000000000..12ffaeffe003b3ccf6c219e19e16477302ef4a5b
--- /dev/null
+++ b/db/schema_migrations/20220112090556
@@ -0,0 +1 @@
+e78e11a47017c67130fe88fa538578553b7015c18cf222b5e7fb7f503254dc6d
\ No newline at end of file
diff --git a/db/schema_migrations/20220112115413 b/db/schema_migrations/20220112115413
new file mode 100644
index 0000000000000000000000000000000000000000..9c8c653f69b6dd8c326b78e0e5ebe238ff7c7448
--- /dev/null
+++ b/db/schema_migrations/20220112115413
@@ -0,0 +1 @@
+1199adba4c13e9234eabadefeb55ed3cfb19e9d5a87c07b90d438e4f48a973f7
\ No newline at end of file
diff --git a/db/schema_migrations/20220112205111 b/db/schema_migrations/20220112205111
new file mode 100644
index 0000000000000000000000000000000000000000..a2d2d42271edcefafec2388564a88c96beca739a
--- /dev/null
+++ b/db/schema_migrations/20220112205111
@@ -0,0 +1 @@
+65d9a1d63e90dfc336d0c69503c0899259fda773bc68a330782c206ac0fc48fd
\ No newline at end of file
diff --git a/db/schema_migrations/20220112230642 b/db/schema_migrations/20220112230642
new file mode 100644
index 0000000000000000000000000000000000000000..c2d8e1d0a6efb4d06d104886122376d216bd5fc4
--- /dev/null
+++ b/db/schema_migrations/20220112230642
@@ -0,0 +1 @@
+c528730414c1dcda5d312f03d4e37a0dbb51ebb0b0b87ada786cf686c358daa7
\ No newline at end of file
diff --git a/db/schema_migrations/20220112232037 b/db/schema_migrations/20220112232037
new file mode 100644
index 0000000000000000000000000000000000000000..83267de0489be4639a51f85be21188c01524f414
--- /dev/null
+++ b/db/schema_migrations/20220112232037
@@ -0,0 +1 @@
+775ac42ad194bd0175a6925e1c2e83c11d57a8d4430ad08a70e3d5275ca2e709
\ No newline at end of file
diff --git a/db/schema_migrations/20220112232605 b/db/schema_migrations/20220112232605
new file mode 100644
index 0000000000000000000000000000000000000000..fb5809b543e4616dd378a1d055575d98de5eee37
--- /dev/null
+++ b/db/schema_migrations/20220112232605
@@ -0,0 +1 @@
+4813b55e933564851f2fec9a2fa5900409eff226fec34ae0be1895307f603904
\ No newline at end of file
diff --git a/db/schema_migrations/20220112232723 b/db/schema_migrations/20220112232723
new file mode 100644
index 0000000000000000000000000000000000000000..2dc2a592980b548d9c905f668a954ee9fc403437
--- /dev/null
+++ b/db/schema_migrations/20220112232723
@@ -0,0 +1 @@
+cbea97a0d067939ba9d713489448cb6e0cc45b2bbd2c717ecf521493cc39d568
\ No newline at end of file
diff --git a/db/schema_migrations/20220113013319 b/db/schema_migrations/20220113013319
new file mode 100644
index 0000000000000000000000000000000000000000..0dc31b950046aac80759bb70e0680e5696267087
--- /dev/null
+++ b/db/schema_migrations/20220113013319
@@ -0,0 +1 @@
+ccfbbbe52b27833453f867c4d7093187d21dbbfebe054b366ff010c54de50974
\ No newline at end of file
diff --git a/db/schema_migrations/20220113014438 b/db/schema_migrations/20220113014438
new file mode 100644
index 0000000000000000000000000000000000000000..936c801bafe032023115754860727ee240321703
--- /dev/null
+++ b/db/schema_migrations/20220113014438
@@ -0,0 +1 @@
+08d8a5a605058598a2f033bbd461518c502fb3da8627240c5d66f887b43f3ac3
\ No newline at end of file
diff --git a/db/schema_migrations/20220113015830 b/db/schema_migrations/20220113015830
new file mode 100644
index 0000000000000000000000000000000000000000..a48974100779bc52d01bb664ac1ab9549b5d07cf
--- /dev/null
+++ b/db/schema_migrations/20220113015830
@@ -0,0 +1 @@
+774a5ff616663d6d0e002bd04d33747982de10b02cbb9ad7d8abfe0b26a2b441
\ No newline at end of file
diff --git a/db/schema_migrations/20220113035519 b/db/schema_migrations/20220113035519
new file mode 100644
index 0000000000000000000000000000000000000000..eb908ae8982ce131f30d9c6daf5b308418e6be4d
--- /dev/null
+++ b/db/schema_migrations/20220113035519
@@ -0,0 +1 @@
+4a90811aace678528b75171868fb178ab885d5aac885048e8eacecaf8b0ee374
\ No newline at end of file
diff --git a/db/schema_migrations/20220113040447 b/db/schema_migrations/20220113040447
new file mode 100644
index 0000000000000000000000000000000000000000..465b51678f7915f1a2bd02096d67c65bf9c3c414
--- /dev/null
+++ b/db/schema_migrations/20220113040447
@@ -0,0 +1 @@
+983e5522b2798ca0d17ca3fd848f527b12afdbdd1482a2d420c4c6ce4fa2c9c4
\ No newline at end of file
diff --git a/db/schema_migrations/20220113111440 b/db/schema_migrations/20220113111440
new file mode 100644
index 0000000000000000000000000000000000000000..e6188a9616f07ecf4394439dade611d7b257be26
--- /dev/null
+++ b/db/schema_migrations/20220113111440
@@ -0,0 +1 @@
+faf899c1aa99e596eb386935ee6ff17a51b7942ee4f6d4cbd1ad2283dd0d40c0
\ No newline at end of file
diff --git a/db/schema_migrations/20220113125401 b/db/schema_migrations/20220113125401
new file mode 100644
index 0000000000000000000000000000000000000000..7241e2e29c75e0d0b27080b1658b8caa7d6dcfaf
--- /dev/null
+++ b/db/schema_migrations/20220113125401
@@ -0,0 +1 @@
+afe57b6b1b8b10e0e26d7f499b25adc5aef9f7c52af644d6a260f0ed3aab16d5
\ No newline at end of file
diff --git a/db/schema_migrations/20220113135449 b/db/schema_migrations/20220113135449
new file mode 100644
index 0000000000000000000000000000000000000000..57e6ede94b5b4a724f1c79a400d5cbe52451a616
--- /dev/null
+++ b/db/schema_migrations/20220113135449
@@ -0,0 +1 @@
+46796379175ce9343907234d3ae14a417442c7c5ebbfcf6987db1d759eca2c3a
\ No newline at end of file
diff --git a/db/schema_migrations/20220113135924 b/db/schema_migrations/20220113135924
new file mode 100644
index 0000000000000000000000000000000000000000..41328a43c371ab3af918b73b98a8ccdde2b38b93
--- /dev/null
+++ b/db/schema_migrations/20220113135924
@@ -0,0 +1 @@
+2a230758c13111c9e3738794008c31a3608dda2f0d071fbde0ad3cd782d29162
\ No newline at end of file
diff --git a/db/schema_migrations/20220113164801 b/db/schema_migrations/20220113164801
new file mode 100644
index 0000000000000000000000000000000000000000..8354489ac3178b45a20bc12b63be755528a9c4ec
--- /dev/null
+++ b/db/schema_migrations/20220113164801
@@ -0,0 +1 @@
+71526ea198c64d23a35f06804f30068591e937df22d74c262fdec9ecf04bf7d4
\ No newline at end of file
diff --git a/db/schema_migrations/20220113164901 b/db/schema_migrations/20220113164901
new file mode 100644
index 0000000000000000000000000000000000000000..977ec8bb51b30feebf0ee54356c5438d1c973297
--- /dev/null
+++ b/db/schema_migrations/20220113164901
@@ -0,0 +1 @@
+b157cec5eab77665ae57f02647c39dc0fb167d78e1894b395c46f59d791ab3e0
\ No newline at end of file
diff --git a/db/schema_migrations/20220114105525 b/db/schema_migrations/20220114105525
new file mode 100644
index 0000000000000000000000000000000000000000..728820cbaf0a1299a4dbea08d7ee745393a6b157
--- /dev/null
+++ b/db/schema_migrations/20220114105525
@@ -0,0 +1 @@
+c9c7e8ff40fd3863095bb927f1aea27fecd5ca77dfc284a7673310e3501476c8
\ No newline at end of file
diff --git a/db/schema_migrations/20220114131950 b/db/schema_migrations/20220114131950
new file mode 100644
index 0000000000000000000000000000000000000000..ca1e1033d9ba2d5e9568a6aa75be18afbb95a04b
--- /dev/null
+++ b/db/schema_migrations/20220114131950
@@ -0,0 +1 @@
+f427f4c0d75308f7c97685e10e27a735dcf284714acd49659f62a6f7752234ef
\ No newline at end of file
diff --git a/db/schema_migrations/20220116175851 b/db/schema_migrations/20220116175851
new file mode 100644
index 0000000000000000000000000000000000000000..47c210714403640ca4b5945370b74b7a81cac5b8
--- /dev/null
+++ b/db/schema_migrations/20220116175851
@@ -0,0 +1 @@
+3fa0d827ab8051d270a13ae5facb1560a87f9f4fef81368b9fbb5d6291948721
\ No newline at end of file
diff --git a/db/schema_migrations/20220117034056 b/db/schema_migrations/20220117034056
new file mode 100644
index 0000000000000000000000000000000000000000..acf76bfb9d6989a0aa0ba02d702ec1ad14b8d73e
--- /dev/null
+++ b/db/schema_migrations/20220117034056
@@ -0,0 +1 @@
+afc54500374602edcdc4fce5acf3673b84882da1afbb5598a6684a5ef480a2d7
\ No newline at end of file
diff --git a/db/schema_migrations/20220117082611 b/db/schema_migrations/20220117082611
new file mode 100644
index 0000000000000000000000000000000000000000..9dead593ffb68d9bcd0cecebfacdb78ed235246c
--- /dev/null
+++ b/db/schema_migrations/20220117082611
@@ -0,0 +1 @@
+28df9a8b5bf73bc33275cfe47f260788fa3263680a97128e086fd1698ccac1d8
\ No newline at end of file
diff --git a/db/schema_migrations/20220117225936 b/db/schema_migrations/20220117225936
new file mode 100644
index 0000000000000000000000000000000000000000..7ced75915e4fce038c0e109847c3439c9caf5ff4
--- /dev/null
+++ b/db/schema_migrations/20220117225936
@@ -0,0 +1 @@
+484eaf2ce1df1e2915b7ea8a5c9f4e044957c25d1ccf5841f24c75791d1a1a13
\ No newline at end of file
diff --git a/db/schema_migrations/20220118015633 b/db/schema_migrations/20220118015633
new file mode 100644
index 0000000000000000000000000000000000000000..8ba4a376bcd097af1262813a93e48b8b2e96465c
--- /dev/null
+++ b/db/schema_migrations/20220118015633
@@ -0,0 +1 @@
+6a73f49306de7c799a39afa3ac1f761840860833a96f1a91cf992c9a3ebfef9b
\ No newline at end of file
diff --git a/db/schema_migrations/20220118020026 b/db/schema_migrations/20220118020026
new file mode 100644
index 0000000000000000000000000000000000000000..fe9dcccbc0ca669924c1b16b0f1e3f918d54444c
--- /dev/null
+++ b/db/schema_migrations/20220118020026
@@ -0,0 +1 @@
+77374c81456f235d3afeb45cdda14552e1ef8047de5aaa3f5bb0a82e4aebe849
\ No newline at end of file
diff --git a/db/schema_migrations/20220118141950 b/db/schema_migrations/20220118141950
new file mode 100644
index 0000000000000000000000000000000000000000..7c6549a1e608f2b7acaee5ac72c62030c53ee2fc
--- /dev/null
+++ b/db/schema_migrations/20220118141950
@@ -0,0 +1 @@
+a4131f86bc415f0c1897e3b975494806ffc5a834dca2b39c998c6a406e695e15
\ No newline at end of file
diff --git a/db/schema_migrations/20220118155846 b/db/schema_migrations/20220118155846
new file mode 100644
index 0000000000000000000000000000000000000000..b5247cb374318e10ac151dd47a92ba37e20bfd2a
--- /dev/null
+++ b/db/schema_migrations/20220118155846
@@ -0,0 +1 @@
+88935eee0781ee1faaf52e3bc89dc5c490c2095d6ccf83e4fd4186641507c173
\ No newline at end of file
diff --git a/db/schema_migrations/20220118155847 b/db/schema_migrations/20220118155847
new file mode 100644
index 0000000000000000000000000000000000000000..caa0dfc590146d1a241c7a1fca103096b3a47d31
--- /dev/null
+++ b/db/schema_migrations/20220118155847
@@ -0,0 +1 @@
+aa73b04aa355111564cdc7adb036a2030a28fbb3b524c3b3dbb8248e27b845d7
\ No newline at end of file
diff --git a/db/schema_migrations/20220118155848 b/db/schema_migrations/20220118155848
new file mode 100644
index 0000000000000000000000000000000000000000..bf3205b5ddad427e27cc6f89b758d7b05d45c064
--- /dev/null
+++ b/db/schema_migrations/20220118155848
@@ -0,0 +1 @@
+4d5adffe1a3e835d6d23f6bd9634993c778fef23d134552d54b003af2a3ff4da
\ No newline at end of file
diff --git a/db/schema_migrations/20220118204039 b/db/schema_migrations/20220118204039
new file mode 100644
index 0000000000000000000000000000000000000000..209204054ff53df3ce8b245d87f75ad5fd11069f
--- /dev/null
+++ b/db/schema_migrations/20220118204039
@@ -0,0 +1 @@
+9b33f6e0c13acbf1adfc1b70f75418ceabc000a748c9216328ef36f1b8716ded
\ No newline at end of file
diff --git a/db/schema_migrations/20220119094023 b/db/schema_migrations/20220119094023
new file mode 100644
index 0000000000000000000000000000000000000000..c2bf5ce88d637787fb07c0cde8a0ea8b5de40a44
--- /dev/null
+++ b/db/schema_migrations/20220119094023
@@ -0,0 +1 @@
+4eddd356d87ce8fc8168dabe678211239e8d4051804d51d3bdce8cc137fa5a0d
\ No newline at end of file
diff --git a/db/schema_migrations/20220119094503 b/db/schema_migrations/20220119094503
new file mode 100644
index 0000000000000000000000000000000000000000..840a4d82593644acb98abf12ee6e7abc50489cbc
--- /dev/null
+++ b/db/schema_migrations/20220119094503
@@ -0,0 +1 @@
+1048b3a9744f212297c0a3aba176556e92e85f199ac861eb3ee4183eff002860
\ No newline at end of file
diff --git a/db/schema_migrations/20220119141407 b/db/schema_migrations/20220119141407
new file mode 100644
index 0000000000000000000000000000000000000000..0ff56c63dd67db28f6d54ff102ff6af07bc1fa55
--- /dev/null
+++ b/db/schema_migrations/20220119141407
@@ -0,0 +1 @@
+18b3ef459c3633ebd4b418b4436d3d50b0dc697fa7c4ef4d2e1f62b01d656bce
\ No newline at end of file
diff --git a/db/schema_migrations/20220119141736 b/db/schema_migrations/20220119141736
new file mode 100644
index 0000000000000000000000000000000000000000..431ed37ea5c2150bf023cb0f06de8489708ea7a7
--- /dev/null
+++ b/db/schema_migrations/20220119141736
@@ -0,0 +1 @@
+faa30b386af9adf3e9f54a0e8e2880310490e4dc1378eae68b346872d0bb8bfd
\ No newline at end of file
diff --git a/db/schema_migrations/20220119143130 b/db/schema_migrations/20220119143130
new file mode 100644
index 0000000000000000000000000000000000000000..8c9092fd187d09ce7e4f22b66deabe18af96d016
--- /dev/null
+++ b/db/schema_migrations/20220119143130
@@ -0,0 +1 @@
+a375f82fe0c1ef87aa6abb2142387b852b135be6e2158fd8456b23dc9bcf2a0e
\ No newline at end of file
diff --git a/db/schema_migrations/20220119144253 b/db/schema_migrations/20220119144253
new file mode 100644
index 0000000000000000000000000000000000000000..ee59402bbcc8a7283ce87924010f068c04864900
--- /dev/null
+++ b/db/schema_migrations/20220119144253
@@ -0,0 +1 @@
+723db0d234a4dadfdad68a92c249ec0b42e519297f48bcb843e89c1ad97032c7
\ No newline at end of file
diff --git a/db/schema_migrations/20220119144458 b/db/schema_migrations/20220119144458
new file mode 100644
index 0000000000000000000000000000000000000000..c5eb43a37301aba3691ed1cc9ca8b2aa79fbedec
--- /dev/null
+++ b/db/schema_migrations/20220119144458
@@ -0,0 +1 @@
+85227d2aa0e984f12362484b23554a4feb1304d055d54da40e20812f2d8c5b9e
\ No newline at end of file
diff --git a/db/schema_migrations/20220119151221 b/db/schema_migrations/20220119151221
new file mode 100644
index 0000000000000000000000000000000000000000..377170d9cb1fa990ecca9b34646d0871fb605404
--- /dev/null
+++ b/db/schema_migrations/20220119151221
@@ -0,0 +1 @@
+7865f26c43c79681f37ceb6e4fecf6153282856907ddfd8211d6d1d57d1fb7f3
\ No newline at end of file
diff --git a/db/schema_migrations/20220119153706 b/db/schema_migrations/20220119153706
new file mode 100644
index 0000000000000000000000000000000000000000..446fee12b44a6bbcc5691b42ba6ee7b46352c21c
--- /dev/null
+++ b/db/schema_migrations/20220119153706
@@ -0,0 +1 @@
+f87eec3c61cfc9dc860fe77af1fbe98c1ea2a9b0dc1b2dbdaaee4276b518af73
\ No newline at end of file
diff --git a/db/schema_migrations/20220119154442 b/db/schema_migrations/20220119154442
new file mode 100644
index 0000000000000000000000000000000000000000..78880a0164c6dcc7d4e1c5d3f34766b88e14903a
--- /dev/null
+++ b/db/schema_migrations/20220119154442
@@ -0,0 +1 @@
+7cb06f695c7e8e733ea50f0b2e8fbb115d5ac0d7e7f000228bd5ced58ab362c9
\ No newline at end of file
diff --git a/db/schema_migrations/20220119170426 b/db/schema_migrations/20220119170426
new file mode 100644
index 0000000000000000000000000000000000000000..51274ac59798648d241dbd18ba19df9496fc2488
--- /dev/null
+++ b/db/schema_migrations/20220119170426
@@ -0,0 +1 @@
+a488fecd8e6e99b8d32ac27f72c6a3575b0ed29baaf242133e5d1abbd5b64314
\ No newline at end of file
diff --git a/db/schema_migrations/20220119193130 b/db/schema_migrations/20220119193130
new file mode 100644
index 0000000000000000000000000000000000000000..5305ff9465e8a5afcae7aab3b25cc430afd513e9
--- /dev/null
+++ b/db/schema_migrations/20220119193130
@@ -0,0 +1 @@
+c991eda1b3a972a7da9bdbd5e1f9957394c52246b78d793b4b35fdec9daf6acd
\ No newline at end of file
diff --git a/db/schema_migrations/20220119201340 b/db/schema_migrations/20220119201340
new file mode 100644
index 0000000000000000000000000000000000000000..0dc36b2dfbada9d34d53f6d37c635354e855818a
--- /dev/null
+++ b/db/schema_migrations/20220119201340
@@ -0,0 +1 @@
+62b35cc5bd0abc5b7bcf4347346de832bbbed723fee7860ec649185d4d5fb53c
\ No newline at end of file
diff --git a/db/schema_migrations/20220119203119 b/db/schema_migrations/20220119203119
new file mode 100644
index 0000000000000000000000000000000000000000..43bdb5b03917f98c4c8afa7a2b4c5dba7f598564
--- /dev/null
+++ b/db/schema_migrations/20220119203119
@@ -0,0 +1 @@
+c0f29fd7f960ffd92a65a00e8dce123b91a604f4d89b7cf0bc419fa80495e2e5
\ No newline at end of file
diff --git a/db/schema_migrations/20220119220620 b/db/schema_migrations/20220119220620
new file mode 100644
index 0000000000000000000000000000000000000000..a6a9abb2accc13eb2a49c40306a2d934961c00e4
--- /dev/null
+++ b/db/schema_migrations/20220119220620
@@ -0,0 +1 @@
+535f476a358dcb3f3472f1e0ec1afef738f995197b5d1f4fcd61e58a9c9e8e75
\ No newline at end of file
diff --git a/db/schema_migrations/20220120033115 b/db/schema_migrations/20220120033115
new file mode 100644
index 0000000000000000000000000000000000000000..ef71ca650cdc033fc676e07643026ee0350a278d
--- /dev/null
+++ b/db/schema_migrations/20220120033115
@@ -0,0 +1 @@
+41b67585574f6309d8e32fe695e65fc43f15f6738db713c1a11e04558a5ec515
\ No newline at end of file
diff --git a/db/schema_migrations/20220120085655 b/db/schema_migrations/20220120085655
new file mode 100644
index 0000000000000000000000000000000000000000..534108786eceaf170f34c712d7745dcdd848bfd0
--- /dev/null
+++ b/db/schema_migrations/20220120085655
@@ -0,0 +1 @@
+966c42749e9d200f2b7295fdbb86e596c33510f0abbf431d40b09629e5e4a6aa
\ No newline at end of file
diff --git a/db/schema_migrations/20220120094340 b/db/schema_migrations/20220120094340
new file mode 100644
index 0000000000000000000000000000000000000000..423adf5cc94179443a386ab397bf5cab6f608737
--- /dev/null
+++ b/db/schema_migrations/20220120094340
@@ -0,0 +1 @@
+69d8283501ba6a4946a60e3812fe2cf3031fc4a915d6e7c6fac3bf272423f2f2
\ No newline at end of file
diff --git a/db/schema_migrations/20220120123700 b/db/schema_migrations/20220120123700
new file mode 100644
index 0000000000000000000000000000000000000000..263901fff19e5c8b6fd074bc530232ab1b5027b0
--- /dev/null
+++ b/db/schema_migrations/20220120123700
@@ -0,0 +1 @@
+9e274eae18520821dd890a11c8c6192da82a6051dce9ec2934b1365e57a10fdb
\ No newline at end of file
diff --git a/db/schema_migrations/20220120123800 b/db/schema_migrations/20220120123800
new file mode 100644
index 0000000000000000000000000000000000000000..6d271f75c0811182043bfd4974da9337e8854983
--- /dev/null
+++ b/db/schema_migrations/20220120123800
@@ -0,0 +1 @@
+9d2f0b0d2cb1a5844bdca5bcb4b82fa5cc6b465fa19177f9f6ca16574128fdc8
\ No newline at end of file
diff --git a/db/schema_migrations/20220120160625 b/db/schema_migrations/20220120160625
new file mode 100644
index 0000000000000000000000000000000000000000..287e364d331717497571e51f60ac0f8b77c9a6fc
--- /dev/null
+++ b/db/schema_migrations/20220120160625
@@ -0,0 +1 @@
+92485ceb25d5733efe9a35a5bd64c9f33253bb10f815590518c6fc8d1c9e5f39
\ No newline at end of file
diff --git a/db/schema_migrations/20220120211831 b/db/schema_migrations/20220120211831
new file mode 100644
index 0000000000000000000000000000000000000000..7601916df62b0e0847d3b2a2b541d301c79c82ba
--- /dev/null
+++ b/db/schema_migrations/20220120211831
@@ -0,0 +1 @@
+68b45f97a2165c934f097ca976fb27ffcb533c57facee95344e3985b5cfd8347
\ No newline at end of file
diff --git a/db/schema_migrations/20220120211832 b/db/schema_migrations/20220120211832
new file mode 100644
index 0000000000000000000000000000000000000000..ed7679d45737d70e5f47d02d486f1051199de011
--- /dev/null
+++ b/db/schema_migrations/20220120211832
@@ -0,0 +1 @@
+dd3a4209a72b470a14a3acc5d06db1f5fec67cb4f19b20b2e4d7d94b302fe122
\ No newline at end of file
diff --git a/db/schema_migrations/20220121214752 b/db/schema_migrations/20220121214752
new file mode 100644
index 0000000000000000000000000000000000000000..84c03a6ed90cd4d2123a2a8bc8add23e3bd4bd57
--- /dev/null
+++ b/db/schema_migrations/20220121214752
@@ -0,0 +1 @@
+c56983a489b56eb6b4a5cd5ae6947a322fd58b8e96bcdee1e38634d99727c432
\ No newline at end of file
diff --git a/db/schema_migrations/20220121214753 b/db/schema_migrations/20220121214753
new file mode 100644
index 0000000000000000000000000000000000000000..5142044be97ad08c7055bb24c4f8600e77fdf040
--- /dev/null
+++ b/db/schema_migrations/20220121214753
@@ -0,0 +1 @@
+b7b9f5e516664e7eb3f7a5307d1871bb4f58a31f4807e0298fbf9414bad567fa
\ No newline at end of file
diff --git a/db/schema_migrations/20220121221651 b/db/schema_migrations/20220121221651
new file mode 100644
index 0000000000000000000000000000000000000000..562751c6084b3a56799cf053e0176b938683b2fa
--- /dev/null
+++ b/db/schema_migrations/20220121221651
@@ -0,0 +1 @@
+a1681c1c619db7f4e7e5a760cee7d06a931aa1f02dccfce46be81d75a03ce8ac
\ No newline at end of file
diff --git a/db/schema_migrations/20220124130028 b/db/schema_migrations/20220124130028
new file mode 100644
index 0000000000000000000000000000000000000000..5ee8e463a55ff5e4c5df34732688ec730eb850eb
--- /dev/null
+++ b/db/schema_migrations/20220124130028
@@ -0,0 +1 @@
+7f2b3e70e33273d75f68bd1fa33103f24a4e4cfc3f2e5777dfd258b5a2e7bf4e
\ No newline at end of file
diff --git a/db/schema_migrations/20220124145019 b/db/schema_migrations/20220124145019
new file mode 100644
index 0000000000000000000000000000000000000000..8de01024798d896a5182a639069b5ce372734b2c
--- /dev/null
+++ b/db/schema_migrations/20220124145019
@@ -0,0 +1 @@
+3b1f7a7b6481a960ac25523e5e1b5abc6c1436332d64d4319d9e4112b0fa765e
\ No newline at end of file
diff --git a/db/schema_migrations/20220124151456 b/db/schema_migrations/20220124151456
new file mode 100644
index 0000000000000000000000000000000000000000..10a7b978e2f49eab743ea7b573b3e19c799fd651
--- /dev/null
+++ b/db/schema_migrations/20220124151456
@@ -0,0 +1 @@
+5ec73b28adb027a4462ec9b268ef9c505e281f1afedce3c592d431cd90808dac
\ No newline at end of file
diff --git a/db/schema_migrations/20220124151949 b/db/schema_migrations/20220124151949
new file mode 100644
index 0000000000000000000000000000000000000000..2d6305b978989edcf57a8cc33507a9e5a6c93fa2
--- /dev/null
+++ b/db/schema_migrations/20220124151949
@@ -0,0 +1 @@
+4eb33deb4c2d5ff587f8af57b8296e46911f24a6ed0b2f7ff1f36243f1a9013d
\ No newline at end of file
diff --git a/db/schema_migrations/20220124152824 b/db/schema_migrations/20220124152824
new file mode 100644
index 0000000000000000000000000000000000000000..5a0db5859f03c2d6c412e6d4c8f2e590dcbd22b6
--- /dev/null
+++ b/db/schema_migrations/20220124152824
@@ -0,0 +1 @@
+acf680cbf06d6eb2c0da44d416ff947e0460593cad74499acda91eb4bec63894
\ No newline at end of file
diff --git a/db/schema_migrations/20220124153233 b/db/schema_migrations/20220124153233
new file mode 100644
index 0000000000000000000000000000000000000000..bfb0d6f3c388fe5984761695d930ac286326f4a7
--- /dev/null
+++ b/db/schema_migrations/20220124153233
@@ -0,0 +1 @@
+f62f3d4cc6f4704e7b4e7d0b6b8e46ed3de4407f0db4282e2ce845aa6c0b3f3f
\ No newline at end of file
diff --git a/db/schema_migrations/20220124153234 b/db/schema_migrations/20220124153234
new file mode 100644
index 0000000000000000000000000000000000000000..dfca9995395669b6489e23c6534dd95bc9064301
--- /dev/null
+++ b/db/schema_migrations/20220124153234
@@ -0,0 +1 @@
+0e8559121504f1a34394b5f613ef2c5554261f6aeaeaaf5a15d018803c4e5452
\ No newline at end of file
diff --git a/db/schema_migrations/20220124180704 b/db/schema_migrations/20220124180704
new file mode 100644
index 0000000000000000000000000000000000000000..ef59507a2e844da51ec78d2c453dd60c634fcf6c
--- /dev/null
+++ b/db/schema_migrations/20220124180704
@@ -0,0 +1 @@
+5b5f47f1d7038518fef71dd8c0758b234bb890be9aab57b78918f7b2dc39bdc4
\ No newline at end of file
diff --git a/db/schema_migrations/20220124180705 b/db/schema_migrations/20220124180705
new file mode 100644
index 0000000000000000000000000000000000000000..c1600192af1b103c147bf42234dfee5271c2b776
--- /dev/null
+++ b/db/schema_migrations/20220124180705
@@ -0,0 +1 @@
+6c147287ba8436bd0231dc22195c95a71d19987d23741c1291a117407f493184
\ No newline at end of file
diff --git a/db/schema_migrations/20220124184338 b/db/schema_migrations/20220124184338
new file mode 100644
index 0000000000000000000000000000000000000000..860b47090c28963e9b9dded8dca33a88e94bb277
--- /dev/null
+++ b/db/schema_migrations/20220124184338
@@ -0,0 +1 @@
+ae696157794bcbe3ebd0dc41d7b3fe4dc61982ad4a96fa503fd7857e0d3dab16
\ No newline at end of file
diff --git a/db/schema_migrations/20220124200927 b/db/schema_migrations/20220124200927
new file mode 100644
index 0000000000000000000000000000000000000000..ff29cc59538500afe9037180de53fc612a33b01f
--- /dev/null
+++ b/db/schema_migrations/20220124200927
@@ -0,0 +1 @@
+688232dde01ea4e8574dca73459094264bde405d799ecaf1a5867adb72576b98
\ No newline at end of file
diff --git a/db/schema_migrations/20220124204046 b/db/schema_migrations/20220124204046
new file mode 100644
index 0000000000000000000000000000000000000000..f8de3adc215fa30c59821d62706c87d996558d2a
--- /dev/null
+++ b/db/schema_migrations/20220124204046
@@ -0,0 +1 @@
+90115936ede32bbf9a299582409cb0686e8072c204c4f91364dfb13195155929
\ No newline at end of file
diff --git a/db/schema_migrations/20220124214131 b/db/schema_migrations/20220124214131
new file mode 100644
index 0000000000000000000000000000000000000000..7454bd8b3d166e237abe52d72fdb61906afd23df
--- /dev/null
+++ b/db/schema_migrations/20220124214131
@@ -0,0 +1 @@
+af60c6df0fb178a4820ea8cb40b402178da7fb4b6ebeabb8739dc45b96225f89
\ No newline at end of file
diff --git a/db/schema_migrations/20220124215857 b/db/schema_migrations/20220124215857
new file mode 100644
index 0000000000000000000000000000000000000000..495e428d2c4f6391be23791aa0997bba59e0adfb
--- /dev/null
+++ b/db/schema_migrations/20220124215857
@@ -0,0 +1 @@
+785c2404175faef7d3d6f81ae8652ca0ced0f4b01def8d6364a4450f0db49ecf
\ No newline at end of file
diff --git a/db/schema_migrations/20220124221521 b/db/schema_migrations/20220124221521
new file mode 100644
index 0000000000000000000000000000000000000000..8400dcbc1e2733f14e15854a94b1554286307570
--- /dev/null
+++ b/db/schema_migrations/20220124221521
@@ -0,0 +1 @@
+4b1dad4fc34717c9b89a770e4e0682b0cee7d421da68223011bb9fde9460d1f8
\ No newline at end of file
diff --git a/db/schema_migrations/20220125083520 b/db/schema_migrations/20220125083520
new file mode 100644
index 0000000000000000000000000000000000000000..c3fbb6beda5b5bec4a7f265d9660d27115254ada
--- /dev/null
+++ b/db/schema_migrations/20220125083520
@@ -0,0 +1 @@
+2c3f7c587b2a20de1d8581584f7392fd81643af4eb7e25ffc8e08514b6ad83ab
\ No newline at end of file
diff --git a/db/schema_migrations/20220125084127 b/db/schema_migrations/20220125084127
new file mode 100644
index 0000000000000000000000000000000000000000..f9ba7a4628b456a60f87ffb4cfcd655738f24757
--- /dev/null
+++ b/db/schema_migrations/20220125084127
@@ -0,0 +1 @@
+c50a21430e52fc6ccbe7ab4aba99ae3a48d1c69858f7886da115f54e19fc27ea
\ No newline at end of file
diff --git a/db/schema_migrations/20220125084348 b/db/schema_migrations/20220125084348
new file mode 100644
index 0000000000000000000000000000000000000000..9d4cbd7c5ed25f8ba6eb4275b58ca4fa8b1cd690
--- /dev/null
+++ b/db/schema_migrations/20220125084348
@@ -0,0 +1 @@
+75eb050fc789eb5775a5d3a88c2573dca5c38e16b63cd342bf46dca55d1adaef
\ No newline at end of file
diff --git a/db/schema_migrations/20220125122228 b/db/schema_migrations/20220125122228
new file mode 100644
index 0000000000000000000000000000000000000000..2add72978c60a04ccb5721c0107d7e8648a93c93
--- /dev/null
+++ b/db/schema_migrations/20220125122228
@@ -0,0 +1 @@
+26600e01d8b31a4308d0e23564e4d4c52488ec87ad7990a410b7cc0c031f12e7
\ No newline at end of file
diff --git a/db/schema_migrations/20220125122640 b/db/schema_migrations/20220125122640
new file mode 100644
index 0000000000000000000000000000000000000000..fdb85bb480aa3fc3c851fd24d1d78e4b374e78b7
--- /dev/null
+++ b/db/schema_migrations/20220125122640
@@ -0,0 +1 @@
+51c7ab860b952281bd7f65d68e7a539a8eee57cac3bbdaf439ff5593f5b065ed
\ No newline at end of file
diff --git a/db/schema_migrations/20220125122725 b/db/schema_migrations/20220125122725
new file mode 100644
index 0000000000000000000000000000000000000000..7a6ef38bfbcb5a6ce9c6ce00a7c5546b6b88d9c5
--- /dev/null
+++ b/db/schema_migrations/20220125122725
@@ -0,0 +1 @@
+7740d1e71571576a709ae5bfd46f60ea3fb4be3f48cddec2cca53f148096cdd7
\ No newline at end of file
diff --git a/db/schema_migrations/20220125230538 b/db/schema_migrations/20220125230538
new file mode 100644
index 0000000000000000000000000000000000000000..45bd8bfb04c76250c79162db364c1db80b924083
--- /dev/null
+++ b/db/schema_migrations/20220125230538
@@ -0,0 +1 @@
+6f3a3712288c3316042426d60f087817eb57a3246b750831aa72f95f30269a5d
\ No newline at end of file
diff --git a/db/schema_migrations/20220126191624 b/db/schema_migrations/20220126191624
new file mode 100644
index 0000000000000000000000000000000000000000..f8cbab243796a12ed37b9fd1181b818fddbd10c0
--- /dev/null
+++ b/db/schema_migrations/20220126191624
@@ -0,0 +1 @@
+33170856a78b469c63d4821692929a1df0c41e4b9d98093e771b122b462c9c03
\ No newline at end of file
diff --git a/db/schema_migrations/20220126201752 b/db/schema_migrations/20220126201752
new file mode 100644
index 0000000000000000000000000000000000000000..e5a1970ec9e510f8a314e93044c5811d248c42bb
--- /dev/null
+++ b/db/schema_migrations/20220126201752
@@ -0,0 +1 @@
+7731772dfac065a60c1626707913ddf6ff632bb69dd5ed6534e8d29e4e03c573
\ No newline at end of file
diff --git a/db/schema_migrations/20220126202654 b/db/schema_migrations/20220126202654
new file mode 100644
index 0000000000000000000000000000000000000000..341e2c6b8bf09322753fc7c9743aca2d69273734
--- /dev/null
+++ b/db/schema_migrations/20220126202654
@@ -0,0 +1 @@
+6067e4e22e49548496454b48171f8168f7d5bf626fedab4351e2a37a3f85731b
\ No newline at end of file
diff --git a/db/schema_migrations/20220126203421 b/db/schema_migrations/20220126203421
new file mode 100644
index 0000000000000000000000000000000000000000..32469cd40eed4b218ca5debd464ba2cd974dcc17
--- /dev/null
+++ b/db/schema_migrations/20220126203421
@@ -0,0 +1 @@
+07f837ddde21e36d1ca6a471dd96350d3020bd30204fca0e093983810c94e54d
\ No newline at end of file
diff --git a/db/schema_migrations/20220126210021 b/db/schema_migrations/20220126210021
new file mode 100644
index 0000000000000000000000000000000000000000..edb9d9c779d6dbd0ac60af75f0422a694c14324c
--- /dev/null
+++ b/db/schema_migrations/20220126210021
@@ -0,0 +1 @@
+fd7940bb6f077c91d7f9928f574443ba4bf33bb90cb702c0a2ecad14398ab1cc
\ No newline at end of file
diff --git a/db/schema_migrations/20220126210022 b/db/schema_migrations/20220126210022
new file mode 100644
index 0000000000000000000000000000000000000000..32cb73ee3eec1ed29ee9104be5c87bbe4967ce72
--- /dev/null
+++ b/db/schema_migrations/20220126210022
@@ -0,0 +1 @@
+80a75bf72b40ee791bebd9ae97a793ce41fbd352841d83421525b6ad78e1c5e8
\ No newline at end of file
diff --git a/db/schema_migrations/20220126210657 b/db/schema_migrations/20220126210657
new file mode 100644
index 0000000000000000000000000000000000000000..a3301b46756ec9481d27bc669972f24cffbf73a4
--- /dev/null
+++ b/db/schema_migrations/20220126210657
@@ -0,0 +1 @@
+853209f3babe2856481591790d9bb67145c4c0c919ed4d8365bb8d498e4f6b8e
\ No newline at end of file
diff --git a/db/schema_migrations/20220127112243 b/db/schema_migrations/20220127112243
new file mode 100644
index 0000000000000000000000000000000000000000..2c591bdde58cceac4e3c39ef498cb59194e87945
--- /dev/null
+++ b/db/schema_migrations/20220127112243
@@ -0,0 +1 @@
+7707b9bcdcd7ec28af31b90355905eb8971c12a90c4334b0ae214e45fac9645a
\ No newline at end of file
diff --git a/db/schema_migrations/20220127112412 b/db/schema_migrations/20220127112412
new file mode 100644
index 0000000000000000000000000000000000000000..af58ff484738207ce5553ebd0f2025deac456b52
--- /dev/null
+++ b/db/schema_migrations/20220127112412
@@ -0,0 +1 @@
+350409be3f491b61a1d757dbd839b48d088339883e8e019d00ad90e6adc350e6
\ No newline at end of file
diff --git a/db/schema_migrations/20220127132200 b/db/schema_migrations/20220127132200
new file mode 100644
index 0000000000000000000000000000000000000000..8dc7ac4ddbdd2ad3db3caf2a8b65eb37f703bb08
--- /dev/null
+++ b/db/schema_migrations/20220127132200
@@ -0,0 +1 @@
+394f1fa34ccf9188f25102ac963829ebee07dddaf02f1d5958ec14d701fb6fe8
\ No newline at end of file
diff --git a/db/schema_migrations/20220127132201 b/db/schema_migrations/20220127132201
new file mode 100644
index 0000000000000000000000000000000000000000..f2c9cbbe38f0d51e685045db7edae3447934dd57
--- /dev/null
+++ b/db/schema_migrations/20220127132201
@@ -0,0 +1 @@
+f8ce7c183352ce08585eda83eb1e22c800b1b2044b93bc11858a74a8bd9a99d4
\ No newline at end of file
diff --git a/db/schema_migrations/20220128093756 b/db/schema_migrations/20220128093756
new file mode 100644
index 0000000000000000000000000000000000000000..fd24b6cd4cd4342f44c566427e627055f0cf61f6
--- /dev/null
+++ b/db/schema_migrations/20220128093756
@@ -0,0 +1 @@
+787b1be4b69ef0eeb049ee6a3d7126dc75094b79fba18f469fffe78b16fce6a3
\ No newline at end of file
diff --git a/db/schema_migrations/20220128103042 b/db/schema_migrations/20220128103042
new file mode 100644
index 0000000000000000000000000000000000000000..de1e50b66bfed8d7f8a0b6f0364c0e2b1f79317c
--- /dev/null
+++ b/db/schema_migrations/20220128103042
@@ -0,0 +1 @@
+57813d4c107938d8e58d6223719c2c67206172342b52655ca4a068c845edeb3a
\ No newline at end of file
diff --git a/db/schema_migrations/20220128155251 b/db/schema_migrations/20220128155251
new file mode 100644
index 0000000000000000000000000000000000000000..11fa6807ed565aec4f0c90a6a9c5ab3f5671159e
--- /dev/null
+++ b/db/schema_migrations/20220128155251
@@ -0,0 +1 @@
+0d121aeecdd6ace1516c2e9b84fefd47d963c4cbe22a0448728241d83da3742e
\ No newline at end of file
diff --git a/db/schema_migrations/20220128155814 b/db/schema_migrations/20220128155814
new file mode 100644
index 0000000000000000000000000000000000000000..209b0874a84f5fc2a1342d1f3bb99c58d9120a5a
--- /dev/null
+++ b/db/schema_migrations/20220128155814
@@ -0,0 +1 @@
+77cc8fc86f2c6a5ed017dde40dd4db796821a35e6ce4d8dcbe24b2cdaccbb5d9
\ No newline at end of file
diff --git a/db/schema_migrations/20220128194722 b/db/schema_migrations/20220128194722
new file mode 100644
index 0000000000000000000000000000000000000000..9c06f452c1e65d52f43640ae64d7789e5703ee4c
--- /dev/null
+++ b/db/schema_migrations/20220128194722
@@ -0,0 +1 @@
+087338f0b438d2aa33bc22bd3973d818c5d1f40948525d95181751722158605b
\ No newline at end of file
diff --git a/db/schema_migrations/20220131000000 b/db/schema_migrations/20220131000000
new file mode 100644
index 0000000000000000000000000000000000000000..f80ceb97f1cad12f2d1f75e715b6c5c3c2815ddd
--- /dev/null
+++ b/db/schema_migrations/20220131000000
@@ -0,0 +1 @@
+08326048e15f368f09bc10ebf5bee3e77e8b43813f66c19d24731497ca6a8485
\ No newline at end of file
diff --git a/db/schema_migrations/20220131000001 b/db/schema_migrations/20220131000001
new file mode 100644
index 0000000000000000000000000000000000000000..72dce62bbced71f6b93a6e8f3607eae3ba98f299
--- /dev/null
+++ b/db/schema_migrations/20220131000001
@@ -0,0 +1 @@
+59fe701bcaa102b7e0c1496198fa4aeea6b2e59132c951d1c9d54562c5e3900e
\ No newline at end of file
diff --git a/db/schema_migrations/20220131135725 b/db/schema_migrations/20220131135725
new file mode 100644
index 0000000000000000000000000000000000000000..d63b24d5d6c06b2dd7e3f828b1eab08ac6a8fd28
--- /dev/null
+++ b/db/schema_migrations/20220131135725
@@ -0,0 +1 @@
+a0e9bb92512b9ddb3fd718e086b0fd116ec307be6acc5789a872b1d3004fdebd
\ No newline at end of file
diff --git a/db/schema_migrations/20220131192643 b/db/schema_migrations/20220131192643
new file mode 100644
index 0000000000000000000000000000000000000000..e947bf0cfbe42174b2a124035aed9426ced9ea31
--- /dev/null
+++ b/db/schema_migrations/20220131192643
@@ -0,0 +1 @@
+3b9068f109685dcfa8a0a1fda886cca3909d29cbc280cf70ed9f3d927def12ac
\ No newline at end of file
diff --git a/db/schema_migrations/20220201034731 b/db/schema_migrations/20220201034731
new file mode 100644
index 0000000000000000000000000000000000000000..59e4fd59720c6692b3f4e165bbfe613210339b3b
--- /dev/null
+++ b/db/schema_migrations/20220201034731
@@ -0,0 +1 @@
+873ff811d4f70c012785297ee8c07eb496994af69d5ae4b266e8f675c88daca4
\ No newline at end of file
diff --git a/db/schema_migrations/20220201141705 b/db/schema_migrations/20220201141705
new file mode 100644
index 0000000000000000000000000000000000000000..92835993156c4001f3a01b09a2053b918b16cbd0
--- /dev/null
+++ b/db/schema_migrations/20220201141705
@@ -0,0 +1 @@
+9eb0c4609fbec79370215d05a9a1faf4208b9dcc2bfeb861feeb7c9f354489ab
\ No newline at end of file
diff --git a/db/schema_migrations/20220201173212 b/db/schema_migrations/20220201173212
new file mode 100644
index 0000000000000000000000000000000000000000..b07c8e371a562a458839847e321f8e2fcc342a15
--- /dev/null
+++ b/db/schema_migrations/20220201173212
@@ -0,0 +1 @@
+7a48d49d576d183198df370593642419da5707d8b018a23f541c448e2aa7ad65
\ No newline at end of file
diff --git a/db/schema_migrations/20220201193033 b/db/schema_migrations/20220201193033
new file mode 100644
index 0000000000000000000000000000000000000000..e40840c66fa09584bec1e75d08f5ccd27e0ed390
--- /dev/null
+++ b/db/schema_migrations/20220201193033
@@ -0,0 +1 @@
+92bbe74c6c3627dd26f709acd2a20f442212eab933f719be815701a3bc429539
\ No newline at end of file
diff --git a/db/schema_migrations/20220201205300 b/db/schema_migrations/20220201205300
new file mode 100644
index 0000000000000000000000000000000000000000..86f6dd234fdf0e497b7f06e31b5f40fb34da5082
--- /dev/null
+++ b/db/schema_migrations/20220201205300
@@ -0,0 +1 @@
+79a636f33f70327206356abd1793b73a5ef5e920a41662e35cbff5597b03a365
\ No newline at end of file
diff --git a/db/schema_migrations/20220202034409 b/db/schema_migrations/20220202034409
new file mode 100644
index 0000000000000000000000000000000000000000..4eb359f45e6d3c16130fed325d8538cb2259a451
--- /dev/null
+++ b/db/schema_migrations/20220202034409
@@ -0,0 +1 @@
+0efe482aa626cf80912feaa1176837253b094fc434f273bee35b5fe3e8ce4243
\ No newline at end of file
diff --git a/db/schema_migrations/20220202105733 b/db/schema_migrations/20220202105733
new file mode 100644
index 0000000000000000000000000000000000000000..473b03d621003f9db3c917aac5e92176eeb0bd8d
--- /dev/null
+++ b/db/schema_migrations/20220202105733
@@ -0,0 +1 @@
+6f2919091a6998f2f18f8dbff3c968e68dc218ab0e51341164d1fc5b8abf72ae
\ No newline at end of file
diff --git a/db/schema_migrations/20220202115350 b/db/schema_migrations/20220202115350
new file mode 100644
index 0000000000000000000000000000000000000000..9b8148ca2d1a7e79558fffee637fa9a66feed5ab
--- /dev/null
+++ b/db/schema_migrations/20220202115350
@@ -0,0 +1 @@
+3bcc97592e8e329e39917deffae6619e69215930a688bebad2949f69155b53f9
\ No newline at end of file
diff --git a/db/schema_migrations/20220203074916 b/db/schema_migrations/20220203074916
new file mode 100644
index 0000000000000000000000000000000000000000..fffd0dcc003aef51d5f80017584c1976cfd0e903
--- /dev/null
+++ b/db/schema_migrations/20220203074916
@@ -0,0 +1 @@
+5bb52cc70aada72e0e569006fd05de0c0d7629559d78bfd361009c91482f02cf
\ No newline at end of file
diff --git a/db/schema_migrations/20220203091304 b/db/schema_migrations/20220203091304
new file mode 100644
index 0000000000000000000000000000000000000000..847620db3d26bde0e8cc81571042a83f52b86167
--- /dev/null
+++ b/db/schema_migrations/20220203091304
@@ -0,0 +1 @@
+dac90da1a8c5af69610dd103c8db9cd70a395ad5f9addafb554a853d6acd2a6e
\ No newline at end of file
diff --git a/db/schema_migrations/20220203123333 b/db/schema_migrations/20220203123333
new file mode 100644
index 0000000000000000000000000000000000000000..9cc146c4ed752a61c1ebc9f4335fcabac62e1472
--- /dev/null
+++ b/db/schema_migrations/20220203123333
@@ -0,0 +1 @@
+87cccb30bb6f27a1acb0dd0cb905040e2a0291cefc5f26bb9a08c8be18034ca3
\ No newline at end of file
diff --git a/db/schema_migrations/20220203133652 b/db/schema_migrations/20220203133652
new file mode 100644
index 0000000000000000000000000000000000000000..7deda2292b41c8c9b4180cddf8c037fb441e387c
--- /dev/null
+++ b/db/schema_migrations/20220203133652
@@ -0,0 +1 @@
+5642cf604a1aaf8bef6098a9918b582e0e336d79ca3b2a005cf90bb8eab0ca13
\ No newline at end of file
diff --git a/db/schema_migrations/20220203134942 b/db/schema_migrations/20220203134942
new file mode 100644
index 0000000000000000000000000000000000000000..7dea7f1f0e73d4a7d821c596bdc45e7be90f89d0
--- /dev/null
+++ b/db/schema_migrations/20220203134942
@@ -0,0 +1 @@
+02f7a38c7bc19b1a266ac1f1d6631f1922fc135518baeb19ee90bebd7c31c6b9
\ No newline at end of file
diff --git a/db/schema_migrations/20220204053655 b/db/schema_migrations/20220204053655
new file mode 100644
index 0000000000000000000000000000000000000000..e096dae0c0764d97e11945a38b81056a41726cac
--- /dev/null
+++ b/db/schema_migrations/20220204053655
@@ -0,0 +1 @@
+d6b7fa6e5be83aa67bb479604bf6ddb9d8caae82fc8ea1ab7f34d5c534174ecf
\ No newline at end of file
diff --git a/db/schema_migrations/20220204093120 b/db/schema_migrations/20220204093120
new file mode 100644
index 0000000000000000000000000000000000000000..debd48e3c5f2190eaa55272e9a858fa2e5e0af5f
--- /dev/null
+++ b/db/schema_migrations/20220204093120
@@ -0,0 +1 @@
+e147a8281f98ee397d7d9b652ce21b943e4e87c11fca906b72db839e0e2fa360
\ No newline at end of file
diff --git a/db/schema_migrations/20220204095121 b/db/schema_migrations/20220204095121
new file mode 100644
index 0000000000000000000000000000000000000000..bf12ca08f5ad4b31e599b09899d4f4a28e2e69a2
--- /dev/null
+++ b/db/schema_migrations/20220204095121
@@ -0,0 +1 @@
+bce595c1c6587e785bc49d6e5a7181b5cc0164f2201375ad82d4bd19c217cd35
\ No newline at end of file
diff --git a/db/schema_migrations/20220204110725 b/db/schema_migrations/20220204110725
new file mode 100644
index 0000000000000000000000000000000000000000..804dc8c6d545283d97efa8c177a795b28ec27e8e
--- /dev/null
+++ b/db/schema_migrations/20220204110725
@@ -0,0 +1 @@
+c87ca83f592c6688c31182fcd4cf6fe282c00a3c92ebe245b66455f57b50fc32
\ No newline at end of file
diff --git a/db/schema_migrations/20220204154220 b/db/schema_migrations/20220204154220
new file mode 100644
index 0000000000000000000000000000000000000000..42da4e8225816d9a0972b9874709d110e08dab9c
--- /dev/null
+++ b/db/schema_migrations/20220204154220
@@ -0,0 +1 @@
+efecc3c6468d8a5036352f5b62e8d70de835d1beb4e45ba6d3906906d0317848
\ No newline at end of file
diff --git a/db/schema_migrations/20220204193000 b/db/schema_migrations/20220204193000
new file mode 100644
index 0000000000000000000000000000000000000000..f0d16b9671c6189c3608100d8664b7ccc95d1109
--- /dev/null
+++ b/db/schema_migrations/20220204193000
@@ -0,0 +1 @@
+9d98618a1e9fd0474c45ac54420fc64a1d90ad77f36be594337e5b117fccdadb
\ No newline at end of file
diff --git a/db/schema_migrations/20220204194347 b/db/schema_migrations/20220204194347
new file mode 100644
index 0000000000000000000000000000000000000000..d506497e0362b4121348a8823e84cb56ce8d47de
--- /dev/null
+++ b/db/schema_migrations/20220204194347
@@ -0,0 +1 @@
+1593e935601ae1f2ab788109687bb40bad026f3f425339a39c8d13d3e4c7e306
\ No newline at end of file
diff --git a/db/schema_migrations/20220207080758 b/db/schema_migrations/20220207080758
new file mode 100644
index 0000000000000000000000000000000000000000..d4adf5ad455d04ff98b5d25c5568faf6868dc23c
--- /dev/null
+++ b/db/schema_migrations/20220207080758
@@ -0,0 +1 @@
+f63be8bd42cc1856c92f9073fdb39c58c45806b483d38b91db007a8661c49a97
\ No newline at end of file
diff --git a/db/schema_migrations/20220207083129 b/db/schema_migrations/20220207083129
new file mode 100644
index 0000000000000000000000000000000000000000..25dca4578f48053c2ea9b07b066144f339bdb7ca
--- /dev/null
+++ b/db/schema_migrations/20220207083129
@@ -0,0 +1 @@
+01cc0139097235991fa2caf8b780ccd1c3ce580647197418424ade83ce9be77e
\ No newline at end of file
diff --git a/db/schema_migrations/20220208080921 b/db/schema_migrations/20220208080921
new file mode 100644
index 0000000000000000000000000000000000000000..ecf3538939031f4f22c54f14bb44a6fc321a2356
--- /dev/null
+++ b/db/schema_migrations/20220208080921
@@ -0,0 +1 @@
+84346c2f608792f259ab91dbc2c8aac8397a2997f890f8e077aad809276bb7cd
\ No newline at end of file
diff --git a/db/schema_migrations/20220208115439 b/db/schema_migrations/20220208115439
new file mode 100644
index 0000000000000000000000000000000000000000..722303216258f9c865dcea52798b14e2e01d2fef
--- /dev/null
+++ b/db/schema_migrations/20220208115439
@@ -0,0 +1 @@
+dbe6760198b8fa068c30871a439298e56802867044a178baa6b8b009f8da13e6
\ No newline at end of file
diff --git a/db/schema_migrations/20220208170445 b/db/schema_migrations/20220208170445
new file mode 100644
index 0000000000000000000000000000000000000000..3a486a586a86577877629155f74cdaf7742ef33e
--- /dev/null
+++ b/db/schema_migrations/20220208170445
@@ -0,0 +1 @@
+e00dd618ca393596f3ff05b44b1a9a36183729a864a5cf4b8f1a262dfcdb932b
\ No newline at end of file
diff --git a/db/schema_migrations/20220208171826 b/db/schema_migrations/20220208171826
new file mode 100644
index 0000000000000000000000000000000000000000..75ae0dcef6186e970c6066ffedde19f03b69b805
--- /dev/null
+++ b/db/schema_migrations/20220208171826
@@ -0,0 +1 @@
+e48473172d7561fb7474e16e291e555843c0ec4543300b007f86cd4a5923db85
\ No newline at end of file
diff --git a/db/schema_migrations/20220209111007 b/db/schema_migrations/20220209111007
new file mode 100644
index 0000000000000000000000000000000000000000..f10e05b891838473ff60c949ddb643e736fe9962
--- /dev/null
+++ b/db/schema_migrations/20220209111007
@@ -0,0 +1 @@
+9462258bcbe45ab80f7ef5a02f8b8d5c0ed6ac69bf04b8934ae3dee2261ba458
\ No newline at end of file
diff --git a/db/schema_migrations/20220211090920 b/db/schema_migrations/20220211090920
new file mode 100644
index 0000000000000000000000000000000000000000..1f08b66e508392e1f5f36e4892c1cc25df29b2bf
--- /dev/null
+++ b/db/schema_migrations/20220211090920
@@ -0,0 +1 @@
+644d38e401ac8179777cb9d3c5fefca2fb55e0c409197bb2d222f7e96e5dd42f
\ No newline at end of file
diff --git a/db/schema_migrations/20220211125954 b/db/schema_migrations/20220211125954
new file mode 100644
index 0000000000000000000000000000000000000000..5f0bb0092541349b0e9e5cba5e94f5210cc1fb34
--- /dev/null
+++ b/db/schema_migrations/20220211125954
@@ -0,0 +1 @@
+73feefe409b9c0f4ea373d0c3f13690df0086fbc4fc212595e959ad65fcc27b1
\ No newline at end of file
diff --git a/db/schema_migrations/20220211214605 b/db/schema_migrations/20220211214605
new file mode 100644
index 0000000000000000000000000000000000000000..89dbee18ee7e872c493f4af8716cc471dc727d9b
--- /dev/null
+++ b/db/schema_migrations/20220211214605
@@ -0,0 +1 @@
+add5ee0b8e090ba740ce738f66ea4f741485a0c84728fecfa5b0488564d55536
\ No newline at end of file
diff --git a/db/schema_migrations/20220212120735 b/db/schema_migrations/20220212120735
new file mode 100644
index 0000000000000000000000000000000000000000..1ec5f9af6816d78ec879a05beb6e1d03c6e66b68
--- /dev/null
+++ b/db/schema_migrations/20220212120735
@@ -0,0 +1 @@
+c075ee9d6efeae4b7a9b6e310f0c3d0bdd0ac6a58dc214427d4de9ae579db50d
\ No newline at end of file
diff --git a/db/schema_migrations/20220213100000 b/db/schema_migrations/20220213100000
new file mode 100644
index 0000000000000000000000000000000000000000..a62215351cd5595b28553ce9a94ac4cb5889450b
--- /dev/null
+++ b/db/schema_migrations/20220213100000
@@ -0,0 +1 @@
+a6c1438ebcffca03e1c42ca9a233d087932fabcfd1eacf20dd801b9f574226e5
\ No newline at end of file
diff --git a/db/schema_migrations/20220213103859 b/db/schema_migrations/20220213103859
new file mode 100644
index 0000000000000000000000000000000000000000..8950d31675e7183394f2653af94829122a7ff298
--- /dev/null
+++ b/db/schema_migrations/20220213103859
@@ -0,0 +1 @@
+ffc9a2dd97ace1f34e0cfca0c407dcf98dabf30379a441ba948261aec531fe85
\ No newline at end of file
diff --git a/db/schema_migrations/20220213104531 b/db/schema_migrations/20220213104531
new file mode 100644
index 0000000000000000000000000000000000000000..72656d85fb015eaa9412f6898de019430f75ad48
--- /dev/null
+++ b/db/schema_migrations/20220213104531
@@ -0,0 +1 @@
+9ce8aa469b9469d25fbba52147e24c95f6242c2ab1e114df8baaf5a45268d2fd
\ No newline at end of file
diff --git a/db/schema_migrations/20220215164709 b/db/schema_migrations/20220215164709
new file mode 100644
index 0000000000000000000000000000000000000000..60179eaeddd9a833f60ec5b07e20f3c79fedd2fc
--- /dev/null
+++ b/db/schema_migrations/20220215164709
@@ -0,0 +1 @@
+af6d142b77bc2787a520f8cbc63c287823a7a65a2edb3eb488e4f0f4efde9fa8
\ No newline at end of file
diff --git a/db/schema_migrations/20220215190020 b/db/schema_migrations/20220215190020
new file mode 100644
index 0000000000000000000000000000000000000000..1d5be90ca1fc5b3424feac34d327ae17778bf75f
--- /dev/null
+++ b/db/schema_migrations/20220215190020
@@ -0,0 +1 @@
+aa92afc5f74f051132aeb73889d7360bbd6258b27c0aedb4fea6a44ccce597b3
\ No newline at end of file
diff --git a/db/schema_migrations/20220216110023 b/db/schema_migrations/20220216110023
new file mode 100644
index 0000000000000000000000000000000000000000..30acd6fdaf2a476dd5ffa1d9b819d77952bcc6b6
--- /dev/null
+++ b/db/schema_migrations/20220216110023
@@ -0,0 +1 @@
+5931c4981c89d65c5aaca05dc8375c2c21bb595e28354d6623986d906ece165d
\ No newline at end of file
diff --git a/db/schema_migrations/20220216201949 b/db/schema_migrations/20220216201949
new file mode 100644
index 0000000000000000000000000000000000000000..466da69ad0ef01905cd03bb8f06f7e1c2987e26f
--- /dev/null
+++ b/db/schema_migrations/20220216201949
@@ -0,0 +1 @@
+481bc7b167ddf46bd11322e4458e48de10483bf34d0e393f7e76a3572c28e09f
\ No newline at end of file
diff --git a/db/schema_migrations/20220217100008 b/db/schema_migrations/20220217100008
new file mode 100644
index 0000000000000000000000000000000000000000..6347388a5ce2af57240f0d8a2c68470981dbdc56
--- /dev/null
+++ b/db/schema_migrations/20220217100008
@@ -0,0 +1 @@
+f52d88262879c40d9ac60a74853b7070036f244fd5f7957c59bbfceb343811d1
\ No newline at end of file
diff --git a/db/schema_migrations/20220217113058 b/db/schema_migrations/20220217113058
new file mode 100644
index 0000000000000000000000000000000000000000..ef801a0e2693cb5437e7cf30a013d7d7423ac419
--- /dev/null
+++ b/db/schema_migrations/20220217113058
@@ -0,0 +1 @@
+d2d236e9ee5fa6e9c1ee97431543e871b78e469b812444bd9386dfecf849947b
\ No newline at end of file
diff --git a/db/schema_migrations/20220217135229 b/db/schema_migrations/20220217135229
new file mode 100644
index 0000000000000000000000000000000000000000..fb80b77347f6d764f414f606e997a1cef40ebea5
--- /dev/null
+++ b/db/schema_migrations/20220217135229
@@ -0,0 +1 @@
+3223f741799216ee6afb4daafbcebfa09bd722d461dd4d64fcbda7d8700ae235
\ No newline at end of file
diff --git a/db/schema_migrations/20220221102333 b/db/schema_migrations/20220221102333
new file mode 100644
index 0000000000000000000000000000000000000000..dfc13fd28a0dc911b3834019208aff56652a13ce
--- /dev/null
+++ b/db/schema_migrations/20220221102333
@@ -0,0 +1 @@
+7aa2cf28363e914ad83c61d45321f701a68111122c75abeb54430c4035d56677
\ No newline at end of file
diff --git a/db/schema_migrations/20220221214928 b/db/schema_migrations/20220221214928
new file mode 100644
index 0000000000000000000000000000000000000000..5c32b3fbd96431279949a64fcf3c652d0a1080ed
--- /dev/null
+++ b/db/schema_migrations/20220221214928
@@ -0,0 +1 @@
+8c9936d1c0f728c2b40dca536f9edb40f4af94a274ccf1dbec984f218710f695
\ No newline at end of file
diff --git a/db/schema_migrations/20220222072536 b/db/schema_migrations/20220222072536
new file mode 100644
index 0000000000000000000000000000000000000000..6a4b4f76ddab7e46b382474860348334530a74ea
--- /dev/null
+++ b/db/schema_migrations/20220222072536
@@ -0,0 +1 @@
+d7ddc369818f0a2403abefea2ac1da5abd1ca41199d3948166f10dfdf9d2fa9d
\ No newline at end of file
diff --git a/db/schema_migrations/20220222191845 b/db/schema_migrations/20220222191845
new file mode 100644
index 0000000000000000000000000000000000000000..88c15bc87c002dad9371183c3c18710d00de9d82
--- /dev/null
+++ b/db/schema_migrations/20220222191845
@@ -0,0 +1 @@
+c528d64cafc072554cd1ef1006a1c359a3135896abae2d5ca20fbbc99ff14f8c
\ No newline at end of file
diff --git a/db/schema_migrations/20220222192524 b/db/schema_migrations/20220222192524
new file mode 100644
index 0000000000000000000000000000000000000000..c49e45f0d613427f16bd9e3a3bbaf892a5dedd26
--- /dev/null
+++ b/db/schema_migrations/20220222192524
@@ -0,0 +1 @@
+b876119bb369a9831736cddf5326b72a74003ec2e17fe863654cb69497fcf236
\ No newline at end of file
diff --git a/db/schema_migrations/20220222192525 b/db/schema_migrations/20220222192525
new file mode 100644
index 0000000000000000000000000000000000000000..6eeec13bbb59e63789b0c10a7c80856db888e59b
--- /dev/null
+++ b/db/schema_migrations/20220222192525
@@ -0,0 +1 @@
+f512ea4c4a2625c647c3d05765152fee963b56962b674f839180fd77c194ccb0
\ No newline at end of file
diff --git a/db/schema_migrations/20220223112304 b/db/schema_migrations/20220223112304
new file mode 100644
index 0000000000000000000000000000000000000000..bfcbf9c12254b9b7f63bbe703beaec62b70a92e3
--- /dev/null
+++ b/db/schema_migrations/20220223112304
@@ -0,0 +1 @@
+57dc23bb2a9faddefe20c1e30a8879ebb1f6f32f17e3cc381acc1d06ad3b598a
\ No newline at end of file
diff --git a/db/schema_migrations/20220223124428 b/db/schema_migrations/20220223124428
new file mode 100644
index 0000000000000000000000000000000000000000..b163accc95708df160cefbff4aa521d013b415d7
--- /dev/null
+++ b/db/schema_migrations/20220223124428
@@ -0,0 +1 @@
+8fb72b15bfaa1b58f87cb3f1836df1e8bfa1a5ddec4e480a2cb6a3c9fafe3bda
\ No newline at end of file
diff --git a/db/schema_migrations/20220224000000 b/db/schema_migrations/20220224000000
new file mode 100644
index 0000000000000000000000000000000000000000..e6e9aefbabb56d308eba715627bd8594eb7535fe
--- /dev/null
+++ b/db/schema_migrations/20220224000000
@@ -0,0 +1 @@
+74b4d572118b7f5da0a80722601a4757ce47ccbdae1af1e84b2304343477d634
\ No newline at end of file
diff --git a/db/schema_migrations/20220224204415 b/db/schema_migrations/20220224204415
new file mode 100644
index 0000000000000000000000000000000000000000..e0faa994b54c78cf8d0fd72c9d24fb3fec06c66f
--- /dev/null
+++ b/db/schema_migrations/20220224204415
@@ -0,0 +1 @@
+1d7105559c8d2da1d86c5625c592edc792d7cd729b8c86c7a2b950c3dd98e975
\ No newline at end of file
diff --git a/db/schema_migrations/20220225133705 b/db/schema_migrations/20220225133705
new file mode 100644
index 0000000000000000000000000000000000000000..97f27e748e09d3ebf890fbe5098a2b9048fe26eb
--- /dev/null
+++ b/db/schema_migrations/20220225133705
@@ -0,0 +1 @@
+aa9ab05f6991f06c465fbc4878e0cbc648dc09b1b7912dbbf3dd68887a9cdd1d
\ No newline at end of file
diff --git a/db/schema_migrations/20220301002101 b/db/schema_migrations/20220301002101
new file mode 100644
index 0000000000000000000000000000000000000000..ab8f76b3bbb0447ff6c75275d01aa1369b49d808
--- /dev/null
+++ b/db/schema_migrations/20220301002101
@@ -0,0 +1 @@
+a19f7f5026fd91cf6f3fcadccd19808920e64005c207b57b46955a0352a68366
\ No newline at end of file
diff --git a/db/schema_migrations/20220301003502 b/db/schema_migrations/20220301003502
new file mode 100644
index 0000000000000000000000000000000000000000..5a2a9ee8334c2856ebc78dc836248a0a81353823
--- /dev/null
+++ b/db/schema_migrations/20220301003502
@@ -0,0 +1 @@
+bbca8df8e60c8d027f672dfdee2b0edef35f4fdc3152ae98450df67633f3998f
\ No newline at end of file
diff --git a/db/schema_migrations/20220301091503 b/db/schema_migrations/20220301091503
new file mode 100644
index 0000000000000000000000000000000000000000..49184ad4262ddb8fee5d3b6ccfffccd0548ad8fc
--- /dev/null
+++ b/db/schema_migrations/20220301091503
@@ -0,0 +1 @@
+4a05ddbc3d2a52a719c6fda8d834611be6f663fbce97b42655a00583d0e2042a
\ No newline at end of file
diff --git a/db/schema_migrations/20220301093434 b/db/schema_migrations/20220301093434
new file mode 100644
index 0000000000000000000000000000000000000000..78886cc9df4f84f6c6d06ecd063fec75436e66bf
--- /dev/null
+++ b/db/schema_migrations/20220301093434
@@ -0,0 +1 @@
+ffdd031395c025ea63ea1adcd63636822e62388a8860c93235f3748918fc30ca
\ No newline at end of file
diff --git a/db/schema_migrations/20220301175104 b/db/schema_migrations/20220301175104
new file mode 100644
index 0000000000000000000000000000000000000000..2553c9575766b3f27e5371be315573c89faf0a59
--- /dev/null
+++ b/db/schema_migrations/20220301175104
@@ -0,0 +1 @@
+52e172b1ca6e21a6864e82597a7aae6e1c4776507a475a88807ec140b8648966
\ No newline at end of file
diff --git a/db/schema_migrations/20220301175426 b/db/schema_migrations/20220301175426
new file mode 100644
index 0000000000000000000000000000000000000000..6a11d9b04b88d56d542d0bdf2f0f534f95c7ee27
--- /dev/null
+++ b/db/schema_migrations/20220301175426
@@ -0,0 +1 @@
+d0a8daf9fb9892fc92b03f13de4d7e470e5c54f03b09f887cdd45bc5eb9a7e37
\ No newline at end of file
diff --git a/db/schema_migrations/20220302110724 b/db/schema_migrations/20220302110724
new file mode 100644
index 0000000000000000000000000000000000000000..700a39b85c595b875574cff9a1fdee71fe70767f
--- /dev/null
+++ b/db/schema_migrations/20220302110724
@@ -0,0 +1 @@
+4f565a313c37d12f24afe26a9e344d4273c54d0f080b3108d56ed98bf7299ecc
\ No newline at end of file
diff --git a/db/schema_migrations/20220302114046 b/db/schema_migrations/20220302114046
new file mode 100644
index 0000000000000000000000000000000000000000..40488b47eb2e60956b1bc001a2f36fbcaf14079b
--- /dev/null
+++ b/db/schema_migrations/20220302114046
@@ -0,0 +1 @@
+4e2de14559b47a9bf3fa8910fdb84ff62cb18442620f4147e40e8026bf4bcf1b
\ No newline at end of file
diff --git a/db/schema_migrations/20220302203410 b/db/schema_migrations/20220302203410
new file mode 100644
index 0000000000000000000000000000000000000000..70326d38a9708aa8284292e0a4ce1ba33e7f264b
--- /dev/null
+++ b/db/schema_migrations/20220302203410
@@ -0,0 +1 @@
+873aac965684e58cfdb6098b20891cbb73614aff833f235d76bfd379498f6fda
\ No newline at end of file
diff --git a/db/schema_migrations/20220303190555 b/db/schema_migrations/20220303190555
new file mode 100644
index 0000000000000000000000000000000000000000..08db64ca2a4ca995dc73192e8f159efd0be79ee2
--- /dev/null
+++ b/db/schema_migrations/20220303190555
@@ -0,0 +1 @@
+f8fa8b83da24bf98c97447a2940c8ca801532c80395b6a65c11f83515f811652
\ No newline at end of file
diff --git a/db/schema_migrations/20220303191047 b/db/schema_migrations/20220303191047
new file mode 100644
index 0000000000000000000000000000000000000000..6e933c08f6b5a40ca8d0b0acbbe3cf4c5839e462
--- /dev/null
+++ b/db/schema_migrations/20220303191047
@@ -0,0 +1 @@
+19566152e16a92263dd5dcfd66299e3b9d8b82acd4edb4bba21f6b9b06fc8070
\ No newline at end of file
diff --git a/db/schema_migrations/20220304052335 b/db/schema_migrations/20220304052335
new file mode 100644
index 0000000000000000000000000000000000000000..5716ea07f7d7f02e05a503b48a4b83dbdd708df0
--- /dev/null
+++ b/db/schema_migrations/20220304052335
@@ -0,0 +1 @@
+ba2bae8d9561eeab907ecf30664a593bdf93ab1041453f93794bf0be4464e92c
\ No newline at end of file
diff --git a/db/schema_migrations/20220304061631 b/db/schema_migrations/20220304061631
new file mode 100644
index 0000000000000000000000000000000000000000..d7b38b30f9f3be845854455552c3afc921f193b0
--- /dev/null
+++ b/db/schema_migrations/20220304061631
@@ -0,0 +1 @@
+7394be90999876473cfe39c38e72f21c7bb36a5038300d6fe1354f15f3d77e21
\ No newline at end of file
diff --git a/db/schema_migrations/20220304062107 b/db/schema_migrations/20220304062107
new file mode 100644
index 0000000000000000000000000000000000000000..9ea552c6a9e80418f43543ff32195dbf3212da30
--- /dev/null
+++ b/db/schema_migrations/20220304062107
@@ -0,0 +1 @@
+a9aace14f847412c2af03cc6de61616a0f48d32d0fd24b25f6b1f85513c87139
\ No newline at end of file
diff --git a/db/schema_migrations/20220304152729 b/db/schema_migrations/20220304152729
new file mode 100644
index 0000000000000000000000000000000000000000..021d4e5ad27c2a11dab4d117d5e67cc3da03446f
--- /dev/null
+++ b/db/schema_migrations/20220304152729
@@ -0,0 +1 @@
+483f8299688a6e24fa77867b7dab8a2dad0c2b7ebe43c56c81c02ab1e0dc4674
\ No newline at end of file
diff --git a/db/schema_migrations/20220304165107 b/db/schema_migrations/20220304165107
new file mode 100644
index 0000000000000000000000000000000000000000..6db7aee6b0f41287b20ea7d4f0202eb8d920424e
--- /dev/null
+++ b/db/schema_migrations/20220304165107
@@ -0,0 +1 @@
+b7090327d2638bbee6646e5ca5a8f8597d97631f10f997698b8a1c1b6329c106
\ No newline at end of file
diff --git a/db/schema_migrations/20220304201847 b/db/schema_migrations/20220304201847
new file mode 100644
index 0000000000000000000000000000000000000000..1dafb1b821ebabc857834d5c9fd8597b53298f59
--- /dev/null
+++ b/db/schema_migrations/20220304201847
@@ -0,0 +1 @@
+d60a313ac68b0edfe1ae219690aacbe74c038b90bc4239f67d14f9ced36d67f6
\ No newline at end of file
diff --git a/db/schema_migrations/20220305223212 b/db/schema_migrations/20220305223212
new file mode 100644
index 0000000000000000000000000000000000000000..b8adc88a7601eef77a171e3b6f35ea8ecb9640e5
--- /dev/null
+++ b/db/schema_migrations/20220305223212
@@ -0,0 +1 @@
+8a0e80b6df1d942e5ec23641c935103cddd96c044e2a960b88bb38284cf4d070
\ No newline at end of file
diff --git a/db/schema_migrations/20220307192534 b/db/schema_migrations/20220307192534
new file mode 100644
index 0000000000000000000000000000000000000000..cf6687d88eab46a8b25dd073f608b02c80fe670d
--- /dev/null
+++ b/db/schema_migrations/20220307192534
@@ -0,0 +1 @@
+b8adcc6d7dc76fd18037de9b2b204e7db8803564df19cbd59f928901c8d97b9c
\ No newline at end of file
diff --git a/db/schema_migrations/20220307192610 b/db/schema_migrations/20220307192610
new file mode 100644
index 0000000000000000000000000000000000000000..17575dc717451e1c084909e2898da3a9cdf958db
--- /dev/null
+++ b/db/schema_migrations/20220307192610
@@ -0,0 +1 @@
+3dd34a92230e36fe1e9761ce39e4edb2a3289c972ce56347e87d8e36818e46d1
\ No newline at end of file
diff --git a/db/schema_migrations/20220307192645 b/db/schema_migrations/20220307192645
new file mode 100644
index 0000000000000000000000000000000000000000..913bbbf5c9695b02168d2ee2313c161c6b268036
--- /dev/null
+++ b/db/schema_migrations/20220307192645
@@ -0,0 +1 @@
+c31db54f15cff7b21272cc2e9e962419ba4422582c227c5af4131fe56c1fc9f8
\ No newline at end of file
diff --git a/db/schema_migrations/20220307192725 b/db/schema_migrations/20220307192725
new file mode 100644
index 0000000000000000000000000000000000000000..1611c196a57282e2edba6c4f78d03959240f52f7
--- /dev/null
+++ b/db/schema_migrations/20220307192725
@@ -0,0 +1 @@
+d1761614c3ac0e8bd33eff58134091ec6c1834ecde3e47290a80da45ab207923
\ No newline at end of file
diff --git a/db/schema_migrations/20220307203458 b/db/schema_migrations/20220307203458
new file mode 100644
index 0000000000000000000000000000000000000000..3063be4650333f9f9fc301700c68deb633d94169
--- /dev/null
+++ b/db/schema_migrations/20220307203458
@@ -0,0 +1 @@
+d4bf5f7c695c9833a07722d724b7a6363f0ebcb7f6d8a15bcf8148bdae5e1b32
\ No newline at end of file
diff --git a/db/schema_migrations/20220307203459 b/db/schema_migrations/20220307203459
new file mode 100644
index 0000000000000000000000000000000000000000..2220fd3cb6109d7765d84b2a825b1391728f544a
--- /dev/null
+++ b/db/schema_migrations/20220307203459
@@ -0,0 +1 @@
+74f6687c0793a2596467338d8b4904bef712e6ff3ad3561e3ab2546eed5cd24d
\ No newline at end of file
diff --git a/db/schema_migrations/20220308000205 b/db/schema_migrations/20220308000205
new file mode 100644
index 0000000000000000000000000000000000000000..27caf959eb9bd6afcc8f0952308130588eb0c524
--- /dev/null
+++ b/db/schema_migrations/20220308000205
@@ -0,0 +1 @@
+c30b1b36ec83df1b4fdf0c3c28656b158beab4f2188875898182c2dfbd073c80
\ No newline at end of file
diff --git a/db/schema_migrations/20220308115219 b/db/schema_migrations/20220308115219
new file mode 100644
index 0000000000000000000000000000000000000000..6e55d2fdabe08ea733a3cb341911526c3e7980a0
--- /dev/null
+++ b/db/schema_migrations/20220308115219
@@ -0,0 +1 @@
+e18ed9e6b2a98c77190ff2ce33f4d2b1984710b438e851d6a526ec8bb1f33c80
\ No newline at end of file
diff --git a/db/schema_migrations/20220308115502 b/db/schema_migrations/20220308115502
new file mode 100644
index 0000000000000000000000000000000000000000..c379b67485c2b2b66ef63e395c309df31e8fa4e1
--- /dev/null
+++ b/db/schema_migrations/20220308115502
@@ -0,0 +1 @@
+0aacf46a4a5b430a718336108f52c1c0bed4283846f36c2ab1de80100dcae0b4
\ No newline at end of file
diff --git a/db/schema_migrations/20220309084838 b/db/schema_migrations/20220309084838
new file mode 100644
index 0000000000000000000000000000000000000000..ba0ae90a3cffccdd6cf0ceb23c6c1a747904936c
--- /dev/null
+++ b/db/schema_migrations/20220309084838
@@ -0,0 +1 @@
+d9d17f94f54840eace48f210e3886423a8dc04109f2ebca8d8edb7d53e0b5688
\ No newline at end of file
diff --git a/db/schema_migrations/20220309084954 b/db/schema_migrations/20220309084954
new file mode 100644
index 0000000000000000000000000000000000000000..944a1385fe73cb0e149f08212762190559d5e296
--- /dev/null
+++ b/db/schema_migrations/20220309084954
@@ -0,0 +1 @@
+6d9c5454372317955c4e16b5a02dece575221f15af60c33df45fffbca169c08c
\ No newline at end of file
diff --git a/db/schema_migrations/20220309100648 b/db/schema_migrations/20220309100648
new file mode 100644
index 0000000000000000000000000000000000000000..a0697655d9a64d8a66b9966e900e5d57f007628d
--- /dev/null
+++ b/db/schema_migrations/20220309100648
@@ -0,0 +1 @@
+3385dc0dc2a3d306e01a719b7a21197ea8468976d37abab932beade4780bb4ff
\ No newline at end of file
diff --git a/db/schema_migrations/20220309154855 b/db/schema_migrations/20220309154855
new file mode 100644
index 0000000000000000000000000000000000000000..01500ce5863e41e57c548f5b2d6c2c1b8b7d0814
--- /dev/null
+++ b/db/schema_migrations/20220309154855
@@ -0,0 +1 @@
+9e62675366f9c2f0fc159a9748409dbcaea240c813ab19ea26d24c966e5fd6c8
\ No newline at end of file
diff --git a/db/schema_migrations/20220310011530 b/db/schema_migrations/20220310011530
new file mode 100644
index 0000000000000000000000000000000000000000..73fa8390231fa1e4aa708b7d96fdc31c5246637b
--- /dev/null
+++ b/db/schema_migrations/20220310011530
@@ -0,0 +1 @@
+a4245a3543796b48f16786e9c178f70d236b3ae4636661f021ad4e8f0c678f2c
\ No newline at end of file
diff --git a/db/schema_migrations/20220310011613 b/db/schema_migrations/20220310011613
new file mode 100644
index 0000000000000000000000000000000000000000..fc62a04f551c8056545385aebb0cc811638b1041
--- /dev/null
+++ b/db/schema_migrations/20220310011613
@@ -0,0 +1 @@
+ef816d9391d67a34121d11e6b6cc37de92768bd21bc301fa10c6652b1a0b66b6
\ No newline at end of file
diff --git a/db/schema_migrations/20220310095341 b/db/schema_migrations/20220310095341
new file mode 100644
index 0000000000000000000000000000000000000000..d52763cce635b8126bf7f39bbc88fe03f516ab6b
--- /dev/null
+++ b/db/schema_migrations/20220310095341
@@ -0,0 +1 @@
+56d906eac31954988bd0659eabbc9f1bad1a47dd616fb99e4b90b56b2bf4c6a0
\ No newline at end of file
diff --git a/db/schema_migrations/20220310101118 b/db/schema_migrations/20220310101118
new file mode 100644
index 0000000000000000000000000000000000000000..c87f727c8b96ef8ea4a16d70fe7db82e52b3dfd2
--- /dev/null
+++ b/db/schema_migrations/20220310101118
@@ -0,0 +1 @@
+e4d6111f19f05b42b51e8d066e221205460514cef88ecf15ca99aa59788c4153
\ No newline at end of file
diff --git a/db/schema_migrations/20220310134207 b/db/schema_migrations/20220310134207
new file mode 100644
index 0000000000000000000000000000000000000000..3ba08608acce46c16e505121753206a5c4bf1cd3
--- /dev/null
+++ b/db/schema_migrations/20220310134207
@@ -0,0 +1 @@
+951abe39e4735f0f71ac6ad1701ffa8688dfd82a59b0383d6c55cef8f6de8e7f
\ No newline at end of file
diff --git a/db/schema_migrations/20220310141349 b/db/schema_migrations/20220310141349
new file mode 100644
index 0000000000000000000000000000000000000000..d52b2d997a4df34d57b99eac3d7e267d3525ea1d
--- /dev/null
+++ b/db/schema_migrations/20220310141349
@@ -0,0 +1 @@
+39785d4140c7345ddbe62417576381654ce22d505ee5c92a84425f0a3f8e4935
\ No newline at end of file
diff --git a/db/schema_migrations/20220311010352 b/db/schema_migrations/20220311010352
new file mode 100644
index 0000000000000000000000000000000000000000..f9f4cf28605d9d95ad9eefa9efb3a4ec8115af3e
--- /dev/null
+++ b/db/schema_migrations/20220311010352
@@ -0,0 +1 @@
+1d1682cb14041f14f691fcf880e6446ae464645a5ccbd36687620c3279f53e25
\ No newline at end of file
diff --git a/db/schema_migrations/20220314094841 b/db/schema_migrations/20220314094841
new file mode 100644
index 0000000000000000000000000000000000000000..f214ecaa9b32f2881f2a17ea16d05fcee9533274
--- /dev/null
+++ b/db/schema_migrations/20220314094841
@@ -0,0 +1 @@
+eabdb1e45a67947401963a971f24ae1b19068c72f5d4dd61d7fd47b8e61f1ed2
\ No newline at end of file
diff --git a/db/schema_migrations/20220314154235 b/db/schema_migrations/20220314154235
new file mode 100644
index 0000000000000000000000000000000000000000..911a5dc98540a3fcaac0f2a695be7e92301d4c64
--- /dev/null
+++ b/db/schema_migrations/20220314154235
@@ -0,0 +1 @@
+b3015220caeb1d21856de8c5026e2db052e98e4fb1c4b4f3a931b8481c2b8240
\ No newline at end of file
diff --git a/db/schema_migrations/20220314162342 b/db/schema_migrations/20220314162342
new file mode 100644
index 0000000000000000000000000000000000000000..8ee5a80c256f9eb702bfa62790917ec446c209c5
--- /dev/null
+++ b/db/schema_migrations/20220314162342
@@ -0,0 +1 @@
+7992448797888fd69d1e5cd4f2602e5a2b49a57052c50b19522f37d711c9f2f2
\ No newline at end of file
diff --git a/ee/lib/ee/gitlab/background_migration/fix_incorrect_max_seats_used.rb b/ee/lib/ee/gitlab/background_migration/fix_incorrect_max_seats_used.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d192ebdb3e9f89432d99efdcc7f71049eb2bccd7
--- /dev/null
+++ b/ee/lib/ee/gitlab/background_migration/fix_incorrect_max_seats_used.rb
@@ -0,0 +1,212 @@
+# frozen_string_literal: true
+
+module EE
+  module Gitlab
+    module BackgroundMigration
+      # Class that fixes the POSSIBLE incorrect `max_seats_used`
+      # in gitlab_subscriptions table
+      module FixIncorrectMaxSeatsUsed
+        class FixIncorrectMaxSeatsUsedJsonLogger < ::Gitlab::JsonLogger
+          def self.file_name_noext
+            'fix_incorrect_max_seats_used_json'
+          end
+        end
+
+        class Namespace < ActiveRecord::Base
+          self.table_name = 'namespaces'
+
+          # disable STI
+          self.inheritance_column = nil
+        end
+
+        class Plan < ActiveRecord::Base
+          self.table_name = 'plans'
+
+          FREE = 'free'
+          BRONZE = 'bronze'
+          SILVER = 'silver'
+          PREMIUM = 'premium'
+          GOLD = 'gold'
+          ULTIMATE = 'ultimate'
+          ULTIMATE_TRIAL = 'ultimate_trial'
+          PREMIUM_TRIAL = 'premium_trial'
+
+          PAID_HOSTED_PLANS = [BRONZE, SILVER, PREMIUM, GOLD, ULTIMATE, ULTIMATE_TRIAL, PREMIUM_TRIAL].freeze
+        end
+
+        class GitlabSubscription < ActiveRecord::Base
+          self.table_name = 'gitlab_subscriptions'
+
+          belongs_to :namespace
+          belongs_to :hosted_plan, class_name: 'Plan'
+          has_many :gitlab_subscription_histories
+
+          before_update :log_previous_state_for_update
+          before_update :reset_seats_for_new_term
+
+          delegate :name, :title, to: :hosted_plan, prefix: :plan, allow_nil: true
+
+          def calculate_seats_owed
+            return 0 unless has_a_paid_hosted_plan?
+
+            [0, max_seats_used - seats].max
+          end
+
+          def has_a_paid_hosted_plan?(include_trials: false)
+            (include_trials || !trial?) &&
+              seats > 0 &&
+              Plan::PAID_HOSTED_PLANS.include?(plan_name)
+          end
+
+          private
+
+          def log_previous_state_for_update
+            attrs = self.attributes.merge(self.attributes_in_database)
+            log_previous_state_to_history(:gitlab_subscription_updated, attrs)
+          end
+
+          def log_previous_state_to_history(change_type, attrs = {})
+            attrs['gitlab_subscription_created_at'] = attrs['created_at']
+            attrs['gitlab_subscription_updated_at'] = attrs['updated_at']
+            attrs['gitlab_subscription_id'] = self.id
+            attrs['change_type'] = change_type
+
+            omitted_attrs = %w(id created_at updated_at seats_in_use seats_owed max_seats_used_changed_at last_seat_refresh_at)
+
+            GitlabSubscriptionHistory.create(attrs.except(*omitted_attrs))
+          end
+
+          def reset_seats_for_new_term
+            return unless new_term?
+
+            self.max_seats_used = attributes['seats_in_use']
+            self.seats_owed = calculate_seats_owed
+          end
+
+          def new_term?
+            persisted? && start_date_changed? && end_date_changed? &&
+              (end_date_was.nil? || start_date >= end_date_was)
+          end
+        end
+
+        class GitlabSubscriptionHistory < ActiveRecord::Base
+          self.table_name = 'gitlab_subscription_histories'
+
+          belongs_to :gitlab_subscription
+        end
+
+        BATCH_SIZE = 200
+
+        def perform(batch = nil)
+          gitlab_subscriptions = if batch == 'batch_2_for_start_date_before_02_aug_2021'
+                                   eligible_gitlab_subscriptions_batch_2
+                                 else
+                                   eligible_gitlab_subscriptions
+                                 end
+
+          gitlab_subscriptions.find_each(batch_size: BATCH_SIZE) do |gs|
+            gs_histories = gs.gitlab_subscription_histories.to_a.sort_by { |gh| gh.id }
+            gs_histories << gs
+
+            last_new_term_index = find_last_new_term_index(gs_histories)
+            next unless last_new_term_index
+
+            reset(gs) if requires_reset(gs, gs_histories, last_new_term_index)
+          end
+        end
+
+        private
+
+        def file_logger
+          @file_logger ||= FixIncorrectMaxSeatsUsedJsonLogger.build
+        end
+
+        def reset(gs)
+          identified_subscription = gs.attributes.merge(namespace_path: gs.namespace.path)
+
+          gs.max_seats_used = gs.seats_in_use
+          gs.seats_owed = gs.calculate_seats_owed
+
+          changes = gs.changes
+          success = gs.save
+
+          file_logger.info({ identified_subscription: identified_subscription, changes: changes, success: success })
+        end
+
+        def new_term?(gs_histories, index)
+          new_start_date = gs_histories[index].start_date
+          previous_end_date = gs_histories[index - 1].end_date
+
+          return false if new_start_date.nil?
+
+          return true if previous_end_date.nil? || new_start_date >= previous_end_date
+
+          false
+        end
+
+        def find_last_new_term_index(gs_histories)
+          return if gs_histories.size < 2
+
+          # to find the latest new subscription term
+          index = gs_histories.size - 1
+          while index > 0
+            return index if new_term?(gs_histories, index)
+
+            index -= 1
+          end
+        end
+
+        def requires_reset(gs, gs_histories, last_new_term_index)
+          new_term_max_seats_used = gs_histories[last_new_term_index].max_seats_used
+          previous_max_seats_used = gs_histories[last_new_term_index - 1].max_seats_used
+
+          # New term `max_seats_used` started from `0`. No need to reset
+          return false if new_term_max_seats_used == 0
+
+          # New term and previous term value differ, we assume the value was already reset
+          return false if new_term_max_seats_used != previous_max_seats_used
+
+          # `max_seats_used` ever increased after the new term start. No need to reset
+          return false if new_term_max_seats_used < gs.max_seats_used
+
+          # Current gitlab_subscription `seats_in_use` is equal to or larger. No need to reset
+          return false if new_term_max_seats_used <= gs.seats_in_use
+
+          true
+        end
+
+        def eligible_gitlab_subscriptions
+          # Only search subscriptions with `start_date` in range `['2021-08-02', '2021-11-20']` because:
+          #   - for subscriptions with `start_date < '2021-08-02'`, we do not enable QSR(Quarterly Subscription Reconciliation)
+          #   - for subscriptions with `start_date > '2021-11-20'`, they should not have such issue
+          #     because the MR https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73078 was merged on `2021-11-09`.
+          #     All rails nodes should have deployed new merged code within 10 days.
+          #
+          # Only need to check if max_seats_used is not 0
+          # Only need to check if max_seats_used > seats_in_use
+          # Only need to check if max_seats_used > seats (zuora subscription quantity)
+
+          GitlabSubscription.preload(:namespace, :hosted_plan, :gitlab_subscription_histories)
+            .where('gitlab_subscriptions.start_date >= ?', Date.parse('2021-08-02'))
+            .where('gitlab_subscriptions.start_date <= ?', Date.parse('2021-11-20'))
+            .where.not(max_seats_used: 0)
+            .where('gitlab_subscriptions.max_seats_used > gitlab_subscriptions.seats_in_use')
+            .where('gitlab_subscriptions.max_seats_used > gitlab_subscriptions.seats')
+        end
+
+        def eligible_gitlab_subscriptions_batch_2
+          # Only search subscriptions with `start_date < '2021-08-02'`
+          # Only need to check if max_seats_used is not 0
+          # Only need to check if max_seats_used > seats_in_use
+          # Only need to check if max_seats_used > seats (zuora subscription quantity)
+
+          GitlabSubscription.preload(:namespace, :hosted_plan, :gitlab_subscription_histories)
+            .where('gitlab_subscriptions.start_date < ?', Date.parse('2021-08-02'))
+            .where.not(max_seats_used: 0)
+            .where('gitlab_subscriptions.max_seats_used > gitlab_subscriptions.seats_in_use')
+            .where('gitlab_subscriptions.max_seats_used > gitlab_subscriptions.seats')
+        end
+      end
+    end
+  end
+end
diff --git a/ee/lib/ee/gitlab/background_migration/populate_namespace_statistics.rb b/ee/lib/ee/gitlab/background_migration/populate_namespace_statistics.rb
new file mode 100644
index 0000000000000000000000000000000000000000..09419014a71371b1f8615d097ad6ccf2fa28df9e
--- /dev/null
+++ b/ee/lib/ee/gitlab/background_migration/populate_namespace_statistics.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module EE
+  module Gitlab
+    module BackgroundMigration
+      module PopulateNamespaceStatistics
+        extend ::Gitlab::Utils::Override
+
+        private
+
+        override :relation
+        def relation(group_ids)
+          ::Group.includes(:route, :namespace_statistics, group_wiki_repository: :shard).where(id: group_ids)
+        end
+      end
+    end
+  end
+end
diff --git a/ee/lib/ee/gitlab/background_migration/populate_test_reports_issue_id.rb b/ee/lib/ee/gitlab/background_migration/populate_test_reports_issue_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4819974a1d9a59e0d6b23a6cfc1d183c144252c4
--- /dev/null
+++ b/ee/lib/ee/gitlab/background_migration/populate_test_reports_issue_id.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module EE
+  module Gitlab
+    module BackgroundMigration
+      # Backfills RequirementsManagement::TestReport issue_id column
+      # Part of the plan to migrate requirements to work items(issues)
+      # More information at: https://gitlab.com/groups/gitlab-org/-/epics/7148
+      module PopulateTestReportsIssueId
+        def perform(start_id, end_id)
+          sql = <<~SQL
+            UPDATE requirements_management_test_reports AS test_reports
+            SET issue_id = requirements.issue_id
+            FROM requirements
+            WHERE test_reports.requirement_id = requirements.id
+            AND test_reports.issue_id IS NULL
+            AND test_reports.id BETWEEN #{start_id} AND #{end_id}
+          SQL
+
+          ActiveRecord::Base.connection.execute(sql)
+
+          mark_job_as_succeeded(start_id, end_id)
+        end
+
+        private
+
+        def mark_job_as_succeeded(*arguments)
+          ::Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
+            self.class.name.demodulize,
+            arguments
+          )
+        end
+      end
+    end
+  end
+end
diff --git a/ee/lib/ee/gitlab/background_migration/recalculate_vulnerability_finding_signatures_for_findings.rb b/ee/lib/ee/gitlab/background_migration/recalculate_vulnerability_finding_signatures_for_findings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..26472c5cc8ffed272ede6565f32e2cbf95d6e95e
--- /dev/null
+++ b/ee/lib/ee/gitlab/background_migration/recalculate_vulnerability_finding_signatures_for_findings.rb
@@ -0,0 +1,87 @@
+# frozen_string_literal: true
+
+module EE
+  module Gitlab
+    module BackgroundMigration
+      # This migration removes all vulnerability_finding_signatures per project finding and re-inserts
+      # the matching signature as provided by `vulnerability_finding.raw_metadata`
+      module RecalculateVulnerabilityFindingSignaturesForFindings
+        extend ::Gitlab::Utils::Override
+
+        ALGORITHM_TYPES = { hash: 1, location: 2, scope_offset: 3 }.with_indifferent_access.freeze
+        SAST_REPORT_TYPE = 0
+        BATCH_SIZE = 1000
+
+        class Vulnerabilities::Finding < ApplicationRecord
+          self.table_name = 'vulnerability_occurrences'
+        end
+
+        class Vulnerabilities::FindingSignature < ApplicationRecord
+          include ::EachBatch
+
+          self.table_name = 'vulnerability_finding_signatures'
+
+          belongs_to :finding, foreign_key: 'finding_id', class_name: 'Vulnerabilities::Finding'
+        end
+
+        override :perform
+        def perform(start_id, stop_id)
+          Vulnerabilities::FindingSignature.joins(:finding).where(id: start_id..stop_id).each_batch(of: BATCH_SIZE) do |signatures|
+            now = Time.now
+            rows = signatures.map(&:finding).map { |occurrence| build_row(occurrence, now) }.compact
+
+            signatures.delete_all
+
+            ApplicationRecord.legacy_bulk_insert(:vulnerability_finding_signatures, rows) # rubocop:disable Gitlab/BulkInsert
+
+            mark_job_as_succeeded(start_id, stop_id)
+          end
+        rescue StandardError => e
+          logger.error(
+            message: "repopulate_vulnerability_finding_signatures failed for range #{start_id} to #{stop_id}",
+            error: e.message
+          )
+        end
+
+        private
+
+        def build_row(finding, now)
+          json = ::Gitlab::Json.parse(finding.raw_metadata)
+          signature = json.dig('tracking', 'items').first&.dig('signatures')&.first
+          bytea = ActiveRecord::Base.connection.escape_bytea(
+            Digest::SHA1.digest(signature.fetch('value'))
+          )
+
+          {
+            finding_id: finding.id,
+            algorithm_type: ALGORITHM_TYPES[signature.fetch('algorithm')],
+            signature_sha: bytea,
+            created_at: now,
+            updated_at: now
+          }
+        rescue JSON::ParserError => e
+          # JSON extraction failed, return nil and skip insert of row
+          logger.error(
+            message: "repopulate_vulnerability_finding_signatures malformed json for #{finding.id}",
+            error: e.message
+          )
+          nil
+        rescue StandardError
+          # JSON extraction failed, return nil and skip insert of row
+          nil
+        end
+
+        def mark_job_as_succeeded(*arguments)
+          ::Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
+            self.class.name.demodulize,
+            arguments
+          )
+        end
+
+        def logger
+          @logger ||= ::Gitlab::BackgroundMigration::Logger.build
+        end
+      end
+    end
+  end
+end
diff --git a/ee/spec/lib/ee/gitlab/background_migration/fix_incorrect_max_seats_used_spec.rb b/ee/spec/lib/ee/gitlab/background_migration/fix_incorrect_max_seats_used_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..73df9fb34d88662caaaf883ef139a9848186580d
--- /dev/null
+++ b/ee/spec/lib/ee/gitlab/background_migration/fix_incorrect_max_seats_used_spec.rb
@@ -0,0 +1,269 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::FixIncorrectMaxSeatsUsed, :saas do
+  describe '#perform' do
+    subject(:migration) { described_class.new }
+
+    let!(:namespaces) { table(:namespaces) }
+    let!(:plans) { table(:plans) }
+
+    let(:seats) { 2 }
+    let(:seats_in_use) { 5 }
+    let(:max_seats_used) { 10 }
+    let(:seats_owed) { [0, max_seats_used - seats].max }
+
+    let(:start_date) { Date.parse('2021-11-10') }
+    let(:end_date) { start_date + 1.year }
+
+    let(:keep_old_seats_attributes_after_renew) { true }
+
+    let(:logger) { instance_spy(Gitlab::BackgroundMigration::FixIncorrectMaxSeatsUsed::FixIncorrectMaxSeatsUsedJsonLogger) }
+
+    let!(:gitlab_subscription) { generate_gitlab_subscription }
+
+    def perform_and_reload
+      migration.perform
+
+      gitlab_subscription.reload
+    end
+
+    def generate_gitlab_subscription
+      initial_start_date = start_date - renewed_count.years
+      initial_end_date = initial_start_date + 1.year
+
+      namespace = namespaces.create!(name: 'gitlab', path: 'gitlab-org', type: 'Group')
+      plan = plans.create!(name: 'gold')
+      gs = Gitlab::BackgroundMigration::FixIncorrectMaxSeatsUsed::GitlabSubscription.create!(
+        namespace_id: namespace.id,
+        seats: seats,
+        seats_in_use: seats_in_use,
+        max_seats_used: max_seats_used,
+        seats_owed: seats_owed,
+        start_date: initial_start_date,
+        end_date: initial_end_date,
+        hosted_plan_id: plan.id)
+
+      renewed_count.downto(1) do |i|
+        old_seats_attributes = { seats: gs.seats, max_seats_used: gs.max_seats_used, seats_owed: gs.seats_owed, seats_in_use: gs.seats_in_use }
+
+        renewed_start_date = gs.end_date
+        renewed_end_date = renewed_start_date + 1.year
+
+        gs.update!(start_date: renewed_start_date, end_date: renewed_end_date)
+        gs.update_columns(old_seats_attributes) if keep_old_seats_attributes_after_renew
+      end
+
+      gs.reload
+    end
+
+    shared_examples 'does not reset max_seats_used and seats_owed' do
+      it 'does not reset max_seats_used and seats_owed', migration: false do
+        expect do
+          perform_and_reload
+        end.to not_change(gitlab_subscription, :max_seats_used)
+          .and not_change(gitlab_subscription, :seats_owed)
+          .and not_change(GitlabSubscriptionHistory, :count)
+      end
+    end
+
+    shared_examples 'resets max_seats_used and seats_owed' do
+      it 'resets max_seats_used and seats_owed', migration: false do
+        gs_before_reset = gitlab_subscription.clone
+
+        expect(Gitlab::BackgroundMigration::FixIncorrectMaxSeatsUsed::FixIncorrectMaxSeatsUsedJsonLogger).to receive(:build).and_return(logger)
+
+        expect do
+          perform_and_reload
+        end.to change(gitlab_subscription, :max_seats_used).from(10).to(5)
+          .and change(gitlab_subscription, :seats_owed).from(8).to(3)
+          .and change(GitlabSubscriptionHistory, :count).by(1)
+
+        expect(logger).to have_received(:info).with(
+          hash_including(
+            identified_subscription: gs_before_reset.attributes.merge(namespace_path: gs_before_reset.namespace.path),
+            changes: hash_including(max_seats_used: [10, 5], seats_owed: [8, 3]),
+            success: true))
+      end
+    end
+
+    shared_examples 'gitlab subscription has one or more renew history' do
+      include_examples 'resets max_seats_used and seats_owed'
+
+      context 'when max_seats_used has already been correctly reset during renew' do
+        let(:keep_old_seats_attributes_after_renew) { false }
+
+        include_examples 'does not reset max_seats_used and seats_owed'
+      end
+
+      context 'when start_date is before 2021-08-02' do
+        let(:start_date) { Date.parse('2021-08-01') }
+
+        include_examples 'does not reset max_seats_used and seats_owed'
+      end
+
+      context 'when start_date is 2021-08-02' do
+        let(:start_date) { Date.parse('2021-08-02') }
+
+        include_examples 'resets max_seats_used and seats_owed'
+      end
+
+      context 'when start_date is 2021-11-20' do
+        let(:start_date) { Date.parse('2021-11-20') }
+
+        include_examples 'resets max_seats_used and seats_owed'
+      end
+
+      context 'when start_date is after 2021-11-20' do
+        let(:start_date) { Date.parse('2021-11-21') }
+
+        include_examples 'does not reset max_seats_used and seats_owed'
+      end
+
+      context 'when batch_2_for_start_date_before_02_aug_2021' do
+        def perform_and_reload
+          migration.perform(batch)
+
+          gitlab_subscription.reload
+        end
+
+        let(:batch) { 'batch_2_for_start_date_before_02_aug_2021' }
+
+        context 'when start_date is before 2021-08-02' do
+          let(:start_date) { Date.parse('2021-08-01') }
+
+          include_examples 'resets max_seats_used and seats_owed'
+        end
+
+        context 'when start_date is 2021-08-02' do
+          let(:start_date) { Date.parse('2021-08-02') }
+
+          include_examples 'does not reset max_seats_used and seats_owed'
+        end
+
+        context 'when start_date is after 2021-08-02' do
+          let(:start_date) { Date.parse('2021-08-03') }
+
+          include_examples 'does not reset max_seats_used and seats_owed'
+        end
+      end
+
+      context 'when max_seats_used is 0' do
+        let(:max_seats_used) { 0 }
+
+        include_examples 'does not reset max_seats_used and seats_owed'
+      end
+
+      context 'when max_seats_used equals to seats_in_use' do
+        let(:max_seats_used) { seats_in_use }
+
+        include_examples 'does not reset max_seats_used and seats_owed'
+      end
+
+      context 'when max_seats_used is less than seats_in_use' do
+        let(:max_seats_used) { seats_in_use - 1 }
+
+        include_examples 'does not reset max_seats_used and seats_owed'
+      end
+
+      context 'when max_seats_used equals to seats' do
+        let(:max_seats_used) { seats }
+
+        include_examples 'does not reset max_seats_used and seats_owed'
+      end
+
+      context 'when max_seats_used is less than seats' do
+        let(:max_seats_used) { seats - 1 }
+
+        include_examples 'does not reset max_seats_used and seats_owed'
+      end
+
+      context 'when max_seats_used increases after renew' do
+        before do
+          gitlab_subscription.update_columns(max_seats_used: max_seats_used + 1)
+        end
+
+        include_examples 'does not reset max_seats_used and seats_owed'
+      end
+
+      context 'when seats_in_use increased to max_seats_used' do
+        before do
+          gitlab_subscription.update_columns(seats_in_use: max_seats_used)
+        end
+
+        include_examples 'does not reset max_seats_used and seats_owed'
+      end
+
+      context 'when seats_in_use increased to greater than max_seats_used' do
+        before do
+          gitlab_subscription.update_columns(seats_in_use: max_seats_used + 1)
+        end
+
+        include_examples 'does not reset max_seats_used and seats_owed'
+      end
+    end
+
+    context 'when gitlab subscription does not have renew history' do
+      let(:renewed_count) { 0 }
+
+      include_examples 'does not reset max_seats_used and seats_owed'
+    end
+
+    context 'when gitlab subscription has one renew history' do
+      let(:renewed_count) { 1 }
+
+      it_behaves_like 'gitlab subscription has one or more renew history'
+    end
+
+    context 'gitlab subscription has more than one renew histories' do
+      let(:renewed_count) { 2 }
+
+      it_behaves_like 'gitlab subscription has one or more renew history'
+    end
+
+    context 'when gitlab subscription has non-renewal update history' do
+      before do
+        gitlab_subscription.update!(auto_renew: !gitlab_subscription.auto_renew)
+        gitlab_subscription.reload
+      end
+
+      context 'when gitlab subscription does not have renew history' do
+        let(:renewed_count) { 0 }
+
+        include_examples 'does not reset max_seats_used and seats_owed'
+      end
+
+      context 'when gitlab subscription has one renew history' do
+        let(:renewed_count) { 1 }
+
+        it_behaves_like 'gitlab subscription has one or more renew history'
+      end
+
+      context 'gitlab subscription has more than one renew histories' do
+        let(:renewed_count) { 2 }
+
+        it_behaves_like 'gitlab subscription has one or more renew history'
+      end
+    end
+  end
+end
+
+RSpec.describe Gitlab::BackgroundMigration::FixIncorrectMaxSeatsUsed::FixIncorrectMaxSeatsUsedJsonLogger do
+  subject { described_class.new('/dev/null') }
+
+  let(:hash_message) { { 'message' => 'Message', 'project_id' => '123' } }
+  let(:string_message) { 'Information' }
+
+  it 'logs a hash as a JSON', migration: false do
+    expect(Gitlab::Json.parse(subject.format_message('INFO', Time.current, nil, hash_message))).to include(hash_message)
+  end
+
+  it 'logs a string as a JSON', migration: false do
+    expect(Gitlab::Json.parse(subject.format_message('INFO', Time.current, nil, string_message))).to include('message' => string_message)
+  end
+
+  it 'logs into the expected file', migration: false do
+    expect(described_class.file_name).to eq('fix_incorrect_max_seats_used_json.log')
+  end
+end
diff --git a/ee/spec/lib/ee/gitlab/background_migration/populate_namespace_statistics_spec.rb b/ee/spec/lib/ee/gitlab/background_migration/populate_namespace_statistics_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9bf4d97b0afe4aebdc2c8c6ff46ea14eae275807
--- /dev/null
+++ b/ee/spec/lib/ee/gitlab/background_migration/populate_namespace_statistics_spec.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::PopulateNamespaceStatistics do
+  include AfterNextHelpers
+
+  let!(:namespaces) { table(:namespaces) }
+  let!(:namespace_statistics) { table(:namespace_statistics) }
+
+  let!(:group1) { namespaces.create!(id: 10, type: 'Group', name: 'group1', path: 'group1') }
+  let!(:group2) { namespaces.create!(id: 20, type: 'Group', name: 'group2', path: 'group2') }
+  let!(:group1_stats) { namespace_statistics.create!(id: 10, namespace_id: 10) }
+
+  let(:repo_size) { 123456 }
+  let(:expected_repo_size) { repo_size.megabytes }
+  let(:ids) { namespaces.pluck(:id) }
+  let(:statistics) { [] }
+
+  subject(:perform) { described_class.new.perform(ids, statistics) }
+
+  before do
+    allow_next(Repository).to receive(:size).and_return(repo_size)
+  end
+
+  context 'when group wikis are not enabled' do
+    it 'does not update wiki stats' do
+      perform
+
+      expect(namespace_statistics.where(wiki_size: 0).count).to eq 2
+    end
+  end
+
+  it 'creates/updates all namespace_statistics and update root storage statistics', :aggregate_failures do
+    stub_licensed_features(group_wikis: true)
+
+    expect(namespace_statistics.count).to eq 1
+
+    expect(Namespaces::ScheduleAggregationWorker).to receive(:perform_async).with(group1.id)
+    expect(Namespaces::ScheduleAggregationWorker).to receive(:perform_async).with(group2.id)
+
+    perform
+
+    expect(namespace_statistics.count).to eq 2
+
+    namespace_statistics.all.each do |stat|
+      expect(stat.wiki_size).to eq expected_repo_size
+      expect(stat.storage_size).to eq expected_repo_size
+    end
+  end
+
+  context 'when just a stat is passed' do
+    let(:statistics) { [:wiki_size] }
+
+    it 'calls the statistics update service with just that stat' do
+      expect(Groups::UpdateStatisticsService).to receive(:new).with(anything, statistics: [:wiki_size]).twice.and_call_original
+
+      perform
+    end
+  end
+end
diff --git a/ee/spec/lib/ee/gitlab/background_migration/recalculate_vulnerability_finding_signatures_for_findings_spec.rb b/ee/spec/lib/ee/gitlab/background_migration/recalculate_vulnerability_finding_signatures_for_findings_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7d21e2c3b616c13a94862419094589f9eb6cc060
--- /dev/null
+++ b/ee/spec/lib/ee/gitlab/background_migration/recalculate_vulnerability_finding_signatures_for_findings_spec.rb
@@ -0,0 +1,180 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::RecalculateVulnerabilityFindingSignaturesForFindings, :migration, schema: 20220326161803 do
+  let(:namespaces) { table(:namespaces) }
+  let(:group) { namespaces.create!(name: 'foo', path: 'foo') }
+  let(:projects) { table(:projects) }
+  let(:findings) { table(:vulnerability_occurrences) }
+  let(:finding_signatures) { table(:vulnerability_finding_signatures) }
+  let(:scanners) { table(:vulnerability_scanners) }
+  let(:identifiers) { table(:vulnerability_identifiers) }
+
+  let!(:project) { projects.create!(namespace_id: group.id, name: 'gitlab', path: 'gitlab') }
+
+  let!(:scanner) do
+    scanners.create!(project_id: project.id, external_id: 'semgrep', name: 'Semgrep')
+  end
+
+  let!(:identifier) do
+    identifiers.create!(project_id: project.id, fingerprint: SecureRandom.hex(20), external_type: 'semgrep_rule_id', external_id: '42', name: '42')
+  end
+
+  let(:raw_tracking_value) do
+    raw_tracking.dig(:tracking, :items).first.fetch(:signatures).first.fetch(:value)
+  end
+
+  it 'updates finding signatures' do
+    finding1 = findings.create!(finding_params)
+    signature1 = finding_signatures.create!(
+      finding_id: finding1.id,
+      algorithm_type: 'scope_offset',
+      signature_sha: Digest::SHA1.digest(raw_tracking_value)
+    )
+
+    finding2 = findings.create!(finding_params)
+    # Generate signature with SHA not matching `raw_metadata`
+    signature2 = finding_signatures.create!(
+      finding_id: finding2.id,
+      algorithm_type: 'scope_offset',
+      signature_sha: Digest::SHA1.digest("foo/bar.rb|Something[0]|else[0]:1")
+    )
+
+    service = described_class.new
+    logger = ::Gitlab::BackgroundMigration::Logger.build
+    service.instance_variable_set(:@logger, logger)
+
+    expect(logger).not_to receive(:error)
+    expect do
+      service.perform(signature1.id, signature2.id)
+    end.to change { finding_signatures.count }.by(0)
+
+    expect(
+      finding_signatures.find_by(finding_id: finding1.id).signature_sha
+    ).to eq Digest::SHA1.digest(raw_tracking_value)
+
+    expect(
+      finding_signatures.find_by(finding_id: finding2.id).signature_sha
+    ).to eq Digest::SHA1.digest(raw_tracking_value)
+  end
+
+  it 'logs error on unexpected failure' do
+    finding = findings.create!(
+      finding_params({}) # empty tracking info
+    )
+    signature = finding_signatures.create!(
+      finding_id: finding.id,
+      algorithm_type: 'scope_offset',
+      signature_sha: Digest::SHA1.digest(raw_tracking_value)
+    )
+
+    service = described_class.new
+
+    allow(ApplicationRecord)
+      .to receive(:legacy_bulk_insert)
+      .and_raise(ActiveRecord::RecordInvalid)
+
+    expect_next_instance_of(::Gitlab::BackgroundMigration::Logger) do |logger|
+      expect(logger).to receive(:error).once
+    end
+    expect do
+      service.perform(signature.id, signature.id)
+    end.to change { finding_signatures.count }.by(-1)
+  end
+
+  it 'logs error on malformed JSON failure' do
+    params = finding_params({})
+    params[:raw_metadata] = '{' # malformed JSON
+
+    finding = findings.create!(params)
+    signature = finding_signatures.create!(
+      finding_id: finding.id,
+      algorithm_type: 'scope_offset',
+      signature_sha: Digest::SHA1.digest(raw_tracking_value)
+    )
+
+    service = described_class.new
+
+    expect_next_instance_of(::Gitlab::BackgroundMigration::Logger) do |logger|
+      expect(logger).to receive(:error).once
+    end
+    expect do
+      service.perform(signature.id, signature.id)
+    end.to change { finding_signatures.count }.by(-1)
+  end
+
+  it 'drops invalid row when metadata is missing tracking' do
+    finding = findings.create!(
+      finding_params({}) # empty tracking info
+    )
+    signature = finding_signatures.create!(
+      finding_id: finding.id,
+      algorithm_type: 'scope_offset',
+      signature_sha: Digest::SHA1.digest(raw_tracking_value)
+    )
+
+    service = described_class.new
+
+    expect_next_instance_of(::Gitlab::BackgroundMigration::Logger).never
+    expect do
+      service.perform(signature.id, signature.id)
+    end.to change { finding_signatures.count }.by(-1)
+  end
+
+  it 'drops invalid row when tracking signatures data is malformed' do
+    finding = findings.create!(
+      finding_params({ "tracking": { "itemssss": [] } }) # malformed tracking info
+    )
+    signature = finding_signatures.create!(
+      finding_id: finding.id,
+      algorithm_type: 'scope_offset',
+      signature_sha: Digest::SHA1.digest(raw_tracking_value)
+    )
+
+    service = described_class.new
+
+    expect_next_instance_of(::Gitlab::BackgroundMigration::Logger).never
+    expect do
+      service.perform(signature.id, signature.id)
+    end.to change { finding_signatures.count }.by(-1)
+  end
+
+  def finding_params(tracking_details = raw_tracking)
+    uuid = SecureRandom.uuid
+
+    {
+      severity: Enums::Vulnerability::SEVERITY_LEVELS[:medium],
+      confidence: Enums::Vulnerability::CONFIDENCE_LEVELS[:medium],
+      report_type: Enums::Vulnerability::REPORT_TYPES[:sast],
+      project_id: project.id,
+      scanner_id: scanner.id,
+      primary_identifier_id: identifier.id,
+      project_fingerprint: SecureRandom.hex(20),
+      location_fingerprint: Digest::SHA1.hexdigest(SecureRandom.hex(10)),
+      uuid: uuid,
+      name: "Vulnerability Finding #{uuid}",
+      metadata_version: '14.0.0',
+      raw_metadata: Gitlab::Json.dump(raw_metadata.merge(tracking_details))
+    }
+  end
+
+  def raw_metadata
+    {
+      "id": "756a4302f62d4b44d8d64e1a925d7a076fcc80918b7319e62bb28d4d4baa2bc8",
+      "category": "sast",
+      "name": "Possible unprotected redirect",
+      "message": "Possible unprotected redirect",
+      "cve": "373414e0effe673bb93d1d8994f3e511ff089ce79337a16577e087556e9ae3cd",
+      "severity": "Low",
+      "confidence": "Low",
+      "scanner": { "id": "brakeman", "name": "Brakeman" },
+      "location": { "file": "app/controllers/groups_controller.rb", "start_line": 6, "class": "GroupsController", "method": "new_group" },
+      "identifiers": [{ "type": "brakeman_warning_code", "name": "Brakeman Warning Code 18", "value": "18", "url": "https://brakemanscanner.org/docs/warning_types/redirect/" }]
+    }
+  end
+
+  def raw_tracking(file = "app/controllers/groups_controller.rb")
+    { "tracking": { "type": "source", "items": [{ "file": file, "line_start": 6, "line_end": 6, "signatures": [{ "algorithm": "scope_offset", "value": "#{file}|GroupsController[0]|new_group[0]:4" }] }] } }
+  end
+end
diff --git a/ee/spec/lib/gitlab/background_migration/populate_test_reports_issue_id_spec.rb b/ee/spec/lib/gitlab/background_migration/populate_test_reports_issue_id_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..628f889f1a5e1571a4238160673a46cc05d185af
--- /dev/null
+++ b/ee/spec/lib/gitlab/background_migration/populate_test_reports_issue_id_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::PopulateTestReportsIssueId, schema: 20211220174504 do
+  let(:issues) { table(:issues) }
+  let(:requirements) { table(:requirements) }
+  let(:namespaces) { table(:namespaces) }
+  let(:users) { table(:users) }
+  let(:projects) { table(:projects) }
+  let(:test_reports) { table(:requirements_management_test_reports) }
+
+  let!(:group) { namespaces.create!(name: 'gitlab', path: 'gitlab-org') }
+  let!(:project) { projects.create!(namespace_id: group.id, name: 'gitlab', path: 'gitlab') }
+
+  let!(:user) { users.create!(email: 'author@example.com', notification_email: 'author@example.com', name: 'author', username: 'author', projects_limit: 10, state: 'active') }
+
+  let!(:issue_1) { issues.create!(iid: 10, state_id: 1, project_id: project.id) }
+  let!(:issue_2) { issues.create!(iid: 11, state_id: 2, project_id: project.id) }
+
+  let!(:requirement_1) { requirements.create!(iid: 10, project_id: project.id, author_id: user.id, issue_id: issue_1.id, title: 'r 1', state: 1, created_at: 2.days.ago, updated_at: 1.day.ago) }
+  let!(:requirement_2) { requirements.create!(iid: 11, project_id: project.id, author_id: user.id, issue_id: issue_2.id, title: 'r 1', state: 1, created_at: 2.days.ago, updated_at: 1.day.ago) }
+
+  let!(:test_report_1) { test_reports.create!(requirement_id: requirement_1.id, state: 1) }
+  let!(:test_report_2) { test_reports.create!(requirement_id: requirement_2.id, state: 1, issue_id: issue_1.id) }
+  let!(:test_report_3) { test_reports.create!(requirement_id: requirement_2.id, state: 2) }
+  let!(:test_report_4) { test_reports.create!(requirement_id: requirement_1.id, state: 2) }
+
+  let(:migration) { described_class::MIGRATION }
+
+  it 'links test reports to requirement issues' do
+    expect do
+      described_class.new.perform(test_report_1.id, test_report_3.id)
+    end
+      .to change { test_report_1.reload.issue_id }.from(nil).to(requirement_1.issue_id)
+      .and not_change { test_report_2.reload.issue_id }
+      .and change { test_report_3.reload.issue_id }.from(nil).to(requirement_2.issue_id)
+      .and not_change { test_report_4.reload.issue_id }
+  end
+end
diff --git a/ee/spec/lib/gitlab/background_migration/remove_all_trace_expiration_dates_spec.rb b/ee/spec/lib/gitlab/background_migration/remove_all_trace_expiration_dates_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..52efc1d46ce3aeb0ffbe9c98a53ef6a4c87a5831
--- /dev/null
+++ b/ee/spec/lib/gitlab/background_migration/remove_all_trace_expiration_dates_spec.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::RemoveAllTraceExpirationDates, :migration,
+               :suppress_gitlab_schemas_validate_connection, schema: 20220131000001 do
+  subject(:perform) { migration.perform(1, 99) }
+
+  let(:migration) { described_class.new }
+
+  let(:trace_in_range)         { create_trace!(id: 10,   created_at: Date.new(2020, 06, 20), expire_at: Date.new(2022, 01, 22)) }
+  let(:trace_outside_range)    { create_trace!(id: 40,   created_at: Date.new(2020, 06, 22), expire_at: Date.new(2021, 01, 22)) }
+  let(:trace_without_expiry)   { create_trace!(id: 30,   created_at: Date.new(2020, 06, 21), expire_at: nil) }
+  let(:archive_in_range)       { create_archive!(id: 10, created_at: Date.new(2020, 06, 20), expire_at: Date.new(2021, 01, 22)) }
+  let(:trace_outside_id_range) { create_trace!(id: 100,  created_at: Date.new(2020, 06, 20), expire_at: Date.new(2021, 02, 22)) }
+
+  before do
+    table(:namespaces).create!(id: 1, name: 'the-namespace', path: 'the-path')
+    table(:projects).create!(id: 1, name: 'the-project', namespace_id: 1)
+    table(:ci_builds).create!(id: 1, allow_failure: false)
+  end
+
+  context 'on gitlab.com', :saas do
+    it 'sets expire_at for artifacts in range to nil' do
+      expect { perform }.to change { trace_in_range.reload.expire_at }.from(trace_in_range.expire_at).to(nil)
+    end
+
+    it 'does not change expire_at timestamps that are not set to midnight' do
+      expect { perform }.not_to change { trace_outside_range.reload.expire_at }
+    end
+
+    it 'does not change expire_at timestamps that are set to midnight on a day other than the 22nd' do
+      expect { perform }.not_to change { trace_without_expiry.reload.expire_at }
+    end
+
+    it 'does not touch artifacts outside id range' do
+      expect { perform }.not_to change { archive_in_range.reload.expire_at }
+    end
+
+    it 'does not touch artifacts outside date range' do
+      expect { perform }.not_to change { trace_outside_id_range.reload.expire_at }
+    end
+  end
+
+  private
+
+  def create_trace!(**args)
+    table(:ci_job_artifacts).create!(**args, project_id: 1, job_id: 1, file_type: 3)
+  end
+
+  def create_archive!(**args)
+    table(:ci_job_artifacts).create!(**args, project_id: 1, job_id: 1, file_type: 1)
+  end
+end
diff --git a/ee/spec/migrations/async_build_trace_expire_at_index_spec.rb b/ee/spec/migrations/async_build_trace_expire_at_index_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..87071c80fc266b52cde510f52f402cab09f04a4a
--- /dev/null
+++ b/ee/spec/migrations/async_build_trace_expire_at_index_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe AsyncBuildTraceExpireAtIndex, feature_category: :continuous_integration do
+  describe '#up' do
+    it 'sets up a delayed concurrent index creation' do
+      expect_next_instance_of(described_class) do |instance|
+        expect(instance).to receive(:prepare_async_index)
+      end
+
+      migrate!
+    end
+  end
+
+  describe '#down' do
+    it 'removes an index' do
+      expect_any_instance_of(described_class) do |instance|
+        expect(instance).to receive(:unprepare_async_index)
+      end
+
+      schema_migrate_down!
+    end
+  end
+end
diff --git a/ee/spec/migrations/schedule_delete_invalid_epic_issues_revised_spec.rb b/ee/spec/migrations/schedule_delete_invalid_epic_issues_revised_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ab871de22924f82b667ef16827c630f40aa9b569
--- /dev/null
+++ b/ee/spec/migrations/schedule_delete_invalid_epic_issues_revised_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe ScheduleDeleteInvalidEpicIssuesRevised, feature_category: :portfolio_management do
+  let(:migration) { described_class::MIGRATION }
+
+  describe '#up' do
+    it 'schedules background jobs for each batch of epics' do
+      migrate!
+
+      expect(migration).to have_scheduled_batched_migration(
+        table_name: :epics,
+        column_name: :id,
+        interval: described_class::INTERVAL,
+        batch_size: described_class::BATCH_SIZE
+      )
+    end
+  end
+
+  describe '#down' do
+    it 'deletes all batched migration records' do
+      migrate!
+      schema_migrate_down!
+
+      expect(migration).not_to have_scheduled_batched_migration
+    end
+  end
+end
diff --git a/ee/spec/migrations/schedule_populate_test_reports_issue_id_spec.rb b/ee/spec/migrations/schedule_populate_test_reports_issue_id_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..fe2bd9ca427e148e054b05a85e64677299c41a62
--- /dev/null
+++ b/ee/spec/migrations/schedule_populate_test_reports_issue_id_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SchedulePopulateTestReportsIssueId, feature_category: :requirements_management do
+  let(:issues) { table(:issues) }
+  let(:requirements) { table(:requirements) }
+  let(:namespaces) { table(:namespaces) }
+  let(:users) { table(:users) }
+  let(:projects) { table(:projects) }
+  let(:test_reports) { table(:requirements_management_test_reports) }
+
+  let!(:group) { namespaces.create!(name: 'gitlab', path: 'gitlab-org') }
+  let!(:project) { projects.create!(namespace_id: group.id, name: 'gitlab', path: 'gitlab') }
+
+  let!(:user) { users.create!(email: 'author@example.com', notification_email: 'author@example.com', name: 'author', username: 'author', projects_limit: 10, state: 'active') }
+
+  let!(:issue_1) { issues.create!(iid: 10, state_id: 1, project_id: project.id) }
+  let!(:issue_2) { issues.create!(iid: 11, state_id: 2, project_id: project.id) }
+
+  let!(:requirement_1) { requirements.create!(iid: 10, project_id: project.id, author_id: user.id, issue_id: issue_1.id, title: 'r 1', state: 1, created_at: 2.days.ago, updated_at: 1.day.ago) }
+  let!(:requirement_2) { requirements.create!(iid: 11, project_id: project.id, author_id: user.id, issue_id: issue_2.id, title: 'r 1', state: 1, created_at: 2.days.ago, updated_at: 1.day.ago) }
+
+  let!(:test_report_1) { test_reports.create!(requirement_id: requirement_1.id, state: 1) }
+  let!(:test_report_2) { test_reports.create!(requirement_id: requirement_2.id, state: 1, issue_id: issue_1.id) }
+  let!(:test_report_3) { test_reports.create!(requirement_id: requirement_2.id, state: 2) }
+  let!(:test_report_4) { test_reports.create!(requirement_id: requirement_1.id, state: 2) }
+  let!(:test_report_5) { test_reports.create!(requirement_id: requirement_1.id, state: 1) }
+
+  let(:migration) { described_class::MIGRATION }
+
+  before do
+    Sidekiq::Worker.clear_all
+    stub_const("#{described_class.name}::BATCH_SIZE", 2)
+  end
+
+  it 'schedules jobs correctly for test reports with null issue_id' do
+    Sidekiq::Testing.fake! do
+      freeze_time do
+        migrate!
+
+        expect(migration).to be_scheduled_delayed_migration(120.seconds, test_report_1.id, test_report_3.id)
+        expect(migration).to be_scheduled_delayed_migration(240.seconds, test_report_4.id, test_report_5.id)
+        expect(BackgroundMigrationWorker.jobs.size).to eq(2)
+      end
+    end
+  end
+end
diff --git a/ee/spec/migrations/schedule_trace_expiry_removal_spec.rb b/ee/spec/migrations/schedule_trace_expiry_removal_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5831ee3fd088e2f6984d310c0cc0e6d2bbba7a82
--- /dev/null
+++ b/ee/spec/migrations/schedule_trace_expiry_removal_spec.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe ScheduleTraceExpiryRemoval, :suppress_gitlab_schemas_validate_connection, feature_category: :build_artifacts do
+  let(:scheduling_migration) { described_class.new }
+  let(:background_migration) { described_class::MIGRATION }
+  let(:matching_row_attrs)   { { created_at: Date.new(2020, 06, 20), expire_at: Date.new(2022, 01, 22), project_id: 1, file_type: 3 } }
+
+  before do
+    Sidekiq::Worker.clear_all
+    stub_const("#{described_class.name}::BATCH_SIZE", 2)
+
+    table(:namespaces).create!(id: 1, name: 'the-namespace', path: 'the-path')
+    table(:projects).create!(id: 1, name: 'the-project', namespace_id: 1)
+
+    1.upto(10) do |n|
+      table(:ci_builds).create!(id: n, allow_failure: false)
+      table(:ci_job_artifacts).create!(id: n, job_id: n, **matching_row_attrs)
+    end
+  end
+
+  context 'on gitlab.com', :saas do
+    describe '#up' do
+      it 'schedules batches of the correct size at 2 minute intervals' do
+        Sidekiq::Testing.fake! do
+          freeze_time do
+            migrate!
+
+            expect(background_migration).to be_scheduled_delayed_migration(240.seconds, 1, 2)
+            expect(background_migration).to be_scheduled_delayed_migration(480.seconds, 3, 4)
+            expect(background_migration).to be_scheduled_delayed_migration(720.seconds, 5, 6)
+            expect(background_migration).to be_scheduled_delayed_migration(960.seconds, 7, 8)
+            expect(background_migration).to be_scheduled_delayed_migration(1200.seconds, 9, 10)
+            expect(BackgroundMigrationWorker.jobs.size).to eq(5)
+          end
+        end
+      end
+    end
+  end
+
+  context 'on self-hosted instances' do
+    describe '#up' do
+      it 'does nothing' do
+        Sidekiq::Testing.fake! do
+          migrate!
+
+          expect(BackgroundMigrationWorker.jobs.size).to eq(0)
+        end
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/background_migration/backfill_ci_queuing_tables.rb b/lib/gitlab/background_migration/backfill_ci_queuing_tables.rb
new file mode 100644
index 0000000000000000000000000000000000000000..63112b5258487d16845cbc17615d9e66ece207fc
--- /dev/null
+++ b/lib/gitlab/background_migration/backfill_ci_queuing_tables.rb
@@ -0,0 +1,153 @@
+# frozen_string_literal: true
+
+module Gitlab
+  module BackgroundMigration
+    # Ensure queuing entries are present even if admins skip upgrades.
+    class BackfillCiQueuingTables
+      class Namespace < ActiveRecord::Base # rubocop:disable Style/Documentation
+        self.table_name = 'namespaces'
+        self.inheritance_column = :_type_disabled
+      end
+
+      class Project < ActiveRecord::Base # rubocop:disable Style/Documentation
+        self.table_name = 'projects'
+
+        belongs_to :namespace
+        has_one :ci_cd_settings, class_name: 'Gitlab::BackgroundMigration::BackfillCiQueuingTables::ProjectCiCdSetting'
+
+        def group_runners_enabled?
+          return false unless ci_cd_settings
+
+          ci_cd_settings.group_runners_enabled?
+        end
+      end
+
+      class ProjectCiCdSetting < ActiveRecord::Base # rubocop:disable Style/Documentation
+        self.table_name = 'project_ci_cd_settings'
+      end
+
+      class Taggings < ActiveRecord::Base # rubocop:disable Style/Documentation
+        self.table_name = 'taggings'
+      end
+
+      module Ci
+        class Build < ActiveRecord::Base # rubocop:disable Style/Documentation
+          include EachBatch
+
+          self.table_name = 'ci_builds'
+          self.inheritance_column = :_type_disabled
+
+          belongs_to :project
+
+          scope :pending, -> do
+            where(status: :pending, type: 'Ci::Build', runner_id: nil)
+          end
+
+          def self.each_batch(of: 1000, column: :id, order: { runner_id: :asc, id: :asc }, order_hint: nil)
+            start = except(:select).select(column).reorder(order)
+            start = start.take
+            return unless start
+
+            start_id = start[column]
+            arel_table = self.arel_table
+
+            1.step do |index|
+              start_cond = arel_table[column].gteq(start_id)
+              stop = except(:select).select(column).where(start_cond).reorder(order)
+              stop = stop.offset(of).limit(1).take
+              relation = where(start_cond)
+
+              if stop
+                stop_id = stop[column]
+                start_id = stop_id
+                stop_cond = arel_table[column].lt(stop_id)
+                relation = relation.where(stop_cond)
+              end
+
+              # Any ORDER BYs are useless for this relation and can lead to less
+              # efficient UPDATE queries, hence we get rid of it.
+              relation = relation.except(:order)
+
+              # Using unscoped is necessary to prevent leaking the current scope used by
+              # ActiveRecord to chain `each_batch` method.
+              unscoped { yield relation, index }
+
+              break unless stop
+            end
+          end
+
+          def tags_ids
+            BackfillCiQueuingTables::Taggings
+              .where(taggable_id: id, taggable_type: 'CommitStatus')
+              .pluck(:tag_id)
+          end
+        end
+
+        class PendingBuild < ActiveRecord::Base # rubocop:disable Style/Documentation
+          self.table_name = 'ci_pending_builds'
+
+          class << self
+            def upsert_from_build!(build)
+              entry = self.new(args_from_build(build))
+
+              self.upsert(
+                entry.attributes.compact,
+                returning: %w[build_id],
+                unique_by: :build_id)
+            end
+
+            def args_from_build(build)
+              project = build.project
+
+              {
+                build_id: build.id,
+                project_id: build.project_id,
+                protected: build.protected?,
+                namespace_id: project.namespace_id,
+                tag_ids: build.tags_ids,
+                instance_runners_enabled: project.shared_runners_enabled?,
+                namespace_traversal_ids: namespace_traversal_ids(project)
+              }
+            end
+
+            def namespace_traversal_ids(project)
+              if project.group_runners_enabled?
+                project.namespace.traversal_ids
+              else
+                []
+              end
+            end
+          end
+        end
+      end
+
+      BATCH_SIZE = 100
+
+      def perform(start_id, end_id)
+        scope = BackfillCiQueuingTables::Ci::Build.pending.where(id: start_id..end_id)
+        pending_builds_query = BackfillCiQueuingTables::Ci::PendingBuild
+          .where('ci_builds.id = ci_pending_builds.build_id')
+          .select(1)
+
+        scope.each_batch(of: BATCH_SIZE) do |builds|
+          builds = builds.where('NOT EXISTS (?)', pending_builds_query)
+          builds = builds.includes(:project, project: [:namespace, :ci_cd_settings])
+
+          builds.each do |build|
+            BackfillCiQueuingTables::Ci::PendingBuild.upsert_from_build!(build)
+          end
+        end
+
+        mark_job_as_succeeded(start_id, end_id)
+      end
+
+      private
+
+      def mark_job_as_succeeded(*arguments)
+        Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
+          self.class.name.demodulize,
+           arguments)
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/background_migration/backfill_integrations_type_new.rb b/lib/gitlab/background_migration/backfill_integrations_type_new.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b07d9371c197d13689c5cb0da10794a2d3d54a74
--- /dev/null
+++ b/lib/gitlab/background_migration/backfill_integrations_type_new.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+module Gitlab
+  module BackgroundMigration
+    # Backfills the new `integrations.type_new` column, which contains
+    # the real class name, rather than the legacy class name in `type`
+    # which is mapped via `Gitlab::Integrations::StiType`.
+    class BackfillIntegrationsTypeNew
+      include Gitlab::Database::DynamicModelHelpers
+
+      def perform(start_id, stop_id, batch_table, batch_column, sub_batch_size, pause_ms)
+        parent_batch_relation = define_batchable_model(batch_table, connection: connection)
+          .where(batch_column => start_id..stop_id)
+
+        parent_batch_relation.each_batch(column: batch_column, of: sub_batch_size) do |sub_batch|
+          process_sub_batch(sub_batch)
+
+          sleep(pause_ms * 0.001) if pause_ms > 0
+        end
+      end
+
+      private
+
+      def connection
+        ApplicationRecord.connection
+      end
+
+      def process_sub_batch(sub_batch)
+        # Extract the start/stop IDs from the current sub-batch
+        sub_start_id, sub_stop_id = sub_batch.pick(Arel.sql('MIN(id), MAX(id)'))
+
+        # This matches the mapping from the INSERT trigger added in
+        # db/migrate/20210721135638_add_triggers_to_integrations_type_new.rb
+        connection.execute(<<~SQL)
+          WITH mapping(old_type, new_type) AS (VALUES
+            ('AsanaService',                   'Integrations::Asana'),
+            ('AssemblaService',                'Integrations::Assembla'),
+            ('BambooService',                  'Integrations::Bamboo'),
+            ('BugzillaService',                'Integrations::Bugzilla'),
+            ('BuildkiteService',               'Integrations::Buildkite'),
+            ('CampfireService',                'Integrations::Campfire'),
+            ('ConfluenceService',              'Integrations::Confluence'),
+            ('CustomIssueTrackerService',      'Integrations::CustomIssueTracker'),
+            ('DatadogService',                 'Integrations::Datadog'),
+            ('DiscordService',                 'Integrations::Discord'),
+            ('DroneCiService',                 'Integrations::DroneCi'),
+            ('EmailsOnPushService',            'Integrations::EmailsOnPush'),
+            ('EwmService',                     'Integrations::Ewm'),
+            ('ExternalWikiService',            'Integrations::ExternalWiki'),
+            ('FlowdockService',                'Integrations::Flowdock'),
+            ('HangoutsChatService',            'Integrations::HangoutsChat'),
+            ('IrkerService',                   'Integrations::Irker'),
+            ('JenkinsService',                 'Integrations::Jenkins'),
+            ('JiraService',                    'Integrations::Jira'),
+            ('MattermostService',              'Integrations::Mattermost'),
+            ('MattermostSlashCommandsService', 'Integrations::MattermostSlashCommands'),
+            ('MicrosoftTeamsService',          'Integrations::MicrosoftTeams'),
+            ('MockCiService',                  'Integrations::MockCi'),
+            ('MockMonitoringService',          'Integrations::MockMonitoring'),
+            ('PackagistService',               'Integrations::Packagist'),
+            ('PipelinesEmailService',          'Integrations::PipelinesEmail'),
+            ('PivotaltrackerService',          'Integrations::Pivotaltracker'),
+            ('PrometheusService',              'Integrations::Prometheus'),
+            ('PushoverService',                'Integrations::Pushover'),
+            ('RedmineService',                 'Integrations::Redmine'),
+            ('SlackService',                   'Integrations::Slack'),
+            ('SlackSlashCommandsService',      'Integrations::SlackSlashCommands'),
+            ('TeamcityService',                'Integrations::Teamcity'),
+            ('UnifyCircuitService',            'Integrations::UnifyCircuit'),
+            ('WebexTeamsService',              'Integrations::WebexTeams'),
+            ('YoutrackService',                'Integrations::Youtrack'),
+
+            -- EE-only integrations
+            ('GithubService',                  'Integrations::Github'),
+            ('GitlabSlackApplicationService',  'Integrations::GitlabSlackApplication')
+          )
+
+          UPDATE integrations SET type_new = mapping.new_type
+          FROM mapping
+          WHERE integrations.id BETWEEN #{sub_start_id} AND #{sub_stop_id}
+            AND integrations.type = mapping.old_type
+        SQL
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/background_migration/encrypt_static_object_token.rb b/lib/gitlab/background_migration/encrypt_static_object_token.rb
new file mode 100644
index 0000000000000000000000000000000000000000..961dea028c93608d3fac2e68a2ad42c4632cf62f
--- /dev/null
+++ b/lib/gitlab/background_migration/encrypt_static_object_token.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+module Gitlab
+  module BackgroundMigration
+    # Populates "static_object_token_encrypted" field with encrypted versions
+    # of values from "static_object_token" field
+    class EncryptStaticObjectToken
+      # rubocop:disable Style/Documentation
+      class User < ActiveRecord::Base
+        include ::EachBatch
+        self.table_name = 'users'
+        scope :with_static_object_token, -> { where.not(static_object_token: nil) }
+        scope :without_static_object_token_encrypted, -> { where(static_object_token_encrypted: nil) }
+      end
+      # rubocop:enable Style/Documentation
+
+      BATCH_SIZE = 100
+
+      def perform(start_id, end_id)
+        ranged_query = User
+          .where(id: start_id..end_id)
+          .with_static_object_token
+          .without_static_object_token_encrypted
+
+        ranged_query.each_batch(of: BATCH_SIZE) do |sub_batch|
+          first, last = sub_batch.pick(Arel.sql('min(id), max(id)'))
+
+          batch_query = User.unscoped
+                          .where(id: first..last)
+                          .with_static_object_token
+                          .without_static_object_token_encrypted
+
+          user_tokens = batch_query.pluck(:id, :static_object_token)
+
+          user_encrypted_tokens = user_tokens.map do |(id, plaintext_token)|
+            next if plaintext_token.blank?
+
+            [id, Gitlab::CryptoHelper.aes256_gcm_encrypt(plaintext_token)]
+          end
+
+          encrypted_tokens_sql = user_encrypted_tokens.compact.map { |(id, token)| "(#{id}, '#{token}')" }.join(',')
+
+          next unless user_encrypted_tokens.present?
+
+          User.connection.execute(<<~SQL)
+              WITH cte(cte_id, cte_token) AS #{::Gitlab::Database::AsWithMaterialized.materialized_if_supported} (
+                SELECT *
+                FROM (VALUES #{encrypted_tokens_sql}) AS t (id, token)
+              )
+              UPDATE #{User.table_name}
+              SET static_object_token_encrypted = cte_token
+              FROM cte
+              WHERE cte_id = id
+          SQL
+        end
+
+        mark_job_as_succeeded(start_id, end_id)
+      end
+
+      private
+
+      def mark_job_as_succeeded(*arguments)
+        Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
+          self.class.name.demodulize,
+          arguments
+        )
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/background_migration/fix_incorrect_max_seats_used.rb b/lib/gitlab/background_migration/fix_incorrect_max_seats_used.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2c09b8c0b2441d9144af85472390d5fe1effd079
--- /dev/null
+++ b/lib/gitlab/background_migration/fix_incorrect_max_seats_used.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Gitlab
+  module BackgroundMigration
+    # rubocop: disable Style/Documentation
+    class FixIncorrectMaxSeatsUsed
+      def perform(batch = nil)
+      end
+    end
+  end
+end
+
+Gitlab::BackgroundMigration::FixIncorrectMaxSeatsUsed.prepend_mod_with('Gitlab::BackgroundMigration::FixIncorrectMaxSeatsUsed')
diff --git a/lib/gitlab/background_migration/merge_topics_with_same_name.rb b/lib/gitlab/background_migration/merge_topics_with_same_name.rb
new file mode 100644
index 0000000000000000000000000000000000000000..07231098a5fe76ffdee6c76c6c405145f26122af
--- /dev/null
+++ b/lib/gitlab/background_migration/merge_topics_with_same_name.rb
@@ -0,0 +1,76 @@
+# frozen_string_literal: true
+
+module Gitlab
+  module BackgroundMigration
+    # The class to merge project topics with the same case insensitive name
+    class MergeTopicsWithSameName
+      # Temporary AR model for topics
+      class Topic < ActiveRecord::Base
+        self.table_name = 'topics'
+      end
+
+      # Temporary AR model for project topic assignment
+      class ProjectTopic < ActiveRecord::Base
+        self.table_name = 'project_topics'
+      end
+
+      def perform(topic_names)
+        topic_names.each do |topic_name|
+          topics = Topic.where('LOWER(name) = ?', topic_name)
+            .order(total_projects_count: :desc, non_private_projects_count: :desc, id: :asc)
+            .to_a
+          topic_to_keep = topics.shift
+          merge_topics(topic_to_keep, topics) if topics.any?
+        end
+      end
+
+      private
+
+      def merge_topics(topic_to_keep, topics_to_remove)
+        description = topic_to_keep.description
+
+        topics_to_remove.each do |topic|
+          description ||= topic.description if topic.description.present?
+          process_avatar(topic_to_keep, topic) if topic.avatar.present?
+
+          ProjectTopic.transaction do
+            ProjectTopic.where(topic_id: topic.id)
+              .where.not(project_id: ProjectTopic.where(topic_id: topic_to_keep).select(:project_id))
+              .update_all(topic_id: topic_to_keep.id)
+            ProjectTopic.where(topic_id: topic.id).delete_all
+          end
+        end
+
+        Topic.where(id: topics_to_remove).delete_all
+
+        topic_to_keep.update(
+          description: description,
+          total_projects_count: total_projects_count(topic_to_keep.id),
+          non_private_projects_count: non_private_projects_count(topic_to_keep.id)
+        )
+      end
+
+      # We intentionally use application code here because we need to copy/remove avatar files
+      def process_avatar(topic_to_keep, topic_to_remove)
+        topic_to_remove = ::Projects::Topic.find(topic_to_remove.id)
+        topic_to_keep = ::Projects::Topic.find(topic_to_keep.id)
+        unless topic_to_keep.avatar.present?
+          topic_to_keep.avatar = topic_to_remove.avatar
+          topic_to_keep.save!
+        end
+
+        topic_to_remove.remove_avatar!
+        topic_to_remove.save!
+      end
+
+      def total_projects_count(topic_id)
+        ProjectTopic.where(topic_id: topic_id).count
+      end
+
+      def non_private_projects_count(topic_id)
+        ProjectTopic.joins('INNER JOIN projects ON project_topics.project_id = projects.id')
+            .where(project_topics: { topic_id: topic_id }).where('projects.visibility_level in (10, 20)').count
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/background_migration/populate_namespace_statistics.rb b/lib/gitlab/background_migration/populate_namespace_statistics.rb
new file mode 100644
index 0000000000000000000000000000000000000000..97927ef48c25a68642eee45b98405f9060b00457
--- /dev/null
+++ b/lib/gitlab/background_migration/populate_namespace_statistics.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+module Gitlab
+  module BackgroundMigration
+    # This class creates/updates those namespace statistics
+    # that haven't been created nor initialized.
+    # It also updates the related namespace statistics
+    class PopulateNamespaceStatistics
+      def perform(group_ids, statistics)
+        # Updating group statistics might involve calling Gitaly.
+        # For example, when calculating `wiki_size`, we will need
+        # to perform the request to check if the repo exists and
+        # also the repository size.
+        #
+        # The `allow_n_plus_1_calls` method is only intended for
+        # dev and test. It won't be raised in prod.
+        ::Gitlab::GitalyClient.allow_n_plus_1_calls do
+          relation(group_ids).each do |group|
+            upsert_namespace_statistics(group, statistics)
+          end
+        end
+      end
+
+      private
+
+      def upsert_namespace_statistics(group, statistics)
+        response = ::Groups::UpdateStatisticsService.new(group, statistics: statistics).execute
+
+        error_message("#{response.message} group: #{group.id}") if response.error?
+      end
+
+      def logger
+        @logger ||= ::Gitlab::BackgroundMigration::Logger.build
+      end
+
+      def error_message(message)
+        logger.error(message: "Namespace Statistics Migration: #{message}")
+      end
+
+      def relation(group_ids)
+        Group.includes(:namespace_statistics).where(id: group_ids)
+      end
+    end
+  end
+end
+
+Gitlab::BackgroundMigration::PopulateNamespaceStatistics.prepend_mod_with('Gitlab::BackgroundMigration::PopulateNamespaceStatistics')
diff --git a/lib/gitlab/background_migration/populate_test_reports_issue_id.rb b/lib/gitlab/background_migration/populate_test_reports_issue_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..301efd0c94397d1dd35973fac4fe797184021e12
--- /dev/null
+++ b/lib/gitlab/background_migration/populate_test_reports_issue_id.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+# rubocop: disable Style/Documentation
+
+module Gitlab
+  module BackgroundMigration
+    class PopulateTestReportsIssueId
+      def perform(start_id, stop_id)
+        # NO OP
+      end
+    end
+  end
+end
+
+Gitlab::BackgroundMigration::PopulateTestReportsIssueId.prepend_mod
diff --git a/lib/gitlab/background_migration/populate_topics_non_private_projects_count.rb b/lib/gitlab/background_migration/populate_topics_non_private_projects_count.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1f2b55004e4503346264fee4b082b03ceb8ce8a3
--- /dev/null
+++ b/lib/gitlab/background_migration/populate_topics_non_private_projects_count.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module Gitlab
+  module BackgroundMigration
+    # The class to populates the non private projects counter of topics
+    class PopulateTopicsNonPrivateProjectsCount
+      SUB_BATCH_SIZE = 100
+
+      # Temporary AR model for topics
+      class Topic < ActiveRecord::Base
+        include EachBatch
+
+        self.table_name = 'topics'
+      end
+
+      def perform(start_id, stop_id)
+        Topic.where(id: start_id..stop_id).each_batch(of: SUB_BATCH_SIZE) do |batch|
+          ApplicationRecord.connection.execute(<<~SQL)
+            WITH batched_relation AS #{Gitlab::Database::AsWithMaterialized.materialized_if_supported} (#{batch.select(:id).limit(SUB_BATCH_SIZE).to_sql})
+            UPDATE topics
+            SET non_private_projects_count = (
+              SELECT COUNT(*) 
+              FROM project_topics 
+              INNER JOIN projects 
+              ON project_topics.project_id = projects.id 
+              WHERE project_topics.topic_id = batched_relation.id 
+              AND projects.visibility_level > 0
+            )
+            FROM batched_relation
+            WHERE topics.id = batched_relation.id
+          SQL
+        end
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/background_migration/populate_vulnerability_reads.rb b/lib/gitlab/background_migration/populate_vulnerability_reads.rb
new file mode 100644
index 0000000000000000000000000000000000000000..656c62d9ee5785172f6918f31a0523020292f4b7
--- /dev/null
+++ b/lib/gitlab/background_migration/populate_vulnerability_reads.rb
@@ -0,0 +1,84 @@
+# frozen_string_literal: true
+
+module Gitlab
+  module BackgroundMigration
+    # rubocop:disable Style/Documentation
+    class PopulateVulnerabilityReads
+      include Gitlab::Database::DynamicModelHelpers
+
+      PAUSE_SECONDS = 0.1
+
+      def perform(start_id, end_id, sub_batch_size)
+        vulnerability_model.where(id: start_id..end_id).each_batch(of: sub_batch_size) do |sub_batch|
+          first, last = sub_batch.pick(Arel.sql('min(id), max(id)'))
+          connection.execute(insert_query(first, last))
+
+          sleep PAUSE_SECONDS
+        end
+
+        mark_job_as_succeeded(start_id, end_id, sub_batch_size)
+      end
+
+      private
+
+      def vulnerability_model
+        define_batchable_model('vulnerabilities', connection: connection)
+      end
+
+      def connection
+        ApplicationRecord.connection
+      end
+
+      def insert_query(start_id, end_id)
+        <<~SQL
+          INSERT INTO vulnerability_reads (
+            vulnerability_id,
+            project_id,
+            scanner_id,
+            report_type,
+            severity,
+            state,
+            has_issues,
+            resolved_on_default_branch,
+            uuid,
+            location_image
+          )
+          SELECT
+            vulnerabilities.id,
+            vulnerabilities.project_id,
+            vulnerability_scanners.id,
+            vulnerabilities.report_type,
+            vulnerabilities.severity,
+            vulnerabilities.state,
+            CASE
+              WHEN
+                vulnerability_issue_links.vulnerability_id IS NOT NULL
+              THEN
+                true
+              ELSE
+                false
+            END
+            has_issues,
+            vulnerabilities.resolved_on_default_branch,
+            vulnerability_occurrences.uuid::uuid,
+            vulnerability_occurrences.location ->> 'image'
+          FROM
+            vulnerabilities
+          INNER JOIN vulnerability_occurrences ON vulnerability_occurrences.vulnerability_id = vulnerabilities.id
+          INNER JOIN vulnerability_scanners ON vulnerability_scanners.id = vulnerability_occurrences.scanner_id
+          LEFT JOIN vulnerability_issue_links ON vulnerability_issue_links.vulnerability_id = vulnerabilities.id
+          WHERE vulnerabilities.id BETWEEN #{start_id} AND #{end_id}
+          ON CONFLICT(vulnerability_id) DO NOTHING;
+        SQL
+      end
+
+      def mark_job_as_succeeded(*arguments)
+        Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
+          self.class.name.demodulize,
+          arguments
+        )
+      end
+    end
+    # rubocop:enable Style/Documentation
+  end
+end
diff --git a/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid.rb b/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9a42d035285ab4fa69264408e83b6cf63f5cd1bb
--- /dev/null
+++ b/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid.rb
@@ -0,0 +1,218 @@
+# frozen_string_literal: true
+
+# rubocop: disable Style/Documentation
+class Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrencesUuid # rubocop:disable Metrics/ClassLength
+  # rubocop: disable Gitlab/NamespacedClass
+  class VulnerabilitiesIdentifier < ActiveRecord::Base
+    self.table_name = "vulnerability_identifiers"
+    has_many :primary_findings, class_name: 'VulnerabilitiesFinding', inverse_of: :primary_identifier, foreign_key: 'primary_identifier_id'
+  end
+
+  class VulnerabilitiesFinding < ActiveRecord::Base
+    include EachBatch
+    include ShaAttribute
+
+    self.table_name = "vulnerability_occurrences"
+
+    has_many :signatures, foreign_key: 'finding_id', class_name: 'VulnerabilityFindingSignature', inverse_of: :finding
+    belongs_to :primary_identifier, class_name: 'VulnerabilitiesIdentifier', inverse_of: :primary_findings, foreign_key: 'primary_identifier_id'
+
+    REPORT_TYPES = {
+      sast: 0,
+      dependency_scanning: 1,
+      container_scanning: 2,
+      dast: 3,
+      secret_detection: 4,
+      coverage_fuzzing: 5,
+      api_fuzzing: 6,
+      cluster_image_scanning: 7,
+      generic: 99
+    }.with_indifferent_access.freeze
+    enum report_type: REPORT_TYPES
+
+    sha_attribute :fingerprint
+    sha_attribute :location_fingerprint
+  end
+
+  class VulnerabilityFindingSignature < ActiveRecord::Base
+    include ShaAttribute
+
+    self.table_name = 'vulnerability_finding_signatures'
+    belongs_to :finding, foreign_key: 'finding_id', inverse_of: :signatures, class_name: 'VulnerabilitiesFinding'
+
+    sha_attribute :signature_sha
+  end
+
+  class VulnerabilitiesFindingPipeline < ActiveRecord::Base
+    include EachBatch
+    self.table_name = "vulnerability_occurrence_pipelines"
+  end
+
+  class Vulnerability < ActiveRecord::Base
+    include EachBatch
+    self.table_name = "vulnerabilities"
+  end
+
+  class CalculateFindingUUID
+    FINDING_NAMESPACES_IDS = {
+      development: "a143e9e2-41b3-47bc-9a19-081d089229f4",
+      test: "a143e9e2-41b3-47bc-9a19-081d089229f4",
+      staging: "a6930898-a1b2-4365-ab18-12aa474d9b26",
+      production: "58dc0f06-936c-43b3-93bb-71693f1b6570"
+    }.freeze
+
+    NAMESPACE_REGEX = /(\h{8})-(\h{4})-(\h{4})-(\h{4})-(\h{4})(\h{8})/.freeze
+    PACK_PATTERN = "NnnnnN"
+
+    def self.call(value)
+      Digest::UUID.uuid_v5(namespace_id, value)
+    end
+
+    def self.namespace_id
+      namespace_uuid = FINDING_NAMESPACES_IDS.fetch(Rails.env.to_sym)
+      # Digest::UUID is broken when using an UUID in namespace_id
+      # https://github.com/rails/rails/issues/37681#issue-520718028
+      namespace_uuid.scan(NAMESPACE_REGEX).flatten.map { |s| s.to_i(16) }.pack(PACK_PATTERN)
+    end
+  end
+  # rubocop: enable Gitlab/NamespacedClass
+
+  # rubocop: disable Metrics/AbcSize,Metrics/MethodLength,Metrics/BlockLength
+  def perform(start_id, end_id)
+    log_info('Migration started', start_id: start_id, end_id: end_id)
+
+    VulnerabilitiesFinding
+      .joins(:primary_identifier)
+      .includes(:signatures)
+      .select(:id, :report_type, :primary_identifier_id, :fingerprint, :location_fingerprint, :project_id, :created_at, :vulnerability_id, :uuid)
+      .where(id: start_id..end_id)
+      .each_batch(of: 50) do |relation|
+      duplicates = find_duplicates(relation)
+      remove_findings(ids: duplicates) if duplicates.present?
+
+      to_update = relation.reject { |finding| duplicates.include?(finding.id) }
+
+      begin
+        known_uuids = Set.new
+        to_be_deleted = []
+
+        mappings = to_update.each_with_object({}) do |finding, hash|
+          uuid = calculate_uuid_v5_for_finding(finding)
+
+          if known_uuids.add?(uuid)
+            hash[finding] = { uuid: uuid }
+          else
+            to_be_deleted << finding.id
+          end
+        end
+
+        # It is technically still possible to have duplicate uuids
+        # if the data integrity is broken somehow and the primary identifiers of
+        # the findings are pointing to different projects with the same fingerprint values.
+        if to_be_deleted.present?
+          log_info('Conflicting UUIDs found within the batch', finding_ids: to_be_deleted)
+
+          remove_findings(ids: to_be_deleted)
+        end
+
+        ::Gitlab::Database::BulkUpdate.execute(%i[uuid], mappings) if mappings.present?
+
+        log_info('Recalculation is done', finding_ids: mappings.keys.pluck(:id))
+      rescue ActiveRecord::RecordNotUnique => error
+        log_info('RecordNotUnique error received')
+
+        match_data = /\(uuid\)=\((?<uuid>\S{36})\)/.match(error.message)
+
+        # This exception returns the **correct** UUIDv5 which probably comes from a later record
+        # and it's the one we can drop in the easiest way before retrying the UPDATE query
+        if match_data
+          uuid = match_data[:uuid]
+          log_info('Conflicting UUID found', uuid: uuid)
+
+          id = VulnerabilitiesFinding.find_by(uuid: uuid)&.id
+          remove_findings(ids: id) if id
+          retry
+        else
+          log_error('Couldnt find conflicting uuid')
+
+          Gitlab::ErrorTracking.track_and_raise_exception(error)
+        end
+      end
+    end
+
+    mark_job_as_succeeded(start_id, end_id)
+  rescue StandardError => error
+    log_error('An exception happened')
+
+    Gitlab::ErrorTracking.track_and_raise_exception(error)
+  end
+  # rubocop: disable Metrics/AbcSize,Metrics/MethodLength,Metrics/BlockLength
+
+  private
+
+  def find_duplicates(relation)
+    to_exclude = []
+    relation.flat_map do |record|
+      # Assuming we're scanning id 31 and the duplicate is id 40
+      # first we'd process 31 and add 40 to the list of ids to remove
+      # then we would process record 40 and add 31 to the list of removals
+      # so we would drop both records
+      to_exclude << record.id
+
+      VulnerabilitiesFinding.where(
+        report_type: record.report_type,
+        location_fingerprint: record.location_fingerprint,
+        primary_identifier_id: record.primary_identifier_id,
+        project_id: record.project_id
+      ).where.not(id: to_exclude).pluck(:id)
+    end
+  end
+
+  def remove_findings(ids:)
+    ids = Array(ids)
+    log_info('Removing Findings and associated records', ids: ids)
+
+    vulnerability_ids = VulnerabilitiesFinding.where(id: ids).pluck(:vulnerability_id).uniq.compact
+
+    VulnerabilitiesFindingPipeline.where(occurrence_id: ids).each_batch { |batch| batch.delete_all }
+    Vulnerability.where(id: vulnerability_ids).each_batch { |batch| batch.delete_all }
+    VulnerabilitiesFinding.where(id: ids).delete_all
+  end
+
+  def calculate_uuid_v5_for_finding(vulnerability_finding)
+    return unless vulnerability_finding
+
+    signatures = vulnerability_finding.signatures.sort_by { |signature| signature.algorithm_type_before_type_cast }
+    location_fingerprint = signatures.last&.signature_sha || vulnerability_finding.location_fingerprint
+
+    uuid_v5_name_components = {
+      report_type: vulnerability_finding.report_type,
+      primary_identifier_fingerprint: vulnerability_finding.fingerprint,
+      location_fingerprint: location_fingerprint,
+      project_id: vulnerability_finding.project_id
+    }
+
+    name = uuid_v5_name_components.values.join('-')
+
+    CalculateFindingUUID.call(name)
+  end
+
+  def log_info(message, **extra)
+    logger.info(migrator: 'RecalculateVulnerabilitiesOccurrencesUuid', message: message, **extra)
+  end
+
+  def log_error(message, **extra)
+    logger.error(migrator: 'RecalculateVulnerabilitiesOccurrencesUuid', message: message, **extra)
+  end
+
+  def logger
+    @logger ||= Gitlab::BackgroundMigration::Logger.build
+  end
+
+  def mark_job_as_succeeded(*arguments)
+    Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
+      'RecalculateVulnerabilitiesOccurrencesUuid',
+      arguments
+    )
+  end
+end
diff --git a/lib/gitlab/background_migration/recalculate_vulnerability_finding_signatures_for_findings.rb b/lib/gitlab/background_migration/recalculate_vulnerability_finding_signatures_for_findings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..20200a1d508d27183875a276f35241f27fff393e
--- /dev/null
+++ b/lib/gitlab/background_migration/recalculate_vulnerability_finding_signatures_for_findings.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Gitlab
+  module BackgroundMigration
+    # rubocop: disable Style/Documentation
+    class RecalculateVulnerabilityFindingSignaturesForFindings
+      def perform(start_id, stop_id)
+      end
+    end
+  end
+end
+
+Gitlab::BackgroundMigration::RecalculateVulnerabilityFindingSignaturesForFindings.prepend_mod
diff --git a/lib/gitlab/background_migration/remove_all_trace_expiration_dates.rb b/lib/gitlab/background_migration/remove_all_trace_expiration_dates.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d47aa76f24ba2e79a85121774b8b84a48149a008
--- /dev/null
+++ b/lib/gitlab/background_migration/remove_all_trace_expiration_dates.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+module Gitlab
+  module BackgroundMigration
+    # Removing expire_at timestamps that shouldn't have
+    # been written to traces on gitlab.com.
+    class RemoveAllTraceExpirationDates
+      include Gitlab::Database::MigrationHelpers
+
+      BATCH_SIZE = 1_000
+
+      # Stubbed class to connect to the CI database
+      # connects_to has to be called in abstract classes.
+      class MultiDbAdaptableClass < ActiveRecord::Base
+        self.abstract_class = true
+
+        if Gitlab::Database.has_config?(:ci)
+          connects_to database: { writing: :ci, reading: :ci }
+        end
+      end
+
+      # Stubbed class to access the ci_job_artifacts table
+      class JobArtifact < MultiDbAdaptableClass
+        include EachBatch
+
+        self.table_name = 'ci_job_artifacts'
+
+        TARGET_TIMESTAMPS = [
+          Date.new(2021, 04, 22).midnight.utc,
+          Date.new(2021, 05, 22).midnight.utc,
+          Date.new(2021, 06, 22).midnight.utc,
+          Date.new(2022, 01, 22).midnight.utc,
+          Date.new(2022, 02, 22).midnight.utc,
+          Date.new(2022, 03, 22).midnight.utc,
+          Date.new(2022, 04, 22).midnight.utc
+        ].freeze
+
+        scope :traces, -> { where(file_type: 3) }
+        scope :between, -> (start_id, end_id) { where(id: start_id..end_id) }
+        scope :in_targeted_timestamps, -> { where(expire_at: TARGET_TIMESTAMPS) }
+      end
+
+      def perform(start_id, end_id)
+        return unless Gitlab.com?
+
+        JobArtifact.traces
+          .between(start_id, end_id)
+          .in_targeted_timestamps
+          .each_batch(of: BATCH_SIZE) { |batch| batch.update_all(expire_at: nil) }
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/background_migration/update_timelogs_null_spent_at.rb b/lib/gitlab/background_migration/update_timelogs_null_spent_at.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b61f2ee7f4cc37e78961594d73310066f756e397
--- /dev/null
+++ b/lib/gitlab/background_migration/update_timelogs_null_spent_at.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module Gitlab
+  module BackgroundMigration
+    # Class to populate spent_at for timelogs
+    class UpdateTimelogsNullSpentAt
+      include Gitlab::Database::DynamicModelHelpers
+
+      BATCH_SIZE = 100
+
+      def perform(start_id, stop_id)
+        define_batchable_model('timelogs', connection: connection)
+            .where(spent_at: nil, id: start_id..stop_id)
+            .each_batch(of: 100) do |subbatch|
+          batch_start, batch_end = subbatch.pick('min(id), max(id)')
+
+          update_timelogs(batch_start, batch_end)
+        end
+      end
+
+      def update_timelogs(batch_start, batch_stop)
+        execute(<<~SQL)
+          UPDATE timelogs
+          SET spent_at = created_at
+          WHERE spent_at IS NULL
+          AND timelogs.id BETWEEN #{batch_start} AND #{batch_stop};
+        SQL
+      end
+
+      def connection
+        @connection ||= ApplicationRecord.connection
+      end
+
+      def execute(sql)
+        connection.execute(sql)
+      end
+    end
+  end
+end
diff --git a/spec/lib/gitlab/background_migration/backfill_ci_queuing_tables_spec.rb b/spec/lib/gitlab/background_migration/backfill_ci_queuing_tables_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..aaf8c124a83ad6bf2def822bdbd383fdfc1b7818
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/backfill_ci_queuing_tables_spec.rb
@@ -0,0 +1,245 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::BackfillCiQueuingTables, :migration,
+               :suppress_gitlab_schemas_validate_connection, schema: 20220208115439 do
+  let(:namespaces)      { table(:namespaces) }
+  let(:projects)        { table(:projects) }
+  let(:ci_cd_settings)  { table(:project_ci_cd_settings) }
+  let(:builds)          { table(:ci_builds) }
+  let(:queuing_entries) { table(:ci_pending_builds) }
+  let(:tags)            { table(:tags) }
+  let(:taggings)        { table(:taggings) }
+
+  subject { described_class.new }
+
+  describe '#perform' do
+    let!(:namespace) do
+      namespaces.create!(
+        id: 10,
+        name: 'namespace10',
+        path: 'namespace10',
+        traversal_ids: [10])
+    end
+
+    let!(:other_namespace) do
+      namespaces.create!(
+        id: 11,
+        name: 'namespace11',
+        path: 'namespace11',
+        traversal_ids: [11])
+    end
+
+    let!(:project) do
+      projects.create!(id: 5, namespace_id: 10, name: 'test1', path: 'test1')
+    end
+
+    let!(:ci_cd_setting) do
+      ci_cd_settings.create!(id: 5, project_id: 5, group_runners_enabled: true)
+    end
+
+    let!(:other_project) do
+      projects.create!(id: 7, namespace_id: 11, name: 'test2', path: 'test2')
+    end
+
+    let!(:other_ci_cd_setting) do
+      ci_cd_settings.create!(id: 7, project_id: 7, group_runners_enabled: false)
+    end
+
+    let!(:another_project) do
+      projects.create!(id: 9, namespace_id: 10, name: 'test3', path: 'test3', shared_runners_enabled: false)
+    end
+
+    let!(:ruby_tag) do
+      tags.create!(id: 22, name: 'ruby')
+    end
+
+    let!(:postgres_tag) do
+      tags.create!(id: 23, name: 'postgres')
+    end
+
+    it 'creates ci_pending_builds for all pending builds in range' do
+      builds.create!(id: 50, status: :pending, name: 'test1', project_id: 5, type: 'Ci::Build')
+      builds.create!(id: 51, status: :created, name: 'test2', project_id: 5, type: 'Ci::Build')
+      builds.create!(id: 52, status: :pending, name: 'test3', project_id: 5, protected: true, type: 'Ci::Build')
+
+      taggings.create!(taggable_id: 52, taggable_type: 'CommitStatus', tag_id: 22)
+      taggings.create!(taggable_id: 52, taggable_type: 'CommitStatus', tag_id: 23)
+
+      builds.create!(id: 60, status: :pending, name: 'test1', project_id: 7, type: 'Ci::Build')
+      builds.create!(id: 61, status: :running, name: 'test2', project_id: 7, protected: true, type: 'Ci::Build')
+      builds.create!(id: 62, status: :pending, name: 'test3', project_id: 7, type: 'Ci::Build')
+
+      taggings.create!(taggable_id: 60, taggable_type: 'CommitStatus', tag_id: 23)
+      taggings.create!(taggable_id: 62, taggable_type: 'CommitStatus', tag_id: 22)
+
+      builds.create!(id: 70, status: :pending, name: 'test1', project_id: 9, protected: true, type: 'Ci::Build')
+      builds.create!(id: 71, status: :failed, name: 'test2', project_id: 9, type: 'Ci::Build')
+      builds.create!(id: 72, status: :pending, name: 'test3', project_id: 9, type: 'Ci::Build')
+
+      taggings.create!(taggable_id: 71, taggable_type: 'CommitStatus', tag_id: 22)
+
+      subject.perform(1, 100)
+
+      expect(queuing_entries.all).to contain_exactly(
+        an_object_having_attributes(
+          build_id: 50,
+          project_id: 5,
+          namespace_id: 10,
+          protected: false,
+          instance_runners_enabled: true,
+          minutes_exceeded: false,
+          tag_ids: [],
+          namespace_traversal_ids: [10]),
+        an_object_having_attributes(
+          build_id: 52,
+          project_id: 5,
+          namespace_id: 10,
+          protected: true,
+          instance_runners_enabled: true,
+          minutes_exceeded: false,
+          tag_ids: match_array([22, 23]),
+          namespace_traversal_ids: [10]),
+        an_object_having_attributes(
+          build_id: 60,
+          project_id: 7,
+          namespace_id: 11,
+          protected: false,
+          instance_runners_enabled: true,
+          minutes_exceeded: false,
+          tag_ids: [23],
+          namespace_traversal_ids: []),
+        an_object_having_attributes(
+          build_id: 62,
+          project_id: 7,
+          namespace_id: 11,
+          protected: false,
+          instance_runners_enabled: true,
+          minutes_exceeded: false,
+          tag_ids: [22],
+          namespace_traversal_ids: []),
+        an_object_having_attributes(
+          build_id: 70,
+          project_id: 9,
+          namespace_id: 10,
+          protected: true,
+          instance_runners_enabled: false,
+          minutes_exceeded: false,
+          tag_ids: [],
+          namespace_traversal_ids: []),
+        an_object_having_attributes(
+          build_id: 72,
+          project_id: 9,
+          namespace_id: 10,
+          protected: false,
+          instance_runners_enabled: false,
+          minutes_exceeded: false,
+          tag_ids: [],
+          namespace_traversal_ids: [])
+      )
+    end
+
+    it 'skips builds that already have ci_pending_builds' do
+      builds.create!(id: 50, status: :pending, name: 'test1', project_id: 5, type: 'Ci::Build')
+      builds.create!(id: 51, status: :created, name: 'test2', project_id: 5, type: 'Ci::Build')
+      builds.create!(id: 52, status: :pending, name: 'test3', project_id: 5, protected: true, type: 'Ci::Build')
+
+      taggings.create!(taggable_id: 50, taggable_type: 'CommitStatus', tag_id: 22)
+      taggings.create!(taggable_id: 52, taggable_type: 'CommitStatus', tag_id: 23)
+
+      queuing_entries.create!(build_id: 50, project_id: 5, namespace_id: 10)
+
+      subject.perform(1, 100)
+
+      expect(queuing_entries.all).to contain_exactly(
+        an_object_having_attributes(
+          build_id: 50,
+          project_id: 5,
+          namespace_id: 10,
+          protected: false,
+          instance_runners_enabled: false,
+          minutes_exceeded: false,
+          tag_ids: [],
+          namespace_traversal_ids: []),
+        an_object_having_attributes(
+          build_id: 52,
+          project_id: 5,
+          namespace_id: 10,
+          protected: true,
+          instance_runners_enabled: true,
+          minutes_exceeded: false,
+          tag_ids: [23],
+          namespace_traversal_ids: [10])
+      )
+    end
+
+    it 'upserts values in case of conflicts' do
+      builds.create!(id: 50, status: :pending, name: 'test1', project_id: 5, type: 'Ci::Build')
+      queuing_entries.create!(build_id: 50, project_id: 5, namespace_id: 10)
+
+      build = described_class::Ci::Build.find(50)
+      described_class::Ci::PendingBuild.upsert_from_build!(build)
+
+      expect(queuing_entries.all).to contain_exactly(
+        an_object_having_attributes(
+          build_id: 50,
+          project_id: 5,
+          namespace_id: 10,
+          protected: false,
+          instance_runners_enabled: true,
+          minutes_exceeded: false,
+          tag_ids: [],
+          namespace_traversal_ids: [10])
+      )
+    end
+  end
+
+  context 'Ci::Build' do
+    describe '.each_batch' do
+      let(:model) { described_class::Ci::Build }
+
+      before do
+        builds.create!(id: 1, status: :pending, name: 'test1', project_id: 5, type: 'Ci::Build')
+        builds.create!(id: 2, status: :pending, name: 'test2', project_id: 5, type: 'Ci::Build')
+        builds.create!(id: 3, status: :pending, name: 'test3', project_id: 5, type: 'Ci::Build')
+        builds.create!(id: 4, status: :pending, name: 'test4', project_id: 5, type: 'Ci::Build')
+        builds.create!(id: 5, status: :pending, name: 'test5', project_id: 5, type: 'Ci::Build')
+      end
+
+      it 'yields an ActiveRecord::Relation when a block is given' do
+        model.each_batch do |relation|
+          expect(relation).to be_a_kind_of(ActiveRecord::Relation)
+        end
+      end
+
+      it 'yields a batch index as the second argument' do
+        model.each_batch do |_, index|
+          expect(index).to eq(1)
+        end
+      end
+
+      it 'accepts a custom batch size' do
+        amount = 0
+
+        model.each_batch(of: 1) { amount += 1 }
+
+        expect(amount).to eq(5)
+      end
+
+      it 'does not include ORDER BYs in the yielded relations' do
+        model.each_batch do |relation|
+          expect(relation.to_sql).not_to include('ORDER BY')
+        end
+      end
+
+      it 'orders ascending' do
+        ids = []
+
+        model.each_batch(of: 1) { |rel| ids.concat(rel.ids) }
+
+        expect(ids).to eq(ids.sort)
+      end
+    end
+  end
+end
diff --git a/spec/lib/gitlab/background_migration/backfill_group_features_spec.rb b/spec/lib/gitlab/background_migration/backfill_group_features_spec.rb
index 2c2740434de77489ce945c60c54823ed2924eca7..e0be5a785b86a050d5dd31eb4ad8f3c13345b1b7 100644
--- a/spec/lib/gitlab/background_migration/backfill_group_features_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_group_features_spec.rb
@@ -2,7 +2,7 @@
 
 require 'spec_helper'
 
-RSpec.describe Gitlab::BackgroundMigration::BackfillGroupFeatures, :migration, schema: 20220314184009 do
+RSpec.describe Gitlab::BackgroundMigration::BackfillGroupFeatures, :migration, schema: 20220302114046 do
   let(:group_features) { table(:group_features) }
   let(:namespaces) { table(:namespaces) }
 
diff --git a/spec/lib/gitlab/background_migration/backfill_integrations_type_new_spec.rb b/spec/lib/gitlab/background_migration/backfill_integrations_type_new_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e6588644b4ff04544abe92bbf4559c308e0fd8b6
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/backfill_integrations_type_new_spec.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::BackfillIntegrationsTypeNew, :migration, schema: 20220212120735 do
+  let(:migration) { described_class.new }
+  let(:integrations) { table(:integrations) }
+
+  let(:namespaced_integrations) do
+    Set.new(
+      %w[
+        Asana Assembla Bamboo Bugzilla Buildkite Campfire Confluence CustomIssueTracker Datadog
+        Discord DroneCi EmailsOnPush Ewm ExternalWiki Flowdock HangoutsChat Harbor Irker Jenkins Jira Mattermost
+        MattermostSlashCommands MicrosoftTeams MockCi MockMonitoring Packagist PipelinesEmail Pivotaltracker
+        Prometheus Pushover Redmine Shimo Slack SlackSlashCommands Teamcity UnifyCircuit WebexTeams Youtrack Zentao
+        Github GitlabSlackApplication
+      ]).freeze
+  end
+
+  before do
+    integrations.connection.execute 'ALTER TABLE integrations DISABLE TRIGGER "trigger_type_new_on_insert"'
+
+    namespaced_integrations.each_with_index do |type, i|
+      integrations.create!(id: i + 1, type: "#{type}Service")
+    end
+
+    integrations.create!(id: namespaced_integrations.size + 1, type: 'LegacyService')
+  ensure
+    integrations.connection.execute 'ALTER TABLE integrations ENABLE TRIGGER "trigger_type_new_on_insert"'
+  end
+
+  it 'backfills `type_new` for the selected records' do
+    # We don't want to mock `Kernel.sleep`, so instead we mock it on the migration
+    # class before it gets forwarded.
+    expect(migration).to receive(:sleep).with(0.05).exactly(5).times
+
+    queries = ActiveRecord::QueryRecorder.new do
+      migration.perform(2, 10, :integrations, :id, 2, 50)
+    end
+
+    expect(queries.count).to be(16)
+    expect(queries.log.grep(/^SELECT/).size).to be(11)
+    expect(queries.log.grep(/^UPDATE/).size).to be(5)
+    expect(queries.log.grep(/^UPDATE/).join.scan(/WHERE .*/)).to eq(
+      [
+        'WHERE integrations.id BETWEEN 2 AND 3',
+        'WHERE integrations.id BETWEEN 4 AND 5',
+        'WHERE integrations.id BETWEEN 6 AND 7',
+        'WHERE integrations.id BETWEEN 8 AND 9',
+        'WHERE integrations.id BETWEEN 10 AND 10'
+      ])
+
+    expect(integrations.where(id: 2..10).pluck(:type, :type_new)).to contain_exactly(
+      ['AssemblaService',           'Integrations::Assembla'],
+      ['BambooService',             'Integrations::Bamboo'],
+      ['BugzillaService',           'Integrations::Bugzilla'],
+      ['BuildkiteService',          'Integrations::Buildkite'],
+      ['CampfireService',           'Integrations::Campfire'],
+      ['ConfluenceService',         'Integrations::Confluence'],
+      ['CustomIssueTrackerService', 'Integrations::CustomIssueTracker'],
+      ['DatadogService',            'Integrations::Datadog'],
+      ['DiscordService',            'Integrations::Discord']
+    )
+
+    expect(integrations.where.not(id: 2..10)).to all(have_attributes(type_new: nil))
+  end
+end
diff --git a/spec/lib/gitlab/background_migration/backfill_member_namespace_for_group_members_spec.rb b/spec/lib/gitlab/background_migration/backfill_member_namespace_for_group_members_spec.rb
index ea07079f9eec0fec64c59d424932fe853f71ba87..e1ef12a14792b137ae68fdb5c6542dfcb8860e92 100644
--- a/spec/lib/gitlab/background_migration/backfill_member_namespace_for_group_members_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_member_namespace_for_group_members_spec.rb
@@ -2,7 +2,7 @@
 
 require 'spec_helper'
 
-RSpec.describe Gitlab::BackgroundMigration::BackfillMemberNamespaceForGroupMembers, :migration, schema: 20220314184009 do
+RSpec.describe Gitlab::BackgroundMigration::BackfillMemberNamespaceForGroupMembers, :migration, schema: 20220120211832 do
   let(:migration) { described_class.new }
   let(:members_table) { table(:members) }
   let(:namespaces_table) { table(:namespaces) }
diff --git a/spec/lib/gitlab/background_migration/backfill_namespace_id_for_namespace_route_spec.rb b/spec/lib/gitlab/background_migration/backfill_namespace_id_for_namespace_route_spec.rb
index f4e8fa1bbac9e6b0cd779f329981e23581d87981..b821efcadb0106fe12edf14b96c3dd200e5d6f1b 100644
--- a/spec/lib/gitlab/background_migration/backfill_namespace_id_for_namespace_route_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_namespace_id_for_namespace_route_spec.rb
@@ -2,7 +2,7 @@
 
 require 'spec_helper'
 
-RSpec.describe Gitlab::BackgroundMigration::BackfillNamespaceIdForNamespaceRoute, :migration, schema: 20220314184009 do
+RSpec.describe Gitlab::BackgroundMigration::BackfillNamespaceIdForNamespaceRoute, :migration, schema: 20220120123800 do
   let(:migration) { described_class.new }
   let(:namespaces_table) { table(:namespaces) }
   let(:projects_table) { table(:projects) }
diff --git a/spec/lib/gitlab/background_migration/backfill_snippet_repositories_spec.rb b/spec/lib/gitlab/background_migration/backfill_snippet_repositories_spec.rb
index 6f6ff9232e09c9efb2318ac5aa204235c4a0ab22..4a50d08b2aad5d04f40400343a4861a04f0ac375 100644
--- a/spec/lib/gitlab/background_migration/backfill_snippet_repositories_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_snippet_repositories_spec.rb
@@ -2,7 +2,7 @@
 
 require 'spec_helper'
 
-RSpec.describe Gitlab::BackgroundMigration::BackfillSnippetRepositories, :migration, schema: 20220314184009,
+RSpec.describe Gitlab::BackgroundMigration::BackfillSnippetRepositories, :migration, schema: 20211202041233,
 feature_category: :source_code_management do
   let(:gitlab_shell) { Gitlab::Shell.new }
   let(:users) { table(:users) }
diff --git a/spec/lib/gitlab/background_migration/encrypt_integration_properties_spec.rb b/spec/lib/gitlab/background_migration/encrypt_integration_properties_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c788b701d79df6e077eb5fe4ec19e0a715f35907
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/encrypt_integration_properties_spec.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::EncryptIntegrationProperties, schema: 20220415124804 do
+  let(:integrations) do
+    table(:integrations) do |integrations|
+      integrations.send :attr_encrypted, :encrypted_properties_tmp,
+                        attribute: :encrypted_properties,
+                        mode: :per_attribute_iv,
+                        key: ::Settings.attr_encrypted_db_key_base_32,
+                        algorithm: 'aes-256-gcm',
+                        marshal: true,
+                        marshaler: ::Gitlab::Json,
+                        encode: false,
+                        encode_iv: false
+    end
+  end
+
+  let!(:no_properties) { integrations.create! }
+  let!(:with_plaintext_1) { integrations.create!(properties: json_props(1)) }
+  let!(:with_plaintext_2) { integrations.create!(properties: json_props(2)) }
+  let!(:with_encrypted) do
+    x = integrations.new
+    x.properties = nil
+    x.encrypted_properties_tmp = some_props(3)
+    x.save!
+    x
+  end
+
+  let(:start_id) { integrations.minimum(:id) }
+  let(:end_id) { integrations.maximum(:id) }
+
+  it 'ensures all properties are encrypted', :aggregate_failures do
+    described_class.new.perform(start_id, end_id)
+
+    props = integrations.all.to_h do |record|
+      [record.id, [Gitlab::Json.parse(record.properties), record.encrypted_properties_tmp]]
+    end
+
+    expect(integrations.count).to eq(4)
+
+    expect(props).to match(
+      no_properties.id => both(be_nil),
+      with_plaintext_1.id => both(eq some_props(1)),
+      with_plaintext_2.id => both(eq some_props(2)),
+      with_encrypted.id => match([be_nil, eq(some_props(3))])
+    )
+  end
+
+  private
+
+  def both(obj)
+    match [obj, obj]
+  end
+
+  def some_props(id)
+    HashWithIndifferentAccess.new({ id: id, foo: 1, bar: true, baz: %w[a string array] })
+  end
+
+  def json_props(id)
+    some_props(id).to_json
+  end
+end
diff --git a/spec/lib/gitlab/background_migration/encrypt_static_object_token_spec.rb b/spec/lib/gitlab/background_migration/encrypt_static_object_token_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4e7b97d33f615a07d5d5dcc55aee5a53263a27e4
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/encrypt_static_object_token_spec.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::EncryptStaticObjectToken do
+  let(:users) { table(:users) }
+  let!(:user_without_tokens) { create_user!(name: 'notoken') }
+  let!(:user_with_plaintext_token_1) { create_user!(name: 'plaintext_1', token: 'token') }
+  let!(:user_with_plaintext_token_2) { create_user!(name: 'plaintext_2', token: 'TOKEN') }
+  let!(:user_with_plaintext_empty_token) { create_user!(name: 'plaintext_3', token: '') }
+  let!(:user_with_encrypted_token) { create_user!(name: 'encrypted', encrypted_token: 'encrypted') }
+  let!(:user_with_both_tokens) { create_user!(name: 'both', token: 'token2', encrypted_token: 'encrypted2') }
+
+  before do
+    allow(Gitlab::CryptoHelper).to receive(:aes256_gcm_encrypt).and_call_original
+    allow(Gitlab::CryptoHelper).to receive(:aes256_gcm_encrypt).with('token') { 'secure_token' }
+    allow(Gitlab::CryptoHelper).to receive(:aes256_gcm_encrypt).with('TOKEN') { 'SECURE_TOKEN' }
+  end
+
+  subject { described_class.new.perform(start_id, end_id) }
+
+  let(:start_id) { users.minimum(:id) }
+  let(:end_id) { users.maximum(:id) }
+
+  it 'backfills encrypted tokens to users with plaintext token only', :aggregate_failures do
+    subject
+
+    new_state = users.pluck(:id, :static_object_token, :static_object_token_encrypted).to_h do |row|
+      [row[0], [row[1], row[2]]]
+    end
+
+    expect(new_state.count).to eq(6)
+
+    expect(new_state[user_with_plaintext_token_1.id]).to match_array(%w[token secure_token])
+    expect(new_state[user_with_plaintext_token_2.id]).to match_array(%w[TOKEN SECURE_TOKEN])
+
+    expect(new_state[user_with_plaintext_empty_token.id]).to match_array(['', nil])
+    expect(new_state[user_without_tokens.id]).to match_array([nil, nil])
+    expect(new_state[user_with_both_tokens.id]).to match_array(%w[token2 encrypted2])
+    expect(new_state[user_with_encrypted_token.id]).to match_array([nil, 'encrypted'])
+  end
+
+  context 'when id range does not include existing user ids' do
+    let(:arguments) { [non_existing_record_id, non_existing_record_id.succ] }
+
+    it_behaves_like 'marks background migration job records' do
+      subject { described_class.new }
+    end
+  end
+
+  private
+
+  def create_user!(name:, token: nil, encrypted_token: nil)
+    email = "#{name}@example.com"
+
+    table(:users).create!(
+      name: name,
+      email: email,
+      username: name,
+      projects_limit: 0,
+      static_object_token: token,
+      static_object_token_encrypted: encrypted_token
+    )
+  end
+end
diff --git a/spec/lib/gitlab/background_migration/fix_vulnerability_occurrences_with_hashes_as_raw_metadata_spec.rb b/spec/lib/gitlab/background_migration/fix_vulnerability_occurrences_with_hashes_as_raw_metadata_spec.rb
index 3cbc05b762a1f3d7912e1321fd9d1994d39574e9..af551861d47d33721081ac13839f2a6429be0145 100644
--- a/spec/lib/gitlab/background_migration/fix_vulnerability_occurrences_with_hashes_as_raw_metadata_spec.rb
+++ b/spec/lib/gitlab/background_migration/fix_vulnerability_occurrences_with_hashes_as_raw_metadata_spec.rb
@@ -2,7 +2,7 @@
 
 require 'spec_helper'
 
-RSpec.describe Gitlab::BackgroundMigration::FixVulnerabilityOccurrencesWithHashesAsRawMetadata, schema: 20220314184009 do
+RSpec.describe Gitlab::BackgroundMigration::FixVulnerabilityOccurrencesWithHashesAsRawMetadata, schema: 20211209203821 do
   let(:users) { table(:users) }
   let(:namespaces) { table(:namespaces) }
   let(:projects) { table(:projects) }
diff --git a/spec/lib/gitlab/background_migration/merge_topics_with_same_name_spec.rb b/spec/lib/gitlab/background_migration/merge_topics_with_same_name_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2c2c048992f40fde6635c070c7fb74faf6d5f8fa
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/merge_topics_with_same_name_spec.rb
@@ -0,0 +1,148 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::MergeTopicsWithSameName, schema: 20220331133802 do
+  def set_avatar(topic_id, avatar)
+    topic = ::Projects::Topic.find(topic_id)
+    topic.avatar = avatar
+    topic.save!
+    topic.avatar.absolute_path
+  end
+
+  it 'merges project topics with same case insensitive name' do
+    namespaces = table(:namespaces)
+    projects = table(:projects)
+    topics = table(:topics)
+    project_topics = table(:project_topics)
+
+    group_1 = namespaces.create!(name: 'space1', type: 'Group', path: 'space1')
+    group_2 = namespaces.create!(name: 'space2', type: 'Group', path: 'space2')
+    group_3 = namespaces.create!(name: 'space3', type: 'Group', path: 'space3')
+    proj_space_1 = namespaces.create!(name: 'proj1', path: 'proj1', type: 'Project', parent_id: group_1.id)
+    proj_space_2 = namespaces.create!(name: 'proj2', path: 'proj2', type: 'Project', parent_id: group_2.id)
+    proj_space_3 = namespaces.create!(name: 'proj3', path: 'proj3', type: 'Project', parent_id: group_3.id)
+    project_1 = projects.create!(namespace_id: group_1.id, project_namespace_id: proj_space_1.id, visibility_level: 20)
+    project_2 = projects.create!(namespace_id: group_2.id, project_namespace_id: proj_space_2.id, visibility_level: 10)
+    project_3 = projects.create!(namespace_id: group_3.id, project_namespace_id: proj_space_3.id, visibility_level: 0)
+    topic_1_keep = topics.create!(
+      name: 'topic1',
+      title: 'Topic 1',
+      description: 'description 1 to keep',
+      total_projects_count: 2,
+      non_private_projects_count: 2
+    )
+    topic_1_remove = topics.create!(
+      name: 'TOPIC1',
+      title: 'Topic 1',
+      description: 'description 1 to remove',
+      total_projects_count: 2,
+      non_private_projects_count: 1
+    )
+    topic_2_remove = topics.create!(
+      name: 'topic2',
+      title: 'Topic 2',
+      total_projects_count: 0
+    )
+    topic_2_keep = topics.create!(
+      name: 'TOPIC2',
+      title: 'Topic 2',
+      description: 'description 2 to keep',
+      total_projects_count: 1
+    )
+    topic_3_remove_1 = topics.create!(
+      name: 'topic3',
+      title: 'Topic 3',
+      total_projects_count: 2,
+      non_private_projects_count: 1
+    )
+    topic_3_keep = topics.create!(
+      name: 'Topic3',
+      title: 'Topic 3',
+      total_projects_count: 2,
+      non_private_projects_count: 2
+    )
+    topic_3_remove_2 = topics.create!(
+      name: 'TOPIC3',
+      title: 'Topic 3',
+      description: 'description 3 to keep',
+      total_projects_count: 2,
+      non_private_projects_count: 1
+    )
+    topic_4_keep = topics.create!(
+      name: 'topic4',
+      title: 'Topic 4'
+    )
+
+    project_topics_1 = []
+    project_topics_3 = []
+    project_topics_removed = []
+
+    project_topics_1 << project_topics.create!(topic_id: topic_1_keep.id, project_id: project_1.id)
+    project_topics_1 << project_topics.create!(topic_id: topic_1_keep.id, project_id: project_2.id)
+    project_topics_removed << project_topics.create!(topic_id: topic_1_remove.id, project_id: project_2.id)
+    project_topics_1 << project_topics.create!(topic_id: topic_1_remove.id, project_id: project_3.id)
+
+    project_topics_3 << project_topics.create!(topic_id: topic_3_keep.id, project_id: project_1.id)
+    project_topics_3 << project_topics.create!(topic_id: topic_3_keep.id, project_id: project_2.id)
+    project_topics_removed << project_topics.create!(topic_id: topic_3_remove_1.id, project_id: project_1.id)
+    project_topics_3 << project_topics.create!(topic_id: topic_3_remove_1.id, project_id: project_3.id)
+    project_topics_removed << project_topics.create!(topic_id: topic_3_remove_2.id, project_id: project_1.id)
+    project_topics_removed << project_topics.create!(topic_id: topic_3_remove_2.id, project_id: project_3.id)
+
+    avatar_paths = {
+      topic_1_keep: set_avatar(topic_1_keep.id, fixture_file_upload('spec/fixtures/avatars/avatar1.png')),
+      topic_1_remove: set_avatar(topic_1_remove.id, fixture_file_upload('spec/fixtures/avatars/avatar2.png')),
+      topic_2_remove: set_avatar(topic_2_remove.id, fixture_file_upload('spec/fixtures/avatars/avatar3.png')),
+      topic_3_remove_1: set_avatar(topic_3_remove_1.id, fixture_file_upload('spec/fixtures/avatars/avatar4.png')),
+      topic_3_remove_2: set_avatar(topic_3_remove_2.id, fixture_file_upload('spec/fixtures/avatars/avatar5.png'))
+    }
+
+    subject.perform(%w[topic1 topic2 topic3 topic4])
+
+    # Topics
+    [topic_1_keep, topic_2_keep, topic_3_keep, topic_4_keep].each(&:reload)
+    expect(topic_1_keep.name).to eq('topic1')
+    expect(topic_1_keep.description).to eq('description 1 to keep')
+    expect(topic_1_keep.total_projects_count).to eq(3)
+    expect(topic_1_keep.non_private_projects_count).to eq(2)
+    expect(topic_2_keep.name).to eq('TOPIC2')
+    expect(topic_2_keep.description).to eq('description 2 to keep')
+    expect(topic_2_keep.total_projects_count).to eq(0)
+    expect(topic_2_keep.non_private_projects_count).to eq(0)
+    expect(topic_3_keep.name).to eq('Topic3')
+    expect(topic_3_keep.description).to eq('description 3 to keep')
+    expect(topic_3_keep.total_projects_count).to eq(3)
+    expect(topic_3_keep.non_private_projects_count).to eq(2)
+    expect(topic_4_keep.reload.name).to eq('topic4')
+
+    [topic_1_remove, topic_2_remove, topic_3_remove_1, topic_3_remove_2].each do |topic|
+      expect { topic.reload }.to raise_error(ActiveRecord::RecordNotFound)
+    end
+
+    # Topic avatars
+    expect(topic_1_keep.avatar).to eq('avatar1.png')
+    expect(File.exist?(::Projects::Topic.find(topic_1_keep.id).avatar.absolute_path)).to be_truthy
+    expect(topic_2_keep.avatar).to eq('avatar3.png')
+    expect(File.exist?(::Projects::Topic.find(topic_2_keep.id).avatar.absolute_path)).to be_truthy
+    expect(topic_3_keep.avatar).to eq('avatar4.png')
+    expect(File.exist?(::Projects::Topic.find(topic_3_keep.id).avatar.absolute_path)).to be_truthy
+
+    [:topic_1_remove, :topic_2_remove, :topic_3_remove_1, :topic_3_remove_2].each do |topic|
+      expect(File.exist?(avatar_paths[topic])).to be_falsey
+    end
+
+    # Project Topic assignments
+    project_topics_1.each do |project_topic|
+      expect(project_topic.reload.topic_id).to eq(topic_1_keep.id)
+    end
+
+    project_topics_3.each do |project_topic|
+      expect(project_topic.reload.topic_id).to eq(topic_3_keep.id)
+    end
+
+    project_topics_removed.each do |project_topic|
+      expect { project_topic.reload }.to raise_error(ActiveRecord::RecordNotFound)
+    end
+  end
+end
diff --git a/spec/lib/gitlab/background_migration/migrate_personal_namespace_project_maintainer_to_owner_spec.rb b/spec/lib/gitlab/background_migration/migrate_personal_namespace_project_maintainer_to_owner_spec.rb
index 90d05ccbe1a05439ddad35d9c2b70c72817ca774..07e77bdbc13f5239dafa22ea4c1220d3299de26c 100644
--- a/spec/lib/gitlab/background_migration/migrate_personal_namespace_project_maintainer_to_owner_spec.rb
+++ b/spec/lib/gitlab/background_migration/migrate_personal_namespace_project_maintainer_to_owner_spec.rb
@@ -2,7 +2,7 @@
 
 require 'spec_helper'
 
-RSpec.describe Gitlab::BackgroundMigration::MigratePersonalNamespaceProjectMaintainerToOwner, :migration, schema: 20220314184009 do
+RSpec.describe Gitlab::BackgroundMigration::MigratePersonalNamespaceProjectMaintainerToOwner, :migration, schema: 20220208080921 do
   let(:migration) { described_class.new }
   let(:users_table) { table(:users) }
   let(:members_table) { table(:members) }
diff --git a/spec/lib/gitlab/background_migration/nullify_orphan_runner_id_on_ci_builds_spec.rb b/spec/lib/gitlab/background_migration/nullify_orphan_runner_id_on_ci_builds_spec.rb
index 7c78350e69713f974db1f76acb71fa3241dafe13..2f0eef3c3994d9f86800f15ecf95b16d4bcb8e0e 100644
--- a/spec/lib/gitlab/background_migration/nullify_orphan_runner_id_on_ci_builds_spec.rb
+++ b/spec/lib/gitlab/background_migration/nullify_orphan_runner_id_on_ci_builds_spec.rb
@@ -3,7 +3,7 @@
 require 'spec_helper'
 
 RSpec.describe Gitlab::BackgroundMigration::NullifyOrphanRunnerIdOnCiBuilds,
-               :suppress_gitlab_schemas_validate_connection, migration: :gitlab_ci, schema: 20220314184009 do
+               :suppress_gitlab_schemas_validate_connection, migration: :gitlab_ci, schema: 20220223112304 do
   let(:namespaces) { table(:namespaces) }
   let(:projects) { table(:projects) }
   let(:ci_runners) { table(:ci_runners) }
diff --git a/spec/lib/gitlab/background_migration/populate_namespace_statistics_spec.rb b/spec/lib/gitlab/background_migration/populate_namespace_statistics_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4a7d52ee7848d42e9400a18d1c25c4b019bcb92a
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/populate_namespace_statistics_spec.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::PopulateNamespaceStatistics do
+  let!(:namespaces) { table(:namespaces) }
+  let!(:namespace_statistics) { table(:namespace_statistics) }
+  let!(:dependency_proxy_manifests) { table(:dependency_proxy_manifests) }
+  let!(:dependency_proxy_blobs) { table(:dependency_proxy_blobs) }
+
+  let!(:group1) { namespaces.create!(id: 10, type: 'Group', name: 'group1', path: 'group1') }
+  let!(:group2) { namespaces.create!(id: 20, type: 'Group', name: 'group2', path: 'group2') }
+
+  let!(:group1_manifest) do
+    dependency_proxy_manifests.create!(group_id: 10, size: 20, file_name: 'test-file', file: 'test', digest: 'abc123')
+  end
+
+  let!(:group2_manifest) do
+    dependency_proxy_manifests.create!(group_id: 20, size: 20, file_name: 'test-file', file: 'test', digest: 'abc123')
+  end
+
+  let!(:group1_stats) { namespace_statistics.create!(id: 10, namespace_id: 10) }
+
+  let(:ids) { namespaces.pluck(:id) }
+  let(:statistics) { [] }
+
+  subject(:perform) { described_class.new.perform(ids, statistics) }
+
+  it 'creates/updates all namespace_statistics and updates root storage statistics', :aggregate_failures do
+    expect(Namespaces::ScheduleAggregationWorker).to receive(:perform_async).with(group1.id)
+    expect(Namespaces::ScheduleAggregationWorker).to receive(:perform_async).with(group2.id)
+
+    expect { perform }.to change(namespace_statistics, :count).from(1).to(2)
+
+    namespace_statistics.all.each do |stat|
+      expect(stat.dependency_proxy_size).to eq 20
+      expect(stat.storage_size).to eq 20
+    end
+  end
+
+  context 'when just a stat is passed' do
+    let(:statistics) { [:dependency_proxy_size] }
+
+    it 'calls the statistics update service with just that stat' do
+      expect(Groups::UpdateStatisticsService)
+        .to receive(:new)
+        .with(anything, statistics: [:dependency_proxy_size])
+        .twice.and_call_original
+
+      perform
+    end
+  end
+
+  context 'when a statistics update fails' do
+    before do
+      error_response = instance_double(ServiceResponse, message: 'an error', error?: true)
+
+      allow_next_instance_of(Groups::UpdateStatisticsService) do |instance|
+        allow(instance).to receive(:execute).and_return(error_response)
+      end
+    end
+
+    it 'logs an error' do
+      expect_next_instance_of(Gitlab::BackgroundMigration::Logger) do |instance|
+        expect(instance).to receive(:error).twice
+      end
+
+      perform
+    end
+  end
+end
diff --git a/spec/lib/gitlab/background_migration/populate_topics_non_private_projects_count_spec.rb b/spec/lib/gitlab/background_migration/populate_topics_non_private_projects_count_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e72e3392210c8ae9a0bf373efe1f126ad3bcfc21
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/populate_topics_non_private_projects_count_spec.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::PopulateTopicsNonPrivateProjectsCount, schema: 20220125122640 do
+  it 'correctly populates the non private projects counters' do
+    namespaces = table(:namespaces)
+    projects = table(:projects)
+    topics = table(:topics)
+    project_topics = table(:project_topics)
+
+    group = namespaces.create!(name: 'group', path: 'group')
+    project_public = projects.create!(namespace_id: group.id, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+    project_internal = projects.create!(namespace_id: group.id, visibility_level: Gitlab::VisibilityLevel::INTERNAL)
+    project_private = projects.create!(namespace_id: group.id, visibility_level: Gitlab::VisibilityLevel::PRIVATE)
+    topic_1 = topics.create!(name: 'Topic1')
+    topic_2 = topics.create!(name: 'Topic2')
+    topic_3 = topics.create!(name: 'Topic3')
+    topic_4 = topics.create!(name: 'Topic4')
+    topic_5 = topics.create!(name: 'Topic5')
+    topic_6 = topics.create!(name: 'Topic6')
+    topic_7 = topics.create!(name: 'Topic7')
+    topic_8 = topics.create!(name: 'Topic8')
+
+    project_topics.create!(topic_id: topic_1.id, project_id: project_public.id)
+    project_topics.create!(topic_id: topic_2.id, project_id: project_internal.id)
+    project_topics.create!(topic_id: topic_3.id, project_id: project_private.id)
+    project_topics.create!(topic_id: topic_4.id, project_id: project_public.id)
+    project_topics.create!(topic_id: topic_4.id, project_id: project_internal.id)
+    project_topics.create!(topic_id: topic_5.id, project_id: project_public.id)
+    project_topics.create!(topic_id: topic_5.id, project_id: project_private.id)
+    project_topics.create!(topic_id: topic_6.id, project_id: project_internal.id)
+    project_topics.create!(topic_id: topic_6.id, project_id: project_private.id)
+    project_topics.create!(topic_id: topic_7.id, project_id: project_public.id)
+    project_topics.create!(topic_id: topic_7.id, project_id: project_internal.id)
+    project_topics.create!(topic_id: topic_7.id, project_id: project_private.id)
+    project_topics.create!(topic_id: topic_8.id, project_id: project_public.id)
+
+    subject.perform(topic_1.id, topic_7.id)
+
+    expect(topic_1.reload.non_private_projects_count).to eq(1)
+    expect(topic_2.reload.non_private_projects_count).to eq(1)
+    expect(topic_3.reload.non_private_projects_count).to eq(0)
+    expect(topic_4.reload.non_private_projects_count).to eq(2)
+    expect(topic_5.reload.non_private_projects_count).to eq(1)
+    expect(topic_6.reload.non_private_projects_count).to eq(1)
+    expect(topic_7.reload.non_private_projects_count).to eq(2)
+    expect(topic_8.reload.non_private_projects_count).to eq(0)
+  end
+end
diff --git a/spec/lib/gitlab/background_migration/populate_vulnerability_reads_spec.rb b/spec/lib/gitlab/background_migration/populate_vulnerability_reads_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c0470f26d9e3110c53752430548520b938152d8e
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/populate_vulnerability_reads_spec.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::PopulateVulnerabilityReads, :migration, schema: 20220326161803 do
+  let(:vulnerabilities) { table(:vulnerabilities) }
+  let(:vulnerability_reads) { table(:vulnerability_reads) }
+  let(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
+  let(:vulnerability_issue_links) { table(:vulnerability_issue_links) }
+  let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
+  let(:user) { table(:users).create!(email: 'author@example.com', username: 'author', projects_limit: 10) }
+  let(:project) { table(:projects).create!(namespace_id: namespace.id) }
+  let(:scanner) { table(:vulnerability_scanners).create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
+  let(:sub_batch_size) { 1000 }
+
+  before do
+    vulnerabilities_findings.connection.execute 'ALTER TABLE vulnerability_occurrences DISABLE TRIGGER "trigger_insert_or_update_vulnerability_reads_from_occurrences"'
+    vulnerabilities.connection.execute 'ALTER TABLE vulnerabilities DISABLE TRIGGER "trigger_update_vulnerability_reads_on_vulnerability_update"'
+    vulnerability_issue_links.connection.execute 'ALTER TABLE vulnerability_issue_links DISABLE TRIGGER "trigger_update_has_issues_on_vulnerability_issue_links_update"'
+
+    10.times.each do |x|
+      vulnerability = create_vulnerability!(
+        project_id: project.id,
+        report_type: 7,
+        author_id: user.id
+      )
+      identifier = table(:vulnerability_identifiers).create!(
+        project_id: project.id,
+        external_type: 'uuid-v5',
+        external_id: 'uuid-v5',
+        fingerprint: Digest::SHA1.hexdigest(vulnerability.id.to_s),
+        name: 'Identifier for UUIDv5')
+
+      create_finding!(
+        vulnerability_id: vulnerability.id,
+        project_id: project.id,
+        scanner_id: scanner.id,
+        primary_identifier_id: identifier.id
+      )
+    end
+  end
+
+  it 'creates vulnerability_reads for the given records' do
+    described_class.new.perform(vulnerabilities.first.id, vulnerabilities.last.id, sub_batch_size)
+
+    expect(vulnerability_reads.count).to eq(10)
+  end
+
+  it 'does not create new records when records already exists' do
+    described_class.new.perform(vulnerabilities.first.id, vulnerabilities.last.id, sub_batch_size)
+    described_class.new.perform(vulnerabilities.first.id, vulnerabilities.last.id, sub_batch_size)
+
+    expect(vulnerability_reads.count).to eq(10)
+  end
+
+  private
+
+  def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0)
+    vulnerabilities.create!(
+      project_id: project_id,
+      author_id: author_id,
+      title: title,
+      severity: severity,
+      confidence: confidence,
+      report_type: report_type
+    )
+  end
+
+  # rubocop:disable Metrics/ParameterLists
+  def create_finding!(
+    project_id:, scanner_id:, primary_identifier_id:, vulnerability_id: nil,
+    name: "test", severity: 7, confidence: 7, report_type: 0,
+    project_fingerprint: '123qweasdzxc', location: { "image" => "alpine:3.4" }, location_fingerprint: 'test',
+    metadata_version: 'test', raw_metadata: 'test', uuid: SecureRandom.uuid)
+    vulnerabilities_findings.create!(
+      vulnerability_id: vulnerability_id,
+      project_id: project_id,
+      name: name,
+      severity: severity,
+      confidence: confidence,
+      report_type: report_type,
+      project_fingerprint: project_fingerprint,
+      scanner_id: scanner_id,
+      primary_identifier_id: primary_identifier_id,
+      location: location,
+      location_fingerprint: location_fingerprint,
+      metadata_version: metadata_version,
+      raw_metadata: raw_metadata,
+      uuid: uuid
+    )
+  end
+  # rubocop:enable Metrics/ParameterLists
+end
diff --git a/spec/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid_spec.rb b/spec/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..543dd204f89a834d46640b3a2a599803a24c379b
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid_spec.rb
@@ -0,0 +1,530 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+def create_background_migration_job(ids, status)
+  proper_status = case status
+                  when :pending
+                    Gitlab::Database::BackgroundMigrationJob.statuses['pending']
+                  when :succeeded
+                    Gitlab::Database::BackgroundMigrationJob.statuses['succeeded']
+                  else
+                    raise ArgumentError
+                  end
+
+  background_migration_jobs.create!(
+    class_name: 'RecalculateVulnerabilitiesOccurrencesUuid',
+    arguments: Array(ids),
+    status: proper_status,
+    created_at: Time.now.utc
+  )
+end
+
+RSpec.describe Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrencesUuid, :suppress_gitlab_schemas_validate_connection, schema: 20211202041233 do
+  let(:background_migration_jobs) { table(:background_migration_jobs) }
+  let(:pending_jobs) { background_migration_jobs.where(status: Gitlab::Database::BackgroundMigrationJob.statuses['pending']) }
+  let(:succeeded_jobs) { background_migration_jobs.where(status: Gitlab::Database::BackgroundMigrationJob.statuses['succeeded']) }
+  let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
+  let(:users) { table(:users) }
+  let(:user) { create_user! }
+  let(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) }
+  let(:scanners) { table(:vulnerability_scanners) }
+  let(:scanner) { scanners.create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
+  let(:scanner2) { scanners.create!(project_id: project.id, external_id: 'test 2', name: 'test scanner 2') }
+  let(:vulnerabilities) { table(:vulnerabilities) }
+  let(:vulnerability_findings) { table(:vulnerability_occurrences) }
+  let(:vulnerability_finding_pipelines) { table(:vulnerability_occurrence_pipelines) }
+  let(:vulnerability_finding_signatures) { table(:vulnerability_finding_signatures) }
+  let(:vulnerability_identifiers) { table(:vulnerability_identifiers) }
+
+  let(:identifier_1) { 'identifier-1' }
+  let!(:vulnerability_identifier) do
+    vulnerability_identifiers.create!(
+      project_id: project.id,
+      external_type: identifier_1,
+      external_id: identifier_1,
+      fingerprint: Gitlab::Database::ShaAttribute.serialize('ff9ef548a6e30a0462795d916f3f00d1e2b082ca'),
+      name: 'Identifier 1')
+  end
+
+  let(:identifier_2) { 'identifier-2' }
+  let!(:vulnerability_identfier2) do
+    vulnerability_identifiers.create!(
+      project_id: project.id,
+      external_type: identifier_2,
+      external_id: identifier_2,
+      fingerprint: Gitlab::Database::ShaAttribute.serialize('4299e8ddd819f9bde9cfacf45716724c17b5ddf7'),
+      name: 'Identifier 2')
+  end
+
+  let(:identifier_3) { 'identifier-3' }
+  let!(:vulnerability_identifier3) do
+    vulnerability_identifiers.create!(
+      project_id: project.id,
+      external_type: identifier_3,
+      external_id: identifier_3,
+      fingerprint: Gitlab::Database::ShaAttribute.serialize('8e91632f9c6671e951834a723ee221c44cc0d844'),
+      name: 'Identifier 3')
+  end
+
+  let(:known_uuid_v4) { "b3cc2518-5446-4dea-871c-89d5e999c1ac" }
+  let(:known_uuid_v5) { "05377088-dc26-5161-920e-52a7159fdaa1" }
+  let(:desired_uuid_v5) { "f3e9a23f-9181-54bf-a5ab-c5bc7a9b881a" }
+
+  subject { described_class.new.perform(start_id, end_id) }
+
+  context "when finding has a UUIDv4" do
+    before do
+      @uuid_v4 = create_finding!(
+        vulnerability_id: nil,
+        project_id: project.id,
+        scanner_id: scanner2.id,
+        primary_identifier_id: vulnerability_identfier2.id,
+        report_type: 0, # "sast"
+        location_fingerprint: Gitlab::Database::ShaAttribute.serialize("fa18f432f1d56675f4098d318739c3cd5b14eb3e"),
+        uuid: known_uuid_v4
+      )
+    end
+
+    let(:start_id) { @uuid_v4.id }
+    let(:end_id) { @uuid_v4.id }
+
+    it "replaces it with UUIDv5" do
+      expect(vulnerability_findings.pluck(:uuid)).to match_array([known_uuid_v4])
+
+      subject
+
+      expect(vulnerability_findings.pluck(:uuid)).to match_array([desired_uuid_v5])
+    end
+
+    it 'logs recalculation' do
+      expect_next_instance_of(Gitlab::BackgroundMigration::Logger) do |instance|
+        expect(instance).to receive(:info).twice
+      end
+
+      subject
+    end
+  end
+
+  context "when finding has a UUIDv5" do
+    before do
+      @uuid_v5 = create_finding!(
+        vulnerability_id: nil,
+        project_id: project.id,
+        scanner_id: scanner.id,
+        primary_identifier_id: vulnerability_identifier.id,
+        report_type: 0, # "sast"
+        location_fingerprint: Gitlab::Database::ShaAttribute.serialize("838574be0210968bf6b9f569df9c2576242cbf0a"),
+        uuid: known_uuid_v5
+      )
+    end
+
+    let(:start_id) { @uuid_v5.id }
+    let(:end_id) { @uuid_v5.id }
+
+    it "stays the same" do
+      expect(vulnerability_findings.pluck(:uuid)).to match_array([known_uuid_v5])
+
+      subject
+
+      expect(vulnerability_findings.pluck(:uuid)).to match_array([known_uuid_v5])
+    end
+  end
+
+  context 'if a duplicate UUID would be generated' do # rubocop: disable RSpec/MultipleMemoizedHelpers
+    let(:v1) do
+      create_vulnerability!(
+        project_id: project.id,
+        author_id: user.id
+      )
+    end
+
+    let!(:finding_with_incorrect_uuid) do
+      create_finding!(
+        vulnerability_id: v1.id,
+        project_id: project.id,
+        scanner_id: scanner.id,
+        primary_identifier_id: vulnerability_identifier.id,
+        report_type: 0, # "sast"
+        location_fingerprint: Gitlab::Database::ShaAttribute.serialize('ca41a2544e941a007a73a666cb0592b255316ab8'), # sha1('youshouldntusethis')
+        uuid: 'bd95c085-71aa-51d7-9bb6-08ae669c262e'
+      )
+    end
+
+    let(:v2) do
+      create_vulnerability!(
+        project_id: project.id,
+        author_id: user.id
+      )
+    end
+
+    let!(:finding_with_correct_uuid) do
+      create_finding!(
+        vulnerability_id: v2.id,
+        project_id: project.id,
+        primary_identifier_id: vulnerability_identifier.id,
+        scanner_id: scanner2.id,
+        report_type: 0, # "sast"
+        location_fingerprint: Gitlab::Database::ShaAttribute.serialize('ca41a2544e941a007a73a666cb0592b255316ab8'), # sha1('youshouldntusethis')
+        uuid: '91984483-5efe-5215-b471-d524ac5792b1'
+      )
+    end
+
+    let(:v3) do
+      create_vulnerability!(
+        project_id: project.id,
+        author_id: user.id
+      )
+    end
+
+    let!(:finding_with_incorrect_uuid2) do
+      create_finding!(
+        vulnerability_id: v3.id,
+        project_id: project.id,
+        scanner_id: scanner.id,
+        primary_identifier_id: vulnerability_identfier2.id,
+        report_type: 0, # "sast"
+        location_fingerprint: Gitlab::Database::ShaAttribute.serialize('ca41a2544e941a007a73a666cb0592b255316ab8'), # sha1('youshouldntusethis')
+        uuid: '00000000-1111-2222-3333-444444444444'
+      )
+    end
+
+    let(:v4) do
+      create_vulnerability!(
+        project_id: project.id,
+        author_id: user.id
+      )
+    end
+
+    let!(:finding_with_correct_uuid2) do
+      create_finding!(
+        vulnerability_id: v4.id,
+        project_id: project.id,
+        scanner_id: scanner2.id,
+        primary_identifier_id: vulnerability_identfier2.id,
+        report_type: 0, # "sast"
+        location_fingerprint: Gitlab::Database::ShaAttribute.serialize('ca41a2544e941a007a73a666cb0592b255316ab8'), # sha1('youshouldntusethis')
+        uuid: '1edd751e-ef9a-5391-94db-a832c8635bfc'
+      )
+    end
+
+    let!(:finding_with_incorrect_uuid3) do
+      create_finding!(
+        vulnerability_id: nil,
+        project_id: project.id,
+        scanner_id: scanner.id,
+        primary_identifier_id: vulnerability_identifier3.id,
+        report_type: 0, # "sast"
+        location_fingerprint: Gitlab::Database::ShaAttribute.serialize('ca41a2544e941a007a73a666cb0592b255316ab8'), # sha1('youshouldntusethis')
+        uuid: '22222222-3333-4444-5555-666666666666'
+      )
+    end
+
+    let!(:duplicate_not_in_the_same_batch) do
+      create_finding!(
+        id: 99999,
+        vulnerability_id: nil,
+        project_id: project.id,
+        scanner_id: scanner2.id,
+        primary_identifier_id: vulnerability_identifier3.id,
+        report_type: 0, # "sast"
+        location_fingerprint: Gitlab::Database::ShaAttribute.serialize('ca41a2544e941a007a73a666cb0592b255316ab8'), # sha1('youshouldntusethis')
+        uuid: '4564f9d5-3c6b-5cc3-af8c-7c25285362a7'
+      )
+    end
+
+    let(:start_id) { finding_with_incorrect_uuid.id }
+    let(:end_id) { finding_with_incorrect_uuid3.id }
+
+    before do
+      4.times do
+        create_finding_pipeline!(project_id: project.id, finding_id: finding_with_incorrect_uuid.id)
+        create_finding_pipeline!(project_id: project.id, finding_id: finding_with_correct_uuid.id)
+        create_finding_pipeline!(project_id: project.id, finding_id: finding_with_incorrect_uuid2.id)
+        create_finding_pipeline!(project_id: project.id, finding_id: finding_with_correct_uuid2.id)
+      end
+    end
+
+    it 'drops duplicates and related records', :aggregate_failures do
+      expect(vulnerability_findings.pluck(:id)).to match_array(
+        [
+          finding_with_correct_uuid.id,
+          finding_with_incorrect_uuid.id,
+          finding_with_correct_uuid2.id,
+          finding_with_incorrect_uuid2.id,
+          finding_with_incorrect_uuid3.id,
+          duplicate_not_in_the_same_batch.id
+        ])
+
+      expect { subject }.to change(vulnerability_finding_pipelines, :count).from(16).to(8)
+        .and change(vulnerability_findings, :count).from(6).to(3)
+        .and change(vulnerabilities, :count).from(4).to(2)
+
+      expect(vulnerability_findings.pluck(:id)).to match_array([finding_with_incorrect_uuid.id, finding_with_incorrect_uuid2.id, finding_with_incorrect_uuid3.id])
+    end
+
+    context 'if there are conflicting UUID values within the batch' do # rubocop: disable RSpec/MultipleMemoizedHelpers
+      let(:end_id) { finding_with_broken_data_integrity.id }
+      let(:vulnerability_5) { create_vulnerability!(project_id: project.id, author_id: user.id) }
+      let(:different_project) { table(:projects).create!(namespace_id: namespace.id) }
+      let!(:identifier_with_broken_data_integrity) do
+        vulnerability_identifiers.create!(
+          project_id: different_project.id,
+          external_type: identifier_2,
+          external_id: identifier_2,
+          fingerprint: Gitlab::Database::ShaAttribute.serialize('4299e8ddd819f9bde9cfacf45716724c17b5ddf7'),
+          name: 'Identifier 2')
+      end
+
+      let(:finding_with_broken_data_integrity) do
+        create_finding!(
+          vulnerability_id: vulnerability_5,
+          project_id: project.id,
+          scanner_id: scanner.id,
+          primary_identifier_id: identifier_with_broken_data_integrity.id,
+          report_type: 0, # "sast"
+          location_fingerprint: Gitlab::Database::ShaAttribute.serialize('ca41a2544e941a007a73a666cb0592b255316ab8'), # sha1('youshouldntusethis')
+          uuid: SecureRandom.uuid
+        )
+      end
+
+      it 'deletes the conflicting record' do
+        expect { subject }.to change { vulnerability_findings.find_by_id(finding_with_broken_data_integrity.id) }.to(nil)
+      end
+    end
+
+    context 'if a conflicting UUID is found during the migration' do # rubocop:disable RSpec/MultipleMemoizedHelpers
+      let(:finding_class) { Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrencesUuid::VulnerabilitiesFinding }
+      let(:uuid) { '4564f9d5-3c6b-5cc3-af8c-7c25285362a7' }
+
+      before do
+        exception = ActiveRecord::RecordNotUnique.new("(uuid)=(#{uuid})")
+
+        call_count = 0
+        allow(::Gitlab::Database::BulkUpdate).to receive(:execute) do
+          call_count += 1
+          call_count.eql?(1) ? raise(exception) : {}
+        end
+
+        allow(finding_class).to receive(:find_by).with(uuid: uuid).and_return(duplicate_not_in_the_same_batch)
+      end
+
+      it 'retries the recalculation' do
+        subject
+
+        expect(Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrencesUuid::VulnerabilitiesFinding)
+          .to have_received(:find_by).with(uuid: uuid).once
+      end
+
+      it 'logs the conflict' do
+        expect_next_instance_of(Gitlab::BackgroundMigration::Logger) do |instance|
+          expect(instance).to receive(:info).exactly(6).times
+        end
+
+        subject
+      end
+
+      it 'marks the job as done' do
+        create_background_migration_job([start_id, end_id], :pending)
+
+        subject
+
+        expect(pending_jobs.count).to eq(0)
+        expect(succeeded_jobs.count).to eq(1)
+      end
+    end
+
+    it 'logs an exception if a different uniquness problem was found' do
+      exception = ActiveRecord::RecordNotUnique.new("Totally not an UUID uniqueness problem")
+      allow(::Gitlab::Database::BulkUpdate).to receive(:execute).and_raise(exception)
+      allow(Gitlab::ErrorTracking).to receive(:track_and_raise_exception)
+
+      subject
+
+      expect(Gitlab::ErrorTracking).to have_received(:track_and_raise_exception).with(exception).once
+    end
+
+    it 'logs a duplicate found message' do
+      expect_next_instance_of(Gitlab::BackgroundMigration::Logger) do |instance|
+        expect(instance).to receive(:info).exactly(3).times
+      end
+
+      subject
+    end
+  end
+
+  context 'when finding has a signature' do
+    before do
+      @f1 = create_finding!(
+        vulnerability_id: nil,
+        project_id: project.id,
+        scanner_id: scanner.id,
+        primary_identifier_id: vulnerability_identifier.id,
+        report_type: 0, # "sast"
+        location_fingerprint: Gitlab::Database::ShaAttribute.serialize('ca41a2544e941a007a73a666cb0592b255316ab8'), # sha1('youshouldntusethis')
+        uuid: 'd15d774d-e4b1-5a1b-929b-19f2a53e35ec'
+      )
+
+      vulnerability_finding_signatures.create!(
+        finding_id: @f1.id,
+        algorithm_type: 2, # location
+        signature_sha: Gitlab::Database::ShaAttribute.serialize('57d4e05205f6462a73f039a5b2751aa1ab344e6e') # sha1('youshouldusethis')
+      )
+
+      vulnerability_finding_signatures.create!(
+        finding_id: @f1.id,
+        algorithm_type: 1, # hash
+        signature_sha: Gitlab::Database::ShaAttribute.serialize('c554d8d8df1a7a14319eafdaae24af421bf5b587') # sha1('andnotthis')
+      )
+
+      @f2 = create_finding!(
+        vulnerability_id: nil,
+        project_id: project.id,
+        scanner_id: scanner.id,
+        primary_identifier_id: vulnerability_identfier2.id,
+        report_type: 0, # "sast"
+        location_fingerprint: Gitlab::Database::ShaAttribute.serialize('ca41a2544e941a007a73a666cb0592b255316ab8'), # sha1('youshouldntusethis')
+        uuid: '4be029b5-75e5-5ac0-81a2-50ab41726135'
+      )
+
+      vulnerability_finding_signatures.create!(
+        finding_id: @f2.id,
+        algorithm_type: 2, # location
+        signature_sha: Gitlab::Database::ShaAttribute.serialize('57d4e05205f6462a73f039a5b2751aa1ab344e6e') # sha1('youshouldusethis')
+      )
+
+      vulnerability_finding_signatures.create!(
+        finding_id: @f2.id,
+        algorithm_type: 1, # hash
+        signature_sha: Gitlab::Database::ShaAttribute.serialize('c554d8d8df1a7a14319eafdaae24af421bf5b587') # sha1('andnotthis')
+      )
+    end
+
+    let(:start_id) { @f1.id }
+    let(:end_id) { @f2.id }
+
+    let(:uuids_before) { [@f1.uuid, @f2.uuid] }
+    let(:uuids_after) { %w[d3b60ddd-d312-5606-b4d3-ad058eebeacb 349d9bec-c677-5530-a8ac-5e58889c3b1a] }
+
+    it 'is recalculated using signature' do
+      expect(vulnerability_findings.pluck(:uuid)).to match_array(uuids_before)
+
+      subject
+
+      expect(vulnerability_findings.pluck(:uuid)).to match_array(uuids_after)
+    end
+  end
+
+  context 'if all records are removed before the job ran' do
+    let(:start_id) { 1 }
+    let(:end_id) { 9 }
+
+    before do
+      create_background_migration_job([start_id, end_id], :pending)
+    end
+
+    it 'does not error out' do
+      expect { subject }.not_to raise_error
+    end
+
+    it 'marks the job as done' do
+      subject
+
+      expect(pending_jobs.count).to eq(0)
+      expect(succeeded_jobs.count).to eq(1)
+    end
+  end
+
+  context 'when recalculation fails' do
+    before do
+      @uuid_v4 = create_finding!(
+        vulnerability_id: nil,
+        project_id: project.id,
+        scanner_id: scanner2.id,
+        primary_identifier_id: vulnerability_identfier2.id,
+        report_type: 0, # "sast"
+        location_fingerprint: Gitlab::Database::ShaAttribute.serialize("fa18f432f1d56675f4098d318739c3cd5b14eb3e"),
+        uuid: known_uuid_v4
+      )
+
+      allow(Gitlab::ErrorTracking).to receive(:track_and_raise_exception)
+      allow(::Gitlab::Database::BulkUpdate).to receive(:execute).and_raise(expected_error)
+    end
+
+    let(:start_id) { @uuid_v4.id }
+    let(:end_id) { @uuid_v4.id }
+    let(:expected_error) { RuntimeError.new }
+
+    it 'captures the errors and does not crash entirely' do
+      expect { subject }.not_to raise_error
+
+      allow(Gitlab::ErrorTracking).to receive(:track_and_raise_exception)
+      expect(Gitlab::ErrorTracking).to have_received(:track_and_raise_exception).with(expected_error).once
+    end
+
+    it_behaves_like 'marks background migration job records' do
+      let(:arguments) { [1, 4] }
+      subject { described_class.new }
+    end
+  end
+
+  it_behaves_like 'marks background migration job records' do
+    let(:arguments) { [1, 4] }
+    subject { described_class.new }
+  end
+
+  private
+
+  def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0)
+    vulnerabilities.create!(
+      project_id: project_id,
+      author_id: author_id,
+      title: title,
+      severity: severity,
+      confidence: confidence,
+      report_type: report_type
+    )
+  end
+
+  # rubocop:disable Metrics/ParameterLists
+  def create_finding!(
+    vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:, id: nil,
+                      name: "test", severity: 7, confidence: 7, report_type: 0,
+                      project_fingerprint: '123qweasdzxc', location_fingerprint: 'test',
+                      metadata_version: 'test', raw_metadata: 'test', uuid: SecureRandom.uuid)
+    vulnerability_findings.create!({
+        id: id,
+        vulnerability_id: vulnerability_id,
+        project_id: project_id,
+        name: name,
+        severity: severity,
+        confidence: confidence,
+        report_type: report_type,
+        project_fingerprint: project_fingerprint,
+        scanner_id: scanner_id,
+        primary_identifier_id: primary_identifier_id,
+        location_fingerprint: location_fingerprint,
+        metadata_version: metadata_version,
+        raw_metadata: raw_metadata,
+        uuid: uuid
+      }.compact
+                                  )
+  end
+  # rubocop:enable Metrics/ParameterLists
+
+  def create_user!(name: "Example User", email: "user@example.com", user_type: nil, created_at: Time.zone.now, confirmed_at: Time.zone.now)
+    users.create!(
+      name: name,
+      email: email,
+      username: name,
+      projects_limit: 0,
+      user_type: user_type,
+      confirmed_at: confirmed_at
+    )
+  end
+
+  def create_finding_pipeline!(project_id:, finding_id:)
+    pipeline = table(:ci_pipelines).create!(project_id: project_id)
+    vulnerability_finding_pipelines.create!(pipeline_id: pipeline.id, occurrence_id: finding_id)
+  end
+end
diff --git a/spec/lib/gitlab/background_migration/remove_all_trace_expiration_dates_spec.rb b/spec/lib/gitlab/background_migration/remove_all_trace_expiration_dates_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..eabc012f98bd3eb5fa246bb229c25ba73ba02e2b
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/remove_all_trace_expiration_dates_spec.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::RemoveAllTraceExpirationDates, :migration,
+               :suppress_gitlab_schemas_validate_connection, schema: 20220131000001 do
+  subject(:perform) { migration.perform(1, 99) }
+
+  let(:migration) { described_class.new }
+
+  let(:trace_in_range)         { create_trace!(id: 10,   created_at: Date.new(2020, 06, 20), expire_at: Date.new(2021, 01, 22)) }
+  let(:trace_outside_range)    { create_trace!(id: 40,   created_at: Date.new(2020, 06, 22), expire_at: Date.new(2021, 01, 22)) }
+  let(:trace_without_expiry)   { create_trace!(id: 30,   created_at: Date.new(2020, 06, 21), expire_at: nil) }
+  let(:archive_in_range)       { create_archive!(id: 10, created_at: Date.new(2020, 06, 20), expire_at: Date.new(2021, 01, 22)) }
+  let(:trace_outside_id_range) { create_trace!(id: 100,  created_at: Date.new(2020, 06, 20), expire_at: Date.new(2021, 01, 22)) }
+
+  before do
+    table(:namespaces).create!(id: 1, name: 'the-namespace', path: 'the-path')
+    table(:projects).create!(id: 1, name: 'the-project', namespace_id: 1)
+    table(:ci_builds).create!(id: 1, allow_failure: false)
+  end
+
+  context 'for self-hosted instances' do
+    it 'sets expire_at for artifacts in range to nil' do
+      expect { perform }.not_to change { trace_in_range.reload.expire_at }
+    end
+
+    it 'does not change expire_at timestamps that are not set to midnight' do
+      expect { perform }.not_to change { trace_outside_range.reload.expire_at }
+    end
+
+    it 'does not change expire_at timestamps that are set to midnight on a day other than the 22nd' do
+      expect { perform }.not_to change { trace_without_expiry.reload.expire_at }
+    end
+
+    it 'does not touch artifacts outside id range' do
+      expect { perform }.not_to change { archive_in_range.reload.expire_at }
+    end
+
+    it 'does not touch artifacts outside date range' do
+      expect { perform }.not_to change { trace_outside_id_range.reload.expire_at }
+    end
+  end
+
+  private
+
+  def create_trace!(**args)
+    table(:ci_job_artifacts).create!(**args, project_id: 1, job_id: 1, file_type: 3)
+  end
+
+  def create_archive!(**args)
+    table(:ci_job_artifacts).create!(**args, project_id: 1, job_id: 1, file_type: 1)
+  end
+end
diff --git a/spec/lib/gitlab/background_migration/remove_vulnerability_finding_links_spec.rb b/spec/lib/gitlab/background_migration/remove_vulnerability_finding_links_spec.rb
index da14381aae25e4f1dffce5922cb167dedd0103db..32134b99e37c33083a82ba1994e8ac4a13757d0d 100644
--- a/spec/lib/gitlab/background_migration/remove_vulnerability_finding_links_spec.rb
+++ b/spec/lib/gitlab/background_migration/remove_vulnerability_finding_links_spec.rb
@@ -2,7 +2,7 @@
 
 require 'spec_helper'
 
-RSpec.describe Gitlab::BackgroundMigration::RemoveVulnerabilityFindingLinks, :migration, schema: 20220314184009 do
+RSpec.describe Gitlab::BackgroundMigration::RemoveVulnerabilityFindingLinks, :migration, schema: 20211202041233 do
   let(:vulnerability_findings) { table(:vulnerability_occurrences) }
   let(:finding_links) { table(:vulnerability_finding_links) }
 
diff --git a/spec/lib/gitlab/background_migration/update_timelogs_null_spent_at_spec.rb b/spec/lib/gitlab/background_migration/update_timelogs_null_spent_at_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..908f11aabc3d5f0f88fe39373e903a13e039a621
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/update_timelogs_null_spent_at_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::UpdateTimelogsNullSpentAt, schema: 20211215090620 do
+  let!(:previous_time) { 10.days.ago }
+  let!(:namespace) { table(:namespaces).create!(name: 'namespace', path: 'namespace') }
+  let!(:project) { table(:projects).create!(namespace_id: namespace.id) }
+  let!(:issue) { table(:issues).create!(project_id: project.id) }
+  let!(:merge_request) { table(:merge_requests).create!(target_project_id: project.id, source_branch: 'master', target_branch: 'feature') }
+  let!(:timelog1) { create_timelog!(issue_id: issue.id) }
+  let!(:timelog2) { create_timelog!(merge_request_id: merge_request.id) }
+  let!(:timelog3) { create_timelog!(issue_id: issue.id, spent_at: previous_time) }
+  let!(:timelog4) { create_timelog!(merge_request_id: merge_request.id, spent_at: previous_time) }
+
+  subject(:background_migration) { described_class.new }
+
+  before do
+    table(:timelogs).where.not(id: [timelog3.id, timelog4.id]).update_all(spent_at: nil)
+  end
+
+  describe '#perform' do
+    it 'sets correct spent_at' do
+      background_migration.perform(timelog1.id, timelog4.id)
+
+      expect(timelog1.reload.spent_at).to be_like_time(timelog1.created_at)
+      expect(timelog2.reload.spent_at).to be_like_time(timelog2.created_at)
+      expect(timelog3.reload.spent_at).to be_like_time(previous_time)
+      expect(timelog4.reload.spent_at).to be_like_time(previous_time)
+      expect(timelog3.reload.spent_at).not_to be_like_time(timelog3.created_at)
+      expect(timelog4.reload.spent_at).not_to be_like_time(timelog4.created_at)
+    end
+  end
+
+  private
+
+  def create_timelog!(**args)
+    table(:timelogs).create!(**args, time_spent: 1)
+  end
+end
diff --git a/spec/migrations/20211203091642_add_index_to_projects_on_marked_for_deletion_at_spec.rb b/spec/migrations/20211203091642_add_index_to_projects_on_marked_for_deletion_at_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7be54bc13cc40a2a1cef01af92406cf78064f555
--- /dev/null
+++ b/spec/migrations/20211203091642_add_index_to_projects_on_marked_for_deletion_at_spec.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe AddIndexToProjectsOnMarkedForDeletionAt, feature_category: :projects do
+  it 'correctly migrates up and down' do
+    reversible_migration do |migration|
+      migration.before -> {
+        expect(ActiveRecord::Base.connection.indexes('projects').map(&:name)).not_to include('index_projects_not_aimed_for_deletion')
+      }
+
+      migration.after -> {
+        expect(ActiveRecord::Base.connection.indexes('projects').map(&:name)).to include('index_projects_not_aimed_for_deletion')
+      }
+    end
+  end
+end
diff --git a/spec/migrations/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb b/spec/migrations/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9fa2ac2313afa5a9ceea0be9d8690e761ef90a03
--- /dev/null
+++ b/spec/migrations/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+require 'spec_helper'
+require_migration!
+
+def create_background_migration_jobs(ids, status, created_at)
+  proper_status = case status
+                  when :pending
+                    Gitlab::Database::BackgroundMigrationJob.statuses['pending']
+                  when :succeeded
+                    Gitlab::Database::BackgroundMigrationJob.statuses['succeeded']
+                  else
+                    raise ArgumentError
+                  end
+
+  background_migration_jobs.create!(
+    class_name: 'RecalculateVulnerabilitiesOccurrencesUuid',
+    arguments: Array(ids),
+    status: proper_status,
+    created_at: created_at
+  )
+end
+
+RSpec.describe RemoveJobsForRecalculateVulnerabilitiesOccurrencesUuid, :migration,
+  feature_category: :vulnerability_management do
+  let!(:background_migration_jobs) { table(:background_migration_jobs) }
+
+  context 'when RecalculateVulnerabilitiesOccurrencesUuid jobs are present' do
+    before do
+      create_background_migration_jobs([1, 2, 3], :succeeded, DateTime.new(2021, 5, 5, 0, 2))
+      create_background_migration_jobs([4, 5, 6], :pending, DateTime.new(2021, 5, 5, 0, 4))
+
+      create_background_migration_jobs([1, 2, 3], :succeeded, DateTime.new(2021, 8, 18, 0, 0))
+      create_background_migration_jobs([4, 5, 6], :pending, DateTime.new(2021, 8, 18, 0, 2))
+      create_background_migration_jobs([7, 8, 9], :pending, DateTime.new(2021, 8, 18, 0, 4))
+    end
+
+    it 'removes all jobs' do
+      expect(background_migration_jobs.count).to eq(5)
+
+      migrate!
+
+      expect(background_migration_jobs.count).to eq(0)
+    end
+  end
+end
diff --git a/spec/migrations/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4_spec.rb b/spec/migrations/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c7401c4790d15e69720f7666c244bea18164374d
--- /dev/null
+++ b/spec/migrations/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4_spec.rb
@@ -0,0 +1,148 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe ScheduleRecalculateUuidOnVulnerabilitiesOccurrences4, feature_category: :vulnerability_management do
+  let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
+  let(:users) { table(:users) }
+  let(:user) { create_user! }
+  let(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) }
+  let(:scanners) { table(:vulnerability_scanners) }
+  let(:scanner) { scanners.create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
+  let(:different_scanner) { scanners.create!(project_id: project.id, external_id: 'test 2', name: 'test scanner 2') }
+  let(:vulnerabilities) { table(:vulnerabilities) }
+  let(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
+  let(:vulnerability_finding_signatures) { table(:vulnerability_finding_signatures) }
+  let(:vulnerability_identifiers) { table(:vulnerability_identifiers) }
+  let(:vulnerability_identifier) do
+    vulnerability_identifiers.create!(
+      project_id: project.id,
+      external_type: 'uuid-v5',
+      external_id: 'uuid-v5',
+      fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a',
+      name: 'Identifier for UUIDv5')
+  end
+
+  let(:different_vulnerability_identifier) do
+    vulnerability_identifiers.create!(
+      project_id: project.id,
+      external_type: 'uuid-v4',
+      external_id: 'uuid-v4',
+      fingerprint: '772da93d34a1ba010bcb5efa9fb6f8e01bafcc89',
+      name: 'Identifier for UUIDv4')
+  end
+
+  let!(:uuidv4_finding) do
+    create_finding!(
+      vulnerability_id: vulnerability_for_uuidv4.id,
+      project_id: project.id,
+      scanner_id: different_scanner.id,
+      primary_identifier_id: different_vulnerability_identifier.id,
+      location_fingerprint: Gitlab::Database::ShaAttribute.serialize('fa18f432f1d56675f4098d318739c3cd5b14eb3e'),
+      uuid: 'b3cc2518-5446-4dea-871c-89d5e999c1ac'
+    )
+  end
+
+  let(:vulnerability_for_uuidv4) do
+    create_vulnerability!(
+      project_id: project.id,
+      author_id: user.id
+    )
+  end
+
+  let!(:uuidv5_finding) do
+    create_finding!(
+      vulnerability_id: vulnerability_for_uuidv5.id,
+      project_id: project.id,
+      scanner_id: scanner.id,
+      primary_identifier_id: vulnerability_identifier.id,
+      location_fingerprint: Gitlab::Database::ShaAttribute.serialize('838574be0210968bf6b9f569df9c2576242cbf0a'),
+      uuid: '77211ed6-7dff-5f6b-8c9a-da89ad0a9b60'
+    )
+  end
+
+  let(:vulnerability_for_uuidv5) do
+    create_vulnerability!(
+      project_id: project.id,
+      author_id: user.id
+    )
+  end
+
+  let(:vulnerability_for_finding_with_signature) do
+    create_vulnerability!(
+      project_id: project.id,
+      author_id: user.id
+    )
+  end
+
+  let!(:finding_with_signature) do
+    create_finding!(
+      vulnerability_id: vulnerability_for_finding_with_signature.id,
+      project_id: project.id,
+      scanner_id: scanner.id,
+      primary_identifier_id: vulnerability_identifier.id,
+      report_type: 0, # "sast"
+      location_fingerprint: Gitlab::Database::ShaAttribute.serialize('123609eafffffa2207a9ca2425ba4337h34fga1b'),
+      uuid: '252aa474-d689-5d2b-ab42-7bbb5a100c02'
+    )
+  end
+
+  before do
+    stub_const("#{described_class}::BATCH_SIZE", 1)
+  end
+
+  around do |example|
+    freeze_time { Sidekiq::Testing.fake! { example.run } }
+  end
+
+  it 'schedules background migrations', :aggregate_failures do
+    migrate!
+
+    expect(BackgroundMigrationWorker.jobs.size).to eq(3)
+    expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, uuidv4_finding.id, uuidv4_finding.id)
+    expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, uuidv5_finding.id, uuidv5_finding.id)
+    expect(described_class::MIGRATION).to be_scheduled_delayed_migration(6.minutes, finding_with_signature.id, finding_with_signature.id)
+  end
+
+  private
+
+  def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0)
+    vulnerabilities.create!(
+      project_id: project_id,
+      author_id: author_id,
+      title: title,
+      severity: severity,
+      confidence: confidence,
+      report_type: report_type
+    )
+  end
+
+  def create_finding!(
+    vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:, location_fingerprint:, uuid:, report_type: 0)
+    vulnerabilities_findings.create!(
+      vulnerability_id: vulnerability_id,
+      project_id: project_id,
+      name: 'test',
+      severity: 7,
+      confidence: 7,
+      report_type: report_type,
+      project_fingerprint: '123qweasdzxc',
+      scanner_id: scanner_id,
+      primary_identifier_id: primary_identifier_id,
+      location_fingerprint: location_fingerprint,
+      metadata_version: 'test',
+      raw_metadata: 'test',
+      uuid: uuid
+    )
+  end
+
+  def create_user!(name: "Example User", email: "user@example.com", user_type: nil)
+    users.create!(
+      name: name,
+      email: email,
+      username: name,
+      projects_limit: 0
+    )
+  end
+end
diff --git a/spec/migrations/20211210140629_encrypt_static_object_token_spec.rb b/spec/migrations/20211210140629_encrypt_static_object_token_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f103ee54990180f20b99b88c2eb445542b889996
--- /dev/null
+++ b/spec/migrations/20211210140629_encrypt_static_object_token_spec.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe EncryptStaticObjectToken, :migration, feature_category: :source_code_management do
+  let!(:background_migration_jobs) { table(:background_migration_jobs) }
+  let!(:users) { table(:users) }
+
+  let!(:user_without_tokens) { create_user!(name: 'notoken') }
+  let!(:user_with_plaintext_token_1) { create_user!(name: 'plaintext_1', token: 'token') }
+  let!(:user_with_plaintext_token_2) { create_user!(name: 'plaintext_2', token: 'TOKEN') }
+  let!(:user_with_encrypted_token) { create_user!(name: 'encrypted', encrypted_token: 'encrypted') }
+  let!(:user_with_both_tokens) { create_user!(name: 'both', token: 'token2', encrypted_token: 'encrypted2') }
+
+  before do
+    stub_const("#{described_class}::BATCH_SIZE", 1)
+  end
+
+  around do |example|
+    freeze_time { Sidekiq::Testing.fake! { example.run } }
+  end
+
+  it 'schedules background migrations' do
+    migrate!
+
+    expect(background_migration_jobs.count).to eq(2)
+    expect(background_migration_jobs.first.arguments).to match_array([user_with_plaintext_token_1.id, user_with_plaintext_token_1.id])
+    expect(background_migration_jobs.second.arguments).to match_array([user_with_plaintext_token_2.id, user_with_plaintext_token_2.id])
+
+    expect(BackgroundMigrationWorker.jobs.size).to eq(2)
+    expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, user_with_plaintext_token_1.id, user_with_plaintext_token_1.id)
+    expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, user_with_plaintext_token_2.id, user_with_plaintext_token_2.id)
+  end
+
+  private
+
+  def create_user!(name:, token: nil, encrypted_token: nil)
+    email = "#{name}@example.com"
+
+    table(:users).create!(
+      name: name,
+      email: email,
+      username: name,
+      projects_limit: 0,
+      static_object_token: token,
+      static_object_token_encrypted: encrypted_token
+    )
+  end
+end
diff --git a/spec/migrations/20211214012507_backfill_incident_issue_escalation_statuses_spec.rb b/spec/migrations/20211214012507_backfill_incident_issue_escalation_statuses_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0df52df43d88409c5abdf1b8bc9395a0973a400c
--- /dev/null
+++ b/spec/migrations/20211214012507_backfill_incident_issue_escalation_statuses_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe BackfillIncidentIssueEscalationStatuses, feature_category: :incident_management do
+  let(:namespaces)  { table(:namespaces) }
+  let(:projects)    { table(:projects) }
+  let(:issues)      { table(:issues) }
+  let(:namespace)   { namespaces.create!(name: 'foo', path: 'foo') }
+  let(:project)     { projects.create!(namespace_id: namespace.id) }
+
+  # Backfill removed - see db/migrate/20220321234317_remove_all_issuable_escalation_statuses.rb.
+  it 'does nothing' do
+    issues.create!(project_id: project.id, issue_type: 1)
+
+    expect { migrate! }.not_to change { BackgroundMigrationWorker.jobs.size }
+  end
+end
diff --git a/spec/migrations/20211217174331_mark_recalculate_finding_signatures_as_completed_spec.rb b/spec/migrations/20211217174331_mark_recalculate_finding_signatures_as_completed_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2d808adf578759ead8cf7fb23318f6dd0225565e
--- /dev/null
+++ b/spec/migrations/20211217174331_mark_recalculate_finding_signatures_as_completed_spec.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+require 'spec_helper'
+require_migration!
+
+def create_background_migration_jobs(ids, status, created_at)
+  proper_status = case status
+                  when :pending
+                    Gitlab::Database::BackgroundMigrationJob.statuses['pending']
+                  when :succeeded
+                    Gitlab::Database::BackgroundMigrationJob.statuses['succeeded']
+                  else
+                    raise ArgumentError
+                  end
+
+  background_migration_jobs.create!(
+    class_name: 'RecalculateVulnerabilitiesOccurrencesUuid',
+    arguments: Array(ids),
+    status: proper_status,
+    created_at: created_at
+  )
+end
+
+RSpec.describe MarkRecalculateFindingSignaturesAsCompleted, :migration, feature_category: :vulnerability_management do
+  let!(:background_migration_jobs) { table(:background_migration_jobs) }
+
+  context 'when RecalculateVulnerabilitiesOccurrencesUuid jobs are present' do
+    before do
+      create_background_migration_jobs([1, 2, 3], :succeeded, DateTime.new(2021, 5, 5, 0, 2))
+      create_background_migration_jobs([4, 5, 6], :pending, DateTime.new(2021, 5, 5, 0, 4))
+
+      create_background_migration_jobs([1, 2, 3], :succeeded, DateTime.new(2021, 8, 18, 0, 0))
+      create_background_migration_jobs([4, 5, 6], :pending, DateTime.new(2021, 8, 18, 0, 2))
+      create_background_migration_jobs([7, 8, 9], :pending, DateTime.new(2021, 8, 18, 0, 4))
+    end
+
+    describe 'gitlab.com' do
+      before do
+        allow(::Gitlab).to receive(:com?).and_return(true)
+      end
+
+      it 'marks all jobs as succeeded' do
+        expect(background_migration_jobs.where(status: 1).count).to eq(2)
+
+        migrate!
+
+        expect(background_migration_jobs.where(status: 1).count).to eq(5)
+      end
+    end
+
+    describe 'self managed' do
+      before do
+        allow(::Gitlab).to receive(:com?).and_return(false)
+      end
+
+      it 'does not change job status' do
+        expect(background_migration_jobs.where(status: 1).count).to eq(2)
+
+        migrate!
+
+        expect(background_migration_jobs.where(status: 1).count).to eq(2)
+      end
+    end
+  end
+end
diff --git a/spec/migrations/20220106111958_add_insert_or_update_vulnerability_reads_trigger_spec.rb b/spec/migrations/20220106111958_add_insert_or_update_vulnerability_reads_trigger_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..263289462ba5690d3a84ff7d8e711b51c9f36ff2
--- /dev/null
+++ b/spec/migrations/20220106111958_add_insert_or_update_vulnerability_reads_trigger_spec.rb
@@ -0,0 +1,151 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe AddInsertOrUpdateVulnerabilityReadsTrigger, feature_category: :vulnerability_management do
+  let(:migration) { described_class.new }
+  let(:vulnerabilities) { table(:vulnerabilities) }
+  let(:vulnerability_reads) { table(:vulnerability_reads) }
+  let(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
+  let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
+  let(:user) { table(:users).create!(id: 13, email: 'author@example.com', username: 'author', projects_limit: 10) }
+  let(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) }
+  let(:scanner) { table(:vulnerability_scanners).create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
+
+  let(:vulnerability) do
+    create_vulnerability!(
+      project_id: project.id,
+      author_id: user.id
+    )
+  end
+
+  let(:vulnerability2) do
+    create_vulnerability!(
+      project_id: project.id,
+      author_id: user.id
+    )
+  end
+
+  let(:identifier) do
+    table(:vulnerability_identifiers).create!(
+      project_id: project.id,
+      external_type: 'uuid-v5',
+      external_id: 'uuid-v5',
+      fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a',
+      name: 'Identifier for UUIDv5')
+  end
+
+  let(:finding) do
+    create_finding!(
+      project_id: project.id,
+      scanner_id: scanner.id,
+      primary_identifier_id: identifier.id
+    )
+  end
+
+  describe '#up' do
+    before do
+      migrate!
+    end
+
+    describe 'UPDATE trigger' do
+      context 'when vulnerability_id is updated' do
+        it 'creates a new vulnerability_reads row' do
+          expect do
+            finding.update!(vulnerability_id: vulnerability.id)
+          end.to change { vulnerability_reads.count }.from(0).to(1)
+        end
+      end
+
+      context 'when vulnerability_id is not updated' do
+        it 'does not create a new vulnerability_reads row' do
+          finding.update!(vulnerability_id: nil)
+
+          expect do
+            finding.update!(location: '')
+          end.not_to change { vulnerability_reads.count }
+        end
+      end
+    end
+
+    describe 'INSERT trigger' do
+      context 'when vulnerability_id is set' do
+        it 'creates a new vulnerability_reads row' do
+          expect do
+            create_finding!(
+              vulnerability_id: vulnerability2.id,
+              project_id: project.id,
+              scanner_id: scanner.id,
+              primary_identifier_id: identifier.id
+            )
+          end.to change { vulnerability_reads.count }.from(0).to(1)
+        end
+      end
+
+      context 'when vulnerability_id is not set' do
+        it 'does not create a new vulnerability_reads row' do
+          expect do
+            create_finding!(
+              project_id: project.id,
+              scanner_id: scanner.id,
+              primary_identifier_id: identifier.id
+            )
+          end.not_to change { vulnerability_reads.count }
+        end
+      end
+    end
+  end
+
+  describe '#down' do
+    before do
+      migration.up
+      migration.down
+    end
+
+    it 'drops the trigger' do
+      expect do
+        finding.update!(vulnerability_id: vulnerability.id)
+      end.not_to change { vulnerability_reads.count }
+    end
+  end
+
+  private
+
+  def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0)
+    vulnerabilities.create!(
+      project_id: project_id,
+      author_id: author_id,
+      title: title,
+      severity: severity,
+      confidence: confidence,
+      report_type: report_type
+    )
+  end
+
+  # rubocop:disable Metrics/ParameterLists
+  def create_finding!(
+    project_id:, scanner_id:, primary_identifier_id:, vulnerability_id: nil,
+    name: "test", severity: 7, confidence: 7, report_type: 0,
+    project_fingerprint: '123qweasdzxc', location: { "image" => "alpine:3.4" }, location_fingerprint: 'test',
+    metadata_version: 'test', raw_metadata: 'test', uuid: SecureRandom.uuid)
+    vulnerabilities_findings.create!(
+      vulnerability_id: vulnerability_id,
+      project_id: project_id,
+      name: name,
+      severity: severity,
+      confidence: confidence,
+      report_type: report_type,
+      project_fingerprint: project_fingerprint,
+      scanner_id: scanner_id,
+      primary_identifier_id: primary_identifier_id,
+      location: location,
+      location_fingerprint: location_fingerprint,
+      metadata_version: metadata_version,
+      raw_metadata: raw_metadata,
+      uuid: uuid
+    )
+  end
+  # rubocop:enable Metrics/ParameterLists
+end
diff --git a/spec/migrations/20220106112043_add_update_vulnerability_reads_trigger_spec.rb b/spec/migrations/20220106112043_add_update_vulnerability_reads_trigger_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..152a551bc7be033458e5629237c625d8195d4c91
--- /dev/null
+++ b/spec/migrations/20220106112043_add_update_vulnerability_reads_trigger_spec.rb
@@ -0,0 +1,128 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe AddUpdateVulnerabilityReadsTrigger, feature_category: :vulnerability_management do
+  let(:migration) { described_class.new }
+  let(:vulnerability_reads) { table(:vulnerability_reads) }
+  let(:issue_links) { table(:vulnerability_issue_links) }
+  let(:vulnerabilities) { table(:vulnerabilities) }
+  let(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
+
+  let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
+  let(:user) { table(:users).create!(id: 13, email: 'author@example.com', username: 'author', projects_limit: 10) }
+  let(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) }
+  let(:issue) { table(:issues).create!(description: '1234', state_id: 1, project_id: project.id) }
+  let(:scanner) { table(:vulnerability_scanners).create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
+
+  let(:vulnerability) do
+    create_vulnerability!(
+      project_id: project.id,
+      report_type: 7,
+      author_id: user.id
+    )
+  end
+
+  let(:identifier) do
+    table(:vulnerability_identifiers).create!(
+      project_id: project.id,
+      external_type: 'uuid-v5',
+      external_id: 'uuid-v5',
+      fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a',
+      name: 'Identifier for UUIDv5')
+  end
+
+  describe '#up' do
+    before do
+      migrate!
+    end
+
+    describe 'UPDATE trigger' do
+      before do
+        create_finding!(
+          vulnerability_id: vulnerability.id,
+          project_id: project.id,
+          scanner_id: scanner.id,
+          report_type: 7,
+          primary_identifier_id: identifier.id
+        )
+      end
+
+      context 'when vulnerability attributes are updated' do
+        it 'updates vulnerability attributes in vulnerability_reads' do
+          expect do
+            vulnerability.update!(severity: 6)
+          end.to change { vulnerability_reads.first.severity }.from(7).to(6)
+        end
+      end
+
+      context 'when vulnerability attributes are not updated' do
+        it 'does not update vulnerability attributes in vulnerability_reads' do
+          expect do
+            vulnerability.update!(title: "New vulnerability")
+          end.not_to change { vulnerability_reads.first }
+        end
+      end
+    end
+  end
+
+  describe '#down' do
+    before do
+      migration.up
+      migration.down
+      create_finding!(
+        vulnerability_id: vulnerability.id,
+        project_id: project.id,
+        scanner_id: scanner.id,
+        report_type: 7,
+        primary_identifier_id: identifier.id
+      )
+    end
+
+    it 'drops the trigger' do
+      expect do
+        vulnerability.update!(severity: 6)
+      end.not_to change { vulnerability_reads.first.severity }
+    end
+  end
+
+  private
+
+  def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0)
+    vulnerabilities.create!(
+      project_id: project_id,
+      author_id: author_id,
+      title: title,
+      severity: severity,
+      confidence: confidence,
+      report_type: report_type
+    )
+  end
+
+  # rubocop:disable Metrics/ParameterLists
+  def create_finding!(
+    project_id:, scanner_id:, primary_identifier_id:, vulnerability_id: nil,
+    name: "test", severity: 7, confidence: 7, report_type: 0,
+    project_fingerprint: '123qweasdzxc', location: { "image" => "alpine:3.4" }, location_fingerprint: 'test',
+    metadata_version: 'test', raw_metadata: 'test', uuid: SecureRandom.uuid)
+    vulnerabilities_findings.create!(
+      vulnerability_id: vulnerability_id,
+      project_id: project_id,
+      name: name,
+      severity: severity,
+      confidence: confidence,
+      report_type: report_type,
+      project_fingerprint: project_fingerprint,
+      scanner_id: scanner_id,
+      primary_identifier_id: primary_identifier_id,
+      location: location,
+      location_fingerprint: location_fingerprint,
+      metadata_version: metadata_version,
+      raw_metadata: raw_metadata,
+      uuid: uuid
+    )
+  end
+  # rubocop:enable Metrics/ParameterLists
+end
diff --git a/spec/migrations/20220106112085_add_update_vulnerability_reads_location_trigger_spec.rb b/spec/migrations/20220106112085_add_update_vulnerability_reads_location_trigger_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9fc40b0b5f176c7bc9aaf83e1cdbcc47935a9a27
--- /dev/null
+++ b/spec/migrations/20220106112085_add_update_vulnerability_reads_location_trigger_spec.rb
@@ -0,0 +1,136 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe AddUpdateVulnerabilityReadsLocationTrigger, feature_category: :vulnerability_management do
+  let(:migration) { described_class.new }
+  let(:vulnerability_reads) { table(:vulnerability_reads) }
+  let(:issue_links) { table(:vulnerability_issue_links) }
+  let(:vulnerabilities) { table(:vulnerabilities) }
+  let(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
+
+  let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
+  let(:user) { table(:users).create!(id: 13, email: 'author@example.com', username: 'author', projects_limit: 10) }
+  let(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) }
+  let(:issue) { table(:issues).create!(description: '1234', state_id: 1, project_id: project.id) }
+  let(:scanner) { table(:vulnerability_scanners).create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
+
+  let(:vulnerability) do
+    create_vulnerability!(
+      project_id: project.id,
+      report_type: 7,
+      author_id: user.id
+    )
+  end
+
+  let(:identifier) do
+    table(:vulnerability_identifiers).create!(
+      project_id: project.id,
+      external_type: 'uuid-v5',
+      external_id: 'uuid-v5',
+      fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a',
+      name: 'Identifier for UUIDv5')
+  end
+
+  describe '#up' do
+    before do
+      migrate!
+    end
+
+    describe 'UPDATE trigger' do
+      context 'when image is updated' do
+        it 'updates location_image in vulnerability_reads' do
+          finding = create_finding!(
+            vulnerability_id: vulnerability.id,
+            project_id: project.id,
+            scanner_id: scanner.id,
+            report_type: 7,
+            location: { "image" => "alpine:3.4" },
+            primary_identifier_id: identifier.id
+          )
+
+          expect do
+            finding.update!(location: { "image" => "alpine:4", "kubernetes_resource" => { "agent_id" => "1234" } })
+          end.to change { vulnerability_reads.first.location_image }.from("alpine:3.4").to("alpine:4")
+        end
+      end
+
+      context 'when image is not updated' do
+        it 'updates location_image in vulnerability_reads' do
+          finding = create_finding!(
+            vulnerability_id: vulnerability.id,
+            project_id: project.id,
+            scanner_id: scanner.id,
+            report_type: 7,
+            location: { "image" => "alpine:3.4", "kubernetes_resource" => { "agent_id" => "1234" } },
+            primary_identifier_id: identifier.id
+          )
+
+          expect do
+            finding.update!(project_fingerprint: "123qweasdzx")
+          end.not_to change { vulnerability_reads.first.location_image }
+        end
+      end
+    end
+  end
+
+  describe '#down' do
+    before do
+      migration.up
+      migration.down
+    end
+
+    it 'drops the trigger' do
+      finding = create_finding!(
+        vulnerability_id: vulnerability.id,
+        project_id: project.id,
+        scanner_id: scanner.id,
+        primary_identifier_id: identifier.id
+      )
+
+      expect do
+        finding.update!(location: '{"image":"alpine:4"}')
+      end.not_to change { vulnerability_reads.first.location_image }
+    end
+  end
+
+  private
+
+  def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0)
+    vulnerabilities.create!(
+      project_id: project_id,
+      author_id: author_id,
+      title: title,
+      severity: severity,
+      confidence: confidence,
+      report_type: report_type
+    )
+  end
+
+  # rubocop:disable Metrics/ParameterLists
+  def create_finding!(
+    project_id:, scanner_id:, primary_identifier_id:, vulnerability_id: nil,
+    name: "test", severity: 7, confidence: 7, report_type: 0,
+    project_fingerprint: '123qweasdzxc', location: { "image" => "alpine:3.4" }, location_fingerprint: 'test',
+    metadata_version: 'test', raw_metadata: 'test', uuid: SecureRandom.uuid)
+    vulnerabilities_findings.create!(
+      vulnerability_id: vulnerability_id,
+      project_id: project_id,
+      name: name,
+      severity: severity,
+      confidence: confidence,
+      report_type: report_type,
+      project_fingerprint: project_fingerprint,
+      scanner_id: scanner_id,
+      primary_identifier_id: primary_identifier_id,
+      location: location,
+      location_fingerprint: location_fingerprint,
+      metadata_version: metadata_version,
+      raw_metadata: raw_metadata,
+      uuid: uuid
+    )
+  end
+  # rubocop:enable Metrics/ParameterLists
+end
diff --git a/spec/migrations/20220106163326_add_has_issues_on_vulnerability_reads_trigger_spec.rb b/spec/migrations/20220106163326_add_has_issues_on_vulnerability_reads_trigger_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e58fdfb1591a7c24c0efe06c26b7097828050328
--- /dev/null
+++ b/spec/migrations/20220106163326_add_has_issues_on_vulnerability_reads_trigger_spec.rb
@@ -0,0 +1,134 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe AddHasIssuesOnVulnerabilityReadsTrigger, feature_category: :vulnerability_management do
+  let(:migration) { described_class.new }
+  let(:vulnerability_reads) { table(:vulnerability_reads) }
+  let(:issue_links) { table(:vulnerability_issue_links) }
+  let(:vulnerabilities) { table(:vulnerabilities) }
+  let(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
+
+  let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
+  let(:user) { table(:users).create!(id: 13, email: 'author@example.com', username: 'author', projects_limit: 10) }
+  let(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) }
+  let(:issue) { table(:issues).create!(description: '1234', state_id: 1, project_id: project.id) }
+  let(:scanner) { table(:vulnerability_scanners).create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
+
+  let(:vulnerability) do
+    create_vulnerability!(
+      project_id: project.id,
+      author_id: user.id
+    )
+  end
+
+  let(:identifier) do
+    table(:vulnerability_identifiers).create!(
+      project_id: project.id,
+      external_type: 'uuid-v5',
+      external_id: 'uuid-v5',
+      fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a',
+      name: 'Identifier for UUIDv5')
+  end
+
+  before do
+    create_finding!(
+      vulnerability_id: vulnerability.id,
+      project_id: project.id,
+      scanner_id: scanner.id,
+      primary_identifier_id: identifier.id
+    )
+
+    @vulnerability_read = vulnerability_reads.first
+  end
+
+  describe '#up' do
+    before do
+      migrate!
+    end
+
+    describe 'INSERT trigger' do
+      it 'updates has_issues in vulnerability_reads' do
+        expect do
+          issue_links.create!(vulnerability_id: vulnerability.id, issue_id: issue.id)
+        end.to change { @vulnerability_read.reload.has_issues }.from(false).to(true)
+      end
+    end
+
+    describe 'DELETE trigger' do
+      let(:issue2) { table(:issues).create!(description: '1234', state_id: 1, project_id: project.id) }
+
+      it 'does not change has_issues when there exists another issue' do
+        issue_link1 = issue_links.create!(vulnerability_id: vulnerability.id, issue_id: issue.id)
+        issue_links.create!(vulnerability_id: vulnerability.id, issue_id: issue2.id)
+
+        expect do
+          issue_link1.delete
+        end.not_to change { @vulnerability_read.reload.has_issues }
+      end
+
+      it 'unsets has_issues when all issues are deleted' do
+        issue_link1 = issue_links.create!(vulnerability_id: vulnerability.id, issue_id: issue.id)
+        issue_link2 = issue_links.create!(vulnerability_id: vulnerability.id, issue_id: issue2.id)
+
+        expect do
+          issue_link1.delete
+          issue_link2.delete
+        end.to change { @vulnerability_read.reload.has_issues }.from(true).to(false)
+      end
+    end
+  end
+
+  describe '#down' do
+    before do
+      migration.up
+      migration.down
+    end
+
+    it 'drops the trigger' do
+      expect do
+        issue_links.create!(vulnerability_id: vulnerability.id, issue_id: issue.id)
+      end.not_to change { @vulnerability_read.has_issues }
+    end
+  end
+
+  private
+
+  def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0)
+    vulnerabilities.create!(
+      project_id: project_id,
+      author_id: author_id,
+      title: title,
+      severity: severity,
+      confidence: confidence,
+      report_type: report_type
+    )
+  end
+
+  # rubocop:disable Metrics/ParameterLists
+  def create_finding!(
+    project_id:, scanner_id:, primary_identifier_id:, vulnerability_id: nil,
+    name: "test", severity: 7, confidence: 7, report_type: 0,
+    project_fingerprint: '123qweasdzxc', location: { "image" => "alpine:3.4" }, location_fingerprint: 'test',
+    metadata_version: 'test', raw_metadata: 'test', uuid: SecureRandom.uuid)
+    vulnerabilities_findings.create!(
+      vulnerability_id: vulnerability_id,
+      project_id: project_id,
+      name: name,
+      severity: severity,
+      confidence: confidence,
+      report_type: report_type,
+      project_fingerprint: project_fingerprint,
+      scanner_id: scanner_id,
+      primary_identifier_id: primary_identifier_id,
+      location: location,
+      location_fingerprint: location_fingerprint,
+      metadata_version: metadata_version,
+      raw_metadata: raw_metadata,
+      uuid: uuid
+    )
+  end
+  # rubocop:enable Metrics/ParameterLists
+end
diff --git a/spec/migrations/20220107064845_populate_vulnerability_reads_spec.rb b/spec/migrations/20220107064845_populate_vulnerability_reads_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1338f826537d2c295f093176a5645554e623797c
--- /dev/null
+++ b/spec/migrations/20220107064845_populate_vulnerability_reads_spec.rb
@@ -0,0 +1,106 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe PopulateVulnerabilityReads, :migration, feature_category: :vulnerability_management do
+  let!(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
+  let!(:user) { table(:users).create!(email: 'author@example.com', username: 'author', projects_limit: 10) }
+  let!(:project) { table(:projects).create!(namespace_id: namespace.id) }
+  let!(:scanner) { table(:vulnerability_scanners).create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
+  let!(:background_migration_jobs) { table(:background_migration_jobs) }
+  let!(:vulnerabilities) { table(:vulnerabilities) }
+  let!(:vulnerability_reads) { table(:vulnerability_reads) }
+  let!(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
+  let!(:vulnerability_issue_links) { table(:vulnerability_issue_links) }
+  let!(:vulnerability_ids) { [] }
+
+  before do
+    stub_const("#{described_class}::BATCH_SIZE", 1)
+    stub_const("#{described_class}::SUB_BATCH_SIZE", 1)
+
+    5.times.each do |x|
+      vulnerability = create_vulnerability!(
+        project_id: project.id,
+        report_type: 7,
+        author_id: user.id
+      )
+      identifier = table(:vulnerability_identifiers).create!(
+        project_id: project.id,
+        external_type: 'uuid-v5',
+        external_id: 'uuid-v5',
+        fingerprint: Digest::SHA1.hexdigest(vulnerability.id.to_s),
+        name: 'Identifier for UUIDv5')
+
+      create_finding!(
+        vulnerability_id: vulnerability.id,
+        project_id: project.id,
+        scanner_id: scanner.id,
+        primary_identifier_id: identifier.id
+      )
+
+      vulnerability_ids << vulnerability.id
+    end
+  end
+
+  around do |example|
+    freeze_time { Sidekiq::Testing.fake! { example.run } }
+  end
+
+  it 'schedules background migrations' do
+    migrate!
+
+    expect(background_migration_jobs.count).to eq(5)
+    expect(background_migration_jobs.first.arguments).to match_array([vulnerability_ids.first, vulnerability_ids.first, 1])
+    expect(background_migration_jobs.second.arguments).to match_array([vulnerability_ids.second, vulnerability_ids.second, 1])
+    expect(background_migration_jobs.third.arguments).to match_array([vulnerability_ids.third, vulnerability_ids.third, 1])
+    expect(background_migration_jobs.fourth.arguments).to match_array([vulnerability_ids.fourth, vulnerability_ids.fourth, 1])
+    expect(background_migration_jobs.fifth.arguments).to match_array([vulnerability_ids.fifth, vulnerability_ids.fifth, 1])
+
+    expect(BackgroundMigrationWorker.jobs.size).to eq(5)
+    expect(described_class::MIGRATION_NAME).to be_scheduled_delayed_migration(2.minutes, vulnerability_ids.first, vulnerability_ids.first, 1)
+    expect(described_class::MIGRATION_NAME).to be_scheduled_delayed_migration(4.minutes, vulnerability_ids.second, vulnerability_ids.second, 1)
+    expect(described_class::MIGRATION_NAME).to be_scheduled_delayed_migration(6.minutes, vulnerability_ids.third, vulnerability_ids.third, 1)
+    expect(described_class::MIGRATION_NAME).to be_scheduled_delayed_migration(8.minutes, vulnerability_ids.fourth, vulnerability_ids.fourth, 1)
+    expect(described_class::MIGRATION_NAME).to be_scheduled_delayed_migration(10.minutes, vulnerability_ids.fifth, vulnerability_ids.fifth, 1)
+  end
+
+  private
+
+  def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0)
+    vulnerabilities.create!(
+      project_id: project_id,
+      author_id: author_id,
+      title: title,
+      severity: severity,
+      confidence: confidence,
+      report_type: report_type
+    )
+  end
+
+  # rubocop:disable Metrics/ParameterLists
+  def create_finding!(
+    vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:, id: nil,
+    name: "test", severity: 7, confidence: 7, report_type: 0,
+    project_fingerprint: '123qweasdzxc', location_fingerprint: 'test',
+    metadata_version: 'test', raw_metadata: 'test', uuid: SecureRandom.uuid)
+    params = {
+      vulnerability_id: vulnerability_id,
+      project_id: project_id,
+      name: name,
+      severity: severity,
+      confidence: confidence,
+      report_type: report_type,
+      project_fingerprint: project_fingerprint,
+      scanner_id: scanner_id,
+      primary_identifier_id: primary_identifier_id,
+      location_fingerprint: location_fingerprint,
+      metadata_version: metadata_version,
+      raw_metadata: raw_metadata,
+      uuid: uuid
+    }
+    params[:id] = id unless id.nil?
+    vulnerabilities_findings.create!(params)
+  end
+  # rubocop:enable Metrics/ParameterLists
+end
diff --git a/spec/migrations/20220120094340_drop_position_from_security_findings_spec.rb b/spec/migrations/20220120094340_drop_position_from_security_findings_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1470f2b3cad6393d834f0c5ae25ac665d65d451c
--- /dev/null
+++ b/spec/migrations/20220120094340_drop_position_from_security_findings_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!('drop_position_from_security_findings')
+
+RSpec.describe DropPositionFromSecurityFindings, feature_category: :vulnerability_management do
+  let(:events) { table(:security_findings) }
+
+  it 'correctly migrates up and down' do
+    reversible_migration do |migration|
+      migration.before -> {
+        expect(events.column_names).to include('position')
+      }
+
+      migration.after -> {
+        events.reset_column_information
+        expect(events.column_names).not_to include('position')
+      }
+    end
+  end
+end
diff --git a/spec/migrations/20220124130028_dedup_runner_projects_spec.rb b/spec/migrations/20220124130028_dedup_runner_projects_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b9189cbae7f7752f2da00e4957463534fbd32a09
--- /dev/null
+++ b/spec/migrations/20220124130028_dedup_runner_projects_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe DedupRunnerProjects, :migration, :suppress_gitlab_schemas_validate_connection,
+  schema: 20220120085655, feature_category: :runner do
+  let(:namespaces) { table(:namespaces) }
+  let(:projects) { table(:projects) }
+  let(:runners) { table(:ci_runners) }
+  let(:runner_projects) { table(:ci_runner_projects) }
+
+  let!(:namespace) { namespaces.create!(name: 'foo', path: 'foo') }
+  let!(:project) { projects.create!(namespace_id: namespace.id) }
+  let!(:project_2) { projects.create!(namespace_id: namespace.id) }
+  let!(:runner) { runners.create!(runner_type: 'project_type') }
+  let!(:runner_2) { runners.create!(runner_type: 'project_type') }
+  let!(:runner_3) { runners.create!(runner_type: 'project_type') }
+
+  let!(:duplicated_runner_project_1) { runner_projects.create!(runner_id: runner.id, project_id: project.id) }
+  let!(:duplicated_runner_project_2) { runner_projects.create!(runner_id: runner.id, project_id: project.id) }
+  let!(:duplicated_runner_project_3) { runner_projects.create!(runner_id: runner_2.id, project_id: project_2.id) }
+  let!(:duplicated_runner_project_4) { runner_projects.create!(runner_id: runner_2.id, project_id: project_2.id) }
+
+  let!(:non_duplicated_runner_project) { runner_projects.create!(runner_id: runner_3.id, project_id: project.id) }
+
+  it 'deduplicates ci_runner_projects table' do
+    expect { migrate! }.to change { runner_projects.count }.from(5).to(3)
+  end
+
+  it 'merges `duplicated_runner_project_1` with `duplicated_runner_project_2`', :aggregate_failures do
+    migrate!
+
+    expect(runner_projects.where(id: duplicated_runner_project_1.id)).not_to(exist)
+
+    merged_runner_projects = runner_projects.find_by(id: duplicated_runner_project_2.id)
+
+    expect(merged_runner_projects).to be_present
+    expect(merged_runner_projects.created_at).to be_like_time(duplicated_runner_project_1.created_at)
+    expect(merged_runner_projects.created_at).to be_like_time(duplicated_runner_project_2.created_at)
+  end
+
+  it 'merges `duplicated_runner_project_3` with `duplicated_runner_project_4`', :aggregate_failures do
+    migrate!
+
+    expect(runner_projects.where(id: duplicated_runner_project_3.id)).not_to(exist)
+
+    merged_runner_projects = runner_projects.find_by(id: duplicated_runner_project_4.id)
+
+    expect(merged_runner_projects).to be_present
+    expect(merged_runner_projects.created_at).to be_like_time(duplicated_runner_project_3.created_at)
+    expect(merged_runner_projects.created_at).to be_like_time(duplicated_runner_project_4.created_at)
+  end
+
+  it 'does not change non duplicated records' do
+    expect { migrate! }.not_to change { non_duplicated_runner_project.reload.attributes }
+  end
+
+  it 'does nothing when there are no runner projects' do
+    runner_projects.delete_all
+
+    migrate!
+
+    expect(runner_projects.count).to eq(0)
+  end
+end
diff --git a/spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb b/spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3abe173196f270f22e7873c5a5f078d9119624f5
--- /dev/null
+++ b/spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!('remove_dangling_running_builds')
+
+RSpec.describe RemoveDanglingRunningBuilds, :suppress_gitlab_schemas_validate_connection,
+  feature_category: :continuous_integration do
+  let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
+  let(:project) { table(:projects).create!(namespace_id: namespace.id) }
+  let(:runner) { table(:ci_runners).create!(runner_type: 1) }
+  let(:builds) { table(:ci_builds) }
+  let(:running_builds) { table(:ci_running_builds) }
+
+  let(:running_build) do
+    builds.create!(
+      name: 'test 1',
+      status: 'running',
+      project_id: project.id,
+      type: 'Ci::Build')
+  end
+
+  let(:failed_build) do
+    builds.create!(
+      name: 'test 2',
+      status: 'failed',
+      project_id: project.id,
+      type: 'Ci::Build')
+  end
+
+  let!(:running_metadata) do
+    running_builds.create!(
+      build_id: running_build.id,
+      project_id: project.id,
+      runner_id: runner.id,
+      runner_type:
+      runner.runner_type)
+  end
+
+  let!(:failed_metadata) do
+    running_builds.create!(
+      build_id: failed_build.id,
+      project_id: project.id,
+      runner_id: runner.id,
+      runner_type: runner.runner_type)
+  end
+
+  it 'removes failed builds' do
+    migrate!
+
+    expect(running_metadata.reload).to be_present
+    expect { failed_metadata.reload }.to raise_error(ActiveRecord::RecordNotFound)
+  end
+end
diff --git a/spec/migrations/20220128155814_fix_approval_rules_code_owners_rule_type_index_spec.rb b/spec/migrations/20220128155814_fix_approval_rules_code_owners_rule_type_index_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3f3fdd0889d4a838f6c29fe75f3b9335b87ee311
--- /dev/null
+++ b/spec/migrations/20220128155814_fix_approval_rules_code_owners_rule_type_index_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!('fix_approval_rules_code_owners_rule_type_index')
+
+RSpec.describe FixApprovalRulesCodeOwnersRuleTypeIndex, :migration, feature_category: :source_code_management do
+  let(:table_name) { :approval_merge_request_rules }
+  let(:index_name) { 'index_approval_rules_code_owners_rule_type' }
+
+  it 'correctly migrates up and down' do
+    reversible_migration do |migration|
+      migration.before -> {
+        expect(subject.index_exists_by_name?(table_name, index_name)).to be_truthy
+      }
+
+      migration.after -> {
+        expect(subject.index_exists_by_name?(table_name, index_name)).to be_truthy
+      }
+    end
+  end
+
+  context 'when the index already exists' do
+    before do
+      subject.add_concurrent_index table_name, :merge_request_id, where: 'rule_type = 2', name: index_name
+    end
+
+    it 'keeps the index' do
+      migrate!
+
+      expect(subject.index_exists_by_name?(table_name, index_name)).to be_truthy
+    end
+  end
+end
diff --git a/spec/migrations/20220202105733_delete_service_template_records_spec.rb b/spec/migrations/20220202105733_delete_service_template_records_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..41762a3a5c311356bf64b4181f36a7c364ca9875
--- /dev/null
+++ b/spec/migrations/20220202105733_delete_service_template_records_spec.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe DeleteServiceTemplateRecords, feature_category: :integrations do
+  let(:integrations) { table(:integrations) }
+  let(:chat_names) { table(:chat_names) }
+  let(:web_hooks) { table(:web_hooks) }
+  let(:slack_integrations) { table(:slack_integrations) }
+  let(:zentao_tracker_data) { table(:zentao_tracker_data) }
+  let(:jira_tracker_data) { table(:jira_tracker_data) }
+  let(:issue_tracker_data) { table(:issue_tracker_data) }
+
+  before do
+    template = integrations.create!(template: true)
+    chat_names.create!(service_id: template.id, user_id: 1, team_id: 1, chat_id: 1)
+    web_hooks.create!(service_id: template.id)
+    slack_integrations.create!(service_id: template.id, team_id: 1, team_name: 'team', alias: 'alias', user_id: 1)
+    zentao_tracker_data.create!(integration_id: template.id)
+    jira_tracker_data.create!(service_id: template.id)
+    issue_tracker_data.create!(service_id: template.id)
+
+    integrations.create!(template: false)
+  end
+
+  it 'deletes template records and associated data' do
+    expect { migrate! }
+      .to change { integrations.where(template: true).count }.from(1).to(0)
+      .and change { chat_names.count }.from(1).to(0)
+      .and change { web_hooks.count }.from(1).to(0)
+      .and change { slack_integrations.count }.from(1).to(0)
+      .and change { zentao_tracker_data.count }.from(1).to(0)
+      .and change { jira_tracker_data.count }.from(1).to(0)
+      .and change { issue_tracker_data.count }.from(1).to(0)
+  end
+
+  it 'does not delete non template records' do
+    expect { migrate! }
+      .not_to change { integrations.where(template: false).count }
+  end
+end
diff --git a/spec/migrations/20220204095121_backfill_namespace_statistics_with_dependency_proxy_size_spec.rb b/spec/migrations/20220204095121_backfill_namespace_statistics_with_dependency_proxy_size_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..cbae5674d78d0f888fe7c8d4b0a96a9752f58297
--- /dev/null
+++ b/spec/migrations/20220204095121_backfill_namespace_statistics_with_dependency_proxy_size_spec.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe BackfillNamespaceStatisticsWithDependencyProxySize, feature_category: :dependency_proxy do
+  let!(:groups) { table(:namespaces) }
+  let!(:group1) { groups.create!(id: 10, name: 'test1', path: 'test1', type: 'Group') }
+  let!(:group2) { groups.create!(id: 20, name: 'test2', path: 'test2', type: 'Group') }
+  let!(:group3) { groups.create!(id: 30, name: 'test3', path: 'test3', type: 'Group') }
+  let!(:group4) { groups.create!(id: 40, name: 'test4', path: 'test4', type: 'Group') }
+
+  let!(:dependency_proxy_blobs) { table(:dependency_proxy_blobs) }
+  let!(:dependency_proxy_manifests) { table(:dependency_proxy_manifests) }
+
+  let!(:group1_manifest) { create_manifest(10, 10) }
+  let!(:group2_manifest) { create_manifest(20, 20) }
+  let!(:group3_manifest) { create_manifest(30, 30) }
+
+  let!(:group1_blob) { create_blob(10, 10) }
+  let!(:group2_blob) { create_blob(20, 20) }
+  let!(:group3_blob) { create_blob(30, 30) }
+
+  describe '#up' do
+    it 'correctly schedules background migrations' do
+      stub_const("#{described_class}::BATCH_SIZE", 2)
+
+      Sidekiq::Testing.fake! do
+        freeze_time do
+          migrate!
+
+          aggregate_failures do
+            expect(described_class::MIGRATION)
+              .to be_scheduled_migration([10, 30], ['dependency_proxy_size'])
+
+            expect(described_class::MIGRATION)
+              .to be_scheduled_delayed_migration(2.minutes, [20], ['dependency_proxy_size'])
+
+            expect(BackgroundMigrationWorker.jobs.size).to eq(2)
+          end
+        end
+      end
+    end
+  end
+
+  def create_manifest(group_id, size)
+    dependency_proxy_manifests.create!(
+      group_id: group_id,
+      size: size,
+      file_name: 'test-file',
+      file: 'test',
+      digest: 'abc123'
+    )
+  end
+
+  def create_blob(group_id, size)
+    dependency_proxy_blobs.create!(
+      group_id: group_id,
+      size: size,
+      file_name: 'test-file',
+      file: 'test'
+    )
+  end
+end
diff --git a/spec/migrations/20220204194347_encrypt_integration_properties_spec.rb b/spec/migrations/20220204194347_encrypt_integration_properties_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5e728bb396ce7773a3ccc25ec1ddfeb52861e762
--- /dev/null
+++ b/spec/migrations/20220204194347_encrypt_integration_properties_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe EncryptIntegrationProperties, :migration, schema: 20220204193000, feature_category: :integrations do
+  subject(:migration) { described_class.new }
+
+  let(:integrations) { table(:integrations) }
+
+  before do
+    stub_const("#{described_class.name}::BATCH_SIZE", 2)
+  end
+
+  it 'correctly schedules background migrations', :aggregate_failures do
+    # update required
+    record1 = integrations.create!(properties: some_props)
+    record2 = integrations.create!(properties: some_props)
+    record3 = integrations.create!(properties: some_props)
+    record4 = integrations.create!(properties: nil)
+    record5 = integrations.create!(properties: nil)
+
+    Sidekiq::Testing.fake! do
+      freeze_time do
+        migrate!
+
+        expect(described_class::MIGRATION).to be_scheduled_migration(record1.id, record2.id)
+        expect(described_class::MIGRATION).to be_scheduled_migration(record3.id, record4.id)
+        expect(described_class::MIGRATION).to be_scheduled_migration(record5.id, record5.id)
+
+        expect(BackgroundMigrationWorker.jobs.size).to eq(3)
+      end
+    end
+  end
+
+  def some_props
+    { iid: generate(:iid), url: generate(:url), username: generate(:username) }.to_json
+  end
+end
diff --git a/spec/migrations/20220208080921_schedule_migrate_personal_namespace_project_maintainer_to_owner_spec.rb b/spec/migrations/20220208080921_schedule_migrate_personal_namespace_project_maintainer_to_owner_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..89583d1050bc41244e54a85b5d4817ef3e5590b4
--- /dev/null
+++ b/spec/migrations/20220208080921_schedule_migrate_personal_namespace_project_maintainer_to_owner_spec.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe ScheduleMigratePersonalNamespaceProjectMaintainerToOwner, feature_category: :subgroups do
+  let!(:migration) { described_class::MIGRATION }
+
+  describe '#up' do
+    it 'schedules background jobs for each batch of members' do
+      migrate!
+
+      expect(migration).to have_scheduled_batched_migration(
+        table_name: :members,
+        column_name: :id,
+        interval: described_class::INTERVAL
+      )
+    end
+  end
+end
diff --git a/spec/migrations/20220211214605_update_integrations_trigger_type_new_on_insert_null_safe_spec.rb b/spec/migrations/20220211214605_update_integrations_trigger_type_new_on_insert_null_safe_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8a6a542bc5ec7fb55df771b0e4b0a9689cd2df39
--- /dev/null
+++ b/spec/migrations/20220211214605_update_integrations_trigger_type_new_on_insert_null_safe_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe UpdateIntegrationsTriggerTypeNewOnInsertNullSafe, :migration, feature_category: :integrations do
+  let(:integrations) { table(:integrations) }
+
+  before do
+    migrate!
+  end
+
+  it 'leaves defined values alone' do
+    record = integrations.create!(type: 'XService', type_new: 'Integrations::Y')
+
+    expect(integrations.find(record.id)).to have_attributes(type: 'XService', type_new: 'Integrations::Y')
+  end
+
+  it 'keeps type_new synchronized with type' do
+    record = integrations.create!(type: 'AbcService', type_new: nil)
+
+    expect(integrations.find(record.id)).to have_attributes(
+      type: 'AbcService',
+      type_new: 'Integrations::Abc'
+    )
+  end
+
+  it 'keeps type synchronized with type_new' do
+    record = integrations.create!(type: nil, type_new: 'Integrations::Abc')
+
+    expect(integrations.find(record.id)).to have_attributes(
+      type: 'AbcService',
+      type_new: 'Integrations::Abc'
+    )
+  end
+end
diff --git a/spec/migrations/20220213103859_remove_integrations_type_spec.rb b/spec/migrations/20220213103859_remove_integrations_type_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8f6d9b0d9b52a8db8939eed7e1ba5cbffd3e2514
--- /dev/null
+++ b/spec/migrations/20220213103859_remove_integrations_type_spec.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe RemoveIntegrationsType, :migration, feature_category: :integrations do
+  subject(:migration) { described_class.new }
+
+  let(:integrations) { table(:integrations) }
+  let(:bg_migration) { instance_double(bg_migration_class) }
+
+  before do
+    stub_const("#{described_class.name}::BATCH_SIZE", 2)
+  end
+
+  it 'performs remaining background migrations', :aggregate_failures do
+    # Already migrated
+    integrations.create!(type: 'SlackService', type_new: 'Integrations::Slack')
+    # update required
+    record1 = integrations.create!(type: 'SlackService')
+    record2 = integrations.create!(type: 'JiraService')
+    record3 = integrations.create!(type: 'SlackService')
+
+    migrate!
+
+    expect(record1.reload.type_new).to eq 'Integrations::Slack'
+    expect(record2.reload.type_new).to eq 'Integrations::Jira'
+    expect(record3.reload.type_new).to eq 'Integrations::Slack'
+  end
+end
diff --git a/spec/migrations/20220222192524_create_not_null_constraint_releases_tag_spec.rb b/spec/migrations/20220222192524_create_not_null_constraint_releases_tag_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b8a37dcd6d98dd1bd45e9b318f59ff3204666729
--- /dev/null
+++ b/spec/migrations/20220222192524_create_not_null_constraint_releases_tag_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+require 'spec_helper'
+require_migration!
+
+RSpec.describe CreateNotNullConstraintReleasesTag, feature_category: :release_orchestration do
+  let!(:releases) { table(:releases) }
+  let!(:migration) { described_class.new }
+
+  before do
+    allow(migration).to receive(:transaction_open?).and_return(false)
+    allow(migration).to receive(:with_lock_retries).and_yield
+  end
+
+  it 'adds a check constraint to tags' do
+    constraint = releases.connection.check_constraints(:releases).find { |constraint| constraint.expression == "tag IS NOT NULL" }
+    expect(constraint).to be_nil
+
+    migration.up
+
+    constraint = releases.connection.check_constraints(:releases).find { |constraint| constraint.expression == "tag IS NOT NULL" }
+    expect(constraint).to be_a(ActiveRecord::ConnectionAdapters::CheckConstraintDefinition)
+  end
+end
diff --git a/spec/migrations/20220222192525_remove_null_releases_spec.rb b/spec/migrations/20220222192525_remove_null_releases_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ce42dea077dee45536fd0b1954e95679f2335721
--- /dev/null
+++ b/spec/migrations/20220222192525_remove_null_releases_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe RemoveNullReleases, feature_category: :release_orchestration do
+  let(:releases) { table(:releases) }
+
+  before do
+    # we need to migrate to before previous migration so an invalid record can be created
+    migrate!
+    migration_context.down(previous_migration(3).version)
+
+    releases.create!(tag: 'good', name: 'good release', released_at: Time.now)
+    releases.create!(tag: nil, name: 'bad release', released_at: Time.now)
+  end
+
+  it 'deletes template records and associated data' do
+    expect { migrate! }
+      .to change { releases.count }.from(2).to(1)
+  end
+end
diff --git a/spec/migrations/20220223124428_schedule_merge_topics_with_same_name_spec.rb b/spec/migrations/20220223124428_schedule_merge_topics_with_same_name_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..425f622581bfc327d8151e6368b6cfaf633a2e22
--- /dev/null
+++ b/spec/migrations/20220223124428_schedule_merge_topics_with_same_name_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe ScheduleMergeTopicsWithSameName, feature_category: :projects do
+  let(:topics) { table(:topics) }
+
+  describe '#up' do
+    before do
+      stub_const("#{described_class}::BATCH_SIZE", 2)
+
+      topics.create!(name: 'topic1')
+      topics.create!(name: 'Topic2')
+      topics.create!(name: 'Topic3')
+      topics.create!(name: 'Topic4')
+      topics.create!(name: 'topic2')
+      topics.create!(name: 'topic3')
+      topics.create!(name: 'topic4')
+      topics.create!(name: 'TOPIC2')
+      topics.create!(name: 'topic5')
+    end
+
+    it 'schedules MergeTopicsWithSameName background jobs', :aggregate_failures do
+      Sidekiq::Testing.fake! do
+        freeze_time do
+          migrate!
+
+          expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, %w[topic2 topic3])
+          expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, %w[topic4])
+          expect(BackgroundMigrationWorker.jobs.size).to eq(2)
+        end
+      end
+    end
+  end
+end
diff --git a/spec/migrations/20220305223212_add_security_training_providers_spec.rb b/spec/migrations/20220305223212_add_security_training_providers_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f67db3b68cde9927e7b58b2ec4f5823536dab55e
--- /dev/null
+++ b/spec/migrations/20220305223212_add_security_training_providers_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe AddSecurityTrainingProviders, :migration, feature_category: :vulnerability_management do
+  include MigrationHelpers::WorkItemTypesHelper
+
+  let!(:security_training_providers) { table(:security_training_providers) }
+
+  it 'creates default data' do
+    # Need to delete all as security training providers are seeded before entire test suite
+    security_training_providers.delete_all
+
+    reversible_migration do |migration|
+      migration.before -> {
+        expect(security_training_providers.count).to eq(0)
+      }
+
+      migration.after -> {
+        expect(security_training_providers.count).to eq(2)
+      }
+    end
+  end
+end
diff --git a/spec/migrations/20220307192610_remove_duplicate_project_tag_releases_spec.rb b/spec/migrations/20220307192610_remove_duplicate_project_tag_releases_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..98e2ba4816b568b8fee98195482711f60d18f8f0
--- /dev/null
+++ b/spec/migrations/20220307192610_remove_duplicate_project_tag_releases_spec.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RemoveDuplicateProjectTagReleases, feature_category: :release_orchestration do
+  let(:namespaces) { table(:namespaces) }
+  let(:projects) { table(:projects) }
+  let(:users) { table(:users) }
+  let(:releases) { table(:releases) }
+
+  let(:namespace) { namespaces.create!(name: 'gitlab', path: 'gitlab-org') }
+  let(:project) { projects.create!(namespace_id: namespace.id, name: 'foo') }
+
+  let(:dup_releases) do
+    Array.new(4).fill do |i|
+      rel = releases.new(project_id: project.id, tag: "duplicate tag", released_at: (DateTime.now + i.days))
+      rel.save!(validate: false)
+      rel
+    end
+  end
+
+  let(:valid_release) do
+    releases.create!(
+      project_id: project.id,
+      tag: "valid tag",
+      released_at: DateTime.now
+    )
+  end
+
+  describe '#up' do
+    it "correctly removes duplicate tags from the same project" do
+      expect(dup_releases.length).to eq 4
+      expect(valid_release).not_to be nil
+      expect(releases.where(tag: 'duplicate tag').count).to eq 4
+      expect(releases.where(tag: 'valid tag').count).to eq 1
+
+      migrate!
+
+      expect(releases.where(tag: 'duplicate tag').count).to eq 1
+      expect(releases.where(tag: 'valid tag').count).to eq 1
+      expect(releases.all.map(&:tag)).to match_array ['valid tag', 'duplicate tag']
+    end
+  end
+end
diff --git a/spec/migrations/20220309084954_remove_leftover_external_pull_request_deletions_spec.rb b/spec/migrations/20220309084954_remove_leftover_external_pull_request_deletions_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8df9907643eddfda6f479742f405f2b38a7e2cbd
--- /dev/null
+++ b/spec/migrations/20220309084954_remove_leftover_external_pull_request_deletions_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe RemoveLeftoverExternalPullRequestDeletions, feature_category: :cell do
+  let(:deleted_records) { table(:loose_foreign_keys_deleted_records) }
+
+  let(:pending_record1) { deleted_records.create!(id: 1, fully_qualified_table_name: 'public.external_pull_requests', primary_key_value: 1, status: 1) }
+  let(:pending_record2) { deleted_records.create!(id: 2, fully_qualified_table_name: 'public.external_pull_requests', primary_key_value: 2, status: 1) }
+  let(:other_pending_record1) { deleted_records.create!(id: 3, fully_qualified_table_name: 'public.projects', primary_key_value: 1, status: 1) }
+  let(:other_pending_record2) { deleted_records.create!(id: 4, fully_qualified_table_name: 'public.ci_builds', primary_key_value: 1, status: 1) }
+  let(:processed_record1) { deleted_records.create!(id: 5, fully_qualified_table_name: 'public.external_pull_requests', primary_key_value: 3, status: 2) }
+  let(:other_processed_record1) { deleted_records.create!(id: 6, fully_qualified_table_name: 'public.ci_builds', primary_key_value: 2, status: 2) }
+
+  let!(:persisted_ids_before) do
+    [
+      pending_record1,
+      pending_record2,
+      other_pending_record1,
+      other_pending_record2,
+      processed_record1,
+      other_processed_record1
+    ].map(&:id).sort
+  end
+
+  let!(:persisted_ids_after) do
+    [
+      other_pending_record1,
+      other_pending_record2,
+      processed_record1,
+      other_processed_record1
+    ].map(&:id).sort
+  end
+
+  def all_ids
+    deleted_records.all.map(&:id).sort
+  end
+
+  it 'deletes pending external_pull_requests records' do
+    expect { migrate! }.to change { all_ids }.from(persisted_ids_before).to(persisted_ids_after)
+  end
+end
diff --git a/spec/migrations/20220310141349_remove_dependency_list_usage_data_from_redis_spec.rb b/spec/migrations/20220310141349_remove_dependency_list_usage_data_from_redis_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5d9be79e76894db0de14ec273e2814c1f3566e73
--- /dev/null
+++ b/spec/migrations/20220310141349_remove_dependency_list_usage_data_from_redis_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RemoveDependencyListUsageDataFromRedis, :migration, :clean_gitlab_redis_shared_state,
+  feature_category: :dependency_management do
+  let(:key) { "DEPENDENCY_LIST_USAGE_COUNTER" }
+
+  describe "#up" do
+    it 'removes the hash from redis' do
+      with_redis do |redis|
+        redis.hincrby(key, 1, 1)
+        redis.hincrby(key, 2, 1)
+      end
+
+      expect { migrate! }.to change { with_redis { |r| r.hgetall(key) } }.from({ '1' => '1', '2' => '1' }).to({})
+    end
+  end
+
+  def with_redis(&block)
+    Gitlab::Redis::SharedState.with(&block)
+  end
+end
diff --git a/spec/migrations/backfill_all_project_namespaces_spec.rb b/spec/migrations/backfill_all_project_namespaces_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..52fa46eea57a70d9fa90ab972d395d337837f550
--- /dev/null
+++ b/spec/migrations/backfill_all_project_namespaces_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe BackfillAllProjectNamespaces, :migration, feature_category: :subgroups do
+  let!(:migration) { described_class::MIGRATION }
+
+  let(:projects) { table(:projects) }
+  let(:namespaces) { table(:namespaces) }
+  let(:user_namespace) { namespaces.create!(name: 'user1', path: 'user1', visibility_level: 20, type: 'User') }
+  let(:parent_group1) { namespaces.create!(name: 'parent_group1', path: 'parent_group1', visibility_level: 20, type: 'Group') }
+  let!(:parent_group1_project) { projects.create!(name: 'parent_group1_project', path: 'parent_group1_project', namespace_id: parent_group1.id, visibility_level: 20) }
+  let!(:user_namespace_project) { projects.create!(name: 'user1_project', path: 'user1_project', namespace_id: user_namespace.id, visibility_level: 20) }
+
+  describe '#up' do
+    it 'schedules background jobs for each batch of namespaces' do
+      migrate!
+
+      expect(migration).to have_scheduled_batched_migration(
+        table_name: :projects,
+        column_name: :id,
+        job_arguments: [nil, 'up'],
+        interval: described_class::DELAY_INTERVAL
+      )
+    end
+  end
+
+  describe '#down' do
+    it 'deletes all batched migration records' do
+      migrate!
+      schema_migrate_down!
+
+      expect(migration).not_to have_scheduled_batched_migration
+    end
+  end
+end
diff --git a/spec/migrations/backfill_cycle_analytics_aggregations_spec.rb b/spec/migrations/backfill_cycle_analytics_aggregations_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..47950f918c31c02a5ecd09241d518ad577599748
--- /dev/null
+++ b/spec/migrations/backfill_cycle_analytics_aggregations_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe BackfillCycleAnalyticsAggregations, :migration, feature_category: :value_stream_management do
+  let(:migration) { described_class.new }
+
+  let(:aggregations) { table(:analytics_cycle_analytics_aggregations) }
+  let(:namespaces) { table(:namespaces) }
+  let(:group_value_streams) { table(:analytics_cycle_analytics_group_value_streams) }
+
+  context 'when there are value stream records' do
+    it 'inserts a record for each top-level namespace' do
+      group1 = namespaces.create!(path: 'aaa', name: 'aaa')
+      subgroup1 = namespaces.create!(path: 'bbb', name: 'bbb', parent_id: group1.id)
+      group2 = namespaces.create!(path: 'ccc', name: 'ccc')
+
+      namespaces.create!(path: 'ddd', name: 'ddd') # not used
+
+      group_value_streams.create!(name: 'for top level group', group_id: group2.id)
+      group_value_streams.create!(name: 'another for top level group', group_id: group2.id)
+
+      group_value_streams.create!(name: 'for subgroup', group_id: subgroup1.id)
+      group_value_streams.create!(name: 'another for subgroup', group_id: subgroup1.id)
+
+      migrate!
+
+      expect(aggregations.pluck(:group_id)).to match_array([group1.id, group2.id])
+    end
+  end
+
+  it 'does nothing' do
+    expect { migrate! }.not_to change { aggregations.count }
+  end
+end
diff --git a/spec/migrations/backfill_group_features_spec.rb b/spec/migrations/backfill_group_features_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1e7729a97d84f62471784439e1af85d5abd31ac1
--- /dev/null
+++ b/spec/migrations/backfill_group_features_spec.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe BackfillGroupFeatures, :migration, feature_category: :feature_flags do
+  let(:migration) { described_class::MIGRATION }
+
+  describe '#up' do
+    it 'schedules background jobs for each batch of namespaces' do
+      migrate!
+
+      expect(migration).to have_scheduled_batched_migration(
+        table_name: :namespaces,
+        column_name: :id,
+        job_arguments: [described_class::BATCH_SIZE],
+        interval: described_class::INTERVAL,
+        batch_size: described_class::BATCH_SIZE
+      )
+    end
+  end
+
+  describe '#down' do
+    it 'deletes all batched migration records' do
+      migrate!
+      schema_migrate_down!
+
+      expect(migration).not_to have_scheduled_batched_migration
+    end
+  end
+end
diff --git a/spec/migrations/backfill_member_namespace_id_for_group_members_spec.rb b/spec/migrations/backfill_member_namespace_id_for_group_members_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..892589dd7702295323500d57ff3fd877b40caa50
--- /dev/null
+++ b/spec/migrations/backfill_member_namespace_id_for_group_members_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe BackfillMemberNamespaceIdForGroupMembers, feature_category: :subgroups do
+  let!(:migration) { described_class::MIGRATION }
+
+  describe '#up' do
+    it 'schedules background jobs for each batch of group members' do
+      migrate!
+
+      expect(migration).to have_scheduled_batched_migration(
+        table_name: :members,
+        column_name: :id,
+        interval: described_class::INTERVAL
+      )
+    end
+  end
+
+  describe '#down' do
+    it 'deletes all batched migration records' do
+      migrate!
+      schema_migrate_down!
+
+      expect(migration).not_to have_scheduled_batched_migration
+    end
+  end
+end
diff --git a/spec/migrations/backfill_namespace_id_for_namespace_routes_spec.rb b/spec/migrations/backfill_namespace_id_for_namespace_routes_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..627b18cd889492919f827e2f0c32543dfa4c8cb4
--- /dev/null
+++ b/spec/migrations/backfill_namespace_id_for_namespace_routes_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe BackfillNamespaceIdForNamespaceRoutes, feature_category: :projects do
+  let!(:migration) { described_class::MIGRATION }
+
+  describe '#up' do
+    it 'schedules background jobs for each batch of routes' do
+      migrate!
+
+      expect(migration).to have_scheduled_batched_migration(
+        table_name: :routes,
+        column_name: :id,
+        interval: described_class::INTERVAL
+      )
+    end
+  end
+
+  describe '#down' do
+    it 'deletes all batched migration records' do
+      migrate!
+      schema_migrate_down!
+
+      expect(migration).not_to have_scheduled_batched_migration
+    end
+  end
+end
diff --git a/spec/migrations/backfill_project_namespaces_for_group_spec.rb b/spec/migrations/backfill_project_namespaces_for_group_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b21ed6e1aa247eff279ae03f03ae239c3bfaad96
--- /dev/null
+++ b/spec/migrations/backfill_project_namespaces_for_group_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe BackfillProjectNamespacesForGroup, feature_category: :subgroups do
+  let!(:migration) { described_class::MIGRATION }
+
+  let(:projects) { table(:projects) }
+  let(:namespaces) { table(:namespaces) }
+  let(:parent_group1) { namespaces.create!(name: 'parent_group1', path: 'parent_group1', visibility_level: 20, type: 'Group') }
+  let!(:parent_group1_project) { projects.create!(name: 'parent_group1_project', path: 'parent_group1_project', namespace_id: parent_group1.id, visibility_level: 20) }
+
+  before do
+    allow(Gitlab).to receive(:com?).and_return(true)
+  end
+
+  describe '#up' do
+    before do
+      stub_const("BackfillProjectNamespacesForGroup::GROUP_ID", parent_group1.id)
+    end
+
+    it 'schedules background jobs for each batch of namespaces' do
+      migrate!
+
+      expect(migration).to have_scheduled_batched_migration(
+        table_name: :projects,
+        column_name: :id,
+        job_arguments: [described_class::GROUP_ID, 'up'],
+        interval: described_class::DELAY_INTERVAL
+      )
+    end
+  end
+
+  describe '#down' do
+    it 'deletes all batched migration records' do
+      migrate!
+      schema_migrate_down!
+
+      expect(migration).not_to have_scheduled_batched_migration
+    end
+  end
+end
diff --git a/spec/migrations/populate_audit_event_streaming_verification_token_spec.rb b/spec/migrations/populate_audit_event_streaming_verification_token_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e2c117903d45330f5335ab228cf538b080bc5bbc
--- /dev/null
+++ b/spec/migrations/populate_audit_event_streaming_verification_token_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe PopulateAuditEventStreamingVerificationToken, feature_category: :audit_events do
+  let(:groups) { table(:namespaces) }
+  let(:destinations) { table(:audit_events_external_audit_event_destinations) }
+  let(:migration) { described_class.new }
+
+  let!(:group) { groups.create!(name: 'test-group', path: 'test-group') }
+  let!(:destination) { destinations.create!(namespace_id: group.id, destination_url: 'https://example.com/destination', verification_token: nil) }
+
+  describe '#up' do
+    it 'adds verification tokens to records created before the migration' do
+      expect do
+        migrate!
+        destination.reload
+      end.to change { destination.verification_token }.from(nil).to(a_string_matching(/\w{24}/))
+    end
+  end
+end
diff --git a/spec/migrations/recreate_index_security_ci_builds_on_name_and_id_parser_with_new_features_spec.rb b/spec/migrations/recreate_index_security_ci_builds_on_name_and_id_parser_with_new_features_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c770976472785ef61d5ccf2fb66dd89bb90b51b7
--- /dev/null
+++ b/spec/migrations/recreate_index_security_ci_builds_on_name_and_id_parser_with_new_features_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe RecreateIndexSecurityCiBuildsOnNameAndIdParserWithNewFeatures, :migration, feature_category: :continuous_integration do
+  let(:db) { described_class.new }
+  let(:pg_class) { table(:pg_class) }
+  let(:pg_index) { table(:pg_index) }
+  let(:async_indexes) { table(:postgres_async_indexes) }
+
+  it 'recreates index' do
+    reversible_migration do |migration|
+      migration.before -> {
+        expect(async_indexes.where(name: described_class::OLD_INDEX_NAME).exists?).to be false
+        expect(db.index_exists?(described_class::TABLE, described_class::COLUMNS, name: described_class::OLD_INDEX_NAME)).to be true
+        expect(db.index_exists?(described_class::TABLE, described_class::COLUMNS, name: described_class::NEW_INDEX_NAME)).to be false
+      }
+
+      migration.after -> {
+        expect(async_indexes.where(name: described_class::OLD_INDEX_NAME).exists?).to be true
+        expect(db.index_exists?(described_class::TABLE, described_class::COLUMNS, name: described_class::OLD_INDEX_NAME)).to be false
+        expect(db.index_exists?(described_class::TABLE, described_class::COLUMNS, name: described_class::NEW_INDEX_NAME)).to be true
+      }
+    end
+  end
+end
diff --git a/spec/migrations/remove_not_null_contraint_on_title_from_sprints_spec.rb b/spec/migrations/remove_not_null_contraint_on_title_from_sprints_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..91687d8d73066d5e2115ec957cbd09a6579dc0a3
--- /dev/null
+++ b/spec/migrations/remove_not_null_contraint_on_title_from_sprints_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe RemoveNotNullContraintOnTitleFromSprints, :migration, feature_category: :team_planning do
+  let(:migration) { described_class.new }
+  let(:namespaces) { table(:namespaces) }
+  let(:sprints) { table(:sprints) }
+  let(:iterations_cadences) { table(:iterations_cadences) }
+
+  let!(:group) { namespaces.create!(name: 'foo', path: 'foo') }
+  let!(:cadence) { iterations_cadences.create!(group_id: group.id, title: "cadence 1") }
+  let!(:iteration1) { sprints.create!(id: 1, title: 'a', group_id: group.id, iterations_cadence_id: cadence.id, start_date: Date.new(2021, 11, 1), due_date: Date.new(2021, 11, 5), iid: 1) }
+
+  describe '#down' do
+    it "removes null titles by setting them with ids" do
+      migration.up
+
+      iteration2 = sprints.create!(id: 2, title: nil, group_id: group.id, iterations_cadence_id: cadence.id, start_date: Date.new(2021, 12, 1), due_date: Date.new(2021, 12, 5), iid: 2)
+
+      migration.down
+
+      expect(iteration1.reload.title).to eq 'a'
+      expect(iteration2.reload.title).to eq '2'
+    end
+  end
+end
diff --git a/spec/migrations/schedule_fix_incorrect_max_seats_used2_spec.rb b/spec/migrations/schedule_fix_incorrect_max_seats_used2_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..26764f855b7e2ea4d9b35f168a541ff56c8e78e5
--- /dev/null
+++ b/spec/migrations/schedule_fix_incorrect_max_seats_used2_spec.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe ScheduleFixIncorrectMaxSeatsUsed2, :migration, feature_category: :purchase do
+  let(:migration_name) { described_class::MIGRATION.to_s.demodulize }
+
+  describe '#up' do
+    it 'schedules a job on Gitlab.com' do
+      allow(Gitlab).to receive(:com?).and_return(true)
+
+      Sidekiq::Testing.fake! do
+        freeze_time do
+          migrate!
+
+          expect(migration_name).to be_scheduled_delayed_migration(1.hour, 'batch_2_for_start_date_before_02_aug_2021')
+          expect(BackgroundMigrationWorker.jobs.size).to eq(1)
+        end
+      end
+    end
+
+    it 'does not schedule any jobs when not Gitlab.com' do
+      allow(Gitlab).to receive(:com?).and_return(false)
+
+      Sidekiq::Testing.fake! do
+        migrate!
+
+        expect(migration_name).not_to be_scheduled_delayed_migration
+        expect(BackgroundMigrationWorker.jobs.size).to eq(0)
+      end
+    end
+  end
+end
diff --git a/spec/migrations/schedule_fix_incorrect_max_seats_used_spec.rb b/spec/migrations/schedule_fix_incorrect_max_seats_used_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..194a1d39ad13363966f3825c88fd67af4ec62350
--- /dev/null
+++ b/spec/migrations/schedule_fix_incorrect_max_seats_used_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe ScheduleFixIncorrectMaxSeatsUsed, :migration, feature_category: :purchase do
+  let(:migration) { described_class.new }
+
+  describe '#up' do
+    it 'schedules a job on Gitlab.com' do
+      allow(Gitlab).to receive(:com?).and_return(true)
+
+      expect(migration).to receive(:migrate_in).with(1.hour, 'FixIncorrectMaxSeatsUsed')
+
+      migration.up
+    end
+
+    it 'does not schedule any jobs when not Gitlab.com' do
+      allow(Gitlab::CurrentSettings).to receive(:com?).and_return(false)
+
+      expect(migration).not_to receive(:migrate_in)
+
+      migration.up
+    end
+  end
+end
diff --git a/spec/migrations/schedule_update_timelogs_null_spent_at_spec.rb b/spec/migrations/schedule_update_timelogs_null_spent_at_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..99ee9e58f4e076d18a25df631f24ea6c9a959206
--- /dev/null
+++ b/spec/migrations/schedule_update_timelogs_null_spent_at_spec.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe ScheduleUpdateTimelogsNullSpentAt, feature_category: :team_planning do
+  let!(:namespace) { table(:namespaces).create!(name: 'namespace', path: 'namespace') }
+  let!(:project) { table(:projects).create!(namespace_id: namespace.id) }
+  let!(:issue) { table(:issues).create!(project_id: project.id) }
+  let!(:merge_request) { table(:merge_requests).create!(target_project_id: project.id, source_branch: 'master', target_branch: 'feature') }
+  let!(:timelog1) { create_timelog!(merge_request_id: merge_request.id) }
+  let!(:timelog2) { create_timelog!(merge_request_id: merge_request.id) }
+  let!(:timelog3) { create_timelog!(merge_request_id: merge_request.id) }
+  let!(:timelog4) { create_timelog!(issue_id: issue.id) }
+  let!(:timelog5) { create_timelog!(issue_id: issue.id) }
+
+  before do
+    table(:timelogs).where.not(id: timelog3.id).update_all(spent_at: nil)
+  end
+
+  it 'correctly schedules background migrations' do
+    stub_const("#{described_class}::BATCH_SIZE", 2)
+
+    Sidekiq::Testing.fake! do
+      freeze_time do
+        migrate!
+
+        expect(described_class::MIGRATION)
+          .to be_scheduled_delayed_migration(2.minutes, timelog1.id, timelog2.id)
+
+        expect(described_class::MIGRATION)
+          .to be_scheduled_delayed_migration(4.minutes, timelog4.id, timelog5.id)
+
+        expect(BackgroundMigrationWorker.jobs.size).to eq(2)
+      end
+    end
+  end
+
+  private
+
+  def create_timelog!(**args)
+    table(:timelogs).create!(**args, time_spent: 1)
+  end
+end
diff --git a/spec/migrations/start_backfill_ci_queuing_tables_spec.rb b/spec/migrations/start_backfill_ci_queuing_tables_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0a189b58c9499591e805a71c9a27d8027a7c692f
--- /dev/null
+++ b/spec/migrations/start_backfill_ci_queuing_tables_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe StartBackfillCiQueuingTables, :suppress_gitlab_schemas_validate_connection,
+  feature_category: :continuous_integration do
+  let(:namespaces) { table(:namespaces) }
+  let(:projects)   { table(:projects) }
+  let(:builds)     { table(:ci_builds) }
+
+  let!(:namespace) do
+    namespaces.create!(name: 'namespace1', path: 'namespace1')
+  end
+
+  let!(:project) do
+    projects.create!(namespace_id: namespace.id, name: 'test1', path: 'test1')
+  end
+
+  let!(:pending_build_1) do
+    builds.create!(status: :pending, name: 'test1', type: 'Ci::Build', project_id: project.id)
+  end
+
+  let!(:running_build) do
+    builds.create!(status: :running, name: 'test2', type: 'Ci::Build', project_id: project.id)
+  end
+
+  let!(:pending_build_2) do
+    builds.create!(status: :pending, name: 'test3', type: 'Ci::Build', project_id: project.id)
+  end
+
+  before do
+    stub_const("#{described_class.name}::BATCH_SIZE", 1)
+  end
+
+  it 'schedules jobs for builds that are pending' do
+    Sidekiq::Testing.fake! do
+      freeze_time do
+        migrate!
+
+        expect(described_class::MIGRATION).to be_scheduled_delayed_migration(
+          2.minutes, pending_build_1.id, pending_build_1.id)
+        expect(described_class::MIGRATION).to be_scheduled_delayed_migration(
+          4.minutes, pending_build_2.id, pending_build_2.id)
+        expect(BackgroundMigrationWorker.jobs.size).to eq(2)
+      end
+    end
+  end
+end
diff --git a/spec/migrations/update_application_settings_container_registry_exp_pol_worker_capacity_default_spec.rb b/spec/migrations/update_application_settings_container_registry_exp_pol_worker_capacity_default_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..66da9e6653d5c279d7e77124409feaf0dc78d318
--- /dev/null
+++ b/spec/migrations/update_application_settings_container_registry_exp_pol_worker_capacity_default_spec.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe UpdateApplicationSettingsContainerRegistryExpPolWorkerCapacityDefault,
+  feature_category: :container_registry do
+  let(:settings) { table(:application_settings) }
+
+  context 'with no rows in the application_settings table' do
+    it 'does not insert a row' do
+      expect { migrate! }.to not_change { settings.count }
+    end
+  end
+
+  context 'with a row in the application_settings table' do
+    before do
+      settings.create!(container_registry_expiration_policies_worker_capacity: capacity)
+    end
+
+    context 'with container_registry_expiration_policy_worker_capacity set to a value different than 0' do
+      let(:capacity) { 1 }
+
+      it 'does not update the row' do
+        expect { migrate! }
+          .to not_change { settings.count }
+          .and not_change { settings.first.container_registry_expiration_policies_worker_capacity }
+      end
+    end
+
+    context 'with container_registry_expiration_policy_worker_capacity set to 0' do
+      let(:capacity) { 0 }
+
+      it 'updates the existing row' do
+        expect { migrate! }
+          .to not_change { settings.count }
+          .and change { settings.first.container_registry_expiration_policies_worker_capacity }.from(0).to(4)
+      end
+    end
+  end
+end
diff --git a/spec/migrations/update_application_settings_protected_paths_spec.rb b/spec/migrations/update_application_settings_protected_paths_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c2bd4e8727d90260e4a0e07f8b9b68df81fee792
--- /dev/null
+++ b/spec/migrations/update_application_settings_protected_paths_spec.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe UpdateApplicationSettingsProtectedPaths, :aggregate_failures,
+  feature_category: :system_access do
+  subject(:migration) { described_class.new }
+
+  let!(:application_settings) { table(:application_settings) }
+  let!(:oauth_paths) { %w[/oauth/authorize /oauth/token] }
+  let!(:custom_paths) { %w[/foo /bar] }
+
+  let(:default_paths) { application_settings.column_defaults.fetch('protected_paths') }
+
+  before do
+    application_settings.create!(protected_paths: custom_paths)
+    application_settings.create!(protected_paths: custom_paths + oauth_paths)
+    application_settings.create!(protected_paths: custom_paths + oauth_paths.take(1))
+  end
+
+  describe '#up' do
+    before do
+      migrate!
+      application_settings.reset_column_information
+    end
+
+    it 'removes the OAuth paths from the default value and persisted records' do
+      expect(default_paths).not_to include(*oauth_paths)
+      expect(default_paths).to eq(described_class::NEW_DEFAULT_PROTECTED_PATHS)
+      expect(application_settings.all).to all(have_attributes(protected_paths: custom_paths))
+    end
+  end
+
+  describe '#down' do
+    before do
+      migrate!
+      schema_migrate_down!
+    end
+
+    it 'adds the OAuth paths to the default value and persisted records' do
+      expect(default_paths).to include(*oauth_paths)
+      expect(default_paths).to eq(described_class::OLD_DEFAULT_PROTECTED_PATHS)
+      expect(application_settings.all).to all(have_attributes(protected_paths: custom_paths + oauth_paths))
+    end
+  end
+end
diff --git a/spec/migrations/update_default_scan_method_of_dast_site_profile_spec.rb b/spec/migrations/update_default_scan_method_of_dast_site_profile_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..15a8e79a610b6a107ecfb910825d062b6e42055e
--- /dev/null
+++ b/spec/migrations/update_default_scan_method_of_dast_site_profile_spec.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe UpdateDefaultScanMethodOfDastSiteProfile, feature_category: :dynamic_application_security_testing do
+  let(:namespaces) { table(:namespaces) }
+  let(:projects) { table(:projects) }
+  let(:dast_sites) { table(:dast_sites) }
+  let(:dast_site_profiles) { table(:dast_site_profiles) }
+
+  before do
+    namespace = namespaces.create!(name: 'test', path: 'test')
+    project = projects.create!(id: 12, namespace_id: namespace.id, name: 'gitlab', path: 'gitlab')
+    dast_site = dast_sites.create!(id: 1, url: 'https://www.gitlab.com', project_id: project.id)
+
+    dast_site_profiles.create!(
+      id: 1,
+      project_id: project.id,
+      dast_site_id: dast_site.id,
+      name: "#{FFaker::Product.product_name.truncate(192)} #{SecureRandom.hex(4)} - 0",
+      scan_method: 0,
+      target_type: 0
+    )
+
+    dast_site_profiles.create!(
+      id: 2,
+      project_id: project.id,
+      dast_site_id: dast_site.id,
+      name: "#{FFaker::Product.product_name.truncate(192)} #{SecureRandom.hex(4)} - 1",
+      scan_method: 0,
+      target_type: 1
+    )
+  end
+
+  it 'updates the scan_method to 1 for profiles with target_type 1' do
+    migrate!
+
+    expect(dast_site_profiles.where(scan_method: 1).count).to eq 1
+    expect(dast_site_profiles.where(scan_method: 0).count).to eq 1
+  end
+end
diff --git a/spec/migrations/update_invalid_member_states_spec.rb b/spec/migrations/update_invalid_member_states_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6ae4b9f3c0fbd941e232bf4b36270434f9f80c0a
--- /dev/null
+++ b/spec/migrations/update_invalid_member_states_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe UpdateInvalidMemberStates, feature_category: :subgroups do
+  let(:members) { table(:members) }
+  let(:groups) { table(:namespaces) }
+  let(:projects) { table(:projects) }
+  let(:users) { table(:users) }
+
+  before do
+    user = users.create!(first_name: 'Test', last_name: 'User', email: 'test@user.com', projects_limit: 1)
+    group = groups.create!(name: 'gitlab', path: 'gitlab-org')
+    project = projects.create!(namespace_id: group.id)
+
+    members.create!(state: 2, source_id: group.id, source_type: 'Group', type: 'GroupMember', user_id: user.id, access_level: 50, notification_level: 0)
+    members.create!(state: 2, source_id: project.id, source_type: 'Project', type: 'ProjectMember', user_id: user.id, access_level: 50, notification_level: 0)
+    members.create!(state: 1, source_id: group.id, source_type: 'Group', type: 'GroupMember', user_id: user.id, access_level: 50, notification_level: 0)
+    members.create!(state: 0, source_id: group.id, source_type: 'Group', type: 'GroupMember', user_id: user.id, access_level: 50, notification_level: 0)
+  end
+
+  it 'updates matching member record states' do
+    expect { migrate! }
+      .to change { members.where(state: 0).count }.from(1).to(3)
+      .and change { members.where(state: 2).count }.from(2).to(0)
+      .and change { members.where(state: 1).count }.by(0)
+  end
+end