aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Wurst <christoph@winzerhof-wurst.at>2024-06-19 12:30:32 +0200
committerChristoph Wurst <christoph@winzerhof-wurst.at>2024-06-19 15:12:56 +0200
commit2753777037c74deeefa061c7d049cfa485c32a72 (patch)
treeeb8de0160b14295f1b0498bfb2acb0600e5a9e47
parentf72f110278b7094a2b3d9b3e7e5caa426161ef16 (diff)
downloadnextcloud-server-fix/dav/limit-sync-token-created-at-updates-stable29.tar.gz
nextcloud-server-fix/dav/limit-sync-token-created-at-updates-stable29.zip
fix(dav): Limit number of UPDATES for sync token created_atfix/dav/limit-sync-token-created-at-updates-stable29
Address book and calendar sync tokens have a created_at column in 26+ and we need to assign a current timestamp to the existing data at upgrade so the data isn't cleaned up immediately. Updating the full table is expensive and fails on clustered setups that limit transaction size. We don't need a timestamp for the oldest rows so we can skip updating them. Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
-rw-r--r--apps/dav/lib/Migration/Version1025Date20240308063933.php30
1 files changed, 29 insertions, 1 deletions
diff --git a/apps/dav/lib/Migration/Version1025Date20240308063933.php b/apps/dav/lib/Migration/Version1025Date20240308063933.php
index a75fc85eccc..37d615cc8a9 100644
--- a/apps/dav/lib/Migration/Version1025Date20240308063933.php
+++ b/apps/dav/lib/Migration/Version1025Date20240308063933.php
@@ -27,6 +27,8 @@ declare(strict_types=1);
namespace OCA\DAV\Migration;
use Closure;
+use OCA\DAV\AppInfo\Application;
+use OCP\AppFramework\Services\IAppConfig;
use OCP\DB\ISchemaWrapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\DB\Types;
@@ -36,10 +38,13 @@ use OCP\Migration\SimpleMigrationStep;
class Version1025Date20240308063933 extends SimpleMigrationStep {
+ private IAppConfig $appConfig;
private IDBConnection $db;
- public function __construct(IDBConnection $db) {
+ public function __construct(IAppConfig $appConfig,
+ IDBConnection $db) {
$this->db = $db;
+ $this->appConfig = $appConfig;
}
/**
@@ -67,7 +72,22 @@ class Version1025Date20240308063933 extends SimpleMigrationStep {
}
public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options): void {
+ // The threshold is higher than the default of \OCA\DAV\BackgroundJob\PruneOutdatedSyncTokensJob
+ // but small enough to fit into a cluster transaction size.
+ // For a 50k users instance that would still keep 10 changes on average.
+ $limit = max(1, (int) $this->appConfig->getAppValue('totalNumberOfSyncTokensToKeep', '500000'));
+
foreach (['addressbookchanges', 'calendarchanges'] as $tableName) {
+ $thresholdSelect = $this->db->getQueryBuilder();
+ $thresholdSelect->select('id')
+ ->from($tableName)
+ ->orderBy('id', 'desc')
+ ->setFirstResult($limit)
+ ->setMaxResults(1);
+ $oldestIdResult = $thresholdSelect->executeQuery();
+ $oldestId = $oldestIdResult->fetchColumn();
+ $oldestIdResult->closeCursor();
+
$qb = $this->db->getQueryBuilder();
$update = $qb->update($tableName)
@@ -76,7 +96,15 @@ class Version1025Date20240308063933 extends SimpleMigrationStep {
$qb->expr()->eq('created_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)),
);
+ // If there is a lot of data we only set timestamp for the most recent rows
+ // because the rest will be deleted by \OCA\DAV\BackgroundJob\PruneOutdatedSyncTokensJob
+ // anyway.
+ if ($oldestId !== false) {
+ $update->andWhere($qb->expr()->gt('id', $qb->createNamedParameter($oldestId, IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT));
+ }
+
$updated = $update->executeStatement();
+
$output->debug('Added a default creation timestamp to ' . $updated . ' rows in ' . $tableName);
}
}