Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails migration extremely slow even when there are no pending migrations

My production rails application takes 167 seconds to run rake db:migrate. The sad part is that there are no migrations to run. I tried to condition the migration running on checking that there are pending migrations but then the check took just as long. The only "excuse" in my mind is that the db is not tiny, there are 1M records there, but I see no reason why that would matter at all. I looked in the log but there is nothing indicating anything going wrong. I am running with

  • Ruby 2.2.0
  • Rails 4.2.0

Does anyone have an idea why this is so, and whether there is anything to do about it?

like image 772
Assaf Shomer Avatar asked Dec 11 '15 14:12

Assaf Shomer


People also ask

How do I reset migration in rails?

just use rake db:reset , that will drop your database (same as undoing all migrations) and reset to the last schema. UPDATE: a more correct approach will be using rake db:migrate:reset . That will drop the database, create it again and run all the migrations, instead of resetting to the latest schema.

Are rails migrations run in a transaction?

On databases that support transactions with statements that change the schema, migrations are wrapped in a transaction. If the database does not support this then when a migration fails the parts of it that succeeded will not be rolled back. You will have to rollback the changes that were made by hand.

How does rails know migrations are pending?

It uses values from the current time for YYYYMMDDHHMMSS and the name of the migration. Once migrations are run, the value YYYYMMDDHHMMSS in migration file, is inserted in a table named schema_migrations .

How do I go down last migration in rails?

rails db:rollback:primary , where primary is the name of the database in your config/databases. yml file, to rollback the last migration. You can make usage of the STEPS attribute here, as usual. rails db:rollback:primary VERSION=your_migration_timestamp , to rollback only the provided migration version.


1 Answers

Running rake db:migrate task also invoke the db:schema:dump task, which will update your db/schema.rb. So even though you have no migrations you are causing other rake tasks to run which could be taking up that time depending on how many migrations/large your database schema is.

You can look into source code of db:* tasks (.../activerecord/railties/databases.rake)

desc "Migrate the database (options: VERSION=x, VERBOSE=false)."
task :migrate => :environment do
  ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
  ActiveRecord::Migrator.migrate("db/migrate/", ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
  Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
end

References: http://guides.rubyonrails.org/active_record_migrations.html#running-migrations

Does rake db:schema:dump recreate schema.rb from migrations or the database itself?

like image 124
ChrisBarthol Avatar answered Sep 28 '22 09:09

ChrisBarthol