pg_ha_migrations 2.3.0 → 2.3.1
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/README.md +17 -3
- data/lib/pg_ha_migrations/safe_statements.rb +25 -0
- data/lib/pg_ha_migrations/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2092871922f1fb41ad0d82a1cda3b1b8ad57bf03b9e9a324d452110926754dba
|
|
4
|
+
data.tar.gz: 9e1e74c22f51cdf6d36333fdd6740ebdd5d5d4e76053a000859e7027b39ac9e5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 88089a7139e0ec580ff9c32574b4fd890d7bf7203740e6d3ec4821a6d03aed728868602de5347b441a2607951234b157cd19485710591b37e27dda803f4f46c7
|
|
7
|
+
data.tar.gz: a52081ab69232926e4484ac0d551437f61b719e0d1514cba507dcbcaf97c363726f2729037170e452f7d7d153847601604f50f92a837a374afc854e0d37f46d1
|
data/README.md
CHANGED
|
@@ -63,9 +63,21 @@ We believe the `force: true` option to ActiveRecord's `create_table` method is a
|
|
|
63
63
|
|
|
64
64
|
### Rollback
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
Although some schema changes are safe to reverse (e.g., dropping a just-created non-unique index), most possible schema changes are not safe to reverse. A few examples relative to database integrity:
|
|
67
|
+
* Dropping a newly added column may result in data loss.
|
|
68
|
+
* Re-adding a dropped unique index (or any other constraint) may fail because data may now exist that violates the constraint.
|
|
69
|
+
* Dropping a enum value simply isn’t supported by Postgres (and wouldn’t be safe since it might be referenced by rows in the database).
|
|
67
70
|
|
|
68
|
-
|
|
71
|
+
These concerns are magnified if we also consider currently running application code (especially across multiple revisions, i.e., during a deploy). For example, the application may expect:
|
|
72
|
+
* Indexes to be present for performant queries.
|
|
73
|
+
* Constraints to hold.
|
|
74
|
+
* Columns to be present.
|
|
75
|
+
|
|
76
|
+
Therefore we require that ["Rollback strategies do not involve reverting the database schema to its previous version"](https://medium.com/paypal-tech/postgresql-at-scale-database-schema-changes-without-downtime-20d3749ed680#360a), and PgHaMigrations does not support ActiveRecord's automatic migration rollback capability.
|
|
77
|
+
|
|
78
|
+
Instead we concentrate on ensuring that operations are safe to apply while both old and new revisions of an application are running. In the rare case where we need to “undo” a schema change, we roll forward, rather than rolling back, by having an engineer write a new schema change and deploying that change.
|
|
79
|
+
|
|
80
|
+
We write all of our migrations with only an `def up` method like:
|
|
69
81
|
|
|
70
82
|
```
|
|
71
83
|
def up
|
|
@@ -73,7 +85,9 @@ def up
|
|
|
73
85
|
end
|
|
74
86
|
```
|
|
75
87
|
|
|
76
|
-
and never use `def change`.
|
|
88
|
+
and never use `def change`.
|
|
89
|
+
|
|
90
|
+
For development environments we iterate by recreating the database from scratch every time we make a change.
|
|
77
91
|
|
|
78
92
|
### Transactional DDL
|
|
79
93
|
|
|
@@ -326,6 +326,31 @@ module PgHaMigrations::SafeStatements
|
|
|
326
326
|
PgHaMigrations::Index.from_table_and_columns(child_table, columns)
|
|
327
327
|
end
|
|
328
328
|
|
|
329
|
+
# A previous run that was interrupted mid-build can leave an invalid index
|
|
330
|
+
# behind on a child partition. Because CREATE INDEX ... IF NOT EXISTS matches
|
|
331
|
+
# on name only (not validity), that leftover would be skipped and never
|
|
332
|
+
# rebuilt, so the parent index would never become valid and this method
|
|
333
|
+
# would raise below on every re-run. When resuming (if_not_exists), drop any
|
|
334
|
+
# invalid child leftovers first so they get rebuilt. They are unattached at
|
|
335
|
+
# this point (the attach step runs only after every child index is built),
|
|
336
|
+
# so they can be dropped concurrently.
|
|
337
|
+
if if_not_exists && child_indexes.present?
|
|
338
|
+
quoted_child_index_names = child_indexes.map { |child_index| connection.quote(child_index.name) }.join(", ")
|
|
339
|
+
|
|
340
|
+
invalid_child_index_names = connection.select_values(<<~SQL)
|
|
341
|
+
SELECT pg_class.relname
|
|
342
|
+
FROM pg_index
|
|
343
|
+
JOIN pg_class ON pg_class.oid = pg_index.indexrelid
|
|
344
|
+
WHERE NOT pg_index.indisvalid
|
|
345
|
+
AND pg_class.relkind = 'i'
|
|
346
|
+
AND pg_class.relname = ANY (ARRAY[#{quoted_child_index_names}])
|
|
347
|
+
SQL
|
|
348
|
+
|
|
349
|
+
child_indexes.select { |index| invalid_child_index_names.include?(index.name) }.each do |child_index|
|
|
350
|
+
safe_remove_concurrent_index(child_index.table.fully_qualified_name, name: child_index.name)
|
|
351
|
+
end
|
|
352
|
+
end
|
|
353
|
+
|
|
329
354
|
# CREATE INDEX ON ONLY parent_table
|
|
330
355
|
unsafe_add_index(
|
|
331
356
|
parent_table.fully_qualified_name,
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pg_ha_migrations
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.3.
|
|
4
|
+
version: 2.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- celeen
|
|
@@ -13,7 +13,7 @@ authors:
|
|
|
13
13
|
- redneckbeard
|
|
14
14
|
bindir: exe
|
|
15
15
|
cert_chain: []
|
|
16
|
-
date: 2026-
|
|
16
|
+
date: 2026-07-31 00:00:00.000000000 Z
|
|
17
17
|
dependencies:
|
|
18
18
|
- !ruby/object:Gem::Dependency
|
|
19
19
|
name: rake
|