zero_downtime_migrations 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 973c17c1d4e2b556771a49e67eb41f64d22655dc
4
- data.tar.gz: ffb23352741be8e007ea9b96d0aaae484480cd56
3
+ metadata.gz: 57fd5eb4562491e398c6357a0d13d1647e88cc34
4
+ data.tar.gz: a15d532d3130ace1169a5473ee5d4b0071c7945d
5
5
  SHA512:
6
- metadata.gz: 841c9c76ff327639b2f233030d74cde99b7e2f8e0d40fd0b87bb4bf8f74b8fcc2127dc59ba53524adf6d7659e30b23bbd29bd54125aec89bd31c5f2892a6e8d6
7
- data.tar.gz: fdcb4f80ac5f442add67e4914ab793af53e85a679f27b7c5a8ca6cf1f7c623b7fa40e660257ada0a3b364949d34e3bb85d558f426193cf1ec46c84c38f3534c2
6
+ metadata.gz: 970ce6605bf9fb36e7523f4819978ca02cd711b72ec43af74caa5caaebfd38072f7b5fd1a409cf3613f11c289f41f54f04321afa00c94d13556b04edf38f13a5
7
+ data.tar.gz: 984caa68bb7e0fe27b0d211744b8b04bad2c7dd40c6967eb4af6884a3871dba74dc3eeb5bff2dfb55e90c421c8675e54e6c894980dc19c396b545fb78b4bc340
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- zero_downtime_migrations (0.0.6)
4
+ zero_downtime_migrations (0.0.7)
5
5
  activerecord
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -36,7 +36,7 @@ These exceptions display clear instructions of how to perform the same operation
36
36
 
37
37
  #### Bad
38
38
 
39
- This migration can potentially lock your database table!
39
+ This can take a long time with significant database size or traffic and lock your table!
40
40
 
41
41
  ```ruby
42
42
  class AddPublishedToPosts < ActiveRecord::Migration[5.0]
@@ -48,7 +48,7 @@ end
48
48
 
49
49
  #### Good
50
50
 
51
- Instead, let's first add the column without a default.
51
+ First lets add the column without a default. When we add a column with a default it has to lock the table while it performs an UPDATE for ALL rows to set this new default.
52
52
 
53
53
  ```ruby
54
54
  class AddPublishedToPosts < ActiveRecord::Migration[5.0]
@@ -58,7 +58,7 @@ class AddPublishedToPosts < ActiveRecord::Migration[5.0]
58
58
  end
59
59
  ```
60
60
 
61
- Then set the new column default in a separate migration. Note that this does not update any existing data.
61
+ Then we’ll set the new column default in a separate migration. Note that this does not update any existing data! This only sets the default for newly inserted rows going forward.
62
62
 
63
63
  ```ruby
64
64
  class SetPublishedDefaultOnPosts < ActiveRecord::Migration[5.0]
@@ -68,7 +68,7 @@ class SetPublishedDefaultOnPosts < ActiveRecord::Migration[5.0]
68
68
  end
69
69
  ```
70
70
 
71
- If necessary then backport the default value for existing data in batches. This should be done in its own migration as well.
71
+ Finally we’ll backport the default value for existing data in batches. This should be done in its own migration as well. Updating in batches allows us to lock 1000 rows at a time (or whatever batch size we prefer).
72
72
 
73
73
  ```ruby
74
74
  class BackportPublishedDefaultOnPosts < ActiveRecord::Migration[5.0]
@@ -85,7 +85,7 @@ end
85
85
 
86
86
  #### Bad
87
87
 
88
- This action can potentially lock your database table while indexing all existing data!
88
+ This action can lock your database table while indexing existing data!
89
89
 
90
90
  ```ruby
91
91
  class IndexUsersOnEmail < ActiveRecord::Migration[5.0]
@@ -99,6 +99,8 @@ end
99
99
 
100
100
  Instead, let's add the index concurrently in its own migration with the DDL transaction disabled.
101
101
 
102
+ This allows PostgreSQL to build the index without locking in a way that prevent concurrent inserts, updates, or deletes on the table. Standard indexes lock out writes (but not reads) on the table.
103
+
102
104
  ```ruby
103
105
  class IndexUsersOnEmail < ActiveRecord::Migration[5.0]
104
106
  disable_ddl_transaction!
@@ -129,9 +131,9 @@ end
129
131
 
130
132
  Instead, let's split apart these types of migrations into separate files.
131
133
 
132
- * Introduce schema changes with methods like `create_table` or `add_column` in one file.
133
- * Update data with methods like `update_all` or `save` in another file.
134
- * Add indexes concurrently within their own file as well.
134
+ * Introduce schema changes with methods like `create_table` or `add_column` in one file. These should be run within a DDL transaction so that they can be rolled back if there are any issues.
135
+ * Update data with methods like `update_all` or `save` in another file. Data migrations tend to be much more error prone than changing the schema or adding indexes.
136
+ * Add indexes concurrently within their own file as well. Indexes should be created without the DDL transaction enabled to avoid table locking.
135
137
 
