Skip to content

Commit c826af4

Browse files
artongemax-nextcloud
authored andcommitted
Move oc_file_metadata.metadata migration to a background job
Signed-off-by: Louis Chemineau <[email protected]> Signed-off-by: Max <[email protected]>
1 parent 6245d1b commit c826af4

File tree

8 files changed

+207
-27
lines changed

8 files changed

+207
-27
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* @copyright Copyright (c) 2024 Louis Chemineau <[email protected]>
6+
*
7+
* @author Louis Chemineau <[email protected]>
8+
*
9+
* @license AGPL-3.0-or-later
10+
*
11+
* This program is free software: you can redistribute it and/or modify
12+
* it under the terms of the GNU Affero General Public License as
13+
* published by the Free Software Foundation, either version 3 of the
14+
* License, or (at your option) any later version.
15+
*
16+
* This program is distributed in the hope that it will be useful,
17+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+
* GNU Affero General Public License for more details.
20+
*
21+
* You should have received a copy of the GNU Affero General Public License
22+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
23+
*
24+
*/
25+
26+
namespace OC\Core\BackgroundJobs;
27+
28+
use OCP\AppFramework\Utility\ITimeFactory;
29+
use OCP\BackgroundJob\IJobList;
30+
use OCP\BackgroundJob\TimedJob;
31+
use OCP\DB\QueryBuilder\IQueryBuilder;
32+
use OCP\IDBConnection;
33+
34+
// Migrate oc_file_metadata.metadata to oc_file_metadata.value.
35+
// This was previously done in a migration, but it is taking to much time in large instances.
36+
// This job will progressively migrate the data 1 hour per night every night.
37+
// Once done, it will remove itself from the job list.
38+
class MetadataMigrationJob extends TimedJob {
39+
public function __construct(
40+
ITimeFactory $time,
41+
private IDBConnection $db,
42+
private IJobList $jobList,
43+
) {
44+
parent::__construct($time);
45+
46+
$this->setTimeSensitivity(\OCP\BackgroundJob\IJob::TIME_INSENSITIVE);
47+
$this->setInterval(24 * 3600);
48+
}
49+
50+
protected function run(mixed $argument): void {
51+
if (!$this->db->createSchema()->getTable('oc_file_metadata')->hasColumn('metadata')) {
52+
return;
53+
}
54+
55+
$updateQuery = $this->db->getQueryBuilder();
56+
$updateQuery->update('file_metadata')
57+
->set('value', $updateQuery->createParameter('value'))
58+
->set('metadata', $updateQuery->createParameter('metadata'))
59+
->where($updateQuery->expr()->eq('id', $updateQuery->createParameter('id')))
60+
->andWhere($updateQuery->expr()->eq('group_name', $updateQuery->createParameter('group_name')));
61+
62+
$selectQuery = $this->db->getQueryBuilder();
63+
$selectQuery->select('id', 'group_name', 'metadata')
64+
->from('file_metadata')
65+
->where($selectQuery->expr()->nonEmptyString('metadata'))
66+
->setMaxResults(1000);
67+
68+
$movedRows = 0;
69+
$startTime = time();
70+
71+
do {
72+
// Stop if execution time is more than one hour.
73+
if (time() - $startTime > 3600) {
74+
return;
75+
}
76+
$movedRows = $this->chunkedCopying($updateQuery, $selectQuery);
77+
} while ($movedRows !== 0);
78+
79+
80+
$this->jobList->remove(MetadataMigrationJob::class);
81+
}
82+
83+
protected function chunkedCopying(IQueryBuilder $updateQuery, IQueryBuilder $selectQuery): int {
84+
$this->db->beginTransaction();
85+
86+
$results = $selectQuery->executeQuery();
87+
88+
while ($row = $results->fetch()) {
89+
$updateQuery
90+
->setParameter('id', (int)$row['id'])
91+
->setParameter('group_name', $row['group_name'])
92+
->setParameter('value', $row['metadata'])
93+
->setParameter('metadata', '')
94+
->executeStatement();
95+
}
96+
97+
$results->closeCursor();
98+
$this->db->commit();
99+
100+
return $results->rowCount();
101+
}
102+
}

core/Migrations/Version27000Date20230309104325.php

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -72,19 +72,19 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
7272
* @param array $options
7373
* @return void
7474
*/
75-
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) {
76-
/** @var ISchemaWrapper $schema */
77-
$schema = $schemaClosure();
78-
$metadataTable = $schema->getTable('file_metadata');
75+
// public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) {
76+
// /** @var ISchemaWrapper $schema */
77+
// $schema = $schemaClosure();
78+
// $metadataTable = $schema->getTable('file_metadata');
7979

80-
if (!$metadataTable->hasColumn('metadata')) {
81-
return;
82-
}
80+
// if (!$metadataTable->hasColumn('metadata')) {
81+
// return;
82+
// }
8383

84-
$this->connection
85-
->getQueryBuilder()
86-
->update('file_metadata')
87-
->set('value', 'metadata')
88-
->executeStatement();
89-
}
84+
// $this->connection
85+
// ->getQueryBuilder()
86+
// ->update('file_metadata')
87+
// ->set('value', 'metadata')
88+
// ->executeStatement();
89+
// }
9090
}

