Skip to content

Fix foreign_key_exists? migration helper

Krasimir Angelov requested to merge ka/fix/394760 into master

What does this MR do and why?

Use .column_exists? rather than checking ActiveRecord::Migrator.current_version, as backported migration break this assumption.

See #394760 (comment 1303224068).

Screenshots or screen recordings

Screenshots are required for UI changes, and strongly recommended for all other merge requests.

How to set up and validate locally

  1. export GITLAB_HOME=/srv/gitlab

  2. Start pre 15.7 version, for example 15.6.8.

docker run \
  --hostname gitlab.example.com \
  --publish 3080:80 \
  --name gitlab \
  --restart always \
  --volume $GITLAB_HOME/config:/etc/gitlab \
  --volume $GITLAB_HOME/logs:/var/log/gitlab \
  --volume $GITLAB_HOME/data:/var/opt/gitlab \
  --shm-size 256m \
gitlab/gitlab-ee:15.6.8-ee.0
  1. Follow the docs to upgrade to gitlab/gitlab-ee:15.9.2-ee.0, migrations will fail as reported with PG::UndefinedColumn: ERROR: column postgres_foreign_keys.constrained_table_name does not exist

  2. Build a new image that includes the fix from this MR

Dockerfile:

FROM gitlab/gitlab-ee:15.9.2-ee.0

COPY migration_helpers.patch /opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/database/migration_helpers.patch
RUN cd /opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/database && patch < migration_helpers.patch

migration_helpers.patch:

--- a/lib/gitlab/database/migration_helpers.rb
+++ b/lib/gitlab/database/migration_helpers.rb
@@ -367,12 +367,12 @@ def validate_foreign_key(source, column, name: nil)
 
       def foreign_key_exists?(source, target = nil, **options)
         # This if block is necessary because foreign_key_exists? is called in down migrations that may execute before
-        # the postgres_foreign_keys view had necessary columns added, or even before the view existed.
+        # the postgres_foreign_keys view had necessary columns added.
         # In that case, we revert to the previous behavior of this method.
         # The behavior in the if block has a bug: it always returns false if the fk being checked has multiple columns.
         # This can be removed after init_schema.rb passes 20221122210711_add_columns_to_postgres_foreign_keys.rb
         # Tracking issue: https://gitlab.com/gitlab-org/gitlab/-/issues/386796
-        if ActiveRecord::Migrator.current_version < 20221122210711
+        unless connection.column_exists?('postgres_foreign_keys', 'constrained_table_name')
           return foreign_keys(source).any? do |foreign_key|
             tables_match?(target.to_s, foreign_key.to_table.to_s) &&
                 options_match?(foreign_key.options, options)
  1. Build with docker build -t gitlab-fk-error:latest ..

  2. Start the container

docker run \
  --hostname gitlab.example.com \
  --publish 3080:80 \
  --name gitlab \
  --restart always \
  --volume $GITLAB_HOME/config:/etc/gitlab \
  --volume $GITLAB_HOME/logs:/var/log/gitlab \
  --volume $GITLAB_HOME/data:/var/opt/gitlab \
  --shm-size 256m \
 gitlab-fk-error:latest 
  1. The migrations will execute successfully.

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Krasimir Angelov

Merge request reports

Loading