2020#
2121
2222import logging
23- from typing import Any , List , Set , Tuple , cast
23+ from typing import Any , Set , Tuple , cast
2424
2525from synapse .api .errors import SynapseError
2626from synapse .storage .database import LoggingTransaction
@@ -332,7 +332,7 @@ def _purge_history_txn(
332332
333333 return referenced_state_groups
334334
335- async def purge_room (self , room_id : str ) -> List [ int ] :
335+ async def purge_room (self , room_id : str ) -> None :
336336 """Deletes all record of a room
337337
338338 Args:
@@ -348,26 +348,23 @@ async def purge_room(self, room_id: str) -> List[int]:
348348 # purge any of those rows which were added during the first.
349349
350350 logger .info ("[purge] Starting initial main purge of [1/2]" )
351- state_groups_to_delete = await self .db_pool .runInteraction (
351+ await self .db_pool .runInteraction (
352352 "purge_room" ,
353353 self ._purge_room_txn ,
354354 room_id = room_id ,
355355 isolation_level = IsolationLevel .READ_COMMITTED ,
356356 )
357357
358358 logger .info ("[purge] Starting secondary main purge of [2/2]" )
359- state_groups_to_delete .extend (
360- await self .db_pool .runInteraction (
361- "purge_room" ,
362- self ._purge_room_txn ,
363- room_id = room_id ,
364- ),
359+ await self .db_pool .runInteraction (
360+ "purge_room" ,
361+ self ._purge_room_txn ,
362+ room_id = room_id ,
365363 )
366- logger .info ("[purge] Done with main purge" )
367364
368- return state_groups_to_delete
365+ logger . info ( "[purge] Done with main purge" )
369366
370- def _purge_room_txn (self , txn : LoggingTransaction , room_id : str ) -> List [ int ] :
367+ def _purge_room_txn (self , txn : LoggingTransaction , room_id : str ) -> None :
371368 # This collides with event persistence so we cannot write new events and metadata into
372369 # a room while deleting it or this transaction will fail.
373370 if isinstance (self .database_engine , PostgresEngine ):
@@ -376,19 +373,6 @@ def _purge_room_txn(self, txn: LoggingTransaction, room_id: str) -> List[int]:
376373 (room_id ,),
377374 )
378375
379- # First, fetch all the state groups that should be deleted, before
380- # we delete that information.
381- txn .execute (
382- """
383- SELECT DISTINCT state_group FROM events
384- INNER JOIN event_to_state_groups USING(event_id)
385- WHERE events.room_id = ?
386- """ ,
387- (room_id ,),
388- )
389-
390- state_groups = [row [0 ] for row in txn ]
391-
392376 # Get all the auth chains that are referenced by events that are to be
393377 # deleted.
394378 txn .execute (
@@ -484,6 +468,8 @@ def _purge_room_txn(self, txn: LoggingTransaction, room_id: str) -> List[int]:
484468 logger .info ("[purge] removing from %s" , table )
485469 txn .execute ("DELETE FROM %s WHERE room_id=?" % (table ,), (room_id ,))
486470
471+ self ._purge_room_state_txn (txn , room_id )
472+
487473 # Other tables we do NOT need to clear out:
488474 #
489475 # - blocked_rooms
@@ -509,4 +495,37 @@ def _purge_room_txn(self, txn: LoggingTransaction, room_id: str) -> List[int]:
509495
510496 self ._invalidate_caches_for_room_and_stream (txn , room_id )
511497
512- return state_groups
498+ def _purge_room_state_txn (
499+ self ,
500+ txn : LoggingTransaction ,
501+ room_id : str ,
502+ ) -> None :
503+ # Delete all edges that reference a state group linked to room_id
504+ logger .info ("[purge] removing %s from state_group_edges" , room_id )
505+ txn .execute (
506+ """
507+ DELETE FROM state_group_edges AS sge WHERE sge.state_group IN (
508+ SELECT id FROM state_groups AS sg WHERE sg.room_id = ?
509+ )""" ,
510+ (room_id ,),
511+ )
512+
513+ # state_groups_state table has a room_id column but no index on it, unlike state_groups,
514+ # so we delete them by matching the room_id through the state_groups table.
515+ logger .info ("[purge] removing %s from state_groups_state" , room_id )
516+ txn .execute (
517+ """
518+ DELETE FROM state_groups_state AS sgs WHERE sgs.state_group IN (
519+ SELECT id FROM state_groups AS sg WHERE sg.room_id = ?
520+ )""" ,
521+ (room_id ,),
522+ )
523+
524+ logger .info ("[purge] removing %s from state_groups" , room_id )
525+ self .db_pool .simple_delete_many_txn (
526+ txn ,
527+ table = "state_groups" ,
528+ column = "room_id" ,
529+ values = [room_id ],
530+ keyvalues = {},
531+ )
0 commit comments