core/Migrations/Version27000Date20230309104802.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,14 @@ class Version27000Date20230309104802 extends SimpleMigrationStep {
4343
* @return null|ISchemaWrapper
4444
*/
4545
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
46-
/** @var ISchemaWrapper $schema */
47-
$schema = $schemaClosure();
48-
$metadataTable = $schema->getTable('file_metadata');
46+
// /** @var ISchemaWrapper $schema */
47+
// $schema = $schemaClosure();
48+
// $metadataTable = $schema->getTable('file_metadata');
4949

50-
if ($metadataTable->hasColumn('metadata')) {
51-
$metadataTable->dropColumn('metadata');
52-
return $schema;
53-
}
50+
// if ($metadataTable->hasColumn('metadata')) {
51+
// $metadataTable->dropColumn('metadata');
52+
// return $schema;
53+
// }
5454

5555
return null;
5656
}

lib/composer/composer/LICENSE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
Copyright (c) Nils Adermann, Jordi Boggiano
23

34
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -17,3 +18,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1718
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1819
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1920
THE SOFTWARE.
21+

lib/composer/composer/autoload_classmap.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,7 @@
895895
'OC\\Core\\BackgroundJobs\\CheckForUserCertificates' => $baseDir . '/core/BackgroundJobs/CheckForUserCertificates.php',
896896
'OC\\Core\\BackgroundJobs\\CleanupLoginFlowV2' => $baseDir . '/core/BackgroundJobs/CleanupLoginFlowV2.php',
897897
'OC\\Core\\BackgroundJobs\\LookupServerSendCheckBackgroundJob' => $baseDir . '/core/BackgroundJobs/LookupServerSendCheckBackgroundJob.php',
898+
'OC\\Core\\BackgroundJobs\\MetadataMigrationJob' => $baseDir . '/core/BackgroundJobs/MetadataMigrationJob.php',
898899
'OC\\Core\\Command\\App\\Disable' => $baseDir . '/core/Command/App/Disable.php',
899900
'OC\\Core\\Command\\App\\Enable' => $baseDir . '/core/Command/App/Enable.php',
900901
'OC\\Core\\Command\\App\\GetPath' => $baseDir . '/core/Command/App/GetPath.php',
@@ -1476,6 +1477,7 @@
14761477
'OC\\RepairException' => $baseDir . '/lib/private/RepairException.php',
14771478
'OC\\Repair\\AddBruteForceCleanupJob' => $baseDir . '/lib/private/Repair/AddBruteForceCleanupJob.php',
14781479
'OC\\Repair\\AddCleanupUpdaterBackupsJob' => $baseDir . '/lib/private/Repair/AddCleanupUpdaterBackupsJob.php',
1480+
'OC\\Repair\\AddMetadataMigrationJob' => $baseDir . '/lib/private/Repair/AddMetadataMigrationJob.php',
14791481
'OC\\Repair\\CleanTags' => $baseDir . '/lib/private/Repair/CleanTags.php',
14801482
'OC\\Repair\\CleanUpAbandonedApps' => $baseDir . '/lib/private/Repair/CleanUpAbandonedApps.php',
14811483
'OC\\Repair\\ClearFrontendCaches' => $baseDir . '/lib/private/Repair/ClearFrontendCaches.php',

lib/composer/composer/autoload_static.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
928928
'OC\\Core\\BackgroundJobs\\CheckForUserCertificates' => __DIR__ . '/../../..' . '/core/BackgroundJobs/CheckForUserCertificates.php',
929929
'OC\\Core\\BackgroundJobs\\CleanupLoginFlowV2' => __DIR__ . '/../../..' . '/core/BackgroundJobs/CleanupLoginFlowV2.php',
930930
'OC\\Core\\BackgroundJobs\\LookupServerSendCheckBackgroundJob' => __DIR__ . '/../../..' . '/core/BackgroundJobs/LookupServerSendCheckBackgroundJob.php',
931+
'OC\\Core\\BackgroundJobs\\MetadataMigrationJob' => __DIR__ . '/../../..' . '/core/BackgroundJobs/MetadataMigrationJob.php',
931932
'OC\\Core\\Command\\App\\Disable' => __DIR__ . '/../../..' . '/core/Command/App/Disable.php',
932933
'OC\\Core\\Command\\App\\Enable' => __DIR__ . '/../../..' . '/core/Command/App/Enable.php',
933934
'OC\\Core\\Command\\App\\GetPath' => __DIR__ . '/../../..' . '/core/Command/App/GetPath.php',
@@ -1509,6 +1510,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
15091510
'OC\\RepairException' => __DIR__ . '/../../..' . '/lib/private/RepairException.php',
15101511
'OC\\Repair\\AddBruteForceCleanupJob' => __DIR__ . '/../../..' . '/lib/private/Repair/AddBruteForceCleanupJob.php',
15111512
'OC\\Repair\\AddCleanupUpdaterBackupsJob' => __DIR__ . '/../../..' . '/lib/private/Repair/AddCleanupUpdaterBackupsJob.php',
1513+
'OC\\Repair\\AddMetadataMigrationJob' => __DIR__ . '/../../..' . '/lib/private/Repair/AddMetadataMigrationJob.php',
15121514
'OC\\Repair\\CleanTags' => __DIR__ . '/../../..' . '/lib/private/Repair/CleanTags.php',
15131515
'OC\\Repair\\CleanUpAbandonedApps' => __DIR__ . '/../../..' . '/lib/private/Repair/CleanUpAbandonedApps.php',
15141516
'OC\\Repair\\ClearFrontendCaches' => __DIR__ . '/../../..' . '/lib/private/Repair/ClearFrontendCaches.php',

