Dbserver: Difference between revisions

From OuroDev
Line 33: Line 33:


Some basic foreign key constraints exist on the GroupCon types, but containers do not resemble a relational database. They are usually read and written as an atomic unit, and are an attempt at producing the behaviour of a semi-structed key-value store using an SQL database. There is no transactional behaviour, and the dbserver acts as a write-back cache: it holds data in ram and will lose data if it crashes. There are multiple workers running SQL commands, and they will run the commands in any order, except when a barrier is used (via sqlFifoBarrier) which causes all commands before the barrier to complete before any commands after the barrier are run.
Some basic foreign key constraints exist on the GroupCon types, but containers do not resemble a relational database. They are usually read and written as an atomic unit, and are an attempt at producing the behaviour of a semi-structed key-value store using an SQL database. There is no transactional behaviour, and the dbserver acts as a write-back cache: it holds data in ram and will lose data if it crashes. There are multiple workers running SQL commands, and they will run the commands in any order, except when a barrier is used (via sqlFifoBarrier) which causes all commands before the barrier to complete before any commands after the barrier are run.
Some operations in dbserver additionally perform blocking or non-blocking database operations using custom SQL, mostly to find particular rows. AccountServer interactions are notable for doing this on the AccSvrLock field.


A container can be ''loaded'' into ram, or ''unloaded'' when not in use. For most containers, anything that relates to a logged-in player will be loaded when the player first connects, and unloaded when the player disconnects. The database is accessed when loading containers into ram, and to persist changes after they have been applied to containers in ram.
A container can be ''loaded'' into ram, or ''unloaded'' when not in use. For most containers, anything that relates to a logged-in player will be loaded when the player first connects, and unloaded when the player disconnects. The database is accessed when loading containers into ram, and to persist changes after they have been applied to containers in ram.

Revision as of 09:24, 6 May 2019

A dbserver instance is a "shard", which is known to players as "a server" (Freedom, Defiant, etc). It performs several roles:

  • storing and retrieving containers in the database on behalf of some of the other servers
  • proxying messages between some other servers
  • coordinating player transfers
  • assorted random features that didn't have anywhere else to live

Despite the name, relatively little of dbserver's code is related to managing the database, and it is not the only server which has a database.

Services

dbserver listens on several ports, each one providing a different service. Most services correspond to another server which will connect to dbserver.

Details of the network protocols are on Dbserver-protocols

Containers

Containers are the fundamental abstraction of objects stored in dbserver. Some containers are stored in the sql database, some are held only in ram, and some are loaded from static data files. Every object is represented by a container, which has a type, a struct representation in dbserver, and either a list of values (for containers that have a template schema) or a data string (for schemaless containers).

Containers are organised into DbLists, with one list of each ContainerType. The network protocol routinely refers to a list_id to identify the type of container. Within each DbList, every container has a unique ID that is used to identify it.

There is a common text format for all containers. This is used in the data string for the ram-only containers, in the flat file storage that is used to load values into the database (from server/db/*.db files), and in the network protocol for sending containers to other servers.

An sql-backed container will have a template, described in server/db/templates. The template gives the names of columns, and their SQL types. The list of values precisely matches the set of columns stored in the database. The struct representation of a container contains a copy of some of these values (for when dbserver needs to interact with the contents), and all non-persisted runtime data (locks, notifications, load/unload status, etc).

All of the structs are subtypes of DbContainer. Containers which only have a list of values will be represented by DbContainer directly - these typically represent data which dbserver stores for other servers, but does not interact with. Some notable container types are:

  • Ents are player characters, represented by EntCon. They have a template, so are stored in SQL.
  • maps are static map data, represented by MapCon. They have no template, and are not persisted: dbserver loads them on startup from server/db/maps.db
  • Teamups, Supergroups, Taskforces, MapGroups, and Leagues contain lists of other containers, represented by GroupCon. All of them have templates, but Teamups and Leagues are not persisted to SQL: they are held only in ram and discarded when dbserver restarts. The other groups are stored in SQL.

Teamups and Leagues will not be written to the database, and will be deleted if present.

Some basic foreign key constraints exist on the GroupCon types, but containers do not resemble a relational database. They are usually read and written as an atomic unit, and are an attempt at producing the behaviour of a semi-structed key-value store using an SQL database. There is no transactional behaviour, and the dbserver acts as a write-back cache: it holds data in ram and will lose data if it crashes. There are multiple workers running SQL commands, and they will run the commands in any order, except when a barrier is used (via sqlFifoBarrier) which causes all commands before the barrier to complete before any commands after the barrier are run.

Some operations in dbserver additionally perform blocking or non-blocking database operations using custom SQL, mostly to find particular rows. AccountServer interactions are notable for doing this on the AccSvrLock field.

A container can be loaded into ram, or unloaded when not in use. For most containers, anything that relates to a logged-in player will be loaded when the player first connects, and unloaded when the player disconnects. The database is accessed when loading containers into ram, and to persist changes after they have been applied to containers in ram.

A container can be locked by another server. The lock is associated with the link to that server, and is released if the link is disconnected. Only one link may lock a container at a time, and updates can only be applied to a container by a server which has locked that container. This means that only one server can be writing to any container at a time.

Containers are sent to servers in the DBSERVER_CONTAINERS message. This can be at the request of the server sending a DBCLIENT_REQ_CONTAINERS message, or on various occasions when dbserver needs to notify another server of the creation or modification of some containers. This message can also be used to lock the containers, so that a subsequent DBCLIENT_SET_CONTAINERS message can send updates. Updates to containers can be sent as a completely new copy of the container, but are more commonly sent as a diff, which contains only the rows that have been changed. Other servers maintain a cache of the container contents that they received from dbserver, and diff their updated version against the original in order to send only the changes.

Command line arguments

-logserver

Start the dbserver as a logserver instead. (This also happens if the executable name is "logserver".)

-noencrypt

Disable encryption between the client and dbserver.

-productionmode

Enable production mode/disable development mode. Document production mode.

-startall

Start all static non-DontAutoStart maps automatically on startup.

-start <n>

Start up to n static maps on startup.

-verbose

Enable verbose logging.

-testcleanshutdown [n]

Run a database shutdown test on the n first containers and then exit. n is 100 by default.

-perfbench

Run a performance benchmark and then exit.

-perfload [n]

Run a load test of n runs on the database and then exit. n is 0 by default.

-perfdup [n]

Run a duplication test of n runs on the database and then exit. n is 0 by default.

-perfupdate [n]

Run an update test of n runs on the database and then exit. n is 0 by default.

-flattosql

Load the on-disk flat format (.defs or .bins) of Ents, Supergroups, Teamups and Leagues to the database, then exit. Only works in development mode.

-sqltoflat

Dump the database containers of Ents, Supergroups, Teamups and Leagues to the on-disk format, then exit. Only works in development mode.

-importdump <dumpfile> [mappingfile brokenfile progressfile splitnames]

Load a dump file. Defaults:

  • mappingfile: conids.map
  • brokenfile: links.bk
  • progressfile: progress.txt
  • splitnames: 0

-fiximport [mappingfile brokenfile progressfile]

Revisit DB (after import?) and fix broken links. Defaults:

  • mappingfile: conids.map
  • brokenfile: links.bk
  • progressfile: progress.txt

-exportdump <dumpfile>

Export a dump file.

-packetdebug

Enable packet debug info (data type and length). Enabled by default if the build is FULLDEBUG, disabled otherwise.

-memlogecho

Echo logs for the generic memlog instance to the console.

-cod

Pass the -cod option to mapservers launched via the launchers connected to this dbserver.