Giter Site home page Giter Site logo

departurerb / departure Goto Github PK

View Code? Open in Web Editor NEW

This project forked from redbooth/departure

137.0 5.0 53.0 639 KB

Percona's pt-online-schema-change runner for ActiveRecord migrations.

License: Other

Ruby 98.95% Shell 0.07% HTML 0.20% Dockerfile 0.78%
mysql schema-migrations activerecord rails

departure's Introduction

Departure

Build Status Code Climate maintainability GitHub commits since latest release (by date)

Departure is an ActiveRecord connection adapter that allows running MySQL online and non-blocking DDL through ActiveRecord::Migration without needing to use a different DSL other than Rails' migrations DSL.

It uses pt-online-schema-change command-line tool of Percona Toolkit which runs MySQL alter table statements without downtime.

Rename from "Percona Migrator"

This project was formerly known as "Percona Migrator", but this incurs in an infringement of Percona's trade mark policy and thus has to be renamed. Said name is likely to cause confusion as to the source of the wrapper.

The next major versions will use "Departure" as gem name.

Installation

Departure relies on pt-online-schema-change from Percona Toolkit

Mac

brew install percona-toolkit

If when running a migration you see an error like:

PerconaMigrator::Error: Cannot connect to MySQL: Cannot connect to MySQL because
the Perl DBI module is not installed or not found.

You also need to install the DBI and DBD::MySQL modules from cpan.

$ sudo cpan
cpan> install DBI
cpan> install DBD::mysql

Linux

Ubuntu/Debian based

apt-get install percona-toolkit

Arch Linux

pacman -S percona-toolkit perl-dbd-mysql

Other distros

For other Linux distributions check out the Percona Toolkit download page to find the package that fits your distribution.

You can also get it from Percona's apt repository

Once installed, add this line to your application's Gemfile:

gem 'departure'

And then execute:

$ bundle

Or install it yourself as:

$ gem install departure

Usage

Once you added it to your app's Gemfile, you can create and run Rails migrations as usual.

All the ALTER TABLE statements will be executed with pt-online-schema-change, which will provide additional output to the migration.

pt-online-schema-change arguments

with environment variable

You can specify any pt-online-schema-change arguments when running the migration. All what you pass in the PERCONA_ARGS env var, will be bypassed to the binary, overwriting any default values. Note the format is the same as in pt-online-schema-change. Check the full list in Percona Toolkit documentation

$ PERCONA_ARGS='--chunk-time=1' bundle exec rake db:migrate:up VERSION=xxx

or even mulitple arguments

$ PERCONA_ARGS='--chunk-time=1 --critical-load Threads_running=55' bundle exec rake db:migrate:up VERSION=xxx

Use caution when using PERCONA_ARGS with db:migrate, as your args will be applied to every call that Departure makes to pt-osc.

with global configuration

You can specify any pt-online-schema-change arguments in global gem configuration using global_percona_args option.

Departure.configure do |config|
  config.global_percona_args = '--chunk-time=1 --critical-load Threads_running=55'
end

Unlike using PERCONA_ARGS, options provided with global configuration will be applied every time sql command is executed via pt-online-schema-change.

Arguments provided in global configuration can be overwritten with PERCONA_ARGS env variable.

We recommend using this option with caution and only when you understand the consequences.

LHM support

If you moved to Soundcloud's Lhm already, we got you covered. Departure overrides Lhm's DSL so that all the alter statements also go through pt-online-schema-change as well.

You can keep your Lhm migrations and start using Rails migration's DSL back again in your next migration.

Configuration

You can override any of the default values from an initializer:

Departure.configure do |config|
  config.tmp_path = '/tmp/'
end

It's strongly recommended to name it after this gems name, such as config/initializers/departure.rb

Disable on per-migration basis

Departure gem is enabled by default. In order to disable it on a particular migration the method disable_departure! should be used.

class UseDepartureMigration < ActiveRecord::Migration[7.1]
  disable_departure!

  def up
    # ...
  end
  # ...
end

Enable on per-migration basis

If you wish to only have Departure enabled per-migration, set config.enabled_by_default = false in the configure block of your departure initializer.

Then, add a uses_departure! statement in migrations where Departure should be used:

class UseDepartureMigration < ActiveRecord::Migration[7.1]
  uses_departure!

  def up
    # ...
  end
  # ...
end

How it works

When booting your Rails app, Departure extends the ActiveRecord::Migration#migrate method to reset the connection and reestablish it using the DepartureAdapter instead of the one you defined in your config/database.yml.

