Signature and mutation type
func (db *DB) WriteBatch(ctx context.Context, mutations []Mutation) error
type Mutation struct {
Collection string
Key, Value []byte
Delete bool
}
Each element is a full replacement or a delete. A delete must have an empty value. All current collections belong to the same shard, so one batch can span collections atomically.
Sequence and duplicates
A nonempty committed batch receives one new database sequence. Its resulting records all use that sequence as their version. A valid empty batch is a no-op. Closed/canceled/poisoned handles can still return errors for empty batches; empty does not bypass lifecycle checks.
Repeated collection/key pairs are allowed. The last mutation determines the visible result, but every input operation contributes to count and encoded-size budgets.
Encoded size
For current format 1, the payload size is:
12 + sum(13 + collection_bytes + key_bytes + value_bytes)
The 12 bytes hold sequence/count. Each mutation contributes a flag plus three 32-bit lengths. The outer WAL frame adds 8 bytes, separate from MaxBatchBytes payload accounting.
The default maximum is 4096 operations and 1 MiB payload. The file format independently rejects frames over 64 MiB. Configured limits can be stricter.
Final-state resource validation
The engine computes final per-key live-data and memtable effects before persistent append. An existing record replacement can free the old logical size. A delete removes live-data accounting but still needs a tombstone in the memtable.
The final distinct entries produced by one batch must fit the configured memtable on their own. If the existing memtable plus new state would exceed its budget, it is flushed first. Buffer thresholds are not permission to split an oversized atomic batch automatically.
Budget accounting is collection/key/value length plus 64 bytes per record. It is not exact Go allocation size. Input copies, encoding buffers, and validation maps temporarily use additional memory.
Commit boundary
- Validate/copy the batch and budgets.
- Checkpoint previous state if necessary.
- Recheck cancellation before the append.
- Write one complete framed batch.
- Sync in durable mode.
- Publish all mutations under the exclusive lock and return nil.
If the pre-append context check fails after an automatic flush, the requested mutation is unapplied, but a checkpoint of older state may already have occurred. Do not equate an API error with “no filesystem activity.”
Retry behavior
No embedded operation ID, deduplication journal, transaction callback, expected version, or distributed coordinator is implemented. A complete frame can recover after an acknowledgement is lost.
Replacement writes with the same desired bytes may be safe for your data model to repeat, but they can advance versions. Application side effects such as charging a customer or sending a message are not made idempotent by WriteBatch.
After an I/O failure, close/reopen and reconcile state before retrying a non-idempotent workflow. The future SyncPath operation-ID design must not be assumed to exist in this API.