-
Notifications
You must be signed in to change notification settings - Fork 7
Storage Backends
Where PlayerData, PDSections and account data physically live is an admin decision, made in
plugins/EverNifeCore/storage.yml. Plugins advise a default; the admin has the final say. The storage
engine is EveryDatabase - EverNifeCore configures
and drives it.
The file is generated with a full set of commented, disabled example backends on first boot, so most
admins only flip enabled and fill in credentials.
storage-backends:
groupedfile: # the entry key is a FREE unique id (name it anything)
enabled: true
type: groupedfile
path: plugins/EverNifeCore/StorageData/groupedfile
format: yaml # yaml | json (file backends only)
mysql:
enabled: false
type: sql
url: "jdbc:mysql://localhost:3306/minecraft"
user: root
pass: ""
pool:
minIdle: 2
maxSize: 10
connectTimeoutSeconds: 5
idleTimeoutSeconds: 30
default-backend: groupedfile # used when nothing more specific is configuredThe entry key is a free unique id, not the type. Declaring several backends of the same type is how
you point different data at different servers - e.g. a mysql_economy and a mysql_points, both
type: sql, on two databases.
Every backend's runtime dependency (JDBC drivers, the Mongo driver) is downloaded up front at boot,
so switching type here never hits a missing dependency.
type: maps to one of these. Full capability matrix and per-backend setup live in the EveryDatabase
wiki - the short version:
type: |
Engine | Good for | EveryDatabase page |
|---|---|---|---|
groupedfile |
key-major files (one file per key, all its collections) | the per-player model; the factory default | Grouped Files |
localfile |
one file per entity | tiny deploys, human-readable | Local Files |
sql |
MySQL / MariaDB (HikariCP pool, JSON column) | production, shared DB | MySQL & MariaDB |
postgresql |
PostgreSQL (HikariCP pool, JSON column) | production, shared DB | PostgreSQL |
h2 |
H2 embedded / file / tcp | embedded / dev | H2 |
mongo |
MongoDB (native BSON documents) | document workloads | MongoDB |
memory |
in-memory only, ephemeral | tests / throwaway servers | In-Memory |
format: yaml | json applies to the file backends (groupedfile / localfile) only; yaml is the
default and json is always written pretty/indented. For choosing among them, see
Choosing a Backend.
⚠️ memorydata is lost on shutdown - the parser warns when you enable it. Use it only for tests.
Once backends are declared, three blocks route the actual data. Each may name a storage-backend-id;
naming a missing or disabled backend is a fail-fast error at boot with a message that points at the
offending key.
playerdata:
storage-backend-id: groupedfile # must be an enabled backend id
collection: evernifecore_playerdata
load-mode: ALL # ALL (default) | RECENT
recent-days: 60 # RECENT: how far back to eager-load
login-timeout-seconds: 5 # how long a login may wait on storage before being denied
orphan-reaper:
enabled: false # opt-in; sweeps section rows whose base is gone
interval-minutes: 360load-mode: ALL loads every player at startup; RECENT eager-loads only players seen in the last
recent-days and lazy-loads the rest on demand.
Generated automatically the first time each PDSection registers - the admin then edits the
storage-backend-id, collection and cache of each entry freely (an admin cache: override wins over
the developer's cache policy).
multi-platform-accounts:
enabled: false
storage-backend-id: "" # empty = default-backendThe backend hosting the whole account family (registry + account-wide sections). On a real network it must be a database shared by every instance. See Accounts.
When several instances share one database, each instance caches rows independently - a write on
instance A must invalidate the same entry on instance B. That is what multi-server-cache-sync does.
multi-server-cache-sync:
enabled: true # default; HARMLESS no-op on a single server
transport: auto # auto | redis | native
redis:
enabled: false
host: localhost
port: 6379Transport resolution:
-
auto(default) - Redis if theredisblock is enabled, else the backends' native change feed when every manager's backend has one, else a silent no-op. -
redis- force the Redis pub/sub transport. -
native- use only the backends' native feed.
Which backends have a native feed: only MongoDB and PostgreSQL. sql (MySQL/MariaDB) and the
file backends do not - for those, cross-instance coherence exists only through Redis.
📌 Current state of the Redis transport. The Redis transport lives in the optional
everydatabase-manager-jedismodule, which is not bundled with EverNifeCore on this version. If you configure aredisblock without that runtime on the classpath, EverNifeCore logs a warning at boot and cache-sync via Redis is a no-op. The native-feed path (Mongo/PostgreSQL) is wired and works today. On a single server the whole block is a harmless no-op regardless.
For the deeper model, see Cross-Process Cache Sync.
logging:
level: warn # warn (default) | info | debug | traceControls the EveryDatabase storage log verbosity (bind reports, conflict/flush lines).
A backend declared enabled: true that does not answer at boot stops the server. This is on by
default, and it is deliberate: booting without the database that holds player data would let every
player join with empty data, and the first save would overwrite the real rows with those empty ones.
Every unreachable backend is reported at once, not one per restart. The report names each one with
its type, the target it was pointed at (with the password redacted), which storage.yml keys
route data to it, and the root cause of the failure; the full stack traces are printed above the
banner.
# plugins/EverNifeCore/config.yml
Settings:
Storage:
STOP_SERVER_IF_STORAGE_IS_UNREACHABLE: true # the defaultTwo things worth knowing before you flip it:
- It only ever stops a BOOT. A failed reload never stops anything - the previously loaded storage is still live and serving, so the report says so and nothing is lost. Fix the config or the database and reload again.
-
falsedoes not make the server work without a database. EverNifeCore stays disabled either way, every plugin that depends on it fails, and whatever data does get written diverges from what the database holds. The only real ways out of a boot failure are starting the database, fixing the url/user/pass, or settingenabled: falseon a backend you no longer use.
| Subcommand | Permission node | What it does |
|---|---|---|
status |
evernifecore.command.storage.status |
Prints the routing (which backend/collection each entity persists on) plus health counters - quit-flush retry backlog, adopted conflicts, last failed write. |
transfer <plugin:section> <backend> |
evernifecore.command.storage.transfer |
Migrates one PDSection's collection to another backend at runtime (see below). |
You are not locked in: a single PDSection's collection can be migrated to another backend at runtime
without editing files by hand - see Legacy Data Migration for
/ecstorage transfer. The underlying builder is EveryDatabase's
Moving Data Between Backends.
- PlayerData & PDSections - what gets stored and how cache policies map on.
- Inline Backends for Plugins - a plugin routing its OWN data elsewhere.
- Accounts - the shared account backend.
- Legacy Data Migration - first-boot import and runtime transfer.
-
Command Framework - how
/ecstorageand other builtin commands are declared.
EverNifeCore · Home · made by Petrus Pradella
Getting Started
Commands & Text
Player Data & Storage
- PlayerData & PDSections
- Accounts
- Storage Backends
- Inline Backends for Plugins
- Legacy Data Migration
- Cooldowns
Config & Minecraft Systems
- Configuration
- Scheduler & Threading
- Items & NBT
- GUI Framework
- Integrations
- Economy
- Version Compatibility
Architecture & Reference