Then, when any migration DSL methods such as add_column or create_table are executed, they all go to the DepartureAdapter. There, the methods that require ALTER TABLE SQL statements, like add_column, are overriden to get executed with Departure::Runner, which deals with the pt-online-schema-change binary. All the others, like create_table, are delegated to the ActiveRecord's built in Mysql2Adapter and so they follow the regular path.

Departure::Runner spawns a new process that runs the pt-online-schema-change binary present in the system, with the appropriate arguments for the generated SQL.

When any errors occur, an ActiveRecord::StatementInvalid exception is raised and the migration is aborted, as all other ActiveRecord connection adapters.

Trouleshooting

Error creating new table: DBD::mysql::db do failed: Can't write; duplicate key in table (TABLE_NAME)

There is a known bug in percona-toolkit version 2.2.15 that prevents schema changes when a table has constraints. You should upgrade to a version later than 2.2.17 to fix the issue.

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/departurerb/departure.

Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

Check the code of conduct here

Changelog

You can consult the changelog here

License

The gem is available as open source under the terms of the MIT License.

GitHub code size in bytes GitHub issues

departure's People

Contributors

anfleene avatar aqeelvn avatar aserafin avatar benlangfeld avatar bhacaz avatar brianjaustin avatar csaura avatar davidenglishmusic avatar davidmyersdev avatar davisben85 avatar dylan-tock avatar enriclluelles avatar etagwerker avatar franciscoj avatar garettarrowood avatar geclos avatar guilleiguaran avatar ionut998 avatar jarednielson avatar magec avatar morantron avatar muffinista avatar nakort avatar nicksieger avatar sauloperez avatar sikachu avatar smoncadamdlive avatar troystauffer avatar wyhaines avatar xjunior avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

departure's Issues

add_index is not using running through Percona for ActiveRecord >= 6.1

Hi there!

Because of this condition, the method add_index is not running through Percona for ActiveRecord > 6.1 because it does not run an "ALTER TABLE" query, which is required here to use the command line.

Is that on purpose?

From what I saw, this conditional was added to use the same code as ActiveRecord 6.1 uses when adding an index here, but I think it is "skipping" the command line accidentally.

If I'm right, what about adding "CREATE INDEX" as a type of query that should run via command line?

Can we add some developers as the maintainer of this gem?

Hi @wyhaines!

Would you mind if we can add some Cookpad developers to the maitener of this gem? Since we've started developing this gem when we are in Cookpad and the team still uses the gem in production.

So, Cookpad developers also can push PRs and reviews issues/PRs so we can improve the support of newer version of Rails. What do you think?

Note:

In fact, I don't understand who has admin permissions of the depaturerb organization because I could not find any people in the organization. Do you know who owns the organization?

Errors when dropping FK

I'm having great troubles removing foreign keys from a table when using departure: the FK to remove is never found.

For investigation purposes, I have created a new Rails project with two simple models with the following migrations:

    create_table :users do |t|
      t.string :name
      t.string :email

      t.timestamps
    end

    create_table :posts do |t|
      t.string :name
      t.text :body
      t.references :user, foreign_key: true

      t.timestamps
    end

After running these migrations and adding some data, add another migration to remove the user column from the posts table:

    remove_reference :posts, :user, index: true, foreign_key: true

This raises the following error:

rake aborted!
StandardError: An error has occurred, all later migrations canceled:

Departure::Error: No foreign keys reference departure_test_development.posts; ignoring --alter-foreign-keys-method.
Error altering new table departure_test_development._posts_new: DBD::mysql::db do failed: Can't DROP 'fk_rails_5b5ddfd518'; check that column/key exists [for Statement "ALTER TABLE departure_test_development._posts_new DROP FOREIGN KEY fk_rails_5b5ddfd518"] at /usr/local/Cellar/percona-toolkit/3.0.4/libexec/bin/pt-online-schema-change line 9142.

: ALTER TABLE posts DROP FOREIGN KEY fk_rails_5b5ddfd518

I have no real clue why this is failing, but according to this article the FK in the temporary table should be prefixed with an extra underscore. Could that be the problem?

Rails 5.2 support

Rails 5.2 was released today but unfortunately Departure gemspec is locking the gem to only support 5.1.x versions.

Not sure if it's only about loosening the dependency a bit or changes introduced in Rails 5.2 would break the current implementation of Departure.

Logging specs fails on specific seeds

On some specific seeds logging specs fails on stdout check.

