online_migrations 0.27.1 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/lib/generators/online_migrations/templates/background_data_migrations_add_iteration_pause.rb.tt +7 -0
- data/lib/generators/online_migrations/templates/initializer.rb.tt +3 -0
- data/lib/generators/online_migrations/templates/install_migration.rb.tt +1 -0
- data/lib/generators/online_migrations/upgrade_generator.rb +9 -8
- data/lib/online_migrations/background_data_migrations/migration.rb +3 -1
- data/lib/online_migrations/background_data_migrations/migration_helpers.rb +2 -2
- data/lib/online_migrations/background_data_migrations/migration_job.rb +2 -1
- data/lib/online_migrations/background_schema_migrations/migration_helpers.rb +10 -6
- data/lib/online_migrations/schema_cache.rb +13 -7
- data/lib/online_migrations/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: babb68ddc337cbc52cb3a10d842dfb427031544fa8b32716b9b0166996f45252
|
4
|
+
data.tar.gz: '08e334985d6ecbe603831ad44a9b535d3e39ee1b7f17bb576fc035b9de11c84c'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca383bfa73dd712076f3ac5ade02767955a7da7ec99306258d70a61b32331226fc22f4a84fea3f37423e7ebce2e805b514077bd13fcee1fcb09ae3ac637ac53f
|
7
|
+
data.tar.gz: 470a1d00e16f00b70a248c0ea2e0a3acfcb3e05b165fe5d12fa966c3f03d2a40c953fe4dd9265d210c330fca0b2536143716a47adfb9f1a8749d3348183e4959
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
## master (unreleased)
|
2
2
|
|
3
|
+
## 0.29.0 (2025-07-10)
|
4
|
+
|
5
|
+
- Add `iteration_pause` column to background data migrations
|
6
|
+
|
7
|
+
Note: Run `bin/rails generate online_migrations:upgrade` if using background data migrations.
|
8
|
+
Make sure all data migrations finished before applying this migration or change its timestamp
|
9
|
+
to be older than all pending db migrations which will enqueue data migrations.
|
10
|
+
|
11
|
+
## 0.28.0 (2025-06-26)
|
12
|
+
|
13
|
+
- Support renaming columns and tables for tables within custom schemas
|
14
|
+
- Include operation name into the background schema migrations names
|
15
|
+
|
3
16
|
## 0.27.1 (2025-05-08)
|
4
17
|
|
5
18
|
- Fix background data migrations to enumerate using the correct shard
|
@@ -110,6 +110,9 @@ OnlineMigrations.configure do |config|
|
|
110
110
|
# The number of seconds that must pass before the cancelling or pausing data migration is considered stuck.
|
111
111
|
config.background_data_migrations.stuck_timeout = 5.minutes
|
112
112
|
|
113
|
+
# The pause interval between each data migration's `process` method execution (in seconds).
|
114
|
+
config.background_data_migrations.iteration_pause = Rails.env.production? ? 0.02 : 0
|
115
|
+
|
113
116
|
# The callback to perform when an error occurs during the data migration.
|
114
117
|
# config.background_data_migrations.error_handler = ->(error, errored_migration) do
|
115
118
|
# Bugsnag.notify(error) do |notification|
|
@@ -13,6 +13,7 @@ class InstallOnlineMigrations < <%= migration_parent %>
|
|
13
13
|
t.bigint :tick_count, default: 0, null: false
|
14
14
|
t.float :time_running, default: 0.0, null: false
|
15
15
|
t.integer :max_attempts, null: false
|
16
|
+
t.float :iteration_pause, default: 0.0, null: false
|
16
17
|
t.string :error_class
|
17
18
|
t.string :error_message
|
18
19
|
t.string :backtrace, array: true
|
@@ -19,33 +19,34 @@ module OnlineMigrations
|
|
19
19
|
private
|
20
20
|
def migrations_to_apply
|
21
21
|
connection = BackgroundDataMigrations::Migration.connection
|
22
|
-
data_table = "background_migrations"
|
23
|
-
schema_table = "background_schema_migrations"
|
24
|
-
columns = connection.columns(data_table).map(&:name)
|
25
22
|
|
26
23
|
migrations = []
|
27
|
-
if connection.table_exists?(
|
24
|
+
if connection.table_exists?(:background_migrations) && !connection.column_exists?(:background_migrations, :shard)
|
28
25
|
migrations << "add_sharding_to_online_migrations"
|
29
26
|
end
|
30
27
|
|
31
|
-
if !connection.table_exists?(
|
28
|
+
if !connection.table_exists?(:background_schema_migrations)
|
32
29
|
migrations << "create_background_schema_migrations"
|
33
30
|
end
|
34
31
|
|
35
|
-
indexes = connection.indexes(
|
32
|
+
indexes = connection.indexes(:background_schema_migrations)
|
36
33
|
unique_index = indexes.find { |i| i.unique && i.columns.sort == ["connection_class_name", "migration_name", "shard"] }
|
37
34
|
if !unique_index
|
38
35
|
migrations << "background_schema_migrations_change_unique_index"
|
39
36
|
end
|
40
37
|
|
41
|
-
if connection.table_exists?(
|
38
|
+
if connection.table_exists?(:background_migrations) && !connection.column_exists?(:background_migrations, :started_at)
|
42
39
|
migrations << "add_timestamps_to_background_migrations"
|
43
40
|
end
|
44
41
|
|
45
|
-
if connection.table_exists?(
|
42
|
+
if connection.table_exists?(:background_migrations)
|
46
43
|
migrations << "change_background_data_migrations"
|
47
44
|
end
|
48
45
|
|
46
|
+
if !connection.column_exists?(:background_data_migrations, :iteration_pause)
|
47
|
+
migrations << "background_data_migrations_add_iteration_pause"
|
48
|
+
end
|
49
|
+
|
49
50
|
migrations
|
50
51
|
end
|
51
52
|
|
@@ -250,7 +250,7 @@ module OnlineMigrations
|
|
250
250
|
def progress
|
251
251
|
if succeeded?
|
252
252
|
100.0
|
253
|
-
elsif
|
253
|
+
elsif tick_total == 0
|
254
254
|
0.0
|
255
255
|
elsif tick_total
|
256
256
|
([tick_count.to_f / tick_total, 1.0].min * 100)
|
@@ -297,6 +297,8 @@ module OnlineMigrations
|
|
297
297
|
self.tick_total ||= on_shard_if_present do
|
298
298
|
data_migration.count
|
299
299
|
end
|
300
|
+
|
301
|
+
self.iteration_pause ||= config.iteration_pause
|
300
302
|
end
|
301
303
|
|
302
304
|
def instrument_status_change
|
@@ -369,7 +369,7 @@ module OnlineMigrations
|
|
369
369
|
# in development and test environments
|
370
370
|
#
|
371
371
|
def enqueue_background_data_migration(migration_name, *arguments, **options)
|
372
|
-
options.assert_valid_keys(:max_attempts, :connection_class_name)
|
372
|
+
options.assert_valid_keys(:max_attempts, :iteration_pause, :connection_class_name)
|
373
373
|
|
374
374
|
migration_name = migration_name.name if migration_name.is_a?(Class)
|
375
375
|
options[:connection_class_name] ||= compute_connection_class_name(migration_name, arguments)
|
@@ -387,7 +387,7 @@ module OnlineMigrations
|
|
387
387
|
migration = Migration.where(migration_name: migration_name, shard: shard).where("arguments = ?", arguments.to_json).first
|
388
388
|
migration ||= Migration.create!(**options, migration_name: migration_name, arguments: arguments, shard: shard)
|
389
389
|
|
390
|
-
if Utils.run_background_migrations_inline?
|
390
|
+
if Utils.run_background_migrations_inline? && !migration.succeeded?
|
391
391
|
job = OnlineMigrations.config.background_data_migrations.job
|
392
392
|
job.constantize.perform_inline(migration.id)
|
393
393
|
end
|
@@ -128,7 +128,8 @@ module OnlineMigrations
|
|
128
128
|
@data_migration.around_process do
|
129
129
|
@migration.data_migration.process(item)
|
130
130
|
|
131
|
-
|
131
|
+
# Migration is refreshed regularly by ticker.
|
132
|
+
pause = @migration.iteration_pause
|
132
133
|
sleep(pause) if pause > 0
|
133
134
|
end
|
134
135
|
@ticker.tick
|
@@ -28,7 +28,7 @@ module OnlineMigrations
|
|
28
28
|
schema_creation = ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaCreation.new(self)
|
29
29
|
definition = schema_creation.accept(create_index)
|
30
30
|
|
31
|
-
enqueue_background_schema_migration(index.name, table_name, definition: definition, **migration_options)
|
31
|
+
enqueue_background_schema_migration("Add index #{index.name}", table_name, definition: definition, **migration_options)
|
32
32
|
end
|
33
33
|
|
34
34
|
def remove_index_in_background(table_name, column_name = nil, name:, **options)
|
@@ -42,7 +42,7 @@ module OnlineMigrations
|
|
42
42
|
end
|
43
43
|
|
44
44
|
definition = "DROP INDEX CONCURRENTLY IF EXISTS #{quote_column_name(name)}"
|
45
|
-
enqueue_background_schema_migration(name, table_name, definition: definition, **migration_options)
|
45
|
+
enqueue_background_schema_migration("Remove index #{name}", table_name, definition: definition, **migration_options)
|
46
46
|
end
|
47
47
|
|
48
48
|
def validate_foreign_key_in_background(from_table, to_table = nil, **options)
|
@@ -62,7 +62,7 @@ module OnlineMigrations
|
|
62
62
|
ALTER TABLE #{quote_table_name(table_name)}
|
63
63
|
VALIDATE CONSTRAINT #{quote_table_name(constraint_name)}
|
64
64
|
SQL
|
65
|
-
enqueue_background_schema_migration(constraint_name, table_name, definition: definition, **options)
|
65
|
+
enqueue_background_schema_migration("Validate #{constraint_name}", table_name, definition: definition, **options)
|
66
66
|
end
|
67
67
|
|
68
68
|
# Ensures that the background schema migration with the provided migration name succeeded.
|
@@ -78,7 +78,7 @@ module OnlineMigrations
|
|
78
78
|
# ensure_background_schema_migration_succeeded("index_users_on_email")
|
79
79
|
#
|
80
80
|
def ensure_background_schema_migration_succeeded(migration_name)
|
81
|
-
migrations = Migration.where(migration_name
|
81
|
+
migrations = Migration.where("migration_name ILIKE ?", "%#{migration_name}%").to_a
|
82
82
|
|
83
83
|
if migrations.empty?
|
84
84
|
Utils.raise_in_prod_or_say_in_dev("Could not find background schema migration(s): '#{migration_name}'.")
|
@@ -97,12 +97,13 @@ module OnlineMigrations
|
|
97
97
|
if connection_class_name
|
98
98
|
klass = connection_class_name.constantize
|
99
99
|
connection_class = Utils.find_connection_class(klass)
|
100
|
-
# Normalize to the real connection class name.
|
101
|
-
connection_class_name = connection_class.name
|
102
100
|
else
|
103
101
|
connection_class = ActiveRecord::Base
|
104
102
|
end
|
105
103
|
|
104
|
+
# Normalize to the real connection class name.
|
105
|
+
connection_class_name = connection_class.name
|
106
|
+
|
106
107
|
shards = Utils.shard_names(connection_class)
|
107
108
|
shards = [nil] if shards.size == 1
|
108
109
|
|
@@ -111,6 +112,9 @@ module OnlineMigrations
|
|
111
112
|
.find_or_create_by!(migration_name: migration_name, shard: shard, connection_class_name: connection_class_name)
|
112
113
|
|
113
114
|
if Utils.run_background_migrations_inline?
|
115
|
+
# Run migration again in development.
|
116
|
+
migration.update_column(:status, :enqueued) if !migration.enqueued?
|
117
|
+
|
114
118
|
runner = MigrationRunner.new(migration)
|
115
119
|
runner.run
|
116
120
|
end
|
@@ -52,15 +52,14 @@ module OnlineMigrations
|
|
52
52
|
private
|
53
53
|
def renamed_table?(connection, table_name)
|
54
54
|
table_renames = OnlineMigrations.config.table_renames
|
55
|
-
if table_renames.key?(table_name)
|
56
|
-
|
57
|
-
table_renames[table_name] if views.include?(table_name)
|
55
|
+
if table_renames.key?(table_name) && connection.view_exists?(table_name)
|
56
|
+
table_renames[table_name]
|
58
57
|
end
|
59
58
|
end
|
60
59
|
|
61
60
|
def renamed_column?(connection, table_name)
|
62
61
|
column_renames = OnlineMigrations.config.column_renames
|
63
|
-
column_renames.key?(table_name) && connection.
|
62
|
+
column_renames.key?(table_name) && connection.view_exists?(table_name)
|
64
63
|
end
|
65
64
|
|
66
65
|
def column_rename_table(table_name)
|
@@ -131,14 +130,21 @@ module OnlineMigrations
|
|
131
130
|
def renamed_table?(pool, table_name)
|
132
131
|
table_renames = OnlineMigrations.config.table_renames
|
133
132
|
if table_renames.key?(table_name)
|
134
|
-
|
135
|
-
|
133
|
+
view_exists = pool.with_connection do |connection|
|
134
|
+
connection.view_exists?(table_name)
|
135
|
+
end
|
136
|
+
|
137
|
+
table_renames[table_name] if view_exists
|
136
138
|
end
|
137
139
|
end
|
138
140
|
|
139
141
|
def renamed_column?(pool, table_name)
|
140
142
|
column_renames = OnlineMigrations.config.column_renames
|
141
|
-
column_renames.key?(table_name)
|
143
|
+
return false if !column_renames.key?(table_name)
|
144
|
+
|
145
|
+
pool.with_connection do |connection|
|
146
|
+
connection.view_exists?(table_name)
|
147
|
+
end
|
142
148
|
end
|
143
149
|
|
144
150
|
def column_rename_table(table_name)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: online_migrations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.29.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- fatkodima
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-07-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -42,6 +42,7 @@ files:
|
|
42
42
|
- lib/generators/online_migrations/install_generator.rb
|
43
43
|
- lib/generators/online_migrations/templates/add_sharding_to_online_migrations.rb.tt
|
44
44
|
- lib/generators/online_migrations/templates/add_timestamps_to_background_migrations.rb.tt
|
45
|
+
- lib/generators/online_migrations/templates/background_data_migrations_add_iteration_pause.rb.tt
|
45
46
|
- lib/generators/online_migrations/templates/background_schema_migrations_change_unique_index.rb.tt
|
46
47
|
- lib/generators/online_migrations/templates/change_background_data_migrations.rb.tt
|
47
48
|
- lib/generators/online_migrations/templates/create_background_schema_migrations.rb.tt
|