Skip to content

User model does not use Foreign Keys to nullify dependents

Discovered by !74177 (merged).

When executing bin/rspec spec/features/profile_spec.rb:29 it fails with:

Puma caught this error: Cross-database data modification of 'gitlab_main, gitlab_ci' were detected within a transaction modifying the 'uploads, routes, namespaces, keys, project_authorizations, events, releases, ci_builds' tables

This happens due:

  1. The profile_spec.rb:29 calls RegistrationsController#destroy
  2. The RegistrationsController#destroy calls current_user.delete_async
  3. The current_user.delete_async calls DeleteUserWorker.perform_async
  4. Since it is feature spec configured to run sidekiq inline
  5. Since it is feature spec it runs controller requests in a separate thread
  6. The DeleteUserWorker.perform calls Users::DestroyService.execute
  7. The Users::DestroyService.execute calls user.destroy
  8. Since user.destroy has has_many builds, pipelines set to nullify within a single transaction this tries to UPDATE ci_builds SET user_id=NULL failing cross-database modification
class User
  has_many :builds,                   dependent: :nullify, class_name: 'Ci::Build' # rubocop:disable Cop/ActiveRecordDependent
  has_many :pipelines,                dependent: :nullify, class_name: 'Ci::Pipeline' # rubocop:disable Cop/ActiveRecordDependent
end

Proposal

Migrate has_many dependent: :nullify to the usage of Loose Foreign Key.

Edited by Kamil Trzciński