Sample environment:

  • Ruby 2.6.6
  • Rails 5.2.0.

Seed 18011: 267 examples, 0 failures, 3 pending
Seed 27815: 267 examples, 1 failure, 3 pending

$ bundle exec rspec --seed 27815
[...]

  1) Departure logging when the migration logging is disabled doesn't send the output to stdout
     Failure/Error:
       expect do
         ActiveRecord::Migrator.new(direction, migration_fixtures, ActiveRecord::SchemaMigration, 1).migrate
       end.to_not output.to_stdout
     
       expected block to not output to stdout, but output "\n   -> Running pt-online-schema-change -h \"localhost\" -P 3306 -u root [filtered_password] --execu...Event  Count\n# ====== =====\n# INSERT     1\nSuccessfully altered `departure_test`.`comments`.\n\n"
     # ./spec/integration_spec.rb:36:in `block (4 levels) in <top (required)>'
     # ./spec/integration_spec.rb:31:in `block (4 levels) in <top (required)>'

Finished in 43.38 seconds (files took 1.05 seconds to load)
267 examples, 1 failure, 3 pending

Sample GitHub Actions build: #83

Code Cimate github integration

Although we do have an account on Code Climate we're not seeing its status on the pull requests. It is something important to have.

SystemStackError: stack level too deep (Module#prepend)

We are getting a SystemStackError: stack level too deep with the strong_migrations gem installed.

/Users/me/.rbenv/versions/2.6.8/lib/ruby/gems/2.6.0/bundler/gems/departure-b7187bcf0061/lib/departure/migration.rb:60:in `migrate'
/Users/me/.rbenv/versions/2.6.8/lib/ruby/gems/2.6.0/gems/strong_migrations-1.4.4/lib/strong_migrations/migration.rb:5:in `migrate'
/Users/me/.rbenv/versions/2.6.8/lib/ruby/gems/2.6.0/bundler/gems/departure-b7187bcf0061/lib/departure/migration.rb:60:in `migrate'
/Users/me/.rbenv/versions/2.6.8/lib/ruby/gems/2.6.0/gems/strong_migrations-1.4.4/lib/strong_migrations/migration.rb:5:in `migrate'
/Users/me/.rbenv/versions/2.6.8/lib/ruby/gems/2.6.0/bundler/gems/departure-b7187bcf0061/lib/departure/migration.rb:60:in `migrate'
/Users/me/.rbenv/versions/2.6.8/lib/ruby/gems/2.6.0/gems/strong_migrations-1.4.4/lib/strong_migrations/migration.rb:5:in `migrate'
/Users/me/.rbenv/versions/2.6.8/lib/ruby/gems/2.6.0/gems/activerecord-6.1.7.3/lib/active_record/migration.rb:1037:in `migrate'
      # departure/migration.rb:21
      alias_method :active_record_migrate, :migrate
      remove_method :migrate
    def migrate(direction)
      if uses_departure?
        departure_migrate(direction)
      else
        reconnect_without_percona
        active_record_migrate(direction) # departure/migration.rb:60
      end
    end

And I received this message from the creator of strong_migrations. "I looked into this for another two gems a while back, and the (older) alias_method pattern isn't compatible with Module#prepend. Updating departure to use Module#prepend should fix it."

enabled_by_default is not yet released?

It looks like maybe this was added after the most recent release?

*** LOCAL GEMS ***

departure (6.2.0)

NoMethodError: undefined method `enabled_by_default=' for #Departure::Configuration:0x0000564e7fb4d240

pt-osc - output maxing at 8 chars

Running migrations locally, I do not encounter this problem. However, when my demo and production servers run migrations during deployment (on VM running Linux, with migration triggered by Capistrano), the logs are always messed up. Here is a gist of one such migration -

https://gist.github.com/garettarrowood/42449b48709d85017a13bd5e522183ab

I think the issue is the read_nonblock(8) method here - https://github.com/redbooth/departure/blob/master/lib/departure/command.rb#L47 .

I'll open a PR, tie my repo to it, and see if just raising the number to 40 solves the problem. But before I do, can you provide some reference why a max length of 8 is used here? What problem might I create by changing it?


Upon further thought - it seems more likely logger.write_no_newline(data) is not working correctly.

Is there a way to alter a table?

I would like to change encoding for one of my tables by using Percona, but the only way I googled is to execute a custom SQL like:

class ChangeCommentsToUtf8mb4 < ActiveRecord::Migration
  def up
    execute "ALTER TABLE comments CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin"
  end
end

but in this case, it won't run with Percona.
Is there a way to alter a table and still run it via Percona?

mysql2 dependency is very restrictive

When a new mysql2 version is released, as happened yesterday with 0.5.6, many applications will attempt to upgrade immediately if they're using tools like Renovate. This gem pins the precise maximum version of mysql (presumably because we've been bitten by new pre-1.0 versions breaking backward compatibility in the past, though I couldn't find evidence of this), blocking such updates until we bump the dependency specification and release a new version of departure. We likely won't do this very quickly, and so we'll create frustration for users who want to stay up to date.

I believe we should:

  1. Set up Renovate in this repo to automatically bump dependency versions to the latest when released.
  2. Run CI on the latest version of these dependencies.
  3. Automatically merge upgrades which pass CI and automatically trigger a release.

or simply relax the dependency specification at least to ~> 0.5 the same as Rails does.

Rails 5 support

Support for Rails v5.1 is currently being implemented in redbooth#81. Although there should be very little difference between the changes required for 5.1 and what is needed for 5.0, it is still to be done.

redbooth#41 is the original issue which contains the body of the discussion.

Add PR template

We need to add a PR template so that contribution guidelines are clear beforehand. This should avoid maintainers asking for the changelog update. There are possibly other things worth asking like adding integration and units tests.

Rails 5.2.0 migration fails with departure

Context

Migration with departure in rails 5.2 fails. This PR has tried to add support to 5.2 but a new issue is noticed.

Issue

Here is a sample error log when doing a simple migration with departure:

Altering `my_database`.`test_tables`...
Creating new table...
Created new table my_database._test_tables_new OK.
Altering new table...
Altered `my_database`.`_test_tables_new` OK.
2018-04-25T16:50:04 Creating triggers...
2018-04-25T16:50:04 Created triggers OK.
2018-04-25T16:50:04 Copying approximately 1 rows...
2018-04-25T16:50:05 Copied rows OK.
2018-04-25T16:50:05 Analyzing new table...
2018-04-25T16:50:05 Swapping tables...
2018-04-25T16:50:05 Swapped original and new tables OK.
2018-04-25T16:50:05 Dropping old table...
2018-04-25T16:50:05 Dropped old table `my_database`.`_test_tables_old` OK.
2018-04-25T16:50:05 Dropping triggers...
2018-04-25T16:50:05 Dropped triggers OK.
# Event  Count
# ====== =====
# INSERT     1
Successfully altered `my_database`.`test_tables`.

   -> 0.8832s
== 20180425111712 AddColumn3ToTestTable: migrated (0.8833s) ===================

rails aborted!
Mysql2::Error: MySQL client is not connected

Reason for failing

This issue is introduced by this rails commit

 def with_advisory_lock
  lock_id = generate_migrator_advisory_lock_id
  connection = Base.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

Comparison with previous rails (5.1.6)

A simplified logic of how migration runs in rails 5.1.6:

  • create new connection to database (connection_1)
  • obtain database lock with connection_1
  • run migration
  • create new connection to database (connection_2
  • release lock with connection_2

In rails 5.2.0 this is slightly changed to:

  • create new connection to database (connection_1)
  • obtain database lock with connection_1
  • run migration
  • release lock with same connection_1

Now when migration is run with departure's percona adapter, the first connection_1 always gets disconnected, because reconnect_with_percona does a new establish_connection, and the existing default connection (connection_1) will be disconnected and replaced with percona_connection under the same connection_specification_name (which is "primary"). Because rails now re-uses the connection object created before migration, this will raise exception because it was disconnected for percona.

Related rails issue:

rails/rails#32622

Solve 'using password on command line' warning

We need to solve the warning below when executing the test suite:

(...)
    when index is set to true
Warning: Using a password on the command line interface can be insecure.
Warning: Using a password on the command line interface can be insecure.
Warning: Using a password on the command line interface can be insecure.
        adds an index for the reference column
(...)

we might need to specify the password of the testing database in a config file.

New release required due to XSS security issues

Due to the following vulnerability:

There is a possible XSS vulnerability in Rails / Action Pack. This vulnerability has been assigned the CVE identifier CVE-2022-22577.

Versions Affected: >= 5.2.0
Not affected: < 5.2.0
Fixed Versions: 7.0.2.4, 6.1.5.1, 6.0.4.8, 5.2.7.1

Fullcontent: https://discuss.rubyonrails.org/t/cve-2022-22577-possible-xss-vulnerability-in-action-pack/80533

The latest released version of the gem is not allowing us to fix this vulnerability. In the version 6.3.0 the latest release, we have this version range:

['>= 5.2.0', '<= 6.1']

RAILS_DEPENDENCY_VERSION = ENV.fetch('RAILS_VERSION', ['>= 5.2.0', '<= 6.1'])

Which does not allow us to update railties and actionrecord to version 6.1.5.1 which fixes the security issues.

Is there a reason why master was not released? It seems to have a version range that corrects the issue.

Support departure when using it in environments together with apartment and octopus

Apartment gem is used for handling multi tenancy on database level. This means, having multiple databases which should have the same schema.
Octopus can be used to take care of master / slave mysql structure and route the queires to the right node (shard)
When using departure in an environment together with apartment and octopus, we are getting the following error:

ActiveRecord::RecordNotUnique: Mysql2::Error: Duplicate entry '20180109094356' for key 'unique_schema_migrations': INSERT INTO `schema_migrations` (`version`) VALUES ('20180109094356'): INSERT INTO `schema_migrations` (`version`) VALUES ('20180109094356')

Doing some investigation, it looks like we are always trying to connect to the same database (the main database which is set in the config file) and not to the one, which was selected by apartment

Document the version number in Departure

With the rename to Departure we've changed the version numbers. This and the release process should be carefully documented. It needs to explain how to proceed when providing support for a major Rails version like 5.0 or 5.1.

Hooks

I wish there were a couple of hooks. Process started & process finished would be nice.

Add CONTRIBUTING.md

So far we only have a little section in the README.md but without any instructions on how to proceed with a code change. This would help onboarding new contributors (hopefully).

Now github adds links to that file when opening a new PR.

Check for pt-osc presence before running

There's an edge case concerning create table and adding and index.

When you run a create table migration that includes an index creation from a machine that doesn't have percona-toolkit installed, the table will be created but the index will not, as the former doesn't go through pt-online-schema-change.

We should check it and raise a PerconaMigrator::CommandNotFoundError accordingly, before running a CREATE TABLE.

This also applies to any other DDL statements that don't go through pt-online-schema-change.

Specs fail out of the box on Big Sur

I am looking to contribute to the gem but am having trouble getting all the specs to pass for the current master.

In running rake spec, a number of them fail: 249 examples, 59 failures, 3 pending

I expect this is likely a config issue related to the perl libraries and OS X Big Sur. The error message for those is:

Departure::Error: DBI.c: loadable library and perl binaries are mismatched (got handshake key 0xc500080, needed 0xc400080)

I ran the cpan setup in the readme for which the last command install DBD::mysql fails with:

./dbdimp.h:20:10: fatal error: 'DBIXS.h' file not found
#include <DBIXS.h>  /* installed by the DBI module                        */

I would welcome any assistance on this. I have yet to google my way out of it.

Get 1st time open source contributions

I believe many issues of this repo could be solved by newbies or first-timers. They are simple enough to jump in and get confidence and experience.

Some sites that showcase open source issues for newcomers are: https://www.codetriage.com/, http://up-for-grabs.net, https://contributor.ninja/, http://www.firsttimersonly.com/, https://yourfirstpr.github.io/ we could post them there.

To do that thought we should describe these issues in detail providing links to the particular files, methods, lines, etc. where things should be implemented.

Cannot update to Rails 6.1.4

Looks like departure is capped at rails <= 6.1

Bundler could not find compatible versions for gem "activerecord":
  In Gemfile:
    departure (~> 6.3.0) was resolved to 6.3.0, which depends on
      activerecord (>= 5.2.0, <= 6.1)

    rails (>= 6.1.4, < 6.2) was resolved to 6.1.4, which depends on
      activerecord (= 6.1.4)

Can you please cut a new release to allow updates?

Sharing the workload

Hi everyone,

this is a call for those regular contributors to jump on and share the workload of maintaining Departure.

My situation has changed a lot since the project started. I spend most of my time shaping Coopdevs and pushing forward Open Food Network which leaves me little room for anything else. Besides, I no longer use it on my projects so I don't have direct incentive to maintain it although I consider it a very useful tool.

Which one of you @guilleiguaran, @wyhaines, @garettarrowood, @aserafin, @muffinista would be open for that? thoughts?

Support for Rails 6.1

Now that Rails 6.1 is out, has there been any attempt to upgrade the gem for new version of AR? The dependency limits it to < 6.1.

ActiveRecord::ConcurrentMigrationError with departure on fresh rails 7.1.3.4 app

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.