You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While restoring table with array fields, Firebird consumes all available memory and restore fails with error "unable to allocate memory from operating system". Same backup can be successfully restored by Firebird 2.1.4. DDL of the table is:
CREATE TABLE RVG (
RYEAR SMALLINT NOT NULL,
INS_ID BIGINT NOT NULL,
R1 DECIMAL(18,2) [1:12],
R4 DECIMAL(18,2) [1:4],
R5 DECIMAL(18,2) [1:4],
R6 DECIMAL(18,2) [1:4],
VK1 COMPUTED BY (R1+R1+R1),
VK2 COMPUTED BY (R1+R1+R1),
VK3 COMPUTED BY (R1+R1+R1),
VK4 COMPUTED BY (R1+R1+R1),
VG COMPUTED BY (R1+R1+R1+R1+R1+R1+R1+R1+R1+R1+R1+R1),
R3 INTEGER [1:4]
ALTER TABLE RVG ADD CONSTRAINT PK_RVG PRIMARY KEY (RYEAR, INS_ID);
Usage of isc_send() instead of isc_start_and_send() forces the looper to always exit with a non-NULL node, so release_blobs() is never called and thus blobs/arrays bound to the current request are never released, at least until the transaction ends. Hence we have a transaction level memory leak.
The dumb but easiest solution could be to restart the request periodically (e.g. if (records % 1000 == 1)) to keep some kind of a balance between memory usage and performance. Or set some flag if we have blobs/arrays stored right before this record and use that flag to restart the request instead of just sending the record. Or combine these two approaches.
Ideally, the engine should be fixed, but this sounds too risky for point releases.
With a 32-bit FB 2.5.2 (release mode) on 64-bit Windows I see VM = 750MB after 1,000,000 records restored, 1.5GB after 2,000,000 records and the OOM error happens at 2,262,000 records. 64-bit FB consumes a bit more memory but unsurprisingly succeeds to restore.
Just for the record, I was restoring using the Services API.