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

Commit 187ab28

Browse files
committed
Messy: Fix undefined state_group for federated historical events
``` 2021-07-13 02:27:57,810 - synapse.handlers.federation - 1248 - ERROR - GET-4 - Failed to backfill from hs1 because NOT NULL constraint failed: event_to_state_groups.state_group Traceback (most recent call last): File "/usr/local/lib/python3.8/site-packages/synapse/handlers/federation.py", line 1216, in try_backfill await self.backfill( File "/usr/local/lib/python3.8/site-packages/synapse/handlers/federation.py", line 1035, in backfill await self._auth_and_persist_event(dest, event, context, backfilled=True) File "/usr/local/lib/python3.8/site-packages/synapse/handlers/federation.py", line 2222, in _auth_and_persist_event await self._run_push_actions_and_persist_event(event, context, backfilled) File "/usr/local/lib/python3.8/site-packages/synapse/handlers/federation.py", line 2244, in _run_push_actions_and_persist_event await self.persist_events_and_notify( File "/usr/local/lib/python3.8/site-packages/synapse/handlers/federation.py", line 3290, in persist_events_and_notify events, max_stream_token = await self.storage.persistence.persist_events( File "/usr/local/lib/python3.8/site-packages/synapse/logging/opentracing.py", line 774, in _trace_inner return await func(*args, **kwargs) File "/usr/local/lib/python3.8/site-packages/synapse/storage/persist_events.py", line 320, in persist_events ret_vals = await yieldable_gather_results(enqueue, partitioned.items()) File "/usr/local/lib/python3.8/site-packages/synapse/storage/persist_events.py", line 237, in handle_queue_loop ret = await self._per_item_callback( File "/usr/local/lib/python3.8/site-packages/synapse/storage/persist_events.py", line 577, in _persist_event_batch await self.persist_events_store._persist_events_and_state_updates( File "/usr/local/lib/python3.8/site-packages/synapse/storage/databases/main/events.py", line 176, in _persist_events_and_state_updates await self.db_pool.runInteraction( File "/usr/local/lib/python3.8/site-packages/synapse/storage/database.py", line 681, in runInteraction result = await self.runWithConnection( File "/usr/local/lib/python3.8/site-packages/synapse/storage/database.py", line 770, in runWithConnection return await make_deferred_yieldable( File "/usr/local/lib/python3.8/site-packages/twisted/python/threadpool.py", line 238, in inContext result = inContext.theWork() # type: ignore[attr-defined] File "/usr/local/lib/python3.8/site-packages/twisted/python/threadpool.py", line 254, in <lambda> inContext.theWork = lambda: context.call( # type: ignore[attr-defined] File "/usr/local/lib/python3.8/site-packages/twisted/python/context.py", line 118, in callWithContext return self.currentContext().callWithContext(ctx, func, *args, **kw) File "/usr/local/lib/python3.8/site-packages/twisted/python/context.py", line 83, in callWithContext return func(*args, **kw) File "/usr/local/lib/python3.8/site-packages/twisted/enterprise/adbapi.py", line 293, in _runWithConnection compat.reraise(excValue, excTraceback) File "/usr/local/lib/python3.8/site-packages/twisted/python/deprecate.py", line 298, in deprecatedFunction return function(*args, **kwargs) File "/usr/local/lib/python3.8/site-packages/twisted/python/compat.py", line 403, in reraise raise exception.with_traceback(traceback) File "/usr/local/lib/python3.8/site-packages/twisted/enterprise/adbapi.py", line 284, in _runWithConnection result = func(conn, *args, **kw) File "/usr/local/lib/python3.8/site-packages/synapse/storage/database.py", line 765, in inner_func return func(db_conn, *args, **kwargs) File "/usr/local/lib/python3.8/site-packages/synapse/storage/database.py", line 549, in new_transaction r = func(cursor, *args, **kwargs) File "/usr/local/lib/python3.8/site-packages/synapse/logging/utils.py", line 69, in wrapped return f(*args, **kwargs) File "/usr/local/lib/python3.8/site-packages/synapse/storage/databases/main/events.py", line 385, in _persist_events_txn self._store_event_state_mappings_txn(txn, events_and_contexts) File "/usr/local/lib/python3.8/site-packages/synapse/storage/databases/main/events.py", line 2065, in _store_event_state_mappings_txn self.db_pool.simple_insert_many_txn( File "/usr/local/lib/python3.8/site-packages/synapse/storage/database.py", line 923, in simple_insert_many_txn txn.execute_batch(sql, vals) File "/usr/local/lib/python3.8/site-packages/synapse/storage/database.py", line 280, in execute_batch self.executemany(sql, args) File "/usr/local/lib/python3.8/site-packages/synapse/storage/database.py", line 300, in executemany self._do_execute(self.txn.executemany, sql, *args) File "/usr/local/lib/python3.8/site-packages/synapse/storage/database.py", line 330, in _do_execute return func(sql, *args) sqlite3.IntegrityError: NOT NULL constraint failed: event_to_state_groups.state_group ```
1 parent 8ebbc5f commit 187ab28

