summaryrefslogtreecommitdiff
path: root/app/models/application_setting.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/application_setting.rb')
-rw-r--r--app/models/application_setting.rb18
1 files changed, 18 insertions, 0 deletions
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index 661b10019ad..eb46be65858 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -426,6 +426,8 @@ class ApplicationSetting < ApplicationRecord
end
def self.create_from_defaults
+ check_schema!
+
transaction(requires_new: true) do
super
end
@@ -434,6 +436,22 @@ class ApplicationSetting < ApplicationRecord
current_without_cache
end
+ # Due to the frequency with which settings are accessed, it is
+ # likely that during a backup restore a running GitLab process
+ # will insert a new `application_settings` row before the
+ # constraints have been added to the table. This would add an
+ # extra row with ID 1 and prevent the primary key constraint from
+ # being added, which made ActiveRecord throw a
+ # IrreversibleOrderError anytime the settings were accessed
+ # (https://gitlab.com/gitlab-org/gitlab/-/issues/36405). To
+ # prevent this from happening, we do a sanity check that the
+ # primary key constraint is present before inserting a new entry.
+ def self.check_schema!
+ return if ActiveRecord::Base.connection.primary_key(self.table_name).present?
+
+ raise "The `#{self.table_name}` table is missing a primary key constraint in the database schema"
+ end
+
# By default, the backend is Rails.cache, which uses
# ActiveSupport::Cache::RedisStore. Since loading ApplicationSetting
# can cause a significant amount of load on Redis, let's cache it in