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

Speed up current state background update. #5738

Merged
merged 2 commits into from
Jul 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/5738.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Reduce database IO usage by optimising queries for current membership.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should probably be merged with 5706?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is the changelog :)

48 changes: 30 additions & 18 deletions synapse/storage/roommember.py
Original file line number Diff line number Diff line change
Expand Up @@ -852,22 +852,25 @@ def add_membership_profile_txn(txn):
@defer.inlineCallbacks
def _background_current_state_membership(self, progress, batch_size):
"""Update the new membership column on current_state_events.

This works by iterating over all rooms in alphebetical order.
"""

if "rooms" not in progress:
rooms = yield self._simple_select_onecol(
table="current_state_events",
keyvalues={},
retcol="DISTINCT room_id",
desc="_background_current_state_membership_get_rooms",
)
progress["rooms"] = rooms
def _background_current_state_membership_txn(txn, last_processed_room):
processed = 0
while processed < batch_size:
txn.execute(
"""
SELECT MIN(room_id) FROM rooms WHERE room_id > ?
""",
(last_processed_room,),
)
row = txn.fetchone()
if not row or not row[0]:
return processed, True

rooms = progress["rooms"]
next_room, = row

def _background_current_state_membership_txn(txn):
processed = 0
while rooms and processed < batch_size:
sql = """
UPDATE current_state_events AS c
SET membership = (
Expand All @@ -876,24 +879,33 @@ def _background_current_state_membership_txn(txn):
)
WHERE room_id = ?
"""
txn.execute(sql, (rooms.pop(),))
txn.execute(sql, (next_room,))
processed += txn.rowcount

last_processed_room = next_room

self._background_update_progress_txn(
txn, _CURRENT_STATE_MEMBERSHIP_UPDATE_NAME, progress
txn,
_CURRENT_STATE_MEMBERSHIP_UPDATE_NAME,
{"last_processed_room": last_processed_room},
)

return processed
return processed, False

result = yield self.runInteraction(
# If we haven't got a last processed room then just use the empty
# string, which will compare before all room IDs correctly.
last_processed_room = progress.get("last_processed_room", "")

row_count, finished = yield self.runInteraction(
"_background_current_state_membership_update",
_background_current_state_membership_txn,
last_processed_room,
)

if not rooms:
if finished:
yield self._end_background_update(_CURRENT_STATE_MEMBERSHIP_UPDATE_NAME)

defer.returnValue(result)
defer.returnValue(row_count)


class _JoinedHostsCache(object):
Expand Down