File tree

3 files changed

+87
-6
lines changed

3 files changed

+87
-6
lines changed

synapse/handlers/federation.py

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -924,7 +924,11 @@ async def _handle_marker_event(self, origin: str, marker_event: EventBase):
924924
origin,
925925
marker_event.room_id,
926926
[insertion_event_id],
927+
# outlier=False,
927928
)
929+
# await self._get_state_after_missing_prev_event(
930+
# origin, marker_event.room_id, insertion_event_id
931+
# )
928932

929933
insertion_event = await self.store.get_event(
930934
insertion_event_id, allow_none=True
@@ -1078,15 +1082,27 @@ async def backfill(
10781082
# Step 2: Persist the rest of the events in the chunk one by one
10791083
events.sort(key=lambda e: e.depth)
10801084

1085+
logger.info("backfill: events=%s", events)
10811086
for event in events:
10821087
if event in events_to_state:
10831088
continue
10841089

10851090
# For paranoia we ensure that these events are marked as
10861091
# non-outliers
1092+
logger.info(
1093+
"backfill: persist event_id=%s (%s) outlier=%s",
1094+
event.event_id,
1095+
event.type,
1096+
event.internal_metadata.is_outlier(),
1097+
)
10871098
assert not event.internal_metadata.is_outlier()
10881099

10891100
context = await self.state_handler.compute_event_context(event)
1101+
logger.info(
1102+
"backfill: context event_id=%s state_group=%s",
1103+
event.event_id,
1104+
context.state_group,
1105+
)
10901106

10911107
# We store these one at a time since each event depends on the
10921108
# previous to work out the state.
@@ -1383,7 +1399,12 @@ async def try_backfill(domains: List[str]) -> bool:
13831399
return False
13841400

13851401
async def _get_events_and_persist(
1386-
self, destination: str, room_id: str, events: Iterable[str]
1402+
self,
1403+
destination: str,
1404+
room_id: str,
1405+
events: Iterable[str],
1406+
# TODO: check if still used
1407+
outlier: bool = True,
13871408
) -> None:
13881409
"""Fetch the given events from a server, and persist them as outliers.
13891410
@@ -1405,7 +1426,7 @@ async def get_event(event_id: str):
14051426
[destination],
14061427
event_id,
14071428
room_version,
1408-
outlier=True,
1429+
outlier=outlier,
14091430
)
14101431
if event is None:
14111432
logger.warning(
@@ -2278,6 +2299,11 @@ async def _auth_and_persist_event(
22782299
server.
22792300
backfilled: True if the event was backfilled.
22802301
"""
2302+
logger.info(
2303+
"_auth_and_persist_event: before event_id=%s state_group=%s",
2304+
event.event_id,
2305+
context.state_group,
2306+
)
22812307
context = await self._check_event_auth(
22822308
origin,
22832309
event,
@@ -2286,6 +2312,11 @@ async def _auth_and_persist_event(
22862312
auth_events=auth_events,
22872313
backfilled=backfilled,
22882314
)
2315+
logger.info(
2316+
"_auth_and_persist_event: after event_id=%s state_group=%s",
2317+
event.event_id,
2318+
context.state_group,
2319+
)
22892320

22902321
await self._run_push_actions_and_persist_event(event, context, backfilled)
22912322

@@ -2667,9 +2698,19 @@ async def _check_event_auth(
26672698
auth_events[(c.type, c.state_key)] = c
26682699

26692700
try:
2701+
logger.info(
2702+
"_check_event_auth: before event_id=%s state_group=%s",
2703+
event.event_id,
2704+
context.state_group,
2705+
)
26702706
context = await self._update_auth_events_and_context_for_auth(
26712707
origin, event, context, auth_events
26722708
)
2709+
logger.info(
2710+
"_check_event_auth: after event_id=%s state_group=%s",
2711+
event.event_id,
2712+
context.state_group,
2713+
)
26732714
except Exception:
26742715
# We don't really mind if the above fails, so lets not fail
26752716
# processing if it does. However, it really shouldn't fail so
@@ -2756,7 +2797,11 @@ async def _update_auth_events_and_context_for_auth(
27562797

27572798
if missing_auth:
27582799
# If we don't have all the auth events, we need to get them.
2759-
logger.info("auth_events contains unknown events: %s", missing_auth)
2800+
logger.info(
2801+
"auth_events contains unknown events for event_id=%s, missing_auth=%s",
2802+
event.event_id,
2803+
missing_auth,
2804+
)
27602805
try:
27612806
try:
27622807
remote_auth_chain = await self.federation_client.get_event_auth(
@@ -2793,9 +2838,13 @@ async def _update_auth_events_and_context_for_auth(
27932838
event.event_id,
27942839
e.event_id,
27952840
)
2796-
context = await self.state_handler.compute_event_context(e)
2841+
# XXX: Main fix is here. It was computing context for the missing auth event
2842+
# and re-assigning to the `context` variable used for the main event
2843+
missing_auth_context = (
2844+
await self.state_handler.compute_event_context(e)
2845+
)
27972846
await self._auth_and_persist_event(
2798-
origin, e, context, auth_events=auth
2847+
origin, e, missing_auth_context, auth_events=auth
27992848
)
28002849

28012850
if e.event_id in event_auth_events:
@@ -2806,13 +2855,20 @@ async def _update_auth_events_and_context_for_auth(
28062855
except Exception:
28072856
logger.exception("Failed to get auth chain")
28082857

2858+
logger.info(
2859+
"_update_auth_events_and_context_for_auth: check outlier event_id=%s outlier=%s",
2860+
event.event_id,
2861+
event.internal_metadata.is_outlier(),
2862+
)
28092863
if event.internal_metadata.is_outlier():
28102864
# XXX: given that, for an outlier, we'll be working with the
28112865
# event's *claimed* auth events rather than those we calculated:
28122866
# (a) is there any point in this test, since different_auth below will
28132867
# obviously be empty
28142868
# (b) alternatively, why don't we do it earlier?
2815-
logger.info("Skipping auth_event fetch for outlier")
2869+
logger.info(
2870+
"Skipping auth_event fetch for outlier event_id=%s", event.event_id
2871+
)
28162872
return context
28172873

28182874
different_auth = event_auth_events.difference(

synapse/state/__init__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,13 @@ async def compute_event_context(
324324
entry = await self.resolve_state_groups_for_events(
325325
event.room_id, event.prev_event_ids()
326326
)
327+
logger.info(
328+
"compute_event_context: resolve_state_groups_for_events\nstate_ids_before_event=%s\nstate_group_before_event=%s\nstate_group_before_event_prev_group=%s\ndeltas_to_state_group_before_event=%s",
329+
entry.state,
330+
entry.state_group,
331+
entry.prev_group,
332+
entry.delta_ids,
333+
)
327334

328335
state_ids_before_event = entry.state
329336
state_group_before_event = entry.state_group
@@ -359,6 +366,10 @@ async def compute_event_context(
359366
#
360367

361368
if not event.is_state():
369+
logger.info(
370+
"compute_event_context: returning with state_group_before_event=%s",
371+
state_group_before_event,
372+
)
362373
return EventContext.with_state(
363374
state_group_before_event=state_group_before_event,
364375
state_group=state_group_before_event,
@@ -390,6 +401,11 @@ async def compute_event_context(
390401
current_state_ids=state_ids_after_event,
391402
)
392403

404+
logger.info(
405+
"compute_event_context: after\nstate_group_after_event=%s",
406+
state_group_after_event,
407+
)
408+
393409
return EventContext.with_state(
394410
state_group=state_group_after_event,
395411
state_group_before_event=state_group_before_event,

synapse/storage/databases/main/events.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2032,6 +2032,13 @@ def _store_event_state_mappings_txn(
20322032
):
20332033
state_groups = {}
20342034
for event, context in events_and_contexts:
2035+
2036+
logger.info(
2037+
"creating state_groups grsesegr event_id=%s outlier=%s %s",
2038+
event.event_id,
2039+
event.internal_metadata.is_outlier(),
2040+
event,
2041+
)
20352042
if event.internal_metadata.is_outlier():
20362043
continue
20372044

@@ -2043,6 +2050,8 @@ def _store_event_state_mappings_txn(
20432050

20442051
state_groups[event.event_id] = context.state_group
20452052

2053+
logger.info("state_groups asdfasdf %s", state_groups)
2054+
20462055
self.db_pool.simple_insert_many_txn(
20472056
txn,
20482057
table="event_to_state_groups",

0 commit comments

Comments
 (0)