You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _posts/2023-06-02-pgsql-phriday-009-schema-change-management.md
+19-15
Original file line number
Diff line number
Diff line change
@@ -29,15 +29,15 @@ A little background context. I work on a team of Rails developers that are const
29
29
30
30
In Rails schema changes are made by developers. There has always been a built-in mechanism to do this as a core part of the Rails framework.
31
31
32
-
This is different than other frameworks that might require a 3rd party tool like [Flyway](https://flywaydb.org).
32
+
This is different from other frameworks that need an additional tool like [Flyway](https://flywaydb.org).
33
33
34
34
For PostgreSQL administrators that aren't used to developers making schema changes all the time, this can be surprising!
35
35
36
-
Most of the time, schema changes like adding nullable columns are no sweat.
36
+
Most of the time schema changes are low impact, like adding a nullable column.
37
37
38
-
Do application developers sometimes make schema changes that cause errors? Yes. Although this risk is present, the benefits of improved development velocity outweigh the risks.
38
+
Do application developers sometimes make schema changes that cause errors? Yes. Although this risk exists, the benefits of having developers move faster making schema changes outweigh the risks.
39
39
40
-
We do attempt to mitigate errors in a couple of ways.
40
+
We also attempt to mitigate the risks of application errors in a couple of ways.
41
41
42
42
Here is the normal workflow.
43
43
@@ -73,7 +73,7 @@ The deployment process takes care of restarting application instances since they
73
73
74
74
#### Do you have a dev-QA-staging or similar series of environments it must pass through first?
75
75
76
-
Developers test their changes including schema modifications on their local development machines. Each Pull Request has a CI build associated to it that must pass before merge. Each Pull Request must receive at least one review.
76
+
Developers test their changes including schema modifications on their local development machines. Each Pull Request has a CI build associated with it with a separate database and builds must pass before merge. Each Pull Request must receive at least one review.
77
77
78
78
Developers may test their changes in a couple of pre-production test environments where they apply their schema modifications and deploy their code changes. This is not required but is a good practice.
79
79
@@ -90,35 +90,39 @@ Our team does not have a easy way to test the effect of long duration locks in p
90
90
91
91
#### What’s different about modifying huge tables with many millions or billions of rows?
92
92
93
-
We do modify tables with billions of rows, but ideally we have partitioned the table before it reaches that size!
93
+
We do modify tables with billions of rows, but ideally we've partitioned the table before it reaches that point!
94
94
95
-
There are various types of schema modifications that are potentially dangerous even on tables with many fewer rows.
95
+
There are various types of schema modifications that are potentially dangerous even on tables with many fewer rows. As a SaaS B2B app, customers rely on our app to conduct their business, and pay a hefty subscription.
96
96
97
-
To help identify those as early as possible, we use [Strong Migrations](https://github.com/ankane/strong_migrations) which hooks into the Rails Migration flow.
98
-
99
-
This tool points out potentially dangerous modifications and suggests safer alternatives.
97
+
To help identify potentially unsafe changes as early as possible, we use [Strong Migrations](https://github.com/ankane/strong_migrations) which hooks into the Rails Migration flow.
100
98
101
99
For huge tables we look for changes that cause long locks on a table. Write locks could block concurrent modifications and cause user facing errors in the application.
102
100
103
101
We’d create the SQL for the modification and test it locally and on a lower environment. For visibility that the change is occurring, we would write it in a Jira ticket and share it on the team so that a second reviewer can approve it. We may plan to perform the modification during a low activity period.
104
102
103
+
If a change is made manually, we then backfill a Rails migration to prevent schema "drift", keeping everything in sync.
104
+
105
105
#### How does Postgres make certain kinds of change easier or more difficult compared to other databases?
106
106
107
-
The [Transactional DDL feature](https://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis) is a nice feature to experiment a bit with schema modifications and know that they’re rolled back. For Rails Migrations that fail to apply due to exceeding a lock timeout or another timeout, it’s nice to know they’ll be rolled back as well.
107
+
The [Transactional DDL feature](https://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis) is a nice feature to experiment a bit with schema modifications and know that they’re rolled back. For Rails Migrations that fail to apply due to exceeding a lock timeout or for another reason, it’s nice to know the modification will be rolled back cleanly.
108
108
109
-
Rarely there can be a consistency problem between Rails application and PostgreSQL. I covered this in the post [Manually Fixing a Rails Migration](/blog/2021/08/30/manual-migration-fix).
109
+
Rarely there can be a consistency problem between the Rails application and PostgreSQL. I covered this in the post [Manually Fixing a Rails Migration](/blog/2021/08/30/manual-migration-fix).
110
110
111
111
112
112
#### Do you believe that "rolling back" a schema change is a useful and/or meaningful concept? When and why, or why not?
113
113
114
-
I don’t normally roll back a schema change. We’d do a lot of pre-release testing inlocal development, CI, lower environments, among multiple developers. However rolling back a transaction that contained a DDL modification is a nice safeguard.
114
+
I don’t normally roll back a schema change. We’d do a lot of pre-release testing in local development, CI, lower environments, and among multiple developers. However rolling back a transaction that contained a DDL modification is a nice safeguard.
115
115
116
-
What is a normal process in the evolution of a schema is that columns are no longer needed because they related to a feature that has been retired or relocated. This could even be entire tables or collections of tables. In those cases it’s nice to remove the columns and tables entirely. Although there may be some coordination with downstream consumers like ETL, shrinking the primary transactional database and removing any unnecessary indexes, constraints, etc. along with those columns and tables, is a win.
116
+
What is a normal process in the evolution of a schema is that columns are no longer needed because they related to a feature that has been retired or relocated. This could even be entire tables or collections of tables.
117
+
118
+
In those cases it’s nice to remove the columns and tables entirely. This can have some risk as well and there are safeguards we use.
117
119
118
120
119
121
#### How do you validate a successful schema change? Do you have any useful processes, automated or manual, that have helped you track down problems with rollout, replication, data quality or corruption, and the like?
120
122
121
-
For Rails, every database that’s managed by Rails has a `schema_version` table. The schema version is inserted into the database with the schema modification. We can confirm the schema change was applied to the database itself by inspecting it. We can view the table fields or indexes with `\d tablename` and similar commands.
123
+
When Rails manages a database it gets a `schema_version` table. The schema version for a Migration (a number) is inserted into this table when it's applied.
124
+
125
+
We can confirm the schema change was applied by querying the table. We can view the table fields or indexes with `\d tablename` and similar commands.
122
126
123
127
A nice pattern is to release the schema changes in advance of their code usage. This provides an opportunity to verify schema changes where applied before new tables or columns are actively used.
0 commit comments