Choose a durability class

v3.0.0

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 DURABILITY and BEGIN ... DURABILITY need no special role.
  • SYNC needs the admin role when auth = scram.

Compare the classes

ClassAlsoCOMMIT returns afterCommitted work a crash can loseUse for
strictd1The commit record is written and synced to the device. One sync per commit.NoneCommits that must not share a sync with others.
group (default)d2The same point as strict, but one sync covers a batch of commits that arrive together.NoneNormal operation.
relaxedd3The commit record is in the log buffer. It is synced later by the WAL drain.Commits from the last relaxed_flush_interval_usBulk 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:

  1. The server key durability.
  2. SET DURABILITY for the session.
  3. BEGIN ... DURABILITY for 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.

KeyDefaultWhat it does
wal_drain_interval_us1000 (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_us10000 (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 ...
FieldMeaning
wal_mean_group_batchHow many commits one sync covers on average. 1.000 means every commit paid for its own sync.
wal_group_commits, wal_group_batchesCommits that went through group commit, and the batches they formed.
wal_syncsLog syncs issued. On an instance with several cores, read it on core 0, which owns the log.
wal_durable_lsnThe 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 META shows wal_stopped=1. On restart, every strict and group commit acknowledged before the stop is recovered. A relaxed commit whose bytes had not reached the device is lost, as in a crash.
  • A COMMIT refused because of that stop may still have been written. Read the data back after the restart.

Next steps