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

Sanity-check database before running upgrades #6982

Merged
merged 1 commit into from
Feb 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/6982.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Check that server_name is correctly set before running database updates.
34 changes: 19 additions & 15 deletions synapse/storage/data_stores/main/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import time

from synapse.api.constants import PresenceState
from synapse.config.homeserver import HomeServerConfig
from synapse.storage.database import Database
from synapse.storage.engines import PostgresEngine
from synapse.storage.util.id_generators import (
Expand Down Expand Up @@ -117,16 +118,6 @@ def __init__(self, database: Database, db_conn, hs):
self._clock = hs.get_clock()
self.database_engine = database.engine

all_users_native = are_all_users_on_domain(
db_conn.cursor(), database.engine, hs.hostname
)
if not all_users_native:
raise Exception(
"Found users in database not native to %s!\n"
"You cannot changed a synapse server_name after it's been configured"
% (hs.hostname,)
)

self._stream_id_gen = StreamIdGenerator(
db_conn,
"events",
Expand Down Expand Up @@ -567,13 +558,26 @@ def search_users(self, term):
)


def are_all_users_on_domain(txn, database_engine, domain):
def check_database_before_upgrade(cur, database_engine, config: HomeServerConfig):
"""Called before upgrading an existing database to check that it is broadly sane
compared with the configuration.
"""
domain = config.server_name

sql = database_engine.convert_param_style(
"SELECT COUNT(*) FROM users WHERE name NOT LIKE ?"
)
pat = "%:" + domain
txn.execute(sql, (pat,))
num_not_matching = txn.fetchall()[0][0]
cur.execute(sql, (pat,))
num_not_matching = cur.fetchall()[0][0]
if num_not_matching == 0:
return True
return False
return

raise Exception(
"Found users in database not native to %s!\n"
"You cannot changed a synapse server_name after it's been configured"
% (domain,)
)


__all__ = ["DataStore", "check_database_before_upgrade"]
15 changes: 13 additions & 2 deletions synapse/storage/prepare_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,20 +278,31 @@ def _upgrade_existing_database(
the current_version wasn't generated by applying those delta files.
database_engine (DatabaseEngine)
config (synapse.config.homeserver.HomeServerConfig|None):
application config, or None if we are connecting to an existing
database which we expect to be configured already
None if we are initialising a blank database, otherwise the application
config
data_stores (list[str]): The names of the data stores to instantiate
on the given database.
is_empty (bool): Is this a blank database? I.e. do we need to run the
upgrade portions of the delta scripts.
"""
if is_empty:
assert not applied_delta_files
else:
assert config
clokep marked this conversation as resolved.
Show resolved Hide resolved

if current_version > SCHEMA_VERSION:
raise ValueError(
"Cannot use this database as it is too "
+ "new for the server to understand"
)

# some of the deltas assume that config.server_name is set correctly, so now
# is a good time to run the sanity check.
if not is_empty and "main" in data_stores:
from synapse.storage.data_stores.main import check_database_before_upgrade

check_database_before_upgrade(cur, database_engine, config)

start_ver = current_version
if not upgraded:
start_ver += 1
Expand Down