Skip to content

Commit 3cdae2e

Browse files
authored
Fix race in new pruning of device lists tables. (#19709)
Follows on from #19473. We should be recording where we have deleted up to in the same transaction as we perform the delete, rather than at the end. This code only starts deleting rows after a month (and the original PR isn't in a release yet), so no server should have run into this problem yet. Also let's log more regularly, as the initial set of deletions will likely take a long time.
1 parent a9361c4 commit 3cdae2e

2 files changed

Lines changed: 28 additions & 17 deletions

File tree

changelog.d/19709.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Reduce database disk space usage by pruning old rows from `device_lists_changes_in_room`.

synapse/storage/databases/main/devices.py

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2583,36 +2583,46 @@ def prune_device_lists_changes_in_room_txn(txn: LoggingTransaction) -> int:
25832583
num_deleted += 1
25842584
min_stream_id = max(min_stream_id, row[0])
25852585

2586+
if num_deleted:
2587+
# Update the max pruned stream ID tracking table so that the
2588+
# safety check knows data up to this point has been deleted.
2589+
self.db_pool.simple_update_one_txn(
2590+
txn,
2591+
table="device_lists_changes_in_room_max_pruned_stream_id",
2592+
keyvalues={},
2593+
updatevalues={"stream_id": min_stream_id},
2594+
)
2595+
25862596
return num_deleted
25872597

2588-
num_rows_deleted = 0
2598+
progress_num_rows_deleted = 0
25892599
while True:
25902600
batch_deleted = await self.db_pool.runInteraction(
25912601
"prune_device_lists_changes_in_room",
25922602
prune_device_lists_changes_in_room_txn,
25932603
)
2594-
num_rows_deleted += batch_deleted
2595-
if batch_deleted < PRUNE_DEVICE_LISTS_BATCH_SIZE:
2604+
2605+
finished = batch_deleted < PRUNE_DEVICE_LISTS_BATCH_SIZE
2606+
2607+
progress_num_rows_deleted += batch_deleted
2608+
2609+
# Periodically report progress in the logs. We do this either when
2610+
# we've deleted a significant number of rows or when we've finished
2611+
# deleting all rows in this round.
2612+
if finished or progress_num_rows_deleted > 10000:
2613+
logger.info(
2614+
"Pruned %d rows from device_lists_changes_in_room",
2615+
progress_num_rows_deleted,
2616+
)
2617+
progress_num_rows_deleted = 0
2618+
2619+
if finished:
25962620
break
25972621

25982622
# Sleep for a short time to avoid hammering the database too much if
25992623
# there are a lot of rows to delete.
26002624
await self.clock.sleep(Duration(milliseconds=100))
26012625

2602-
if num_rows_deleted:
2603-
# Update the max pruned stream ID tracking table so that the
2604-
# safety check knows data up to this point has been deleted.
2605-
await self.db_pool.simple_update_one(
2606-
table="device_lists_changes_in_room_max_pruned_stream_id",
2607-
keyvalues={},
2608-
updatevalues={"stream_id": prune_before_stream_id},
2609-
desc="prune_device_lists_changes_in_room_update_max_pruned",
2610-
)
2611-
2612-
logger.info(
2613-
"Pruned %d rows from device_lists_changes_in_room", num_rows_deleted
2614-
)
2615-
26162626

26172627
class DeviceBackgroundUpdateStore(SQLBaseStore):
26182628
_instance_name: str

0 commit comments

Comments
 (0)