fix(core): Fix execution pruning queries (#5562)

* fix(core): Execution pruning should delete query should use the `OR` operator

* fix(core): Prune executions in a chunk to avoid sqlite error "Expression tree is too large"

* reduce the memory usage during execution pruning
This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™ 2023-02-24 18:02:34 +01:00 committed by GitHub
parent 1c86a59e62
commit 88de6613bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -44,7 +44,7 @@ import {
import pick from 'lodash.pick';
import type { FindOptionsWhere } from 'typeorm';
import { LessThanOrEqual } from 'typeorm';
import { LessThanOrEqual, In } from 'typeorm';
import { DateUtils } from 'typeorm/util/DateUtils';
import config from '@/config';
import * as Db from '@/Db';
@ -212,7 +212,9 @@ async function pruneExecutionData(this: WorkflowHooks): Promise<void> {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const utcDate = DateUtils.mixedDateToUtcDatetimeString(date);
const toPrune: FindOptionsWhere<IExecutionFlattedDb> = { stoppedAt: LessThanOrEqual(utcDate) };
const toPrune: Array<FindOptionsWhere<IExecutionFlattedDb>> = [
{ stoppedAt: LessThanOrEqual(utcDate) },
];
if (maxCount > 0) {
const executions = await Db.collections.Execution.find({
@ -223,27 +225,29 @@ async function pruneExecutionData(this: WorkflowHooks): Promise<void> {
});
if (executions[0]) {
toPrune.id = LessThanOrEqual(executions[0].id);
toPrune.push({ id: LessThanOrEqual(executions[0].id) });
}
}
const isBinaryModeDefaultMode = config.getEnv('binaryDataManager.mode') === 'default';
try {
const executions = isBinaryModeDefaultMode
? []
: await Db.collections.Execution.find({
select: ['id'],
where: toPrune,
});
await Db.collections.Execution.delete(toPrune);
setTimeout(() => {
throttling = false;
}, timeout * 1000);
let executionIds: Array<IExecutionFlattedDb['id']>;
do {
executionIds = (
await Db.collections.Execution.find({
select: ['id'],
where: toPrune,
take: 100,
})
).map(({ id }) => id);
await Db.collections.Execution.delete({ id: In(executionIds) });
// Mark binary data for deletion for all executions
if (!isBinaryModeDefaultMode)
await BinaryDataManager.getInstance().markDataForDeletionByExecutionIds(
executions.map(({ id }) => id),
);
await BinaryDataManager.getInstance().markDataForDeletionByExecutionIds(executionIds);
} while (executionIds.length > 0);
} catch (error) {
ErrorReporter.error(error);
throttling = false;