{"record":{"id":"c33c6fee18f20573","repo":"juicedata/juicefs","slug":"scan-dir-stats","errorCode":null,"errorMessage":"scan dir stats","messagePattern":"scan dir stats","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/meta/tkv.go","lineNumber":529,"sourceCode":"\t\terr = json.Unmarshal(body, &old)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"json: %s\", err)\n\t\t}\n\t\tif !old.DirStats && format.DirStats {\n\t\t\t// remove dir stats as they are outdated\n\t\t\tvar keys [][]byte\n\t\t\tprefix := m.fmtKey(\"U\")\n\t\t\terr := m.client.txn(Background(), func(tx *kvTxn) error {\n\t\t\t\ttx.scan(prefix, nextKey(prefix), true, func(k, v []byte) bool {\n\t\t\t\t\tif len(k) == 9 {\n\t\t\t\t\t\tkeys = append(keys, k)\n\t\t\t\t\t}\n\t\t\t\t\treturn true\n\t\t\t\t})\n\t\t\t\treturn nil\n\t\t\t}, 0)\n\t\t\tif err != nil {\n\t\t\t\treturn errors.Wrap(err, \"scan dir stats\")\n\t\t\t}\n\t\t\terr = m.txn(Background(), func(tx *kvTxn) error {\n\t\t\t\tfor _, key := range keys {\n\t\t\t\t\ttx.delete(key)\n\t\t\t\t}\n\t\t\t\tm.genLog(tx, time.Now(), \"INIT_ENABLE_DIRSTATS()\")\n\t\t\t\treturn nil\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\treturn errors.Wrap(err, \"delete dir stats\")\n\t\t\t}\n\t\t}\n\t\tif !old.UserGroupQuota && format.UserGroupQuota {\n\t\t\t// remove user group quota as they are outdated\n\t\t\tuserPrefix := m.fmtKey(\"QU\")\n\t\t\tgroupPrefix := m.fmtKey(\"QG\")\n\t\t\terr := m.txn(Background(), func(tx *kvTxn) error {\n\t\t\t\ttx.deleteKeys(userPrefix)","sourceCodeStart":511,"sourceCodeEnd":547,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/meta/tkv.go#L511-L547","documentation":"In kvMeta.doInit (pkg/meta/tkv.go:529), when a volume's format is updated to enable DirStats, the code first scans and collects stale dir-stat keys (prefix \"U\") in a read transaction; a failure of that scan transaction is wrapped as \"scan dir stats\". This happens during `juicefs format --enable-dirstats` (or mount with format update) on TiKV/etcd/Badger/FDB engines.","triggerScenarios":"Formatting/re-formatting a KV-engine volume where old.DirStats is false and the new format enables DirStats, and the scan transaction against the KV store fails (network to TiKV/PD, etcd timeouts, store unavailable).","commonSituations":"Enabling the dirstats feature on a large old volume whose TiKV/etcd cluster is slow or partially unreachable; transient network partition between client and KV store during format.","solutions":["Check connectivity/health of the KV cluster (TiKV PD, etcd endpoints) and retry the format command.","Re-run `juicefs format` with the same flags; the operation is only executed when toggling the feature, so a healthy retry completes it.","If a specific store keeps failing, inspect its logs (region errors, leader changes) and repair before re-formatting."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// check KV cluster health before formatting\nfor _, ep := range pdEndpoints {\n    if !reachable(ep) { return fmt.Errorf(\"PD endpoint %s unreachable\", ep) }\n}","typeGuard":null,"tryCatchPattern":"if err := formatVolume(); err != nil {\n    if strings.Contains(err.Error(), \"scan dir stats\") {\n        // KV cluster issue; verify TiKV/PD or etcd health and retry\n    }\n}","preventionTips":["Verify KV cluster health (PD, etcd endpoints) before running format/mount.","Enable dirstats during a maintenance window on large legacy volumes.","Monitor region/leader errors in TiKV logs when running format operations."],"tags":["go","kv","tikv","etcd","format","dirstats"],"backgroundTag":"network-request-failed","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}