-
Notifications
You must be signed in to change notification settings - Fork 57
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
Comments
I'm seeing this too across multiple apps at Doximity that use departure. |
@krismichalski are you sure reverting that PR works? I tried # Make all connections in the connection pool to use PerconaAdapter
# instead of the current adapter.
def reconnect_with_percona
ActiveRecord::Base.establish_connection(connection_config.merge(adapter: 'percona'))
end (changed from https://github.com/departurerb/departure/blob/master/lib/departure/migration.rb#L73C1-L78C8) and that still results in a different connection ID after I would also not recommend that patch to work around the issue; it effectively disables running pt-online-schema-change in favour of the default Rails migration runner (I noticed this when running in a Docker container without ptosc installed). One could try using the |
@brianjaustin Thank you so much for your message above! Due to this, I can confirm using the suggested patch indeed disables After your message, I spent a bunch of hours trying to understand what changed in Rails to cause this, and I finally found it! The change that broke departure happened on On Rails 7.0.8.7, this is how it is defined: def with_advisory_lock
lock_id = generate_migrator_advisory_lock_id
with_advisory_lock_connection do |connection| # <===========================
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
end
def with_advisory_lock_connection(&block)
pool = ActiveRecord::ConnectionAdapters::ConnectionHandler.new.establish_connection(
ActiveRecord::Base.connection_db_config
)
pool.with_connection(&block)
ensure
pool&.disconnect!
end And this is how it is defined on 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 Note that on Here is the Rails PR containing the abovementioned change. I don't know exactly how to patch Departure to make it work with these changes in
|
I'm getting
ActiveRecord::ConcurrentMigrationError: Failed to release advisory lock
on fresh rails 7.1.3.4 app.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
rails new departure_sample_rails_71_app -d mysql
departure
toGemfile
bundle install
rails db:create
rails g migration create_things
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
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
In rails 7.0.8.4
connection.instance_variable_get(:@config)[:adapter]
returnsmysql2
before and afteryield
.In rails 7.1.3.4
connection.instance_variable_get(:@config)[:adapter]
returnsmysql2
beforeyield
andpercona
after.Here are the logs from
log/development.log
during the migration:at some point the SQL commands are duplicated and I believe that the second
RELEASE_LOCK
fails and causes the error to be raised.The text was updated successfully, but these errors were encountered: