Berserk Docs

Managing with the CLI

Manage databases, tables, views, tokens, remote sites and cluster internals with bzrk

bzrk manages a cluster's resources from the terminal. Install the CLI and sign in first: Berserk CLI.

Identifying resources

Each command reaches a resource by one kind of identifier (bzrk help resources prints the same):

IdentifierResources
Name or iddatabase, table, view, service account, site principal, remote site
Nameingest token, connection, profile
Path, a slash-separated name such as oncall/nightly-error-digestworkflow, alert, dashboard
Idworkflow run, running query (bzrk ps), service account token, site token, remote table

Tables, views and ingest tokens belong to a database: --database, else the profile's database, else default.

Anyone signed in can list and read databases, tables, views and ingest tokens. Creating, changing, deleting or restoring one takes an admin or a maintainer, and so do the bzrk admin janitor, stream and vidx commands that change anything. Anyone else is refused with a permission error.

A command group run without a command runs its list, or status for bzrk auth, bzrk admin vidx and bzrk admin vidx writes: bzrk table is bzrk table list. A group without either prints its help and exits 2.

--database and the output formats (--json, --csv, --tsv) work only with the commands that read them, and bzrk <command> -h lists them under Global options; elsewhere they are refused with exit 2.

Deleting and restoring

A deleted database, table, view or ingest token can be restored for a while: 5 minutes for a view, longer for the rest. The delete prints the date it stays restorable until, and so does list --include-deleted:

bzrk table delete events
# Deleted table 'events'. Restorable for 7 days, until 2026-05-27T10:00:00+00:00: `bzrk table restore events`
bzrk table list --include-deleted
bzrk table restore events
  • --immediate skips the restore window: the database or table cannot be restored, and its data is cleaned up within minutes.
  • A database that still has tables, views or ingest tokens is deleted only with --cascade (--dry-run lists them), and bzrk database restore restores what the cascade deleted.
  • A table is not deleted while a view or an ingest token uses it; change those first with bzrk view set-tables or bzrk ingest-token update-routing.
  • A deleted name stays taken until it can no longer be restored. A restored ingest token works again with its old value.
  • --json lists carry deleted_at and restorable_until for a deleted row.

Workflows, alerts, dashboards and connections cannot be restored.

Connecting clusters

One cluster can query another's tables (Querying other clusters). On the cluster being queried, an admin creates a site principal and its token; on the cluster querying it, an admin registers the remote site with that token and maps its tables:

# On the cluster being queried
bzrk site-principal create acme-eu --databases logs,traces
bzrk site-principal token create acme-eu to-acme-eu --simple > token.txt

# On the cluster querying it: the token is read from stdin, never from the command line
bzrk remote-site add acme-eu --url https://berserk.acme.example --cluster-function no < token.txt
bzrk remote-site table map acme-eu --local-database default --local-name AcmeLogs \
  --remote-database logs --remote-table Logs

--databases (all, or a comma-separated list) and --cluster-function (yes or no) have no default. bzrk site-principal also takes list, get, set-databases, enable, disable, delete and token list|revoke; bzrk remote-site takes list, get, update, set-token, remove and table list|unmap. A token is rotated by creating a new one, bzrk remote-site set-token, and revoking the old one.

Operator commands

Commands for running a cluster live under bzrk admin, apart from the everyday ones:

Every replica that opens segments reports its vector-index format level to meta: 0 predates release 1, 1 reads and drops the new format, 2 writes it. bzrk vidx status lists each live replica with its pod (when it registered one), its level and when it last reported, then how many replicas of each kind meta can see and how many of those are at level 0:

  • nursery — from its poll of meta, or from its registration heartbeat while it is not polling
  • janitor — from its registration heartbeat, which keeps running through a long merge
  • qws-cloud, qws-nursery — query workers, from their registration
  • query — the query service itself, which reads segments when it runs its workers in process
bzrk admin vidx status
bzrk admin vidx status --json

The last line is the verdict:

  • level-0 replicas are live — at least one replica below release 1 is running.
  • No level-0 replica is live — every replica meta can see is at level 1 or above.
  • Unknown — meta restarted too recently to have heard from every live replica (its list is complete after the longest liveness window it uses, which the output names). Run it again once that has passed.

The verdict covers only replicas meta can see. One that cannot register at all, say a pod with no address meta can record, is missing from the list without making the verdict unknown. Before relying on "no level-0 replica", check the per-kind counts against the replica counts of the deployment. A meta older than this command answers with an error that says so.

The floor: line is the environment's vector-index floor (vidxFloor), which meta enforces: a nursery below it holds no lease, a janitor below it is given no merge task, and a query worker below it stays registered but is left out of the pool coordinators draw from. Replicas below the floor are still listed, marked below floor, and a closing line counts them. --json carries the same as vidx_floor, below_floor and a below_floor flag per replica.

After the verdict come the write gate, as bzrk vidx writes status prints it, and every table's live segments, named database.table, by vector-index format: unknown (published before meta recorded formats), none, legacy (today's VCEN/VTPH/VTPC artifacts) and v1, with how many v1 segments left a field unindexed for a transient reason. A closing line counts the segments the rewrite has yet to reach: anything but v1 on a table with vector fields, and anything unknown or legacy elsewhere. --json carries them as writes and inventory; both are null from a meta that predates them.

bzrk admin vidx writes — whether writers may write the new format

bzrk admin vidx writes status
bzrk admin vidx writes open
bzrk admin vidx writes close

Writes of the new format are closed until they are opened, and who opens them is the environment's vidxWrites (BZRK_VIDX_WRITES on meta). In auto, the default, the gate authority opens writes itself the first time open would succeed, and logs it with vidx.reason=auto_opened. In manual, only open opens them. close holds writes closed in either mode: meta in auto does not reopen them, across restarts and changes of authority, until an operator runs open, which releases the hold even when it is refused. close on writes that never opened holds them too, which keeps auto from opening them in the first place. status prints the mode on its mode: line, says when an operator's close holds writes, and lists what keeps them from opening; --json carries writes_mode and closed_by_operator_at_nanos.

open succeeds only when the floor is at least 1, one grant period has passed since the last close, and a window has held on meta: every nursery holding a lease reports level 2, every query worker level 1 or more, and a level-2 janitor has polled for a merge task within every grant period. Any lapse starts the window again, and so does a meta restart. Otherwise meta refuses and names every unmet condition; status lists the same conditions without trying.

Meta hands each level-2 nursery and janitor a grant with every poll while writes are open. A writer starts a new-format build only under an unexpired grant, timed from when it sent its poll, so close stops new builds within one grant period; builds already started finish. A restarted meta grants nothing until its window has held again, and meta stops granting while any nursery holding a lease is below level 2 or any query worker below level 1. While writes are open, meta refuses a lease to a nursery below level 2. Open only after a settled deploy in which every meta pod runs this release: meta checks the gate protocol of every meta that registers one, but cannot see a meta that predates it, and open repeats this reminder. One meta at a time is the gate authority, the holder of a Postgres advisory lock; only it opens writes and grants, and status says when the meta you reached is not it. Any meta closes writes. Meta gives merge tasks with a v1 input only to level-2 janitors, and while writes are open, tasks for tables with vector fields too. The window (vidx_window_secs, 300 by default) and the grant period (vidx_grant_period_secs, 30 by default) are meta configuration.

On this page