Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ActiveRecord::ConcurrentMigrationError with departure on fresh rails 7.1.3.4 app #110

Open
krismichalski opened this issue Jun 12, 2024 · 0 comments

Comments

@krismichalski
Copy link

krismichalski commented Jun 12, 2024

I'm getting ActiveRecord::ConcurrentMigrationError: Failed to release advisory lock on fresh rails 7.1.3.4 app.

╰─ rails db:migrate
Including for_alter statements
== 20240612095004 CreateThings: migrating =====================================
-- create_table(:things)
   -> 0.0076s
== 20240612095004 CreateThings: migrated (0.0076s) ============================

bin/rails aborted!
ActiveRecord::ConcurrentMigrationError:  (ActiveRecord::ConcurrentMigrationError)

Failed to release advisory lock


Tasks: TOP => db:migrate
(See full trace by running task with --trace

Environment

macOS Sonoma 14.4.1
mySQL 8.0.34 for macos13 on arm64
pt-online-schema-change 3.5.5
ruby 3.2.2
rails 7.1.3.4
departure 6.7.0

Steps to reproduce

  1. rails new departure_sample_rails_71_app -d mysql
  2. Add departure to Gemfile
  3. bundle install
  4. rails db:create
  5. rails g migration create_things
  6. rails db:migrate

There will be an error, but changes in database will appear - it's possible to do rails db:rollback which reverts the changes and produces the same error.

Additional notes

There was a similar issue in the past for rails 5.2.0 - #31 - and reverting the fix for that issue (#32) fixes the problem for rails 7.1.3.4.

After adding:
config/initializers/departure_connection_base_overwrite.rb

module Departure
  class ConnectionBase < ActiveRecord::Base
    def self.establish_connection(config = nil)
      super
    end
  end

  class OriginalAdapterConnection < ConnectionBase; end
end

rails db:migrate works without issue.

The problem is in this rails method: https://github.com/rails/rails/blob/v7.1.3.4/activerecord/lib/active_record/migration.rb#L1594

      def with_advisory_lock
        lock_id = generate_migrator_advisory_lock_id

        got_lock = connection.get_advisory_lock(lock_id)
        raise ConcurrentMigrationError unless got_lock
        load_migrated # reload schema_migrations to be sure it wasn't changed by another process before we got the lock
        yield
      ensure
        if got_lock && !connection.release_advisory_lock(lock_id)
          raise ConcurrentMigrationError.new(
            ConcurrentMigrationError::RELEASE_LOCK_FAILED_MESSAGE
          )
        end
      end

In rails 7.0.8.4 connection.instance_variable_get(:@config)[:adapter] returns mysql2 before and after yield.
In rails 7.1.3.4 connection.instance_variable_get(:@config)[:adapter] returns mysql2 before yield and percona after.

Here are the logs from log/development.log during the migration:

   (0.1ms)  SELECT GET_LOCK('2327322385476548145', 0)
  ActiveRecord::SchemaMigration Load (0.2ms)  SELECT `schema_migrations`.`version` FROM `schema_migrations` ORDER BY `schema_migrations`.`version` ASC
  ActiveRecord::InternalMetadata Load (0.6ms)  SELECT * FROM `ar_internal_metadata` WHERE `ar_internal_metadata`.`key` = 'environment' ORDER BY `ar_internal_metadata`.`key` ASC LIMIT 1
Migrating to CreateThings (20240612095004)
   (0.2ms)  SET NAMES utf8mb4,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.wait_timeout = 2147483
   (0.1ms)  SET NAMES utf8mb4,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.wait_timeout = 2147483
   (6.2ms)  CREATE TABLE `things` (`id` bigint NOT NULL AUTO_INCREMENT PRIMARY KEY, `created_at` datetime(6) NOT NULL)
   (8.2ms)  CREATE TABLE `things` (`id` bigint NOT NULL AUTO_INCREMENT PRIMARY KEY, `created_at` datetime(6) NOT NULL)
  ActiveRecord::SchemaMigration Create (0.5ms)  INSERT INTO `schema_migrations` (`version`) VALUES ('20240612095004')
   (0.4ms)  SELECT RELEASE_LOCK('2327322385476548145')
   (1.3ms)  SELECT RELEASE_LOCK('2327322385476548145')

at some point the SQL commands are duplicated and I believe that the second RELEASE_LOCK fails and causes the error to be raised.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant