Docs / EventSourcingDB / API / restore-backup

restore-backup

Restores a backup into an empty database: a full backup followed by its increments, or a backup that the v1 API created.

  • Route: POST /api/v2/management/restore-backup
  • Category: management
  • Authentication: required, with the API token
  • Answer: a stream of NDJSON

A restore only goes into a database that holds no events and no schemas, so it takes the full backup and all of its increments in one request: once the full backup is restored, the database is no longer empty. It checks every part, schema, and event of the backup as it reads it, and until it is over, the database refuses reads and writes. If it fails, it removes what it restored so far, so that the database is empty again. Backup and Restore explains the background, including which versions restore which backups.

Request#

The body is a stream of NDJSON, with the content type application/x-ndjson, and has no limit on its size, while each of its lines may hold at most 601 KiB, not counting its newline, which is more than any item of a backup takes, see Limits. It holds either:

  • a full backup followed by its increments, each exactly as create-backup sent it, in the order in which they were created, or
  • a backup that the v1 API created, on its own, with its schema, event, and error lines, each with a payload.

In a backup of the v2 API, each part is made of these items, one per line:

Type Meaning
backup Begins a part. Its formatVersion has to be 2. Its lastBackedUpEvent has to be null for the first part, which is the full backup, and has to name the event the part before it ended at for every further part.
eventSchema A schema, checked as registering a schema checks it. The schemas of a part come before its events. Every part brings every schema again, and the same schema is taken once.
event An event, checked value by value as writing events checks it, against the chain of hashes of the events before it, against the clock of the server, and against the schema of its type.
lastBackedUpEvent Skipped, since the event a part ended at follows from its events.
heartbeat Skipped, wherever it stands.
error Marks a part whose creation failed, which the restore refuses.
end Ends a part. Every part needs it.

In a backup of the v1 API, the schemas come before the events as well, and there is no end line to check for. The v1 API backs up an empty database as an empty body, so the restore takes an empty body for such a backup and restores nothing: the database stays empty, and the answer is the end item alone. A backup that is empty by mistake, for example because the job that created it failed, looks the same, so check that a backup holds what you expect before you restore it.

Send the parts one after the other, without anything between them, and with --data-binary, which keeps their line breaks: -d removes them, and the restore then refuses the body as malformed. To restore a full backup and two increments:

cat full-backup.ndjson increment-1.ndjson increment-2.ndjson \
  | curl \
      -X POST \
      -H "authorization: Bearer secret" \
      -H "content-type: application/x-ndjson" \
      --data-binary @- \
      http://localhost:3000/api/v2/management/restore-backup

Answer#

The answer is a stream of items, one per line, which tells the outcome of the restore:

Type Data When
error code, description, and details When the backup cannot be restored, see Errors.
heartbeat empty Once the whole backup has been read, while nothing else is sent for a while and the restore still runs.
end empty Once, as the last item, when the stream ends cleanly. Without an error item before it, the backup was restored.

Heartbeats and the end item work as on every stream of the API, see Streams, with one difference: a restore sends heartbeats only once it has read the whole backup. While the backup is still being sent, the data of the client keeps the connection alive.

A client that goes away while it sends the backup breaks off reading it, which fails the restore, as backup-unreadable describes. Once the whole backup has been read, though, the restore runs to its end even if its client is gone.

A restore that succeeds is answered with the end item alone:

{"type":"end","data":{}}

Errors#

The restore reports these errors as an error item, followed by the end item. After any of them, the database is as it was before the restore, since a restore that has begun removes what it restored so far:

  • license-invalid: The license expired while the server ran. It is checked before any line of the backup.
  • backup-unreadable: Reading the body broke off, because the connection dropped or the client sent nothing for more than five seconds.
  • backup-malformed: A line is not an item that a backup holds at its place, such as an empty line, a schema after an event, a part that begins before the one before it has ended, or an event without a subject. This includes a line that is longer than any item of a backup can be, and a schema that takes more as a backup writes it than any schema of a backup can.
  • backup-format-unknown: A backup item names a formatVersion other than 2, or none, as in a backup that a newer version created.
  • full-backup-missing: The body begins with an increment rather than with a full backup.
  • backup-increment-disconnected: An increment does not follow on the event the part before it ended at, as when an increment is missing, sent twice, or out of order.
  • backup-incomplete: The body ends while a part of a backup of the v2 API is still open, without its end item. A part without its end item that another part follows is reported as backup-malformed instead.
  • backup-failed: A part holds an error item, or a backup of the v1 API an error line, since creating it failed.
  • event-schema-malformed: A schema of the backup is not a valid JSON Schema, or holds a number with more than 1,000 digits before or after its decimal point.
  • event-schema-not-object: A schema of the backup does not describe an object.
  • event-schema-too-complex: A schema of the backup refers back to a part of itself, or reaches more than 10,000 subschemas, counting a referenced one each time it is referenced.
  • event-schema-already-registered: The backup brings two different schemas for the same event type.
  • store-not-empty: The database holds events or schemas. This is checked before the first line of the backup is read.
  • event-chain-broken: An event of the backup does not follow on the one before it, or does not match its hash.
  • event-hash-version-unknown: An event of the backup has a hash of a version that this version does not know, as one that a newer version wrote.
  • backup-ahead-of-clock: An event of the backup lies more than an hour beyond the clock of the server, such as one dated 9999-12-31. The same backup restores once the clock has caught up.
  • event-too-large: An event of the backup is larger than the maximum event size.
  • subject-too-long: The subject of an event of the backup is longer than 1,024 characters.
  • subject-too-deep: The subject of an event of the backup has more than 32 segments.
  • event-schema-violated: An event of the backup does not match the schema that the backup holds for its type.
  • event-schema-unregistered: The server runs with --require-event-schemas, and an event of the backup has a type for which the backup holds no schema before it.
  • capacity-exceeded: The backup holds more events than the license permits.
  • indexes-rebuilding: The indexes are still being rebuilt after an upgrade, which a restore needs complete to tell whether the database is empty.
  • store-read-only: The database is in read-only mode.
  • disk-full: The disk is almost full, so the database refuses writes.
  • restore-in-progress: Another restore is running.
  • file-unreadable: A file of the store that the restore needs is damaged, such as an events file whose checksum no longer matches.
  • store-failed: The store refuses writes after a failure to store one, or reads and writes after a restore that could not empty it again.
  • server-shutting-down: The server began to shut down after the restore had sent a heartbeat. Before that, the server answers with 503 instead.

Status Codes#

Before the stream begins, the server answers with a status code other than 200 where it cannot take the request at all, as described in Errors:

  • 400: The content type of the body is not application/x-ndjson.
  • 401: The API token is missing or wrong.
  • 429: Too many requests were sent; the answer says when to try again.
  • 500: The server failed unexpectedly before the stream began, for example because a restore that failed could not empty the database again. Once the stream has begun, it breaks off without its end item instead.
  • 503: The server is shutting down, or began to shut down before the stream began, which includes the whole time the backup is being sent.