juicedata/juicefs · error
only %d records inserted
Error message
only %d records inserted
What it means
During backup loading (sql_bak.go), records are inserted into the SQL metadata engine in batches inside a transaction. xorm's Insert returns the number of rows affected; if it differs from the batch size, JuiceFS treats the insert as incomplete and fails with this error to avoid silently writing a partial backup. It indicates a partially-failed multi-row insert that the driver did not report as an error.
Source
Thrown at pkg/meta/sql_bak.go:861
for _, st := range stats {
rows = append(rows, &dirStats{
Inode: Ino(st.Inode),
DataLength: st.DataLength,
UsedInodes: st.UsedInodes,
UsedSpace: st.UsedSpace,
})
}
return m.insertRows(rows)
}
func (m *dbMeta) insertRows(beans []interface{}) error {
batch := m.getTxnBatchNum()
for len(beans) > 0 {
bs := min(batch, len(beans))
err := m.txn(func(s *xorm.Session) error {
n, err := s.Insert(beans[:bs])
if err == nil && int(n) != bs {
err = fmt.Errorf("only %d records inserted", n)
}
return err
})
if err != nil {
logger.Errorf("Write %d beans: %s", bs, err)
return err
}
beans = beans[bs:]
}
return nil
}
func (m *dbMeta) prepareLoad(ctx Context, opt *LoadOption) error {
opt.check()
if err := m.checkAddr(); err != nil {
return err
}
if err := m.syncAllTables(); err != nil {View on GitHub (pinned to c9a67b23e8)
Solutions
- Retry the load; if it recurs, check the target DB's affected-rows semantics and driver DSN flags (e.g. enable CLIENT_FOUND_ROWS on MySQL).
- Verify the backup file is not corrupt and the target metadata engine is empty before loading (duplicate keys can change affected-row counts).
- Check the database server error log for silently dropped or truncated statements and ensure the table schema matches the dump version.
- If a specific engine consistently misreports counts, upgrade JuiceFS and file an issue with the engine type and driver version.
Example fix
// before
n, err := s.Insert(beans[:bs])
if err == nil && int(n) != bs {
err = fmt.Errorf("only %d records inserted", n)
}
// after (operator-side: load into a clean, empty database)
# ensure target tables are empty first
juicefs dump sqlite3://old.db out.json
rm -f new.db && juicefs format sqlite3://new.db vol
juicefs load sqlite3://new.db out.json Defensive patterns
Strategy: validation
Validate before calling
rows, _ := targetDB.Query("SELECT COUNT(*) FROM jfs_...") // confirm target tables are empty before load Try / catch
if err := juicefsLoad(metaURL, dumpFile); err != nil { log.Fatalf("load failed (partial write possible, re-load into clean DB): %v", err) } Prevention
- Always load into a freshly formatted, empty metadata store
- Match driver/DSN flags between environments (CLIENT_FOUND_ROWS)
- Validate the dump file with juicefs dump/load round-trip in CI
When it happens
Trigger: Calling `juicefs load` (meta.Load/Write fallback path) where `s.Insert(beans[:bs])` returns n < bs, e.g. the database silently skipped rows due to a driver quirk, row-count truncation, or a replaced row counting as fewer affected rows.
Common situations: Restoring a large dump into MySQL/PostgreSQL/SQLite where the driver reports affected-row counts differently (e.g. CLIENT_FOUND_ROWS off, upserts counting as 2), or a storage-side constraint swallowed part of the batch.
Related errors
- create table delegationToken: %s
- unable to use data source %s: %s
- The entry of the root inode was not found
- not implemented, use kvMeta.LoadMetaV2 instead
- database %s is used by volume %s
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/69b38285ed6dfd99.
Report an issue: GitHub.