{"record":{"id":"36ae4a0a9af854d5","repo":"juicedata/juicefs","slug":"dump-trash-nodes","errorCode":null,"errorMessage":"dump trash nodes","messagePattern":"dump trash nodes","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/meta/sql_bak.go","lineNumber":141,"sourceCode":"\t}\n\n\tvar rows []node\n\tif err := m.execTxn(ctx, func(s *xorm.Session) error {\n\t\treturn s.Where(\"inode >= ?\", TrashInode).Find(&rows)\n\t}); err != nil {\n\t\treturn err\n\t}\n\tnodes := make([]*pb.Node, 0, len(rows))\n\tvar attr Attr\n\tfor _, n := range rows {\n\t\tpn := pool.Get().(*pb.Node)\n\t\tpn.Inode = uint64(n.Inode)\n\t\tm.parseAttr(&n, &attr)\n\t\tpn.Data = m.marshal(&attr)\n\t\tnodes = append(nodes, pn)\n\t}\n\tif err := dumpResult(ctx, ch, &dumpedResult{&pb.Batch{Nodes: nodes}, release}); err != nil {\n\t\treturn errors.Wrap(err, \"dump trash nodes\")\n\t}\n\n\tvar maxInode uint64\n\terr := m.execTxn(ctx, func(s *xorm.Session) error {\n\t\tvar row node\n\t\tok, err := s.Select(\"max(inode) as inode\").Where(\"inode < ?\", TrashInode).Get(&row)\n\t\tif ok {\n\t\t\tmaxInode = uint64(row.Inode)\n\t\t}\n\t\treturn err\n\t})\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"max inode\")\n\t}\n\n\treturn sqlQueryBatch(ctx, opt, maxInode, func(ctx context.Context, start, end uint64) (int, error) {\n\t\tvar rows []node\n\t\tif err := m.execTxn(ctx, func(s *xorm.Session) error {","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/meta/sql_bak.go#L123-L159","documentation":"In dbMeta.dumpNodes (pkg/meta/sql_bak.go:141), the trash-node batch produced from `inode >= TrashInode` rows is pushed to the dump channel via dumpResult; any failure there (consumer gone, context canceled, marshal/write error) is wrapped as \"dump trash nodes\". It surfaces while running `juicefs dump` against a SQL metadata engine.","triggerScenarios":"Running `juicefs dump <meta-url> out.json` (DumpMeta) on a MySQL/PostgreSQL/SQLite volume; the dumpResult send fails because the output writer errored, the destination filled up, or the dump context was canceled/timed out while emitting the trash segment.","commonSituations":"Disk full on the node writing the dump file; operator Ctrl-C or pipeline (e.g. `| gzip`) closing early; SQL connection dropped mid-dump; very large trash producing long-running dumps that hit timeouts.","solutions":["Check the underlying wrapped error and the dump destination: free disk space, verify the output file/stream is writable, and keep any pipe consumers alive.","Re-run `juicefs dump` with `--threads` lowered and without interruption; use `--skip-trash` if trash content is not needed.","Verify SQL engine connectivity/stability (connection limits, timeouts) if the wrap hides a DB error."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"null","typeGuard":null,"tryCatchPattern":"if err := runDump(); err != nil {\n    if strings.Contains(err.Error(), \"dump trash nodes\") {\n        logger.Errorf(\"dump failed while writing trash segment: %v\", err)\n        // check disk space / output stream, then retry with --skip-trash\n    }\n}","preventionTips":["Ensure ample free disk space for the dump file before starting `juicefs dump`.","Avoid piping the dump into consumers that may exit early; write to a file first.","Use `--skip-trash` when trash content is not needed to shorten the dump."],"tags":["go","dump","trash","sql","backup"],"backgroundTag":"file-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"}