From 6e86f9f9f003fc76b43bc180be49e2271318704d Mon Sep 17 00:00:00 2001 From: DarkPhoenix2704 Date: Thu, 14 May 2026 12:06:57 +0000 Subject: [PATCH] fix: concurrency --- packages/nocodb/src/db/BaseModelSqlv2.ts | 16 +++++++++++++--- .../v0/nc_202605120000_operation_logs.ts | 2 -- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/nocodb/src/db/BaseModelSqlv2.ts b/packages/nocodb/src/db/BaseModelSqlv2.ts index fc7959983a..08a43579a0 100644 --- a/packages/nocodb/src/db/BaseModelSqlv2.ts +++ b/packages/nocodb/src/db/BaseModelSqlv2.ts @@ -3319,12 +3319,22 @@ class BaseModelSqlv2 implements IBaseModelSqlV2 { undo: param?.undo, }); - await this.runOps(preInsertOps.map((f) => f())); + // Cap in-flight preInsertOps so many nested LTAR capture SELECTs + // don't saturate the knex pool. Mutating closures only build + // .toQuery() strings (no connection), so the cap mainly limits + // the capture-SELECT side. Resolved strings are handed back to + // runOps to keep its serial UPDATE/DELETE walk. + const preInsertResolved = await processConcurrently( + preInsertOps, + (f) => f(), + 5, + ); + await this.runOps(preInsertResolved.map((s) => Promise.resolve(s))); // Deposit displacement capture for the trace decorator. // `displacedRecords` was populated by capture-ops in - // preInsertOps (parallel SELECTs ran during Promise.all, - // before runOps walked the UPDATE/DELETE strings serially). + // preInsertOps (SELECTs ran under the concurrency cap above, + // before runOps walked the resulting UPDATE/DELETE strings serially). // Skipped under replay — replay reads from meta.extra, doesn't // re-capture. if (displacedRecords.length > 0 && !isReplay()) { diff --git a/packages/nocodb/src/meta/migrations/v0/nc_202605120000_operation_logs.ts b/packages/nocodb/src/meta/migrations/v0/nc_202605120000_operation_logs.ts index cfc3eced8e..0adba2e6f0 100644 --- a/packages/nocodb/src/meta/migrations/v0/nc_202605120000_operation_logs.ts +++ b/packages/nocodb/src/meta/migrations/v0/nc_202605120000_operation_logs.ts @@ -61,8 +61,6 @@ const up = async (knex: Knex) => { ['fk_user_id', 'tab_id', 'scope_type', 'scope_id', 'status', 'seq'], 'nc_op_logs_user_tab_scope_status_seq_idx', ); - // Cleanup queries (per-workspace pruning, TTL sweeps). - table.index(['fk_workspace_id', 'base_id'], 'nc_op_logs_ws_base_idx'); table.index(['cleanup_due_at'], 'nc_op_logs_cleanup_due_at_idx'); }); };