diff options
author | Richard van der Hoff <1389908+richvdh@users.noreply.github.com> | 2020-09-07 11:41:50 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-07 11:41:50 +0100 |
commit | 5b452df23b02fa98d0277e79fa6154af981c4f3a (patch) | |
tree | cbc4a01968f3ea0eab5f96d375c1e3d8cb7cdc4a | |
parent | Add tests for `last_successful_stream_ordering` (#8258) (diff) | |
download | synapse-5b452df23b02fa98d0277e79fa6154af981c4f3a.tar.xz |
Run database updates in a transaction (#8265)
Fixes: #6467
Diffstat (limited to '')
-rw-r--r-- | changelog.d/8265.bugfix | 1 | ||||
-rw-r--r-- | synapse/storage/prepare_database.py | 27 |
2 files changed, 23 insertions, 5 deletions
diff --git a/changelog.d/8265.bugfix b/changelog.d/8265.bugfix new file mode 100644 index 0000000000..981a836d21 --- /dev/null +++ b/changelog.d/8265.bugfix @@ -0,0 +1 @@ +Fix logstanding bug which could lead to incomplete database upgrades on SQLite. diff --git a/synapse/storage/prepare_database.py b/synapse/storage/prepare_database.py index 964d8d9eb8..229acb2da7 100644 --- a/synapse/storage/prepare_database.py +++ b/synapse/storage/prepare_database.py @@ -19,12 +19,15 @@ import logging import os import re from collections import Counter -from typing import TextIO +from typing import Optional, TextIO import attr +from synapse.config.homeserver import HomeServerConfig +from synapse.storage.engines import BaseDatabaseEngine from synapse.storage.engines.postgres import PostgresEngine -from synapse.storage.types import Cursor +from synapse.storage.types import Connection, Cursor +from synapse.types import Collection logger = logging.getLogger(__name__) @@ -47,7 +50,12 @@ class UpgradeDatabaseException(PrepareDatabaseException): pass -def prepare_database(db_conn, database_engine, config, databases=["main", "state"]): +def prepare_database( + db_conn: Connection, + database_engine: BaseDatabaseEngine, + config: Optional[HomeServerConfig], + databases: Collection[str] = ["main", "state"], +): """Prepares a physical database for usage. Will either create all necessary tables or upgrade from an older schema version. @@ -57,15 +65,24 @@ def prepare_database(db_conn, database_engine, config, databases=["main", "state Args: db_conn: database_engine: - config (synapse.config.homeserver.HomeServerConfig|None): + config : application config, or None if we are connecting to an existing database which we expect to be configured already - databases (list[str]): The name of the databases that will be used + databases: The name of the databases that will be used with this physical database. Defaults to all databases. """ try: cur = db_conn.cursor() + + # sqlite does not automatically start transactions for DDL / SELECT statements, + # so we start one before running anything. This ensures that any upgrades + # are either applied completely, or not at all. + # + # (psycopg2 automatically starts a transaction as soon as we run any statements + # at all, so this is redundant but harmless there.) + cur.execute("BEGIN TRANSACTION") + version_info = _get_or_create_schema_state(cur, database_engine) if version_info: |