diff --git a/changelog.d/18948.bugfix b/changelog.d/18948.bugfix new file mode 100644 index 00000000000..7a8af0a286c --- /dev/null +++ b/changelog.d/18948.bugfix @@ -0,0 +1 @@ +Compute a user's last seen timestamp from their devices' last seen timestamps instead of IPs, because the latter are automatically cleared according to `user_ips_max_age`. diff --git a/synapse/storage/databases/main/__init__.py b/synapse/storage/databases/main/__init__.py index de55c452aea..83b480adafe 100644 --- a/synapse/storage/databases/main/__init__.py +++ b/synapse/storage/databases/main/__init__.py @@ -299,10 +299,14 @@ def get_users_paginate_txn( FROM users as u LEFT JOIN profiles AS p ON u.name = p.full_user_id LEFT JOIN erased_users AS eu ON u.name = eu.user_id + LEFT JOIN ( + SELECT user_id, MAX(last_seen) AS last_seen_ts + FROM devices GROUP BY user_id + ) lsd ON u.name = lsd.user_id LEFT JOIN ( SELECT user_id, MAX(last_seen) AS last_seen_ts FROM user_ips GROUP BY user_id - ) ls ON u.name = ls.user_id + ) lsi ON u.name = lsi.user_id {where_clause} """ sql = "SELECT COUNT(*) as total_users " + sql_base @@ -312,7 +316,8 @@ def get_users_paginate_txn( sql = f""" SELECT name, user_type, is_guest, admin, deactivated, shadow_banned, displayname, avatar_url, creation_ts * 1000 as creation_ts, approved, - eu.user_id is not null as erased, last_seen_ts, locked + eu.user_id is not null as erased, + COALESCE(lsd.last_seen_ts, lsi.last_seen_ts) as last_seen_ts, locked {sql_base} ORDER BY {order_by_column} {order}, u.name ASC LIMIT ? OFFSET ?