Skip to content

Commit f983a77

Browse files
authored
Set our own stream position from the current sequence value on startup (#17309)
1 parent 12d7303 commit f983a77

File tree

3 files changed

+147
-178
lines changed

3 files changed

+147
-178
lines changed

changelog.d/17309.misc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
When rolling back to a previous Synapse version and then forwards again to this release, don't require server operators to manually run SQL.

synapse/storage/util/id_generators.py

+20-3
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,6 @@ def __init__(
276276
# no active writes in progress.
277277
self._max_position_of_local_instance = self._max_seen_allocated_stream_id
278278

279-
# This goes and fills out the above state from the database.
280-
self._load_current_ids(db_conn, tables)
281-
282279
self._sequence_gen = build_sequence_generator(
283280
db_conn=db_conn,
284281
database_engine=db.engine,
@@ -303,6 +300,13 @@ def __init__(
303300
positive=positive,
304301
)
305302

303+
# This goes and fills out the above state from the database.
304+
# This may read on the PostgreSQL sequence, and
305+
# SequenceGenerator.check_consistency might have fixed up the sequence, which
306+
# means the SequenceGenerator needs to be setup before we read the value from
307+
# the sequence.
308+
self._load_current_ids(db_conn, tables, sequence_name)
309+
306310
self._max_seen_allocated_stream_id = max(
307311
self._current_positions.values(), default=1
308312
)
@@ -327,6 +331,7 @@ def _load_current_ids(
327331
self,
328332
db_conn: LoggingDatabaseConnection,
329333
tables: List[Tuple[str, str, str]],
334+
sequence_name: str,
330335
) -> None:
331336
cur = db_conn.cursor(txn_name="_load_current_ids")
332337

@@ -360,6 +365,18 @@ def _load_current_ids(
360365
if instance in self._writers
361366
}
362367

368+
# If we're a writer, we can assume we're at the end of the stream
369+
# Usually, we would get that from the stream_positions, but in some cases,
370+
# like if we rolled back Synapse, the stream_positions table might not be up to
371+
# date. If we're using Postgres for the sequences, we can just use the current
372+
# sequence value as our own position.
373+
if self._instance_name in self._writers:
374+
if isinstance(self._db.engine, PostgresEngine):
375+
cur.execute(f"SELECT last_value FROM {sequence_name}")
376+
row = cur.fetchone()
377+
assert row is not None
378+
self._current_positions[self._instance_name] = row[0]
379+
363380
# We set the `_persisted_upto_position` to be the minimum of all current
364381
# positions. If empty we use the max stream ID from the DB table.
365382
min_stream_id = min(self._current_positions.values(), default=None)

0 commit comments

Comments
 (0)