{"record":{"id":"3ebf253e54bcc167","repo":"juicedata/juicefs","slug":"max-inode","errorCode":null,"errorMessage":"max inode","messagePattern":"max inode","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/meta/sql_bak.go","lineNumber":154,"sourceCode":"\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 {\n\t\t\treturn s.Where(\"inode >= ? AND inode < ?\", start, end).Find(&rows)\n\t\t}); err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tnodes := make([]*pb.Node, 0, len(rows))\n\t\tvar attr Attr\n\t\tfor _, n := range rows {\n\t\t\tpn := pool.Get().(*pb.Node)\n\t\t\tpn.Inode = uint64(n.Inode)\n\t\t\tm.parseAttr(&n, &attr)\n\t\t\tpn.Data = m.marshal(&attr)\n\t\t\tnodes = append(nodes, pn)\n\t\t}","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/meta/sql_bak.go#L136-L172","documentation":"dbMeta.dumpNodes (pkg/meta/sql_bak.go:154) wraps the failure of the `SELECT max(inode) ... WHERE inode < TrashInode` query as \"max inode\". This query establishes the upper bound for batched dumping of regular (non-trash) nodes during `juicefs dump`.","triggerScenarios":"Running `juicefs dump` on a SQL metadata engine when the max-inode query fails: DB connection error, query timeout, table missing/corrupt, or transaction abort inside execTxn.","commonSituations":"Metadata database under heavy load or failover during a dump; wrong credentials/network to MySQL/PostgreSQL mid-run; SQLite file locked by another process; schema corruption after a failed upgrade.","solutions":["Read the wrapped cause: test connectivity to the metadata DB (`juicefs status <meta-url>`) and re-run the dump.","Check DB server logs for the failing query (timeout/lock wait); raise timeouts or run the dump off-peak.","For SQLite, ensure no other process holds a write lock on the .db file; for MySQL/PG, verify the juicefs_* node table exists and is intact (run `juicefs fsck`)."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// pre-flight: verify the metadata DB is reachable\nstatus, err := juicefsStatus(metaURL)\nif err != nil { return fmt.Errorf(\"metadata engine unreachable: %w\", err) }","typeGuard":null,"tryCatchPattern":"if err := dumpMeta(); err != nil {\n    if strings.Contains(err.Error(), \"max inode\") {\n        // inspect wrapped DB error; check connectivity/locks, then retry\n    }\n}","preventionTips":["Run dumps during low DB load and confirm DB connectivity beforehand with `juicefs status`.","For SQLite, ensure no concurrent writers hold the database lock.","Monitor DB server logs for lock-wait/timeout errors during long dumps."],"tags":["go","dump","sql","database-query"],"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-14T00:17:10.932Z"}