diff --git a/includes/functions.php b/includes/functions.php index 9f44e36..a5702de 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -258,15 +258,34 @@ function frequent_ips(int $min_connections, ?string $since = null): array { /** * Delete connections older than retention_days setting. + * Rows are removed in batches so each transaction stays small — a single + * giant DELETE would lock a large part of the table while the fetch cron + * keeps inserting rows. + * * Returns the number of rows deleted. */ function purge_old_connections(): int { - $days = max(1, (int)get_setting('retention_days', '7')); + $days = max(1, (int)get_setting('retention_days', '7')); + $cutoff = date('Y-m-d H:i:s', time() - $days * 86400); + $s = db()->prepare( - 'DELETE FROM connections WHERE occurred_at < NOW() - INTERVAL ? DAY' + 'DELETE FROM connections + WHERE occurred_at < ? + ORDER BY id + LIMIT 5000' ); - $s->execute([$days]); - return $s->rowCount(); + + $total = 0; + do { + $s->execute([$cutoff]); + $deleted = $s->rowCount(); + $total += $deleted; + if ($deleted > 0) { + usleep(100_000); // 100 ms between batches to ease lock pressure + } + } while ($deleted >= 5000); + + return $total; } // ── Upstream version check ────────────────────────────────────────────────────