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

Commit

Permalink
Run database updates in a transaction (#8265)
Browse files Browse the repository at this point in the history
Fixes: #6467
  • Loading branch information
richvdh authored Sep 7, 2020
1 parent 765437d commit 5b452df
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 5 deletions.
1 change: 1 addition & 0 deletions changelog.d/8265.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix logstanding bug which could lead to incomplete database upgrades on SQLite.
27 changes: 22 additions & 5 deletions synapse/storage/prepare_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@
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__)

Expand All @@ -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.
Expand All @@ -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:
Expand Down

0 comments on commit 5b452df

Please sign in to comment.