1
+ # Overview
2
+
1
3
This schema change splits the "instance state" enum that instances and VMMs
2
4
share into two enums, one for instance states and one for VMM states. Variants
3
5
used by only one of these objects only appear in the corresponding enum. This
@@ -14,7 +16,8 @@ Second, Postgres and/or CRDB don't support all the schema change primitives we
14
16
might use to deprecate the old state column. Specifically:
15
17
16
18
* CockroachDB doesn't support altering column types without enabling an
17
- experimental flag (cockroachdb#49329).
19
+ experimental flag
20
+ (see https://github.com/cockroachdb/cockroach/issues/49329?version=v22.1).
18
21
* Postgres doesn't support removing enum variants (adding and renaming are OK),
19
22
so we can't shrink and directly reuse the existing instance state enum without
20
23
leaving a set of "reserved"/"unused" variants around.
@@ -26,28 +29,36 @@ might use to deprecate the old state column. Specifically:
26
29
was added in v22.2).
27
30
28
31
These limitations make it hard to change the schema idempotently. To get around
29
- this for instances, do the following:
30
-
31
- . Create an `instance_state_v2` enum with the variants of interest.
32
- . Create a new `downlevel_state` column in the instance table (`ALTER TABLE ADD
33
- COLUMN` supports ` IF NOT EXISTS`).
34
- . Copy all existing instance states to that column.
35
- . Drop the existing `state` column (`ALTER TABLE DROP COLUMN` supports `IF
36
- EXISTS`).
37
- . Recreate the `state` column with the new type.
38
- . Populate the column's values based on what was saved in the `downlevel_state`
39
- column.
40
- . Add a `NOT NULL` qualifier to the new `state` column.
41
- . Drop the `downlevel_state` column.
42
-
43
- VMMs are similar, except that the new enum is called `vmm_state` .
44
-
45
- Once all this work is done the original `instance_state` enum can be dropped.
46
-
47
- There are two other small details to keep in mind:
48
-
49
- - Any views that depend on the affected state columns need to be dropped before
50
- removing the old columns and recreated after the migration is done.
51
- - Deleting and recreating a state column (instead of modifying it in place)
52
- changes its column index in its table, so these columns need to be moved
53
- to the (current) ends of the table definitions in dbinit.sql.
32
+ this, the change uses the following general procedure to change a column's type
33
+ from one enum to another:
34
+
35
+ . Create a new enum with the variants of interest.
36
+ . Create a new temporary column to hold the old object state. (Adding a column
37
+ supports `IF NOT EXISTS` ).
38
+ . Copy the old object state to the temporary column.
39
+ . Drop the old column (this supports `IF EXISTS` ).
40
+ . Recreate the state column with the new type.
41
+ . Populate the column's values using the data saved in the temporary column.
42
+ . Add a `NOT NULL` qualifier to the new column.
43
+ . Drop the temporary column.
44
+
45
+ Note that deleting and recreating columns this way (instead of modfying them in
46
+ place) changes their column indices in the affected table. These columns need to
47
+ be moved to the (current) ends of the table definitions in dbinit.sql, or the
48
+ schema upgrade tests will fail.
49
+
50
+ # Upgrade steps
51
+
52
+ The individual transactions in this upgrade do the following:
53
+
54
+ * `up01` and `up02` drop views that depend on the `state` column in the `vmm`
55
+ table.
56
+ * `up03` through `up10` change the `instance` table's state enum using the
57
+ procedure described above.
58
+ * `up11` through `up18` upgrade the `vmm` table.
59
+ * `up19` and `up21` recreate the views deleted at the beginning of this
60
+ procedure.
61
+ * `up20` deletes the now-unused `instance_state` enum.
62
+ * `up22` adds a constraint to the `instance` table that requires that an
63
+ instance be in the `vmm` state if and only if it has a non-NULL active
64
+ Propolis ID.
0 commit comments