Skip to content

Commit 292bbb8

Browse files
authored
Fix a bug causing device list pruning to skip some rows when the transaction gets retried. (#19947)
Introduced in: #19473 Noticed in: #19556 (comment) I have not experienced the bug in the real world, it's just something I noticed by reading. -- Fix bug in `_prune_device_lists_changes_in_room` when transaction is retried The `nonlocal` variable is a footgun as it increments the counter even though the transaction did not commit yet and may still be retried. --------- Signed-off-by: Olivier 'reivilibre <oliverw@matrix.org>
1 parent 733620a commit 292bbb8

2 files changed

Lines changed: 12 additions & 5 deletions

File tree

changelog.d/19947.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix a bug causing device list pruning to skip some rows when the transaction gets retried.

synapse/storage/databases/main/devices.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2561,9 +2561,14 @@ def get_prune_before_stream_id_txn(txn: LoggingTransaction) -> int | None:
25612561
# We default to 0 here as that is less than all possible stream IDs.
25622562
min_stream_id = 0
25632563

2564-
def prune_device_lists_changes_in_room_txn(txn: LoggingTransaction) -> int:
2565-
nonlocal min_stream_id
2566-
2564+
def prune_device_lists_changes_in_room_txn(
2565+
txn: LoggingTransaction, min_stream_id: int
2566+
) -> tuple[int, int]:
2567+
"""
2568+
Returns tuple of:
2569+
- number of rows deleted
2570+
- new `min_stream_id` for the next iteration
2571+
"""
25672572
delete_sql = """
25682573
DELETE FROM device_lists_changes_in_room
25692574
WHERE stream_id IN (
@@ -2596,13 +2601,14 @@ def prune_device_lists_changes_in_room_txn(txn: LoggingTransaction) -> int:
25962601
updatevalues={"stream_id": min_stream_id},
25972602
)
25982603

2599-
return num_deleted
2604+
return num_deleted, min_stream_id
26002605

26012606
progress_num_rows_deleted = 0
26022607
while True:
2603-
batch_deleted = await self.db_pool.runInteraction(
2608+
batch_deleted, min_stream_id = await self.db_pool.runInteraction(
26042609
"prune_device_lists_changes_in_room",
26052610
prune_device_lists_changes_in_room_txn,
2611+
min_stream_id,
26062612
)
26072613

26082614
finished = batch_deleted < PRUNE_DEVICE_LISTS_BATCH_SIZE

0 commit comments

Comments
 (0)