{"record":{"id":"6f306293b22a3039","repo":"juicedata/juicefs","slug":"claim-delayed-slice-d","errorCode":null,"errorMessage":"claim delayed slice %d","messagePattern":"claim delayed slice (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/meta/sql.go","lineNumber":4081,"sourceCode":"\t\t\tif err != nil {\n\t\t\t\treturn errors.Wrapf(err, \"get delslices %d\", ds.Id)\n\t\t\t}\n\t\t\tif !found {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tm.decodeDelayedSlices(del.Slices, &ss)\n\t\t\tclean, err := scan(ss, del.Deleted)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif !clean {\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\t// Deleting the delayed row claims cleanup; rollback restores it on failure.\n\t\t\taffected, err := tx.Delete(&delslices{Id: del.Id})\n\t\t\tif err != nil {\n\t\t\t\treturn errors.Wrapf(err, \"claim delayed slice %d\", del.Id)\n\t\t\t}\n\t\t\tif affected == 0 {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tif affected != 1 {\n\t\t\t\treturn fmt.Errorf(\"delete delayed slice %d affected %d rows\", del.Id, affected)\n\t\t\t}\n\t\t\tfor _, s := range ss {\n\t\t\t\tif _, e := tx.Exec(m.sqlConv(\"update chunk_ref set refs=refs-1 where chunkid=? AND size=?\"), s.Id, s.Size); e != nil {\n\t\t\t\t\treturn e\n\t\t\t\t}\n\t\t\t}\n\t\t\tm.genLog(ctx, tx, time.Now().UnixNano(), \"CLEANUP_TRASH_SLICES(%d,%d)\", del.Id, del.Deleted)\n\t\t\tclaimed = true\n\t\t\treturn nil\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err","sourceCodeStart":4063,"sourceCodeEnd":4099,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/meta/sql.go#L4063-L4099","documentation":"After the scan callback says a delayed slice is fully cleaned, the code deletes the delslices row to atomically \"claim\" the cleanup (rollback restores it if the transaction fails). If the DELETE statement itself errors, the failure is wrapped as \"claim delayed slice %d\" and gc aborts.","triggerScenarios":"`juicefs gc` trash-slice cleanup on SQL metadata where the transactional DELETE FROM delslices fails due to a database error, deadlock, or lost connection while holding the row lock.","commonSituations":"Concurrent gc processes from multiple clients contending for the same delslices row; DB deadlock detection killing the transaction; network interruption during the gc transaction.","solutions":["Re-run `juicefs gc` — the claim is transactional so it is safe to retry","Avoid running multiple `juicefs gc` instances concurrently against the same volume","Check the wrapped cause for deadlock details; run gc serially or in low-traffic windows","Check DB connectivity/stability if failures recur"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"claim delayed slice\") {\n    // transactional claim failed; safe to re-run `juicefs gc`\n}","preventionTips":["Do not run multiple concurrent `juicefs gc` processes","Keep gc transactions short; run during quiet periods","Ensure DB connection stability for the whole gc run"],"tags":["database","gc","sql","transaction"],"backgroundTag":"database-write-failed","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}