136
138
  ```ruby
137
139
  class AddPublishedToPosts < ActiveRecord::Migration[5.0]
@@ -163,7 +165,7 @@ end
163
165
 
164
166
  #### Bad
165
167
 
166
- The DDL transaction should only be disabled for migrations that add indexes.
168
+ The DDL transaction should only be disabled for migrations that add indexes. All other types of migrations should keep the DDL transaction enabled so that changes can be rolled back if any unexpected errors occur.
167
169
 
168
170
  ```ruby
169
171
  class AddPublishedToPosts < ActiveRecord::Migration[5.0]
@@ -12,9 +12,12 @@ module ZeroDowntimeMigrations
12
12
  <<-MESSAGE.strip_heredoc
13
13
  Adding a column with a default is unsafe!
14
14
 
15
- This action can potentially lock your database table!
15
+ This can take a long time with significant database
16
+ size or traffic and lock your table!
16
17
 
17
- Instead, let's first add the column without a default.
18
+ First lets add the column without a default. When we add
19
+ a column with a default it has to lock the table while it
20
+ performs an UPDATE for ALL rows to set this new default.
18
21
 
19
22
  class Add#{column_title}To#{table_title} < ActiveRecord::Migration
20
23
  def change
@@ -22,8 +25,9 @@ module ZeroDowntimeMigrations
22
25
  end
23
26
  end
24
27
 
25
- Then set the new column default in a separate migration. Note that
26
- this does not update any existing data.
28
+ Then we’ll set the new column default in a separate migration.
29
+ Note that this does not update any existing data! This only
30
+ sets the default for newly inserted rows going forward.
27
31
 
28
32
  class AddDefault#{column_title}To#{table_title} < ActiveRecord::Migration
29
33
  def change
@@ -31,8 +35,10 @@ module ZeroDowntimeMigrations
31
35
  end
32
36
  end
33
37
 
34
- If necessary then backport the default value for existing data in batches.
35
- This should be done in its own migration as well.
38
+ Finally we’ll backport the default value for existing data in
39
+ batches. This should be done in its own migration as well.
40
+ Updating in batches allows us to lock 1000 rows at a time
41
+ (or whatever batch size we prefer).
36
42
 
37
43
  class BackportDefault#{column_title}To#{table_title} < ActiveRecord::Migration
38
44
  def change
@@ -12,11 +12,15 @@ module ZeroDowntimeMigrations
12
12
  <<-MESSAGE.strip_heredoc
13
13
  Adding a non-concurrent index is unsafe!
14
14
 
15
- This action can potentially lock your database table!
15
+ This action can lock your database table while indexing existing data!
16
16
 
17
17
  Instead, let's add the index concurrently in its own migration with
18
18
  the DDL transaction disabled.
19
19
 
20
+ This allows PostgreSQL to build the index without locking in a way
21
+ that prevent concurrent inserts, updates, or deletes on the table.
22
+ Standard indexes lock out writes (but not reads) on the table.
23
+
20
24
  class Index#{table_title}On#{column_title} < ActiveRecord::Migration
21
25
  disable_ddl_transaction!
22
26
 
@@ -13,6 +13,8 @@ module ZeroDowntimeMigrations
13
13
  Disabling the DDL transaction is unsafe!
14
14
 
15
15
  The DDL transaction should only be disabled for migrations that add indexes.
16
+ All other types of migrations should keep the DDL transaction enabled so
17
+ that changes can be rolled back if any unexpected errors occur.
16
18
 
17
19
  Any other data or schema changes must live in their own migration files with
18
20
  the DDL transaction enabled just in case they need to be rolled back.
@@ -14,9 +14,16 @@ module ZeroDowntimeMigrations
14
14
 
15
15
  Instead, let's split apart these types of migrations into separate files.
16
16
 
17
- * Introduce schema changes with methods like `create_table` or `add_column` in one file.
17
+ * Introduce schema changes with methods like `create_table` or `add_column`
18
+ in one file. These should be run within a DDL transaction so that they
19
+ can be rolled back if there are any issues.
20
+
18
21
  * Update data with methods like `update_all` or `save` in another file.
19
- * Add indexes concurrently within their own file as well.
22
+ Data migrations tend to be much more error prone than changing the
23
+ schema or adding indexes.
24
+
25
+ * Add indexes concurrently within their own file as well. Indexes should
26
+ be created without the DDL transaction enabled to avoid table locking.
20
27
 
21
28
  If you're 100% positive that this migration is already safe, then simply
22
29
  add a call to `safety_assured` to your migration.
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.required_ruby_version = ">= 2.0.0"
12
12
  s.summary = "Zero downtime migrations with ActiveRecord and PostgreSQL"
13
13
  s.test_files = `git ls-files -- spec/*`.split("\n")
14
- s.version = "0.0.6"
14
+ s.version = "0.0.7"
15
15
 
16
16
  s.add_dependency "activerecord"
17
17
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zero_downtime_migrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - LendingHome
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-21 00:00:00.000000000 Z
11
+ date: 2016-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord