Repository: matrix-org/synapse

Issue:
500 When calling purge_rooms
<!--

**IF YOU HAVE SUPPORT QUESTIONS ABOUT RUNNING OR CONFIGURING YOUR OWN HOME SERVER**:
You will likely get better support more quickly if you ask in ** #synapse:matrix.org ** ;)


This is a bug report template. By following the instructions below and
filling out the sections with your information, you will help the us to get all
the necessary data to fix your issue.

You can also preview your report before submitting it. You may remove sections
that aren't relevant to your particular case.

Text between <!-- and --​> marks will be invisible in the report.

-->

### Description

I'm getting a 500, "Internal server error" when calling the `/purge_room` endpoint. 

### Steps to reproduce

- Just make a request to `/purge_room` for any room. 

Here's an example of the request options for one of the 500 responses:
```
"options": {
  "qs": {
    "access_token": "<redacted>"
  },
  "url": "http://localhost:9090/_synapse/admin/v1/purge_room",
  "json": true,
  "body": {
    "room_id": "<redacted>"
  },
  "method": "POST",
  "simple": true,
  "resolveWithFullResponse": false,
  "transform2xxOnly": false
},
```


<!--
Describe how what happens differs from what you expected.

If you can identify any relevant log snippets from _homeserver.log_, please include
those (please be careful to remove any personal or private data). Please surround them with
``` (three backticks, on a line on their own), so that they are formatted legibly.
-->
Here are some logs around the handling of that request:

```
2020-01-14 15:43:45,857 - synapse.access.http.8008 - 233 - INFO - POST-52320 - 10.1.15.61 - 8008 - Received request: POST /_synapse/admin/v1/purge_room?access_token=<redacted>
2020-01-14 15:43:45,860 - synapse.storage.data_stores.main.events - 1682 - INFO - POST-52320 - [purge] removing <redacted> from event_auth
2020-01-14 15:43:45,861 - synapse.storage.data_stores.main.events - 1682 - INFO - POST-52320 - [purge] removing <redacted> from event_edges
2020-01-14 15:43:45,861 - synapse.storage.data_stores.main.events - 1682 - INFO - POST-52320 - [purge] removing <redacted> from event_push_actions_staging
2020-01-14 15:43:45,862 - synapse.storage.data_stores.main.events - 1682 - INFO - POST-52320 - [purge] removing <redacted> from event_reference_hashes
2020-01-14 15:43:45,862 - synapse.storage.data_stores.main.events - 1682 - INFO - POST-52320 - [purge] removing <redacted> from event_relations
2020-01-14 15:43:45,863 - synapse.storage.data_stores.main.events - 1682 - INFO - POST-52320 - [purge] removing <redacted> from event_to_state_groups
2020-01-14 15:43:45,863 - synapse.storage.data_stores.main.events - 1682 - INFO - POST-52320 - [purge] removing <redacted> from redactions
2020-01-14 15:43:45,864 - synapse.storage.data_stores.main.events - 1682 - INFO - POST-52320 - [purge] removing <redacted> from rejections
2020-01-14 15:43:45,864 - synapse.storage.data_stores.main.events - 1682 - INFO - POST-52320 - [purge] removing <redacted> from state_events
2020-01-14 15:43:45,865 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from current_state_events
2020-01-14 15:43:45,865 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from event_backward_extremities
2020-01-14 15:43:45,866 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from event_forward_extremities
2020-01-14 15:43:45,866 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from event_json
2020-01-14 15:43:45,867 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from event_push_actions
2020-01-14 15:43:45,867 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from event_search
2020-01-14 15:43:45,867 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from events
2020-01-14 15:43:45,868 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from group_rooms
2020-01-14 15:43:45,868 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from public_room_list_stream
2020-01-14 15:43:45,869 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from receipts_graph
2020-01-14 15:43:45,869 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from receipts_linearized
2020-01-14 15:43:45,870 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from room_aliases
2020-01-14 15:43:45,870 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from room_depth
2020-01-14 15:43:45,870 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from room_memberships
2020-01-14 15:43:45,871 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from room_stats_state
2020-01-14 15:43:45,871 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from room_stats_current
2020-01-14 15:43:45,871 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from room_stats_historical
2020-01-14 15:43:45,872 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from room_stats_earliest_token
2020-01-14 15:43:45,872 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from rooms
2020-01-14 15:43:45,873 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from stream_ordering_to_exterm
2020-01-14 15:43:45,873 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from users_in_public_rooms
2020-01-14 15:43:45,873 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from users_who_share_private_rooms
2020-01-14 15:43:45,874 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from appservice_room_list
2020-01-14 15:43:45,874 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from e2e_room_keys
2020-01-14 15:43:45,875 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from event_push_summary
2020-01-14 15:43:45,875 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from pusher_throttle
2020-01-14 15:43:45,876 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from group_summary_rooms
2020-01-14 15:43:45,876 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from local_invites
2020-01-14 15:43:45,877 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from room_account_data
2020-01-14 15:43:45,877 - synapse.storage.data_stores.main.events - 1728 - INFO - POST-52320 - [purge] removing <redacted> from room_tags
2020-01-14 15:43:45,878 - synapse.storage.data_stores.main.events - 1756 - INFO - POST-52320 - [purge] done
2020-01-14 15:43:45,878 - synapse.http.server - 109 - ERROR - POST-52320 - Failed handle request via 'PurgeRoomServlet': <XForwardedForRequest at 0x7f265447b0d0 method='POST' uri='/_synapse/admin/v1/purge_room?access_token=<redacted>' clientproto='HTTP/1.1' site=8008>
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
result = g.send(result)
StopIteration: []
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
result = g.send(result)
StopIteration: []
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/synapse/http/server.py", line 77, in wrapped_request_handler
await h(self, request)
File "/usr/local/lib/python3.7/site-packages/synapse/http/server.py", line 326, in _async_render
callback_return = await callback_return
File "/usr/local/lib/python3.7/site-packages/synapse/rest/admin/purge_room_servlet.py", line 55, in on_POST
await self.pagination_handler.purge_room(body["room_id"])
File "/usr/local/lib/python3.7/site-packages/synapse/handlers/pagination.py", line 281, in purge_room
await self.storage.purge_events.purge_room(room_id)
File "/usr/local/lib/python3.7/site-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
result = g.send(result)
File "/usr/local/lib/python3.7/site-packages/synapse/storage/purge_events.py", line 37, in purge_room
yield self.stores.main.purge_room_state(room_id, state_groups_to_delete)
AttributeError: 'DataStore' object has no attribute 'purge_room_state'
2020-01-14 15:43:45,879 - synapse.access.http.8008 - 302 - INFO - POST-52320 - 10.1.15.61 - 8008 - {<redacted>} Processed request: 0.022sec/0.000sec (0.008sec, 0.000sec) (0.001sec/0.020sec/2) 55B 500 "POST /_synapse/admin/v1/purge_room?access_token=<redacted> HTTP/1.1" "PostmanRuntime/7.21.0" [0 dbevts]
2020-01-14 15:43:46,071 - synapse.storage.TIME - 347 - INFO - - Total database time: 0.690% {purge_room(1): 0.189%, get_users_whose_devices_changed(4): 0.074%, delete_pusher(2): 0.058%}
```


### Version information

<!-- IMPORTANT: please answer the following questions, to help us narrow down the problem -->

<!-- Was this issue identified on matrix.org or another homeserver? -->
- **Homeserver**: A private, unfederated server

<!--
 What version of Synapse is running?

You can find the Synapse version with this command:

$ curl http://localhost:8008/_synapse/admin/v1/server_version

(You may need to replace `localhost:8008` if Synapse is not configured to
listen on that port.)
-->
- **Version**: "server_version": "1.8.0", "python_version": "3.7.6"

- **Install method**: Docker
<!-- examples: package manager/git clone/pip  -->

- **Platform**: matrixdotorg/synapse:v1.8.0-py3
<!--
Tell us about the environment in which your homeserver is operating
distro, hardware, if it's running in a vm/container, etc.
-->



Discussion:

Resolving patch:
diff --git a/synapse/storage/purge_events.py b/synapse/storage/purge_events.py
--- a/synapse/storage/purge_events.py
+++ b/synapse/storage/purge_events.py
@@ -34,7 +34,7 @@ def purge_room(self, room_id: str):
         """
 
         state_groups_to_delete = yield self.stores.main.purge_room(room_id)
-        yield self.stores.main.purge_room_state(room_id, state_groups_to_delete)
+        yield self.stores.state.purge_room_state(room_id, state_groups_to_delete)
 
     @defer.inlineCallbacks
     def purge_history(self, room_id, token, delete_local_events):


Test patch:
diff --git a/tests/rest/admin/test_admin.py b/tests/rest/admin/test_admin.py
--- a/tests/rest/admin/test_admin.py
+++ b/tests/rest/admin/test_admin.py
@@ -337,7 +337,7 @@ def test_purge_room(self):
             "local_invites",
             "room_account_data",
             "room_tags",
-            "state_groups",
+            # "state_groups",  # Current impl leaves orphaned state groups around.
             "state_groups_state",
         ):
             count = self.get_success(
@@ -351,8 +351,6 @@ def test_purge_room(self):
 
             self.assertEqual(count, 0, msg="Rows not purged in {}".format(table))
 
-    test_purge_room.skip = "Disabled because it's currently broken"
-
 
 class QuarantineMediaTestCase(unittest.HomeserverTestCase):
     """Test /quarantine_media admin API.