online_migrations 0.35.0 → 0.36.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 +9 -0
- data/README.md +2 -0
- data/lib/generators/online_migrations/templates/background_data_migrations_convert_cursor.rb.tt +9 -0
- data/lib/generators/online_migrations/upgrade_generator.rb +2 -0
- data/lib/online_migrations/background_data_migrations/migration.rb +11 -2
- data/lib/online_migrations/background_data_migrations/migration_job.rb +1 -0
- data/lib/online_migrations/background_data_migrations/migration_status_validator.rb +0 -2
- data/lib/online_migrations/background_data_migrations/scheduler.rb +2 -3
- data/lib/online_migrations/background_schema_migrations/migration.rb +3 -7
- data/lib/online_migrations/background_schema_migrations/migration_runner.rb +2 -3
- data/lib/online_migrations/background_schema_migrations/scheduler.rb +2 -2
- data/lib/online_migrations/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6740adaa6d20273e8d148e8e0788a6e27c6c6701187fe60e006ff3ba8e2129d2
|
|
4
|
+
data.tar.gz: 445a3ef72888dd358cc5d917ca31de7499df3368797c9c73324704e0e2d8307a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 338cf3a26b64efb827b5691addc67987048e0522f467d89c5ff4a18494f6b0e3cbeb93513e419a01b04be643d9f7e7a36c1aaf1b0a9d7f5c8158ecff1eb315e7
|
|
7
|
+
data.tar.gz: 4a6b9282a87124e037b3f101a5856d4a8756e86f9fb5b8bf3a4e42e7e2790e0edbd78b7263b8e9c653bedc25700d8a3fb8ade671e2f99e1e74dbfd49780c20eb
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
## master (unreleased)
|
|
2
2
|
|
|
3
|
+
## 0.36.0 (2026-07-20)
|
|
4
|
+
|
|
5
|
+
- Serialize to JSON `cursor` value for background data migrations
|
|
6
|
+
|
|
7
|
+
Note: Run `bin/rails generate online_migrations:upgrade` if using background migrations.
|
|
8
|
+
|
|
9
|
+
- Do not consider running background migrations as stuck
|
|
10
|
+
- Do not automatically retry stuck background migrations
|
|
11
|
+
|
|
3
12
|
## 0.35.0 (2026-07-01)
|
|
4
13
|
|
|
5
14
|
- Drop support for Ruby < 3.3
|
data/README.md
CHANGED
|
@@ -342,6 +342,8 @@ during writes works automatically). For most column type changes, this does not
|
|
|
342
342
|
|
|
343
343
|
```ruby
|
|
344
344
|
class CleanupChangeFilesSizeType < ActiveRecord::Migration[8.0]
|
|
345
|
+
disable_ddl_transaction!
|
|
346
|
+
|
|
345
347
|
def up
|
|
346
348
|
cleanup_column_type_change :files, :size
|
|
347
349
|
end
|
data/lib/generators/online_migrations/templates/background_data_migrations_convert_cursor.rb.tt
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
class BackgroundDataMigrationsConvertCursor < <%= migration_parent %>
|
|
2
|
+
def change
|
|
3
|
+
up_only do
|
|
4
|
+
OnlineMigrations::DataMigrations::Migration.find_each do |migration|
|
|
5
|
+
OnlineMigrations::DataMigrations::Migration.where(id: migration.id).update_all(cursor: migration.cursor)
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -52,6 +52,8 @@ module OnlineMigrations
|
|
|
52
52
|
|
|
53
53
|
enum :status, STATUSES.index_with(&:to_s)
|
|
54
54
|
|
|
55
|
+
serialize :cursor, coder: JSON
|
|
56
|
+
|
|
55
57
|
validates :migration_name, presence: true
|
|
56
58
|
validates :arguments, uniqueness: { scope: [:migration_name, :shard] }
|
|
57
59
|
|
|
@@ -66,6 +68,13 @@ module OnlineMigrations
|
|
|
66
68
|
migration_name.sub(/^(::)?#{namespace}::/, "")
|
|
67
69
|
end
|
|
68
70
|
|
|
71
|
+
# TODO: delete in some future version
|
|
72
|
+
def cursor
|
|
73
|
+
self[:cursor]
|
|
74
|
+
rescue JSON::ParserError
|
|
75
|
+
cursor_before_type_cast
|
|
76
|
+
end
|
|
77
|
+
|
|
69
78
|
def migration_name=(class_name)
|
|
70
79
|
class_name = class_name.name if class_name.is_a?(Class)
|
|
71
80
|
write_attribute(:migration_name, self.class.normalize_migration_name(class_name))
|
|
@@ -111,13 +120,13 @@ module OnlineMigrations
|
|
|
111
120
|
end
|
|
112
121
|
|
|
113
122
|
# Returns whether a migration is stuck, which is defined as having a status of
|
|
114
|
-
#
|
|
123
|
+
# cancelling or pausing, and not having been updated in the last 5 minutes.
|
|
115
124
|
#
|
|
116
125
|
# @return [Boolean] whether the migration is stuck.
|
|
117
126
|
#
|
|
118
127
|
def stuck?
|
|
119
128
|
stuck_timeout = OnlineMigrations.config.background_data_migrations.stuck_timeout
|
|
120
|
-
(
|
|
129
|
+
(cancelling? || pausing?) && updated_at <= stuck_timeout.ago
|
|
121
130
|
end
|
|
122
131
|
|
|
123
132
|
# @private
|
|
@@ -13,14 +13,12 @@ module OnlineMigrations
|
|
|
13
13
|
# enqueued -> failed occurs when the migration job fails to be enqueued, or
|
|
14
14
|
# if the migration is deleted before is starts running.
|
|
15
15
|
"enqueued" => ["running", "paused", "cancelled", "failed"],
|
|
16
|
-
# running -> enqueued occurs when the migration is stuck and rescheduled by the scheduler.
|
|
17
16
|
# running -> succeeded occurs when the migration completes successfully.
|
|
18
17
|
# running -> pausing occurs when a user pauses the migration as it's performing.
|
|
19
18
|
# running -> cancelling occurs when a user cancels the migration as it's performing.
|
|
20
19
|
# running -> errored occurs when the migration raised an error during the last run.
|
|
21
20
|
# running -> failed occurs when the migration raises an error when running and retry attempts exceeded.
|
|
22
21
|
"running" => [
|
|
23
|
-
"enqueued",
|
|
24
22
|
"succeeded",
|
|
25
23
|
"pausing",
|
|
26
24
|
"cancelling",
|
|
@@ -36,11 +36,10 @@ module OnlineMigrations
|
|
|
36
36
|
migrations_to_enqueue = []
|
|
37
37
|
|
|
38
38
|
with_lock do
|
|
39
|
-
|
|
40
|
-
runnable_migrations = migrations_with_existing_classes(relation.pending) + stuck_migrations
|
|
39
|
+
runnable_migrations = migrations_with_existing_classes(relation.pending)
|
|
41
40
|
|
|
42
41
|
# Ensure no more than 'concurrency' migrations are running at the same time.
|
|
43
|
-
remaining_to_enqueue = concurrency -
|
|
42
|
+
remaining_to_enqueue = concurrency - relation.running.count
|
|
44
43
|
if remaining_to_enqueue > 0
|
|
45
44
|
runnable_migrations.take(remaining_to_enqueue).each do |migration|
|
|
46
45
|
migration.update!(status: :enqueued)
|
|
@@ -23,6 +23,7 @@ module OnlineMigrations
|
|
|
23
23
|
MAX_IDENTIFIER_LENGTH = 63
|
|
24
24
|
|
|
25
25
|
self.table_name = :background_schema_migrations
|
|
26
|
+
self.ignored_columns += ["parent_id", "composite"]
|
|
26
27
|
|
|
27
28
|
scope :queue_order, -> { order(created_at: :asc) }
|
|
28
29
|
scope :active, -> { where(status: [:pending, :running, :errored]) }
|
|
@@ -80,15 +81,10 @@ module OnlineMigrations
|
|
|
80
81
|
def progress
|
|
81
82
|
end
|
|
82
83
|
|
|
83
|
-
# Whether the migration is considered stuck
|
|
84
|
+
# Whether the migration is considered stuck.
|
|
84
85
|
#
|
|
85
86
|
def stuck?
|
|
86
|
-
|
|
87
|
-
running? && !index_build_in_progress?
|
|
88
|
-
else
|
|
89
|
-
stuck_timeout = (statement_timeout || 1.day) + 10.minutes
|
|
90
|
-
running? && updated_at <= stuck_timeout.seconds.ago
|
|
91
|
-
end
|
|
87
|
+
index_addition? && running? && !index_build_in_progress?
|
|
92
88
|
end
|
|
93
89
|
|
|
94
90
|
# Mark this migration as ready to be processed again.
|
|
@@ -44,9 +44,8 @@ module OnlineMigrations
|
|
|
44
44
|
# Background schema migrations could take a while to run. It is possible, that the process
|
|
45
45
|
# never reaches this (or the rescue below) line of code. E.g., when it is force quitted
|
|
46
46
|
# (SIGKILL etc.) and so the migration will end up in the "running" state and the query is
|
|
47
|
-
# still executing (or already finished) in the database. This migration can
|
|
48
|
-
# manually retried
|
|
49
|
-
# this migration is stuck.
|
|
47
|
+
# still executing (or already finished) in the database. This migration can be safely
|
|
48
|
+
# manually retried.
|
|
50
49
|
|
|
51
50
|
migration.update!(status: :succeeded, finished_at: Time.current)
|
|
52
51
|
|
|
@@ -35,8 +35,8 @@ module OnlineMigrations
|
|
|
35
35
|
|
|
36
36
|
private
|
|
37
37
|
def find_migration(**options)
|
|
38
|
-
|
|
39
|
-
runnable_migrations = (Migration.pending + Migration.errored
|
|
38
|
+
active_migrations = Migration.running.to_a
|
|
39
|
+
runnable_migrations = (Migration.pending + Migration.errored).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 }
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: online_migrations
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.36.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- fatkodima
|
|
@@ -41,6 +41,7 @@ files:
|
|
|
41
41
|
- lib/generators/online_migrations/templates/add_sharding_to_online_migrations.rb.tt
|
|
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
|
+
- lib/generators/online_migrations/templates/background_data_migrations_convert_cursor.rb.tt
|
|
44
45
|
- lib/generators/online_migrations/templates/background_data_migrations_remove_iteration_pause_default.rb.tt
|
|
45
46
|
- lib/generators/online_migrations/templates/background_migrations_change_status_default.rb.tt
|
|
46
47
|
- lib/generators/online_migrations/templates/background_schema_migrations_change_unique_index.rb.tt
|