strong_migrations 0.6.5 → 0.6.6
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 +5 -0
- data/README.md +9 -5
- data/lib/generators/strong_migrations/install_generator.rb +17 -0
- data/lib/generators/strong_migrations/templates/initializer.rb.tt +17 -0
- data/lib/strong_migrations.rb +13 -0
- data/lib/strong_migrations/checker.rb +44 -1
- data/lib/strong_migrations/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 140b74a0133d3db034a54fc178e4f95e53fbdec0c569dc2ade222efc96b83a6b
|
4
|
+
data.tar.gz: f4aadca5f15f85849b975630bdb937e3eef00498c0e806f6ca7cd8112d859fd4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f79d4dbd4342e45af9799f4d303c8ad8af68e8aa24fc5e86667547ec2a4c8ce95e123a6b3f0eb1851573d7a1bebd89a6795f4afffd4a319a0a9f0d73293f3ee
|
7
|
+
data.tar.gz: a784f11afffd45d827d7135d1f8fb822979ba851f6d8b54e09025ff9144f32f5091dce8e080901bac51237be74894571c6d007eddf373e3007de4886f5391b54
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -18,7 +18,11 @@ Add this line to your application’s Gemfile:
|
|
18
18
|
gem 'strong_migrations'
|
19
19
|
```
|
20
20
|
|
21
|
-
|
21
|
+
And run:
|
22
|
+
|
23
|
+
```sh
|
24
|
+
rails generate strong_migrations:install
|
25
|
+
```
|
22
26
|
|
23
27
|
## Checks
|
24
28
|
|
@@ -621,20 +625,20 @@ Check the [source code](https://github.com/ankane/strong_migrations/blob/master/
|
|
621
625
|
|
622
626
|
## Timeouts
|
623
627
|
|
624
|
-
It’s
|
628
|
+
It’s extremely important to set a short lock timeout for migrations. This way, if a migration can’t acquire a lock in a timely manner, other statements won’t be stuck behind it. We also recommend setting a long statement timeout so migrations can run for a while.
|
625
629
|
|
626
630
|
Create `config/initializers/strong_migrations.rb` with:
|
627
631
|
|
628
632
|
```ruby
|
629
|
-
StrongMigrations.statement_timeout = 1.hour
|
630
633
|
StrongMigrations.lock_timeout = 10.seconds
|
634
|
+
StrongMigrations.statement_timeout = 1.hour
|
631
635
|
```
|
632
636
|
|
633
637
|
Or set the timeouts directly on the database user that runs migrations. For Postgres, use:
|
634
638
|
|
635
639
|
```sql
|
636
|
-
ALTER ROLE myuser SET statement_timeout = '1h';
|
637
640
|
ALTER ROLE myuser SET lock_timeout = '10s';
|
641
|
+
ALTER ROLE myuser SET statement_timeout = '1h';
|
638
642
|
```
|
639
643
|
|
640
644
|
Note: If you use PgBouncer in transaction mode, you must set timeouts on the database user.
|
@@ -651,7 +655,7 @@ Use the version from your latest migration.
|
|
651
655
|
|
652
656
|
## Target Version
|
653
657
|
|
654
|
-
If your development database version is different from production, you can specify the production version so the right checks
|
658
|
+
If your development database version is different from production, you can specify the production version so the right checks run in development.
|
655
659
|
|
656
660
|
```ruby
|
657
661
|
StrongMigrations.target_postgresql_version = "10"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "rails/generators"
|
2
|
+
|
3
|
+
module StrongMigrations
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < Rails::Generators::Base
|
6
|
+
source_root File.join(__dir__, "templates")
|
7
|
+
|
8
|
+
def create_initializer
|
9
|
+
template "initializer.rb", "config/initializers/strong_migrations.rb"
|
10
|
+
end
|
11
|
+
|
12
|
+
def start_after
|
13
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Mark existing migrations as safe
|
2
|
+
StrongMigrations.start_after = <%= start_after %>
|
3
|
+
|
4
|
+
# Set timeouts
|
5
|
+
# If you use PgBouncer in transaction mode, delete these lines and set timeouts on the database user
|
6
|
+
StrongMigrations.lock_timeout = 10.seconds
|
7
|
+
StrongMigrations.statement_timeout = 1.hour
|
8
|
+
|
9
|
+
# Analyze tables automatically (to update planner statistics) after an index is added
|
10
|
+
StrongMigrations.auto_analyze = true
|
11
|
+
|
12
|
+
# Add custom checks
|
13
|
+
# StrongMigrations.add_check do |method, args|
|
14
|
+
# if method == :add_index && args[0].to_s == "users"
|
15
|
+
# stop! "No more indexes on the users table"
|
16
|
+
# end
|
17
|
+
# end
|
data/lib/strong_migrations.rb
CHANGED
@@ -19,6 +19,7 @@ module StrongMigrations
|
|
19
19
|
attr_accessor :auto_analyze, :start_after, :checks, :error_messages,
|
20
20
|
:target_postgresql_version, :target_mysql_version, :target_mariadb_version,
|
21
21
|
:enabled_checks, :lock_timeout, :statement_timeout, :helpers
|
22
|
+
attr_writer :lock_timeout_limit
|
22
23
|
end
|
23
24
|
self.auto_analyze = false
|
24
25
|
self.start_after = 0
|
@@ -230,6 +231,18 @@ end",
|
|
230
231
|
self.enabled_checks = (error_messages.keys - [:remove_index]).map { |k| [k, {}] }.to_h
|
231
232
|
self.helpers = false
|
232
233
|
|
234
|
+
# private
|
235
|
+
def self.developer_env?
|
236
|
+
defined?(Rails) && (Rails.env.development? || Rails.env.test?)
|
237
|
+
end
|
238
|
+
|
239
|
+
def self.lock_timeout_limit
|
240
|
+
unless defined?(@lock_timeout_limit)
|
241
|
+
@lock_timeout_limit = developer_env? ? false : 10
|
242
|
+
end
|
243
|
+
@lock_timeout_limit
|
244
|
+
end
|
245
|
+
|
233
246
|
def self.add_check(&block)
|
234
247
|
checks << block
|
235
248
|
end
|
@@ -7,6 +7,7 @@ module StrongMigrations
|
|
7
7
|
@new_tables = []
|
8
8
|
@safe = false
|
9
9
|
@timeouts_set = false
|
10
|
+
@lock_timeout_checked = false
|
10
11
|
end
|
11
12
|
|
12
13
|
def safety_assured
|
@@ -21,6 +22,7 @@ module StrongMigrations
|
|
21
22
|
|
22
23
|
def perform(method, *args)
|
23
24
|
set_timeouts
|
25
|
+
check_lock_timeout
|
24
26
|
|
25
27
|
unless safe?
|
26
28
|
case method
|
@@ -259,6 +261,7 @@ Then add the foreign key in separate migrations."
|
|
259
261
|
result
|
260
262
|
end
|
261
263
|
|
264
|
+
# TODO allow string timeouts in 0.7.0
|
262
265
|
def set_timeouts
|
263
266
|
if !@timeouts_set
|
264
267
|
if StrongMigrations.statement_timeout
|
@@ -350,7 +353,7 @@ Then add the foreign key in separate migrations."
|
|
350
353
|
|
351
354
|
def target_version(target_version)
|
352
355
|
version =
|
353
|
-
if target_version &&
|
356
|
+
if target_version && StrongMigrations.developer_env?
|
354
357
|
target_version.to_s
|
355
358
|
else
|
356
359
|
yield
|
@@ -358,6 +361,46 @@ Then add the foreign key in separate migrations."
|
|
358
361
|
Gem::Version.new(version)
|
359
362
|
end
|
360
363
|
|
364
|
+
def check_lock_timeout
|
365
|
+
limit = StrongMigrations.lock_timeout_limit
|
366
|
+
|
367
|
+
if limit && !@lock_timeout_checked
|
368
|
+
if postgresql?
|
369
|
+
lock_timeout = connection.select_all("SHOW lock_timeout").first["lock_timeout"]
|
370
|
+
lock_timeout_sec = timeout_to_sec(lock_timeout)
|
371
|
+
if lock_timeout_sec == 0
|
372
|
+
warn "[strong_migrations] WARNING: No lock timeout set. This is dangerous."
|
373
|
+
elsif lock_timeout_sec > limit
|
374
|
+
warn "[strong_migrations] WARNING: Lock timeout is longer than #{limit} seconds: #{lock_timeout}. This is dangerous."
|
375
|
+
end
|
376
|
+
elsif mysql? || mariadb?
|
377
|
+
lock_timeout = connection.select_all("SHOW VARIABLES LIKE 'lock_wait_timeout'").first["Value"]
|
378
|
+
if lock_timeout.to_i > limit
|
379
|
+
warn "[strong_migrations] WARNING: Lock timeout is longer than #{limit} seconds: #{lock_timeout}. This is dangerous."
|
380
|
+
end
|
381
|
+
end
|
382
|
+
@lock_timeout_checked = true
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
def timeout_to_sec(timeout)
|
387
|
+
suffixes = {
|
388
|
+
"ms" => 1,
|
389
|
+
"s" => 1000,
|
390
|
+
"min" => 1000 * 60,
|
391
|
+
"h" => 1000 * 60 * 60,
|
392
|
+
"d" => 1000 * 60 * 60 * 24
|
393
|
+
}
|
394
|
+
timeout_ms = timeout.to_i
|
395
|
+
suffixes.each do |k, v|
|
396
|
+
if timeout.end_with?(k)
|
397
|
+
timeout_ms *= v
|
398
|
+
break
|
399
|
+
end
|
400
|
+
end
|
401
|
+
timeout_ms / 1000.0
|
402
|
+
end
|
403
|
+
|
361
404
|
def helpers?
|
362
405
|
StrongMigrations.helpers
|
363
406
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: strong_migrations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2020-05-
|
13
|
+
date: 2020-05-08 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -108,6 +108,8 @@ files:
|
|
108
108
|
- CONTRIBUTING.md
|
109
109
|
- LICENSE.txt
|
110
110
|
- README.md
|
111
|
+
- lib/generators/strong_migrations/install_generator.rb
|
112
|
+
- lib/generators/strong_migrations/templates/initializer.rb.tt
|
111
113
|
- lib/strong_migrations.rb
|
112
114
|
- lib/strong_migrations/alphabetize_columns.rb
|
113
115
|
- lib/strong_migrations/checker.rb
|