strong_migrations 0.6.5 → 0.6.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|