{"record":{"id":"4fca18b4176c2c82","repo":"juicedata/juicefs","slug":"create-table-node-symlink-xattr-s","errorCode":null,"errorMessage":"create table node, symlink, xattr: %s","messagePattern":"create table node, symlink, xattr: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/meta/sql.go","lineNumber":586,"sourceCode":"}\n\nfunc (m *dbMeta) syncTable(beans ...interface{}) error {\n\terr := m.db.Sync2(beans...)\n\tif err != nil && strings.Contains(err.Error(), \"Duplicate key\") {\n\t\terr = nil\n\t}\n\treturn err\n}\n\nfunc (m *dbMeta) syncAllTables() error {\n\tif err := m.syncTable(new(setting), new(counter)); err != nil {\n\t\treturn fmt.Errorf(\"create table setting, counter: %s\", err)\n\t}\n\tif err := m.syncTable(new(edge)); err != nil {\n\t\treturn fmt.Errorf(\"create table edge: %s\", err)\n\t}\n\tif err := m.syncTable(new(node), new(symlink), new(xattr)); err != nil {\n\t\treturn fmt.Errorf(\"create table node, symlink, xattr: %s\", err)\n\t}\n\tif err := m.syncTable(new(chunk), new(sliceRef), new(delslices)); err != nil {\n\t\treturn fmt.Errorf(\"create table chunk, chunk_ref, delslices: %s\", err)\n\t}\n\tif err := m.syncTable(new(session2), new(sustained), new(delfile)); err != nil {\n\t\treturn fmt.Errorf(\"create table session2, sustaind, delfile: %s\", err)\n\t}\n\tif err := m.syncTable(new(flock), new(plock), new(dirQuota), new(userGroupQuota)); err != nil {\n\t\treturn fmt.Errorf(\"create table flock, plock, dirQuota, userGroupQuota: %s\", err)\n\t}\n\tif err := m.syncTable(new(dirStats)); err != nil {\n\t\treturn fmt.Errorf(\"create table dirStats: %s\", err)\n\t}\n\tif err := m.syncTable(new(detachedNode)); err != nil {\n\t\treturn fmt.Errorf(\"create table detachedNode: %s\", err)\n\t}\n\tif err := m.syncTable(new(acl)); err != nil {\n\t\treturn fmt.Errorf(\"create table acl: %s\", err)","sourceCodeStart":568,"sourceCodeEnd":604,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/meta/sql.go#L568-L604","documentation":"syncAllTables (pkg/meta/sql.go:585) creates/auto-migrates the core inode tables `node`, `symlink`, and `xattr` via xorm Sync2; failure is wrapped as \"create table node, symlink, xattr: %s\". These are the central tables of the metadata schema, so any DDL failure here prevents the volume from initializing. Duplicate-key races are ignored by syncTable; everything else propagates.","triggerScenarios":"Metadata engine initialization (`juicefs format`/`mount`) when Sync2 on the node/symlink/xattr beans fails: missing CREATE privileges, existing incompatible tables from an older JuiceFS version, or DB resource limits (disk, max tables).","commonSituations":"Upgrading a volume where an old node table lacks newer columns and ALTER is denied; a DB user downgraded to read-only after initial format; SQLite file on a full disk.","solutions":["Inspect the wrapped driver error for 'denied', 'read-only', or 'disk full' and fix that root cause.","Ensure the DB user has CREATE and ALTER privileges so Sync2 can add missing columns to existing tables.","After backup, drop incompatible leftover tables from an aborted init and retry.","Free disk space on the database host if the error indicates storage exhaustion.","Re-run the command; table creation is idempotent once the underlying issue is fixed."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Preflight: check core tables are absent or migrateable and user has ALTER\n// MySQL:\n//   SELECT COUNT(*) FROM information_schema.columns\n//     WHERE table_schema='jfs' AND table_name='jfs_node';\n//   SHOW GRANTS FOR CURRENT_USER();  -- must include ALTER/CREATE\n// If jfs_node exists with an old schema, plan a backup before upgrading.","typeGuard":null,"tryCatchPattern":"if err := initMeta(); err != nil {\n    if strings.Contains(err.Error(), \"create table node, symlink, xattr\") {\n        return fmt.Errorf(\"core inode table migration failed; check ALTER grants and schema version: %w\", err)\n    }\n    return err\n}","preventionTips":["Back up metadata (juicefs dump) before version upgrades that change the schema.","Keep DDL grants in place permanently; Sync2 migrates tables on every init, not only at format.","Monitor DB disk usage; node/xattr tables are the largest and fill space first.","Initialize the volume once with full rights even if later runtime use is DML-only."],"tags":["database","schema-migration","ddl","inode"],"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-14T00:17:10.932Z"}