online_migrations 0.32.0 → 0.33.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 +8 -0
- data/docs/background_data_migrations.md +4 -2
- data/docs/background_schema_migrations.md +1 -1
- data/lib/generators/online_migrations/templates/background_migrations_change_status_default.rb.tt +8 -0
- data/lib/generators/online_migrations/templates/install_migration.rb.tt +2 -2
- data/lib/generators/online_migrations/upgrade_generator.rb +5 -0
- data/lib/online_migrations/background_data_migrations/migration.rb +18 -17
- data/lib/online_migrations/background_data_migrations/migration_helpers.rb +1 -1
- data/lib/online_migrations/background_data_migrations/migration_job.rb +13 -10
- data/lib/online_migrations/background_data_migrations/migration_status_validator.rb +13 -9
- data/lib/online_migrations/background_data_migrations/scheduler.rb +6 -5
- data/lib/online_migrations/background_schema_migrations/migration.rb +7 -7
- data/lib/online_migrations/background_schema_migrations/migration_helpers.rb +2 -2
- data/lib/online_migrations/background_schema_migrations/migration_runner.rb +1 -1
- data/lib/online_migrations/background_schema_migrations/migration_status_validator.rb +6 -6
- data/lib/online_migrations/background_schema_migrations/scheduler.rb +1 -1
- data/lib/online_migrations/change_column_type_helpers.rb +4 -1
- 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: 7f092b18d7bc864ba2232a41727e136bb86469279bdc3ad4c04a49a49628fb95
|
|
4
|
+
data.tar.gz: b7349d9b1c818ed4fefd078f7262bb380bb22a34109be13d2ead3191f338dbc9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4a52e29b327dbecae7f1c31fa4020fa5b428c5f830ea34215695bfd827c787c90146dda6dd12045a5c7f4cc2136741bb1a08b76b2a3ad7273f69c028d192a764
|
|
7
|
+
data.tar.gz: 6175ee34939fbdc6c21605320c36cfdeca971458381e1d6e465e7b464b302914f87f69c7bbcfc50c3b150fc9b9d6d8d34e0d0a1fd2a0573940aa1efa36e983a5
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
## master (unreleased)
|
|
2
2
|
|
|
3
|
+
## 0.33.0 (2026-02-04)
|
|
4
|
+
|
|
5
|
+
- Change background migrations default status to "pending"
|
|
6
|
+
|
|
7
|
+
Note: Run `bin/rails generate online_migrations:upgrade` if using background migrations.
|
|
8
|
+
|
|
9
|
+
- Fix copying partial indexes when changing column type
|
|
10
|
+
|
|
3
11
|
## 0.32.0 (2026-01-07)
|
|
4
12
|
|
|
5
13
|
- Add ability to create delayed background migrations
|
|
@@ -300,7 +300,8 @@ end
|
|
|
300
300
|
|
|
301
301
|
Data Migrations can be in various states during its execution:
|
|
302
302
|
|
|
303
|
-
* **
|
|
303
|
+
* **pending**: A migration has been created by the user.
|
|
304
|
+
* **enqueued**: A migration has been enqueued by the scheduler.
|
|
304
305
|
* **running**: A migration is being performed by a migration executor.
|
|
305
306
|
* **pausing**: A migration has been told to pause but is finishing work.
|
|
306
307
|
* **paused**: A migration was paused in the middle of the run by the user.
|
|
@@ -312,7 +313,8 @@ Data Migrations can be in various states during its execution:
|
|
|
312
313
|
migration.pause
|
|
313
314
|
```
|
|
314
315
|
|
|
315
|
-
* **
|
|
316
|
+
* **errored**: A migration raised an error during last run.
|
|
317
|
+
* **failed**: A migration raises an error when running and retry attempts exceeded.
|
|
316
318
|
* **succeeded**: A migration finished without error.
|
|
317
319
|
* **cancelling**: A migration has been told to cancel but is finishing work.
|
|
318
320
|
* **cancelled**: A migration was cancelled by the user.
|
|
@@ -132,7 +132,7 @@ Available events:
|
|
|
132
132
|
|
|
133
133
|
Background Schema Migrations can be in various states during its execution:
|
|
134
134
|
|
|
135
|
-
* **
|
|
135
|
+
* **pending**: A migration has been created by the user.
|
|
136
136
|
* **running**: A migration is being performed by a migration executor.
|
|
137
137
|
* **errored**: A migration raised an error during last run.
|
|
138
138
|
* **failed**: A migration raises an error when running and retry attempts exceeded.
|
data/lib/generators/online_migrations/templates/background_migrations_change_status_default.rb.tt
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
class BackgroundDataMigrationsChangeStatusDefault < <%= migration_parent %>
|
|
2
|
+
def change
|
|
3
|
+
safety_assured do
|
|
4
|
+
change_column_default :background_data_migrations, :status, from: "enqueued", to: "pending"
|
|
5
|
+
change_column_default :background_schema_migrations, :status, from: "enqueued", to: "pending"
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
end
|
|
@@ -3,7 +3,7 @@ class InstallOnlineMigrations < <%= migration_parent %>
|
|
|
3
3
|
create_table :background_data_migrations do |t|
|
|
4
4
|
t.string :migration_name, null: false
|
|
5
5
|
t.jsonb :arguments, default: [], null: false
|
|
6
|
-
t.string :status, default: "
|
|
6
|
+
t.string :status, default: "pending", null: false
|
|
7
7
|
t.string :shard
|
|
8
8
|
t.string :cursor
|
|
9
9
|
t.string :jid
|
|
@@ -28,7 +28,7 @@ class InstallOnlineMigrations < <%= migration_parent %>
|
|
|
28
28
|
t.string :migration_name, null: false
|
|
29
29
|
t.string :table_name, null: false
|
|
30
30
|
t.string :definition, null: false
|
|
31
|
-
t.string :status, default: "
|
|
31
|
+
t.string :status, default: "pending", null: false
|
|
32
32
|
t.string :shard
|
|
33
33
|
t.integer :statement_timeout
|
|
34
34
|
t.datetime :started_at
|
|
@@ -52,6 +52,11 @@ module OnlineMigrations
|
|
|
52
52
|
migrations << "background_data_migrations_remove_iteration_pause_default"
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
+
status_column = connection.columns(:background_data_migrations).find { |c| c.name == "status" }
|
|
56
|
+
if status_column.default == "enqueued"
|
|
57
|
+
migrations << "background_migrations_change_status_default"
|
|
58
|
+
end
|
|
59
|
+
|
|
55
60
|
migrations
|
|
56
61
|
end
|
|
57
62
|
|
|
@@ -11,11 +11,13 @@ module OnlineMigrations
|
|
|
11
11
|
include ShardAware
|
|
12
12
|
|
|
13
13
|
STATUSES = [
|
|
14
|
-
"
|
|
14
|
+
"pending", # The migration has been created by the user.
|
|
15
|
+
"enqueued", # The migration has been enqueued by the scheduler.
|
|
15
16
|
"running", # The migration is being performed by a migration executor.
|
|
16
17
|
"pausing", # The migration has been told to pause but is finishing work.
|
|
17
18
|
"paused", # The migration was paused in the middle of the run by the user.
|
|
18
|
-
"
|
|
19
|
+
"errored", # The migration raised an error during last run.
|
|
20
|
+
"failed", # The migration raises an error when running and retry attempts exceeded.
|
|
19
21
|
"succeeded", # The migration finished without error.
|
|
20
22
|
"cancelling", # The migration has been told to cancel but is finishing work.
|
|
21
23
|
"cancelled", # The migration was cancelled by the user.
|
|
@@ -25,8 +27,10 @@ module OnlineMigrations
|
|
|
25
27
|
COMPLETED_STATUSES = ["succeeded", "failed", "cancelled"]
|
|
26
28
|
|
|
27
29
|
ACTIVE_STATUSES = [
|
|
30
|
+
"pending",
|
|
28
31
|
"enqueued",
|
|
29
32
|
"running",
|
|
33
|
+
"failed",
|
|
30
34
|
"pausing",
|
|
31
35
|
"paused",
|
|
32
36
|
"cancelling",
|
|
@@ -87,7 +91,7 @@ module OnlineMigrations
|
|
|
87
91
|
end
|
|
88
92
|
|
|
89
93
|
# Returns whether the migration is active, which is defined as
|
|
90
|
-
# having a status of enqueued, running, pausing, paused, or cancelling.
|
|
94
|
+
# having a status of pending, enqueued, running, pausing, paused, or cancelling.
|
|
91
95
|
#
|
|
92
96
|
# @return [Boolean] whether the migration is active.
|
|
93
97
|
#
|
|
@@ -107,22 +111,18 @@ module OnlineMigrations
|
|
|
107
111
|
end
|
|
108
112
|
|
|
109
113
|
# Returns whether a migration is stuck, which is defined as having a status of
|
|
110
|
-
# cancelling or pausing, and not having been updated in the last 5 minutes.
|
|
114
|
+
# running, cancelling or pausing, and not having been updated in the last 5 minutes.
|
|
111
115
|
#
|
|
112
116
|
# @return [Boolean] whether the migration is stuck.
|
|
113
117
|
#
|
|
114
118
|
def stuck?
|
|
115
119
|
stuck_timeout = OnlineMigrations.config.background_data_migrations.stuck_timeout
|
|
116
|
-
(cancelling? || pausing?) && updated_at <= stuck_timeout.ago
|
|
120
|
+
(running? || cancelling? || pausing?) && updated_at <= stuck_timeout.ago
|
|
117
121
|
end
|
|
118
122
|
|
|
119
123
|
# @private
|
|
120
124
|
def start
|
|
121
|
-
if
|
|
122
|
-
update!(started_at: Time.current)
|
|
123
|
-
data_migration.after_start
|
|
124
|
-
true
|
|
125
|
-
elsif enqueued?
|
|
125
|
+
if enqueued?
|
|
126
126
|
update!(status: :running, started_at: Time.current)
|
|
127
127
|
data_migration.after_start
|
|
128
128
|
true
|
|
@@ -137,7 +137,7 @@ module OnlineMigrations
|
|
|
137
137
|
#
|
|
138
138
|
def enqueue
|
|
139
139
|
if delayed?
|
|
140
|
-
|
|
140
|
+
pending!
|
|
141
141
|
true
|
|
142
142
|
else
|
|
143
143
|
false
|
|
@@ -153,7 +153,7 @@ module OnlineMigrations
|
|
|
153
153
|
|
|
154
154
|
if paused? || delayed? || stuck?
|
|
155
155
|
update!(status: :cancelled, finished_at: Time.current)
|
|
156
|
-
elsif enqueued?
|
|
156
|
+
elsif pending? || enqueued? || errored?
|
|
157
157
|
cancelled!
|
|
158
158
|
else
|
|
159
159
|
cancelling!
|
|
@@ -169,7 +169,7 @@ module OnlineMigrations
|
|
|
169
169
|
def pause
|
|
170
170
|
return false if completed?
|
|
171
171
|
|
|
172
|
-
if enqueued? || delayed? || stuck?
|
|
172
|
+
if pending? || enqueued? || delayed? || stuck? || errored?
|
|
173
173
|
paused!
|
|
174
174
|
else
|
|
175
175
|
pausing!
|
|
@@ -184,7 +184,7 @@ module OnlineMigrations
|
|
|
184
184
|
#
|
|
185
185
|
def resume
|
|
186
186
|
if paused?
|
|
187
|
-
|
|
187
|
+
pending!
|
|
188
188
|
true
|
|
189
189
|
else
|
|
190
190
|
false
|
|
@@ -235,13 +235,14 @@ module OnlineMigrations
|
|
|
235
235
|
end
|
|
236
236
|
|
|
237
237
|
# @private
|
|
238
|
-
def persist_error(error)
|
|
238
|
+
def persist_error(error, attempt)
|
|
239
239
|
backtrace = error.backtrace
|
|
240
240
|
backtrace_cleaner = OnlineMigrations.config.backtrace_cleaner
|
|
241
241
|
backtrace = backtrace_cleaner.clean(backtrace) if backtrace_cleaner
|
|
242
|
+
status = attempt >= max_attempts ? :failed : :errored
|
|
242
243
|
|
|
243
244
|
update!(
|
|
244
|
-
status:
|
|
245
|
+
status: status,
|
|
245
246
|
finished_at: Time.current,
|
|
246
247
|
error_class: error.class.name,
|
|
247
248
|
error_message: error.message,
|
|
@@ -290,7 +291,7 @@ module OnlineMigrations
|
|
|
290
291
|
def retry
|
|
291
292
|
if failed?
|
|
292
293
|
update!(
|
|
293
|
-
status: :
|
|
294
|
+
status: :pending,
|
|
294
295
|
started_at: nil,
|
|
295
296
|
finished_at: nil,
|
|
296
297
|
error_class: nil,
|
|
@@ -382,7 +382,7 @@ module OnlineMigrations
|
|
|
382
382
|
connection_class = options[:connection_class_name].constantize
|
|
383
383
|
shards = Utils.shard_names(connection_class)
|
|
384
384
|
shards = [nil] if shards.size == 1
|
|
385
|
-
status = delay ? :delayed : :
|
|
385
|
+
status = delay ? :delayed : :pending
|
|
386
386
|
|
|
387
387
|
shards.each do |shard|
|
|
388
388
|
# Can't use `find_or_create_by` or hash syntax here, because it does not correctly work with json `arguments`.
|
|
@@ -8,23 +8,17 @@ module OnlineMigrations
|
|
|
8
8
|
|
|
9
9
|
sidekiq_options backtrace: true
|
|
10
10
|
|
|
11
|
-
sidekiq_retry_in do |count,
|
|
11
|
+
sidekiq_retry_in do |count, exception, jobhash|
|
|
12
12
|
migration_id = jobhash["args"].fetch(0)
|
|
13
13
|
migration = Migration.find(migration_id)
|
|
14
|
+
migration.persist_error(exception, count + 1)
|
|
15
|
+
OnlineMigrations.config.background_data_migrations.error_handler.call(exception, migration)
|
|
14
16
|
|
|
15
17
|
if count + 1 >= migration.max_attempts
|
|
16
18
|
:kill
|
|
17
19
|
end
|
|
18
20
|
end
|
|
19
21
|
|
|
20
|
-
sidekiq_retries_exhausted do |jobhash, exception|
|
|
21
|
-
migration_id = jobhash["args"].fetch(0)
|
|
22
|
-
migration = Migration.find(migration_id)
|
|
23
|
-
migration.persist_error(exception)
|
|
24
|
-
|
|
25
|
-
OnlineMigrations.config.background_data_migrations.error_handler.call(exception, migration)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
22
|
TICKER_INTERVAL = 5 # seconds
|
|
29
23
|
|
|
30
24
|
def initialize
|
|
@@ -57,6 +51,15 @@ module OnlineMigrations
|
|
|
57
51
|
end
|
|
58
52
|
|
|
59
53
|
def on_resume
|
|
54
|
+
if @migration.errored? # the job was retried
|
|
55
|
+
@migration.update!(
|
|
56
|
+
status: :running,
|
|
57
|
+
error_class: nil,
|
|
58
|
+
error_message: nil,
|
|
59
|
+
backtrace: nil
|
|
60
|
+
)
|
|
61
|
+
end
|
|
62
|
+
|
|
60
63
|
@data_migration.after_resume
|
|
61
64
|
end
|
|
62
65
|
|
|
@@ -126,7 +129,7 @@ module OnlineMigrations
|
|
|
126
129
|
end
|
|
127
130
|
|
|
128
131
|
def each_iteration(item, _migration_id)
|
|
129
|
-
if @migration.cancelling? || @migration.pausing? || @migration.paused?
|
|
132
|
+
if @migration.cancelling? || @migration.cancelled? || @migration.pausing? || @migration.paused?
|
|
130
133
|
# Finish this exact sidekiq job. When the migration is paused
|
|
131
134
|
# and will be resumed, a new job will be enqueued.
|
|
132
135
|
finished = true
|
|
@@ -6,6 +6,7 @@ module OnlineMigrations
|
|
|
6
6
|
class MigrationStatusValidator < ActiveModel::Validator
|
|
7
7
|
# Valid status transitions a Migration can make.
|
|
8
8
|
VALID_STATUS_TRANSITIONS = {
|
|
9
|
+
"pending" => ["enqueued", "paused", "cancelled"],
|
|
9
10
|
# enqueued -> running occurs when the migration starts performing.
|
|
10
11
|
# enqueued -> paused occurs when the migration is paused before starting.
|
|
11
12
|
# enqueued -> cancelled occurs when the migration is cancelled before starting.
|
|
@@ -15,11 +16,13 @@ module OnlineMigrations
|
|
|
15
16
|
# running -> succeeded occurs when the migration completes successfully.
|
|
16
17
|
# running -> pausing occurs when a user pauses the migration as it's performing.
|
|
17
18
|
# running -> cancelling occurs when a user cancels the migration as it's performing.
|
|
18
|
-
# running ->
|
|
19
|
+
# running -> errored occurs when the migration raised an error during the last run.
|
|
20
|
+
# running -> failed occurs when the migration raises an error when running and retry attempts exceeded.
|
|
19
21
|
"running" => [
|
|
20
22
|
"succeeded",
|
|
21
23
|
"pausing",
|
|
22
24
|
"cancelling",
|
|
25
|
+
"errored",
|
|
23
26
|
"failed",
|
|
24
27
|
],
|
|
25
28
|
# pausing -> paused occurs when the migration actually halts performing and
|
|
@@ -32,22 +35,23 @@ module OnlineMigrations
|
|
|
32
35
|
# nothing in its collection to process.
|
|
33
36
|
# pausing -> failed occurs when the job raises an exception after the
|
|
34
37
|
# user has paused it.
|
|
35
|
-
"pausing" => ["paused", "cancelling", "succeeded", "failed"],
|
|
36
|
-
# paused ->
|
|
38
|
+
"pausing" => ["paused", "cancelling", "succeeded", "errored", "failed"],
|
|
39
|
+
# paused -> pending occurs when the migration is resumed after being paused.
|
|
37
40
|
# paused -> cancelled when the user cancels the migration after it is paused.
|
|
38
|
-
"paused" => ["
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
"paused" => ["pending", "cancelled"],
|
|
42
|
+
"errored" => ["running", "failed", "cancelled", "paused"],
|
|
43
|
+
# failed -> pending occurs when the migration is retried after encounting an error.
|
|
44
|
+
"failed" => ["pending"],
|
|
41
45
|
# cancelling -> cancelled occurs when the migration actually halts performing
|
|
42
46
|
# and occupies a status of cancelled.
|
|
43
47
|
# cancelling -> succeeded occurs when the migration completes immediately after
|
|
44
48
|
# being cancelled. See description for pausing -> succeeded.
|
|
45
49
|
# cancelling -> failed occurs when the job raises an exception after the
|
|
46
50
|
# user has cancelled it.
|
|
47
|
-
"cancelling" => ["cancelled", "succeeded", "failed"],
|
|
48
|
-
# delayed ->
|
|
51
|
+
"cancelling" => ["cancelled", "succeeded", "errored", "failed"],
|
|
52
|
+
# delayed -> pending occurs when the delayed migration was approved by the user to start running.
|
|
49
53
|
# delayed -> cancelled occurs when the delayed migration was cancelled.
|
|
50
|
-
"delayed" => ["
|
|
54
|
+
"delayed" => ["pending", "cancelled"],
|
|
51
55
|
}
|
|
52
56
|
|
|
53
57
|
def validate(record)
|
|
@@ -34,13 +34,13 @@ module OnlineMigrations
|
|
|
34
34
|
relation = relation.where(shard: shard) if shard
|
|
35
35
|
|
|
36
36
|
with_lock do
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
stuck_migrations, active_migrations = relation.running.partition(&:stuck?)
|
|
38
|
+
runnable_migrations = relation.pending + stuck_migrations
|
|
39
39
|
|
|
40
40
|
# Ensure no more than 'concurrency' migrations are running at the same time.
|
|
41
|
-
remaining_to_enqueue = concurrency -
|
|
41
|
+
remaining_to_enqueue = concurrency - active_migrations.count
|
|
42
42
|
if remaining_to_enqueue > 0
|
|
43
|
-
migrations_to_enqueue =
|
|
43
|
+
migrations_to_enqueue = runnable_migrations.take(remaining_to_enqueue)
|
|
44
44
|
migrations_to_enqueue.each do |migration|
|
|
45
45
|
enqueue_migration(migration)
|
|
46
46
|
end
|
|
@@ -67,10 +67,11 @@ module OnlineMigrations
|
|
|
67
67
|
def enqueue_migration(migration)
|
|
68
68
|
job = OnlineMigrations.config.background_data_migrations.job
|
|
69
69
|
job_class = job.constantize
|
|
70
|
+
migration.update!(status: :enqueued)
|
|
70
71
|
|
|
71
72
|
jid = job_class.perform_async(migration.id)
|
|
72
73
|
if jid
|
|
73
|
-
migration.update!(
|
|
74
|
+
migration.update!(jid: jid)
|
|
74
75
|
end
|
|
75
76
|
end
|
|
76
77
|
end
|
|
@@ -11,7 +11,7 @@ module OnlineMigrations
|
|
|
11
11
|
include ShardAware
|
|
12
12
|
|
|
13
13
|
STATUSES = [
|
|
14
|
-
"
|
|
14
|
+
"pending", # The migration has been created by the user.
|
|
15
15
|
"running", # The migration is being performed by a migration executor.
|
|
16
16
|
"errored", # The migration raised an error during last run.
|
|
17
17
|
"failed", # The migration raises an error when running and retry attempts exceeded.
|
|
@@ -25,7 +25,7 @@ module OnlineMigrations
|
|
|
25
25
|
self.table_name = :background_schema_migrations
|
|
26
26
|
|
|
27
27
|
scope :queue_order, -> { order(created_at: :asc) }
|
|
28
|
-
scope :active, -> { where(status: [:
|
|
28
|
+
scope :active, -> { where(status: [:pending, :running, :errored]) }
|
|
29
29
|
|
|
30
30
|
alias_attribute :name, :migration_name
|
|
31
31
|
|
|
@@ -59,12 +59,12 @@ module OnlineMigrations
|
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
# Returns whether the migration is active, which is defined as
|
|
62
|
-
# having a status of
|
|
62
|
+
# having a status of pending, or running.
|
|
63
63
|
#
|
|
64
64
|
# @return [Boolean] whether the migration is active.
|
|
65
65
|
#
|
|
66
66
|
def active?
|
|
67
|
-
|
|
67
|
+
pending? || running?
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
# Returns whether this migration is pausable.
|
|
@@ -98,7 +98,7 @@ module OnlineMigrations
|
|
|
98
98
|
def retry
|
|
99
99
|
if failed?
|
|
100
100
|
update!(
|
|
101
|
-
status: :
|
|
101
|
+
status: :pending,
|
|
102
102
|
attempts: 0,
|
|
103
103
|
started_at: nil,
|
|
104
104
|
finished_at: nil,
|
|
@@ -119,7 +119,7 @@ module OnlineMigrations
|
|
|
119
119
|
#
|
|
120
120
|
def enqueue
|
|
121
121
|
if delayed?
|
|
122
|
-
|
|
122
|
+
pending!
|
|
123
123
|
true
|
|
124
124
|
else
|
|
125
125
|
false
|
|
@@ -133,7 +133,7 @@ module OnlineMigrations
|
|
|
133
133
|
def cancel
|
|
134
134
|
if completed?
|
|
135
135
|
false
|
|
136
|
-
elsif
|
|
136
|
+
elsif pending? || errored? || delayed? || stuck?
|
|
137
137
|
cancelled!
|
|
138
138
|
true
|
|
139
139
|
end
|
|
@@ -107,7 +107,7 @@ module OnlineMigrations
|
|
|
107
107
|
shards = Utils.shard_names(connection_class)
|
|
108
108
|
shards = [nil] if shards.size == 1
|
|
109
109
|
|
|
110
|
-
status = delay ? :delayed : :
|
|
110
|
+
status = delay ? :delayed : :pending
|
|
111
111
|
|
|
112
112
|
shards.each do |shard|
|
|
113
113
|
migration = Migration.create_with(**options, status: status)
|
|
@@ -115,7 +115,7 @@ module OnlineMigrations
|
|
|
115
115
|
|
|
116
116
|
if Utils.run_background_migrations_inline?
|
|
117
117
|
# Run migration again in development.
|
|
118
|
-
migration.update_column(:status, :
|
|
118
|
+
migration.update_column(:status, :pending) if !migration.pending?
|
|
119
119
|
|
|
120
120
|
runner = MigrationRunner.new(migration)
|
|
121
121
|
runner.run
|
|
@@ -13,7 +13,7 @@ module OnlineMigrations
|
|
|
13
13
|
def run
|
|
14
14
|
return if migration.cancelled? || migration.succeeded?
|
|
15
15
|
|
|
16
|
-
migration.running! if migration.
|
|
16
|
+
migration.running! if migration.pending? || migration.errored?
|
|
17
17
|
migration_payload = { migration: migration }
|
|
18
18
|
|
|
19
19
|
if migration.attempts == 0
|
|
@@ -5,8 +5,8 @@ module OnlineMigrations
|
|
|
5
5
|
# @private
|
|
6
6
|
class MigrationStatusValidator < ActiveModel::Validator
|
|
7
7
|
VALID_STATUS_TRANSITIONS = {
|
|
8
|
-
#
|
|
9
|
-
"
|
|
8
|
+
# pending -> running occurs when the migration starts performing.
|
|
9
|
+
"pending" => ["running", "cancelled"],
|
|
10
10
|
# running -> succeeded occurs when the migration completes successfully.
|
|
11
11
|
# running -> errored occurs when the migration raised an error during the last run.
|
|
12
12
|
# running -> failed occurs when the migration raises an error when running and retry attempts exceeded.
|
|
@@ -14,12 +14,12 @@ module OnlineMigrations
|
|
|
14
14
|
# errored -> running occurs when previously errored migration starts running
|
|
15
15
|
# errored -> failed occurs when the migration raises an error when running and retry attempts exceeded.
|
|
16
16
|
"errored" => ["running", "failed", "cancelled"],
|
|
17
|
-
# failed ->
|
|
17
|
+
# failed -> pending occurs when the failed migration is enqueued to be retried.
|
|
18
18
|
# failed -> running occurs when the failed migration is retried.
|
|
19
|
-
"failed" => ["
|
|
20
|
-
# delayed ->
|
|
19
|
+
"failed" => ["pending", "running", "cancelled"],
|
|
20
|
+
# delayed -> pending occurs when the delayed migration was approved by the user to start running.
|
|
21
21
|
# delayed -> cancelled occurs when the delayed migration was cancelled.
|
|
22
|
-
"delayed" => ["
|
|
22
|
+
"delayed" => ["pending", "cancelled"],
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
def validate(record)
|
|
@@ -36,7 +36,7 @@ module OnlineMigrations
|
|
|
36
36
|
private
|
|
37
37
|
def find_migration(**options)
|
|
38
38
|
stuck_migrations, active_migrations = Migration.running.partition(&:stuck?)
|
|
39
|
-
runnable_migrations = (Migration.
|
|
39
|
+
runnable_migrations = (Migration.pending + Migration.errored + stuck_migrations).sort_by(&:created_at)
|
|
40
40
|
|
|
41
41
|
if options.key?(:shard)
|
|
42
42
|
runnable_migrations = runnable_migrations.select { |migration| migration.shard.to_s == options[:shard].to_s }
|
|
@@ -436,7 +436,10 @@ module OnlineMigrations
|
|
|
436
436
|
}
|
|
437
437
|
|
|
438
438
|
options[:using] = index.using if index.using
|
|
439
|
-
|
|
439
|
+
|
|
440
|
+
if index.where
|
|
441
|
+
options[:where] = index.where.gsub(/\b#{from_column}\b/, to_column)
|
|
442
|
+
end
|
|
440
443
|
|
|
441
444
|
if index.opclasses.present?
|
|
442
445
|
opclasses = index.opclasses.dup
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: online_migrations
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.33.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- fatkodima
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-
|
|
10
|
+
date: 2026-02-04 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: activerecord
|
|
@@ -42,6 +42,7 @@ files:
|
|
|
42
42
|
- lib/generators/online_migrations/templates/add_timestamps_to_background_migrations.rb.tt
|
|
43
43
|
- lib/generators/online_migrations/templates/background_data_migrations_add_iteration_pause.rb.tt
|
|
44
44
|
- lib/generators/online_migrations/templates/background_data_migrations_remove_iteration_pause_default.rb.tt
|
|
45
|
+
- lib/generators/online_migrations/templates/background_migrations_change_status_default.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
|