lib/private/Repair.php

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,13 @@
3434
*/
3535
namespace OC;
3636

37-
use OC\Repair\CleanUpAbandonedApps;
38-
use OCP\AppFramework\QueryException;
39-
use OCP\AppFramework\Utility\ITimeFactory;
40-
use OCP\Collaboration\Resources\IManager;
41-
use OCP\EventDispatcher\IEventDispatcher;
42-
use OCP\Migration\IOutput;
43-
use OCP\Migration\IRepairStep;
4437
use OC\DB\Connection;
4538
use OC\DB\ConnectionAdapter;
4639
use OC\Repair\AddBruteForceCleanupJob;
4740
use OC\Repair\AddCleanupUpdaterBackupsJob;
41+
use OC\Repair\AddMetadataMigrationJob;
4842
use OC\Repair\CleanTags;
43+
use OC\Repair\CleanUpAbandonedApps;
4944
use OC\Repair\ClearFrontendCaches;
5045
use OC\Repair\ClearGeneratedAvatarCache;
5146
use OC\Repair\Collation;
@@ -85,6 +80,12 @@
8580
use OC\Repair\RepairMimeTypes;
8681
use OC\Repair\SqliteAutoincrement;
8782
use OC\Template\JSCombiner;
83+
use OCP\AppFramework\QueryException;
84+
use OCP\AppFramework\Utility\ITimeFactory;
85+
use OCP\Collaboration\Resources\IManager;
86+
use OCP\EventDispatcher\IEventDispatcher;
87+
use OCP\Migration\IOutput;
88+
use OCP\Migration\IRepairStep;
8889
use Psr\Log\LoggerInterface;
8990
use Throwable;
9091

@@ -210,6 +211,7 @@ public static function getRepairSteps(): array {
210211
\OCP\Server::get(AddTokenCleanupJob::class),
211212
\OCP\Server::get(CleanUpAbandonedApps::class),
212213
\OCP\Server::get(AddMissingSecretJob::class),
214+
\OCP\Server::get(AddRemoveOldTasksBackgroundJob::class),
213215
];
214216
}
215217

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
/**
3+
* @copyright Copyright (c) 2024 Louis Chmn <[email protected]>
4+
*
5+
* @author Louis Chmn <[email protected]>
6+
*
7+
* @license GNU AGPL version 3 or any later version
8+
*
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Affero General Public License as
11+
* published by the Free Software Foundation, either version 3 of the
12+
* License, or (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU Affero General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Affero General Public License
20+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
21+
*
22+
*/
23+
namespace OC\Repair;
24+
25+
use OC\Core\BackgroundJobs\MetadataMigrationJob;
26+
use OCP\BackgroundJob\IJobList;
27+
use OCP\IDBConnection;
28+
use OCP\Migration\IOutput;
29+
use OCP\Migration\IRepairStep;
30+
31+
class AddMetadataMigrationJob implements IRepairStep {
32+
public function __construct(
33+
private IJobList $jobList,
34+
private IDBConnection $db,
35+
) {
36+
}
37+
38+
public function getName() {
39+
return 'Queue a job to migrate the file_metadata table and delete the metadata column once empty';
40+
}
41+
42+
public function run(IOutput $output) {
43+
$schema = $this->db->createSchema();
44+
$metadataTable = $schema->getTable('oc_file_metadata');
45+
46+
if (!$metadataTable->hasColumn('metadata')) {
47+
return;
48+
}
49+
50+
$selectQuery = $this->db->getQueryBuilder();
51+
$result = $selectQuery->select('id', 'group_name', 'metadata')
52+
->from('file_metadata')
53+
->where($selectQuery->expr()->nonEmptyString('metadata'))
54+
->setMaxResults(1)
55+
->executeQuery();
56+
57+
if ($result->rowCount() === 0) {
58+
$output->info('Removing metadata column from the file_metadata table.');
59+
$metadataTable->dropColumn('metadata');
60+
$this->db->migrateToSchema($schema);
61+
return;
62+
}
63+
64+
if ($this->jobList->has(MetadataMigrationJob::class, null)) {
65+
return;
66+
}
67+
68+
$this->jobList->add(MetadataMigrationJob::class);
69+
}
70+
}

0 commit comments

Comments
 (0)