{"record":{"id":"47640ad8a6b092f1","repo":"juicedata/juicefs","slug":"produce-meta-records-s","errorCode":null,"errorMessage":"produce meta records: %s","messagePattern":"produce meta records: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/gc_external.go","lineNumber":62,"sourceCode":"\tdelFlag bool,\n\tmaxMtime time.Time,\n) error {\n\tlogger.Infof(\"Using external sort mode, dir: %s\", extSortDir)\n\n\teg, sortCtx := errgroup.WithContext(c)\n\tsortMetaCtx := meta.WrapWithoutCancel(sortCtx, c.Pid(), c.Uid(), c.Gids())\n\tblobWithPrefix := object.WithPrefix(blob, \"chunks/\")\n\tmetaSorter, objSorter, err := newGcExternalSorters(sortCtx, extSortDir, threads)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tleakedObj, waitLeakedObj := startGcObjectDeleters(c, blobWithPrefix, threads, delFlag)\n\n\teg.Go(func() error {\n\t\tdefer stats.slices.Done()\n\t\tif err := scanGcMetaRecords(sortMetaCtx, m, metaSorter.Input(), stats.slices); err != nil {\n\t\t\treturn errors.Errorf(\"produce meta records: %s\", err)\n\t\t}\n\t\tmetaSorter.CloseInput()\n\t\treturn nil\n\t})\n\n\teg.Go(func() error {\n\t\tdefer stats.scanned.Done()\n\t\tif err := scanGcObjectRecords(sortCtx, blobWithPrefix, objSorter.Input(), threads, chunkConf.HashPrefix, maxMtime, stats.prefixes, stats.scanned, stats.skipped); err != nil {\n\t\t\treturn errors.Errorf(\"produce object records: %s\", err)\n\t\t}\n\t\tobjSorter.CloseInput()\n\t\treturn nil\n\t})\n\n\teg.Go(func() error {\n\t\tif err := mergeGcSortedRecords(sortCtx, metaSorter, objSorter, chunkConf.BlockSize, stats, leakedObj); err != nil {\n\t\t\treturn errors.Errorf(\"merge sorted records: %s\", err)\n\t\t}","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/cmd/gc_external.go#L44-L80","documentation":"Wrapped error from the external-sort GC path when scanGcMetaRecords — the errgroup worker that streams all slices from the metadata engine into the meta sorter — fails. The metadata scan is the source of truth for which blocks are live, so its failure aborts the whole GC run via errgroup. The engine error code is embedded in the message.","triggerScenarios":"`juicefs gc --ext-sort ...` while m.ScanSlices over Redis/SQL/TiKV fails: engine connection dropped mid-scan, engine restarted, scan timeout on very large volumes, or the progress callback returning an error on ctx cancellation.","commonSituations":"Long GC on a huge volume outlasting a flaky Redis connection; SQL server max_execution_time or connection limit hit; TiKV region errors; another admin restarting the metadata service mid-GC.","solutions":["Check the embedded engine error and confirm the metadata service is healthy/reachable.","Re-run GC when the engine is stable; use a read replica if available.","Increase engine-side timeouts (e.g. Redis timeout config) for very large volumes.","Lower `--threads` to reduce engine load during the scan.","Pin client/engine versions to avoid mixed-version scan incompatibility."],"exampleFix":"// before\njuicefs gc --ext-sort /tmp/sort mysql://user:pass@host/jfs\n// after increasing resilience\njuicefs gc --ext-sort /tmp/sort --threads 8 mysql://user:pass@host/jfs","handlingStrategy":"retry","validationCode":"juicefs status $META_URL > /dev/null || { echo 'metadata engine unreachable'; exit 1; }","typeGuard":null,"tryCatchPattern":"if strings.Contains(out, \"produce meta records:\") {\n    // engine error during slice scan; backoff and retry, check engine logs\n}","preventionTips":["Verify engine stability before starting GC on large volumes","Increase engine timeouts for long scans","Use replicas for read-heavy maintenance work"],"tags":["go","metadata","gc","external-sort","database"],"backgroundTag":"database-query-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"}