Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Indentation tweaks (hopefully to put the code blocks in the <li>s)
Browse files Browse the repository at this point in the history
  • Loading branch information
reivilibre committed May 30, 2023
1 parent 2ef49b5 commit c5d94bf
Showing 1 changed file with 28 additions and 28 deletions.
56 changes: 28 additions & 28 deletions docs/development/database_schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ SCHEMA_COMPAT_VERSION = ... # unimportant at this stage
```

**Invariants:**
* `old_column` is read by Synapse and written to by Synapse.
1. `old_column` is read by Synapse and written to by Synapse.


#### Synapse version `N + 1`
Expand All @@ -239,9 +239,9 @@ SCHEMA_COMPAT_VERSION = ... # unimportant at this stage

**Changes:**
1.
```sql
ALTER TABLE mytable ADD COLUMN new_column INTEGER;
```
```sql
ALTER TABLE mytable ADD COLUMN new_column INTEGER;
```

**Invariants:**
1. `old_column` is read by Synapse and written to by Synapse.
Expand All @@ -260,19 +260,19 @@ SCHEMA_COMPAT_VERSION = S + 1 # we can't roll back to a time before new_column e

**Changes:**
1. On Postgres, add a `NOT VALID` constraint to ensure new rows are compliant. *SQLite does not have such a construct, but it would be unnecessary anyway since there is no way to concurrently perform this migration on SQLite.*
```sql
ALTER TABLE mytable ADD CONSTRAINT CHECK new_column_not_null (new_column IS NOT NULL) NOT VALID;
```
```sql
ALTER TABLE mytable ADD CONSTRAINT CHECK new_column_not_null (new_column IS NOT NULL) NOT VALID;
```
2. Start a background update to perform migration: it should gradually run e.g.
```sql
UPDATE mytable SET new_column = old_column * 100 WHERE 0 < mytable_id AND mytable_id <= 5;
```
This background update is technically pointless on SQLite, but you must schedule it anyway so that the `portdb` script to migrate to Postgres still works.
```sql
UPDATE mytable SET new_column = old_column * 100 WHERE 0 < mytable_id AND mytable_id <= 5;
```
This background update is technically pointless on SQLite, but you must schedule it anyway so that the `portdb` script to migrate to Postgres still works.
3. Upon completion of the background update, you should run `VALIDATE CONSTRAINT` on Postgres to turn the `NOT VALID` constraint into a valid one.
```sql
ALTER TABLE mytable VALIDATE CONSTRAINT new_column_not_null;
```
This will take some time but does **NOT** hold an exclusive lock over the table.
```sql
ALTER TABLE mytable VALIDATE CONSTRAINT new_column_not_null;
```
This will take some time but does **NOT** hold an exclusive lock over the table.

**Invariants:**
1. `old_column` is read by Synapse and written to by Synapse.
Expand All @@ -292,17 +292,17 @@ SCHEMA_COMPAT_VERSION = S + 1 # we can't roll back to a time before new_column e

**Changes:**
1. (Postgres) Update the table to populate values of `new_column` in case the background update had not completed. Additionally, `VALIDATE CONSTRAINT` to make the check fully valid.
```sql
-- you ideally want an index on `new_column` or e.g. `(new_column) WHERE new_column IS NULL` first, or perhaps you can find a way to skip this if the `NOT NULL` constraint has already been validated.
UPDATE mytable SET new_column = old_column * 100 WHERE new_column IS NULL;
```sql
-- you ideally want an index on `new_column` or e.g. `(new_column) WHERE new_column IS NULL` first, or perhaps you can find a way to skip this if the `NOT NULL` constraint has already been validated.
UPDATE mytable SET new_column = old_column * 100 WHERE new_column IS NULL;
-- this is a no-op if it already ran as part of the background update
ALTER TABLE mytable VALIDATE CONSTRAINT new_column_not_null;
```
-- this is a no-op if it already ran as part of the background update
ALTER TABLE mytable VALIDATE CONSTRAINT new_column_not_null;
```
2. (SQLite) Recreate the table by precisely following [the 12-step procedure for SQLite table schema changes](https://www.sqlite.org/lang_altertable.html#otheralter).
During this table rewrite, you should recreate `new_column` as `NOT NULL` and populate any outstanding `NULL` values at the same time.
Unfortunately, you can't drop `old_column` yet because it must be present for compatibility with the Postgres schema, as needed by `portdb`.
(Otherwise you could do this all in one go with SQLite!)
During this table rewrite, you should recreate `new_column` as `NOT NULL` and populate any outstanding `NULL` values at the same time.
Unfortunately, you can't drop `old_column` yet because it must be present for compatibility with the Postgres schema, as needed by `portdb`.
(Otherwise you could do this all in one go with SQLite!)
**Invariants:**
1. `old_column` is written to by Synapse (but no longer read by Synapse!).
Expand All @@ -325,7 +325,7 @@ SCHEMA_COMPAT_VERSION = S + 3 # we can't roll back to a time before new_column w
2. `new_column` is read by Synapse and written to by Synapse. Moreover, all rows have a non-`NULL` value in this field, as guaranteed by a schema constraint.

**Notes:**
1. We can't drop `old_column` yet because that would break a rollback to the previous version of Synapse.
1. We can't drop `old_column` yet because that would break a rollback to the previous version of Synapse. \
**TODO:** It may be possible to relax this and drop the column straight away as long as the previous version of Synapse detected a rollback occurred and stopped attempting to write to the column. This could possibly be done by checking whether the database's schema compatibility version was `S + 3`.


Expand All @@ -338,6 +338,6 @@ SCHEMA_COMPAT_VERSION = S + 4 # we can't roll back to a time before old_column w

**Changes:**
1.
```sql
ALTER TABLE mytable DROP COLUMN old_column;
```
```sql
ALTER TABLE mytable DROP COLUMN old_column;
```

0 comments on commit c5d94bf

Please sign in to comment.