Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

[Bug]: `couch_bt_engine:init/2` can crash with `noproc` when `couch_file` idle-closes before `set_db_pid`

Chiusa
#6,178 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@nickva ci sta già lavorando.

Dal 28/10/2026.

  • #6184 di @nickva — aperta

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
55/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
erlang
Ambito
backend, databases

Direzione di ricerca

Read couch_bt_engine.erl around line 893 and trace the open-to-set_db_pid sequence alongside couch_file’s idle-close checks and the ioq wait described here. The reproduction blocks ioq and waits past the 60-second idle timer; use it to confirm the failure and verify the engine keeps the file alive until it claims it, including when initialization or compaction I/O is delayed.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

bug needs-triage
Version

No response

Describe the problem you're encountering

After couch_file:open/2, the file process is linked to the caller, but nothing holds a lasting monitor on it until init_state/4 calls:

couch_file:set_db_pid(Fd, self())

at couch_bt_engine.erl:893.

couch_file closes itself when it looks idle. init/1 arms:

erlang:send_after(?INITIAL_WAIT, self(), maybe_close)

where ?INITIAL_WAIT is 60 seconds.

When the message arrives, is_idle/1 checks monitored_by. If the only monitor is couch_stats_process_tracker, the process stops with reason normal. If it is busy, it re-checks every 10 seconds using ?MONITOR_CHECK.

So, if the time between open and set_db_pid exceeds 60 seconds and one of those checks lands while nothing monitors the file, couch_file stops.

Callers hold a monitor only for the duration of each direct gen_server:call. A request waiting in the ioq queue monitors the ioq server, not the file, so a backed-up ioq is enough to expose the gap. Compaction I/O is not bypassed by default.

Because the exit reason is normal, the link does not take the caller down. The next direct call fails with noproc.

Expected Behaviour

A file opened by couch_bt_engine:init/2 stays open until the engine has claimed it, however long the init takes. Opening a database or finishing a compaction should not fail because IO was slow.

Steps to Reproduce
  1. Start a dev node: ./dev/run -n 1 --admin=adm:pass
  2. Attach a shell: ./dev/remsh
  3. Paste:
%% Create a db file with a header.
Path = filename:join(config:get("couchdb", "database_dir"), "idle_close_repro.couch"),
file:delete(Path),
{ok, Fd0} = couch_file:open(Path, [create]),
ok = couch_file:write_header(Fd0, couch_bt_engine_header:new(), [sync]),
ok = couch_file:close(Fd0),

%% Block ioq.
Ioq = whereis(ioq),
true = erlang:suspend_process(Ioq),

%% Open the db. read_header/1 waits on ioq; the 60s timer starts.
{Pid, Ref} = spawn_monitor(fun() ->
    ioq:set_io_priority({db_compact, <<"repro">>}),
    exit({result, catch couch_bt_engine:init(Path, [])})
end),
timer:sleep(1000),

%% Freeze init and let ioq reply. Now nothing monitors the file.
true = erlang:suspend_process(Pid),
true = erlang:resume_process(Ioq),

%% couch_file idle-closes after 60s.
timer:sleep(61000),

%% Resume init. sync/1 hits the dead file.
true = erlang:resume_process(Pid),
receive {'DOWN', Ref, process, Pid, Reason} -> Reason end.
  1. The result is:
{result,{'EXIT',{noproc,{gen_server,call,
                                  [<0.12353.0>,sync,infinity]}}}}
Your Environment

No response

Additional Context

No response

Lingua principale
Erlang
Stelle
7k
Fork
1.1k
Merge medio
11h 29m
PR unite (30g)
37

Preparare l'ambiente

Apri in Codespaces

Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di apache/couchdb

Tutte le issue di apache/couchdb

Issue simili

Altre issue su Backend & API Design

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.