Skip to content

Storage and Backups

joogiebear edited this page Jul 15, 2026 · 2 revisions

Storage & Backups

Backends

RoyalBank stores accounts, balances, tiers, transactions, and anti-abuse state via HikariCP, on either SQLite (default, single server) or MySQL (shared across a network). Pick one in the storage: section of config.yml:

storage:
  type: SQLITE            # or MYSQL
  sqlite-file: bank.db
  mysql:
    host: localhost
    port: 3306
    database: royalbank
    username: root
    password: ""
    properties: "useSSL=false"
    pool-size: 10

The JDBC driver and HikariCP are downloaded at runtime by Paper's library loader — nothing is bundled into the jar. Changing type needs a full restart, and RoyalBank does not migrate data between the two backends.

SQLite (default)

A bank.db file in plugins/RoyalBank/. You'll also see bank.db-wal and bank.db-shm alongside it — SQLite's write-ahead log and shared-memory files. They're normal; don't delete them while the server is running.

MySQL (networks)

Create the database once (CREATE DATABASE royalbank;) and grant your user access; RoyalBank creates its tables on first connect. Use MySQL when you want bank accounts shared across a network of servers.

Reliability model

  • Every money operation moves through Vault and persists the balance in a single database transaction. If the write fails, the Vault side is rolled back — money is never created or destroyed by a half-completed operation.
  • Online players' accounts are cached in memory (loaded on join, evicted on quit). GUIs and PlaceholderAPI read the cache, not the database, so normal play doesn't hammer disk.
  • The database uses WAL mode with a busy timeout, so reads and writes don't block each other.
  • Transaction pruning and backups run asynchronously on dedicated connections, off the main thread.
  • Existing databases are migrated automatically on startup as new columns are introduced — no manual schema steps.

Backups

/bank admin backup
  • Backups are written to plugins/RoyalBank/backups/.
  • The command uses SQLite VACUUM INTO rather than copying the live file, so you get a clean, consistent snapshot even while the server is running (a raw file copy of an active WAL database can be corrupt).
  • It runs off the main thread, so backing up a large database doesn't stall the server or cause lag.
  • SQLite only. On MySQL, /bank admin backup is a no-op — use your database's own backup tooling (mysqldump, snapshots, etc.) instead.

Recommended routine

  • Run /bank admin backup before major config edits, plugin updates, or economy changes.
  • For scheduled backups, trigger /bank admin backup from a command-scheduler plugin (or copy the backups/ folder off-server on your own cron).

Restoring

  1. Stop the server.
  2. Replace plugins/RoyalBank/bank.db with the backup file (rename it back to bank.db).
  3. Delete any stale bank.db-wal / bank.db-shm next to it.
  4. Start the server.

Housekeeping

  • Keep transactions.max-per-player at a sane number (default 100) so the transaction table can't grow without bound. Pruning runs on startup when transactions.prune-on-startup is true.
  • Don't hand-edit bank.db while the server is running. Use the admin commands, or stop the server first.

Clone this wiki locally