Choose a durability class
Pick strict, group or relaxed commits for the server, a session or one transaction, and tune the relaxed loss window.
In this article
A durability class decides when COMMIT returns: after the commit record is on disk, or as soon as it is in the log buffer. Use group (the default) for normal work, strict when each commit must pay for its own sync, and relaxed only for data you can rebuild, such as a bulk load. You can set the class for the whole server, for a session, or for one transaction.
Before you begin
- Read Durability and the write-ahead log for how commits reach the log.
- Changing the server default means editing the config file and restarting
kds_server.SET DURABILITYandBEGIN ... DURABILITYneed no special role. SYNCneeds theadminrole whenauth = scram.
Compare the classes
| Class | Also | COMMIT returns after | Committed work a crash can lose | Use for |
|---|---|---|---|---|
strict | d1 | The commit record is written and synced to the device. One sync per commit. | None | Commits that must not share a sync with others. |
group (default) | d2 | The same point as strict, but one sync covers a batch of commits that arrive together. | None | Normal operation. |
relaxed | d3 | The commit record is in the log buffer. It is synced later by the WAL drain. | Commits from the last relaxed_flush_interval_us | Bulk loads and data you can rebuild. |
strict and group have the same durability point. They differ only in batching. With one connection committing at a time, a batch holds one commit, so group costs the same as strict.
The class is applied at COMMIT. Inside an explicit transaction, one wait covers every write in it.
Step 1: Set the server default
Set durability in the config file. The value is case-insensitive.
# kds.conf
durability = group # strict | group | relaxed (or d1 | d2 | d3)
Restart the server with the file:
./build/kds_server --config kds.conf
Every new session starts with this class.
Step 2: Change the class for a session
SET DURABILITY sets the class for the session’s next transactions, including autocommit statements:
kdbs> SET DURABILITY RELAXED;
SET durability=relaxed
kdbs> BEGIN TRANSACTION;
BEGIN trx_id=19 isolation=read committed durability=relaxed
It never changes a transaction that is already open. Inside a transaction it is refused, and the transaction stays open:
kdbs> SET DURABILITY STRICT;
ERR cannot change the durability class inside a transaction
An unknown name is refused:
kdbs> SET DURABILITY fast;
ERR unknown durability class 'fast'; expected strict|d1, group|d2 or relaxed|d3
Step 3: Override the class for one transaction
Add DURABILITY <class> to BEGIN. It can come before or after ISOLATION LEVEL.
kdbs> BEGIN TRANSACTION DURABILITY STRICT;
BEGIN trx_id=20 isolation=read committed durability=strict
kdbs> ROLLBACK;
ROLLBACK
kdbs> BEGIN ISOLATION LEVEL REPEATABLE READ DURABILITY D1;
BEGIN trx_id=21 isolation=repeatable read durability=strict
The class is chosen in three layers, each overriding the one before:
- The server key
durability. SET DURABILITYfor the session.BEGIN ... DURABILITYfor one transaction.
Clients that use the binary protocol (KWP/1) pass the class in the transaction-begin frame: 0 means the session default, and 1, 2, 3 mean strict, group, relaxed. The commit acknowledgment carries a flag when the commit was acknowledged as relaxed.
Step 4: Tune the relaxed window
Two keys control how long a relaxed commit can stay unsynced. Both are server settings.
| Key | Default | What it does |
|---|---|---|
wal_drain_interval_us | 1000 (1 ms) | How often the WAL drain runs. It syncs relaxed commits and closes group batches that nobody waits on. A tick with nothing to write does no I/O. There is one drain cadence for the instance. 0 disables it, and relaxed commits then stay unsynced until the next checkpoint or shutdown. |
relaxed_flush_interval_us | 10000 (10 ms) | How long a relaxed commit may stay unsynced. This is the loss window. |
relaxed_flush_interval_us is also a latency setting. The sync that enforces it runs on the reactor thread, so the statement running at that moment waits for the device. A larger value makes these pauses less frequent and makes the loss window longer. It cannot remove them.
# kds.conf: a bulk-load instance
durability = relaxed
relaxed_flush_interval_us = 10000
wal_drain_interval_us = 1000
checkpoint_interval_ms (default 5000) controls how often dirty data pages are written to the data file. It does not change when COMMIT returns.
Step 5: Force a sync with SYNC
SYNC makes the log and the data pages durable now. Use it after a relaxed bulk load, before you depend on the data. It replies OK synced.
SYNC;
Verify
Check the class each transaction got: the BEGIN reply shows it in durability=.
Check how commits are synced with SHOW META (the full reply has many more fields; these are the WAL ones):
kdbs> SHOW META;
... wal_topology=single wal_durable_lsn=46600 wal_syncs=19 wal_interval_syncs=0 wal_group_commits=13 wal_group_batches=13 wal_mean_group_batch=1.000 wal_group_batch_max=1 ...
| Field | Meaning |
|---|---|
wal_mean_group_batch | How many commits one sync covers on average. 1.000 means every commit paid for its own sync. |
wal_group_commits, wal_group_batches | Commits that went through group commit, and the batches they formed. |
wal_syncs | Log syncs issued. On an instance with several cores, read it on core 0, which owns the log. |
wal_durable_lsn | The end of the durable log. |
What can still be lost
- If the log device refuses a write or a sync, the server stops all writes until a restart, and
SHOW METAshowswal_stopped=1. On restart, everystrictandgroupcommit acknowledged before the stop is recovered. Arelaxedcommit whose bytes had not reached the device is lost, as in a crash. - A
COMMITrefused because of that stop may still have been written. Read the data back after the restart.
Next steps
- BEGIN, COMMIT, ROLLBACK, SET: full syntax.
- Server configuration: every WAL and durability key.
- Back up and restore: copies that survive the loss of the data file.