Skip to content

cachedict inflight registry: sqlite 'file is not a database' under concurrent job-array access #304

Description

@sdascoli

Summary

When a grid of experiments is submitted as a single slurm job array (via TaskInfra.job_array()), and each job independently accesses a shared cached step (same folder) that computes a large set of items, exca's cachedict inflight registry sqlite database gets corrupted:

sqlite3.DatabaseError: file is not a database

The corruption then cascades into FileNotFoundError on full-uid.yaml and submitit.core.utils.UncompletedJobError for the sub-tasks, failing the whole run.

Environment

  • exca 0.5.27
  • Python 3.12, Linux, slurm cluster (submitit backend)

Scenario

  • ~18 experiments submitted together via TaskInfra.job_array().
  • Each job calls into the same shared cached pipeline (a Cached step backend + a map that computes ~432 items) pointing at the same cache folder.
  • All ~18 jobs start ~simultaneously, so many concurrently query/populate the same inflight registry.
  • Pre-warming the cache once (single builder) before submitting the array does not prevent it: the concurrent jobs still re-open/validate the shared registry and corrupt it.

Stacktrace

WARNING - exca.cachedict.inflight:349 - Waiting for 432 in-flight items (of 432 requested) held by: <jobid> [slurm:RUNNING] x432
WARNING - exca.cachedict.registry:234 - Inflight registry query: file is not a database
Traceback (most recent call last):
  File ".../exca/cachedict/registry.py", line 222, in _safe_execute
    return self._retry_on_lock(run)
  File ".../exca/cachedict/registry.py", line 130, in _retry_on_lock
    return fn()
  File ".../exca/cachedict/registry.py", line 211, in run
    return fn(conn)
  File ".../exca/cachedict/inflight.py", line 316, in _do
    rows = registry.select_in_chunks(
  File ".../exca/cachedict/registry.py", line 49, in select_in_chunks
    out.extend(conn.execute(sql, batch).fetchall())
sqlite3.DatabaseError: file is not a database

Also observed alongside it:

FileNotFoundError: [Errno 2] No such file or directory: '.../<cache-uid>/full-uid.yaml'
submitit.core.utils.UncompletedJobError: Job <jobid> (task: 0) with path .../logs/<jobid>/<jobid>_0_result.pkl

Expected

Concurrent readers/writers of a shared cachedict (typical when a job array shares one cache folder) should not corrupt the sqlite inflight registry. Either serialize/guard registry writes robustly across processes, tolerate concurrent access, or fail loudly with a clear message instead of silently corrupting the DB.

Notes

Happy to help repro. Workaround we used: disable the Slurm timelines sub-infra so items are computed in-process (removing the concurrent writers to that registry).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions