Should Rails migration be thread safe?

Now that multiple database support has landed in Rails, I was wondering if Rails migration should be updated such that it is thread safe. Since migration can be run against different databases, one can speed up migrations by running it concurrently using threads. This was what we tried to do at Discourse but we quickly ran into thread-safety issues. In particular, lines like the following were causing problems for us.

Was wondering if the core team has any thoughts about this.

5 Likes

I’m curious: how is Discourse using multiple databases? I would think that multiple processes would be faster except in the case of large numbers of databases, especially for migrations where there is almost no need for cross-process communication.

We’re using GitHub - discourse/rails_multisite: Multi tenancy for Rails applications where each site gets its own database.

We opted for threads initially because it is easier to get proper logging going.

2 Likes

Note number wise some our clusters run upwards of 200 databases per rails app

Hence migrations being a challenge for a single process

2 Likes

What you mean is that you want migration to be concurrent, not thread safe. Well… chances are that if an application is using multiple databases they are still somehow interconnected in a logical and/or technical way. That probably warrants analysing the migration and determining if there are dependencies and how those should be dealt with.

Initially I would say that making migrations thread-safe so it is possible to run tasks concurrently is not worth it. After the start of the SDLC migrations probably are only minor (add a column, change a constraint, that kind of stuff) so concurrent migrations will not deliver a lot of value.

Agree. But parallelizing migrations will probably run into different problems. Having 200 databases per rails app that makes me curious about how many database servers you use for that and immediately raises all kind of performance/reliability flags. This being an outlier probably already warranted a different way to migrate them than use the standard migration mechanism.

Sorry let me clarify, we want to run migrations concurrently for different databases using threads. Migrations for the same database cannot be done concurrently and ActiveRecord actually protects against it by taking our an advisory lock before the start of each migration.

My concern is that if you use multiple databases in a single app that there are interconnections between them that prevent concurrent migrations to be worthwhile. That leaves edge cases that might benefit but I think you can deal with them by running multiple migration processes instead of threads.

Not that I think that your question isn’t worthwhile to think about.