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

Long running user deactivations via admin API are not deduplicated and can starve DB connections #16055

Open
Half-Shot opened this issue Aug 2, 2023 · 4 comments
Labels
A-Account-Deactivation "Deleting"/"Removing" a user, GDPR erasure (erased) A-Admin-API S-Minor Blocks non-critical functionality, workarounds exist. T-Defect Bugs, crashes, hangs, security vulnerabilities, or other reported issues.

Comments

@Half-Shot
Copy link
Collaborator

Half-Shot commented Aug 2, 2023

https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#deactivate-account can be used to deactivate a users session. However, because it does (potentially) expensive things like deleting devices it can take a long time to run. For serious device hoarders, this can cause the request to time out.

The HTTP request will time out but the DB query does not, leading to the case where it's an easy footgun to retry a "failed" user deactivation and end up having multiple concurreent slow queries jamming up the database connection pool. Do it enough times, or to enough users and the main process will be starved out of connections.

Separately, it's probably not good that deactivations are taking minutes to run.

Example output:

SELECT left(query, 90) as query, state FROM pg_stat_activity WHERE state IS NOT NULL AND query LIKE 'DELETE%';

                                           query                                            | state
--------------------------------------------------------------------------------------------+--------
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE1','DEVICE2','DEVICE3','YI | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE44','DEVICE5','DEVICE6','IA | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE7','DEVICE8','DEVICE9','OD | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE1','DEVICE2','DEVICE3','YI | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE7','DEVICE8','DEVICE9','OD | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE1','DEVICE2','DEVICE3','YI | active
 DELETE FROM device_inbox WHERE device_id = ANY(ARRAY['DEVICE1','DEVICE2','DEVICE3 | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE1','DEVICE2','DEVICE3','YI | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE7','DEVICE8','DEVICE9','OD | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE1','DEVICE2','DEVICE3','YI | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE7','DEVICE8','DEVICE9','OD | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE44','DEVICE5','DEVICE6','IA | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE44','DEVICE5','DEVICE6','IA | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE7','DEVICE8','DEVICE9','OD | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE44','DEVICE5','DEVICE6','IA | active
 DELETE FROM device_inbox WHERE device_id = ANY(ARRAY['DEVICE7','DEVICE8','DEVICE9 | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE1','DEVICE2','DEVICE3','YI | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE44','DEVICE5','DEVICE6','IA | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE1','DEVICE2','DEVICE3','YI | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE7','DEVICE8','DEVICE9','OD | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE44','DEVICE5','DEVICE6','IA | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE44','DEVICE5','DEVICE6','IA | active
 DELETE FROM device_inbox WHERE device_id = ANY(ARRAY['DEVICE44','DEVICE5','DEVICE6 | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE44','DEVICE5','DEVICE6','IA | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE44','DEVICE5','DEVICE6','IA | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE7','DEVICE8','DEVICE9','OD | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE44','DEVICE5','DEVICE6','IA | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE1','DEVICE2','DEVICE3','YI | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE1','DEVICE2','DEVICE3','YI | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE7','DEVICE8','DEVICE9','OD | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE7','DEVICE8','DEVICE9','OD | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE1','DEVICE2','DEVICE3','YI | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE44','DEVICE5','DEVICE6','IA | active
 DELETE FROM devices WHERE device_id = ANY(ARRAY['DEVICE7','DEVICE8','DEVICE9','OD | active

@clokep
Copy link
Member

clokep commented Aug 2, 2023

We should likely treat these as the v2 room purge API which are done in the background with a progress exposed.

@Half-Shot Half-Shot added T-Defect Bugs, crashes, hangs, security vulnerabilities, or other reported issues. A-Admin-API A-Account-Deactivation "Deleting"/"Removing" a user, GDPR erasure (erased) S-Minor Blocks non-critical functionality, workarounds exist. labels Aug 2, 2023
@Half-Shot
Copy link
Collaborator Author

Half-Shot commented Aug 2, 2023

(I've put this as a S-Minor because I believe you have to be an admin to really trigger this one, and the workaround is "don't do it")

@erikjohnston
Copy link
Member

I think the correct fix here is to fix #16098, which should make these queries cheap.

@reivilibre
Copy link
Contributor

Hard to argue with 'just don't do it to yourself', but not all invocations of the API will be done manually with curl, some might be using a tool that uses e.g. the Rust SDK, which will automatically retry timed out requests (ask me how I know ;-)).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A-Account-Deactivation "Deleting"/"Removing" a user, GDPR erasure (erased) A-Admin-API S-Minor Blocks non-critical functionality, workarounds exist. T-Defect Bugs, crashes, hangs, security vulnerabilities, or other reported issues.
Projects
None yet
Development

No branches or pull requests

4 participants