{"record":{"id":"21ea78bcf066a4a2","repo":"tursodatabase/turso","slug":"database-was-busy","errorCode":null,"errorMessage":"database was busy","messagePattern":"database was busy","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"perf/join-benchmark/main.rs","lineNumber":173,"sourceCode":"        });\n    }\n    Ok(queries)\n}\n\nfn set_timeout(statement: &mut turso_core::Statement, timeout_seconds: u64) {\n    let timeout = (timeout_seconds != 0).then(|| Duration::from_secs(timeout_seconds));\n    statement.set_query_timeout_override(Some(timeout));\n}\n\nfn execute(database: &Database, statement: &mut turso_core::Statement) -> Result<u64> {\n    let mut result_rows = 0_u64;\n    loop {\n        match statement.step()? {\n            StepResult::Row => result_rows = result_rows.saturating_add(1),\n            StepResult::IO | StepResult::Yield | StepResult::Sleep { .. } => database.io.step()?,\n            StepResult::Done => return Ok(result_rows),\n            StepResult::Interrupt => bail!(\"query was interrupted\"),\n            StepResult::Busy => bail!(\"database was busy\"),\n        }\n    }\n}\n\nfn print_plan(connection: &Arc<turso_core::Connection>, query: &Query) -> Result<()> {\n    let sql = format!(\"EXPLAIN QUERY PLAN FORMAT=JSON {}\", query.sql);\n    let rows = connection.prepare(sql)?.run_collect_rows()?;\n    let Some(Value::Text(plan)) = rows.first().and_then(|row| row.first()) else {\n        bail!(\"query {} did not return a JSON plan\", query.name);\n    };\n    let plan: JsonValue = serde_json::from_str(plan.as_str())?;\n    println!(\"{}\", json!({\"query\": query.name, \"plan\": plan}));\n    Ok(())\n}\n","sourceCodeStart":155,"sourceCodeEnd":188,"githubUrl":"https://github.com/tursodatabase/turso/blob/492c4a71cd7c2649e7df83da1471b74f4b1c7aa9/perf/join-benchmark/main.rs#L155-L188","documentation":"Error propagated from turso_core statement stepping in the join benchmark's execute(): the database reported a busy condition, meaning a lock could not be acquired within the configured timeout (set via set_timeout/query_timeout_override) because another connection held the database. It surfaces to main when a benchmark query times out waiting for the database instead of completing.","triggerScenarios":"statement.step() yields Busy during the execute loop, typically because another connection/process holds a conflicting lock on the database being benchmarked.","commonSituations":"Another tursodb/sqlite process has the database file open with an active write transaction; a leftover crashed process still holds the lock; running two benchmark instances against the same DB file concurrently.","solutions":["Ensure no other process/connection is using the database file: `lsof <db-file>` and close or kill holders.","Run the benchmark against a private copy of the database file.","Retry the benchmark after the conflicting transaction finishes.","If concurrency is intentional, add busy-retry handling instead of failing immediately."],"exampleFix":"// before\nStepResult::Busy => bail!(\"database was busy\"),\n// after\nStepResult::Busy => { std::thread::sleep(Duration::from_millis(50)); continue; }","handlingStrategy":"retry","validationCode":"// before starting: ensure no other process holds the DB\n// lsof <db-file>  → must be empty","typeGuard":null,"tryCatchPattern":"loop {\n    match statement.step() {\n        Ok(StepResult::Busy) => {\n            std::thread::sleep(Duration::from_millis(50));\n            continue;\n        }\n        other => break other.map_err(Into::into),\n    }\n}","preventionTips":["Run benchmarks against a private copy of the database file","Ensure no other tursodb/sqlite process has the file open during runs","Add bounded busy-retry with backoff in benchmark harnesses"],"tags":["rust","benchmark","database-lock","busy"],"backgroundTag":"database-locked","analyzedSha":"492c4a71cd7c2649e7df83da1471b74f4b1c7aa9","analyzedAt":"2026-09-13T18:13:59.796Z","contentChangedAt":"2026-09-13T18:13:59.796Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}