Skip to content

surreal db

/

CLI commands

upgrade-check

The upgrade-check command checks a 3.3 datastore before it moves to 4.0. It lists the stored definitions and records that 4.0 refuses, fails on or treats differently, each with a severity, the effect on 4.0, a fix and a link to the upgrade guide. The check only reads, and never runs a stored definition, so it is safe to run against a production server.

The command belongs to the 3.3 release line of the database and is not part of 4.0, because the check has to run while the datastore can still go back to 3.3. Upgrade to the latest 3.3 release to get it. If the default database component is already 4.0, run the 3.3 one with +3, as in surreal +3 db upgrade-check. See Version names.

Usage
surreal db upgrade-check [OPTIONS]

Options

NameDefaultEnvironment variableDescription
--endpoint, -e<ENDPOINT>
ws://localhost:8000NoneThe server to check, or the path of a stopped datastore, such as surrealkv://path/to/data or rocksdb://path/to/data.
--username, -u<USERNAME>
NoneSURREAL_USERUsername to sign in with. Also accepted as --user.
--password, -p<PASSWORD>
NoneSURREAL_PASSPassword to sign in with. Also accepted as --pass.
--token, -t<TOKEN>
NoneSURREAL_TOKENToken to authenticate with, instead of a username and password.
--auth-level<AUTH_LEVEL>
rootSURREAL_AUTH_LEVELLevel the user is defined on: root, namespace or database. A namespace user needs --namespace, and a database user needs --namespace and --database.
--namespace<NAMESPACE>
NoneSURREAL_NAMESPACECheck one namespace only. Also accepted as --ns.
--database<DATABASE>
NoneSURREAL_DATABASECheck one database of the namespace only. Needs --namespace. Also accepted as --db.
--json
NoneNonePrint the report as JSON, in the shape the /upgrade-check HTTP route returns.
--scan-records[ROWS]
NoneNoneAlso read up to ROWS records of each table, to find problems in records as well as in definitions. Without a value, reads up to 1000. Off by default.
--scan-total<ROWS>
NoneNoneWith --scan-records, the most records read across all tables. The server's default is 100,000.
--scan-seconds<SECONDS>
NoneNoneWith --scan-records, the longest time the record scan runs. The server's default is 30.
--client-side
NoneNoneRead the definitions with INFO statements and run the check in the command, instead of asking the server to run it.
--log, -l<LOG>
infoSURREAL_LOGThe logging level for the command-line tool. Possible values: none, full, error, warn, info, debug, trace.

To check every namespace of a running server, sign in as a root user:

surreal db upgrade-check --endpoint http://localhost:8000 --username root --password secret

Each finding gives its location, the reason, the rule that found it, what 4.0 does, the fix and a link. The last line gives the verdict and the counts. The report below comes from a database with a view whose FROM names its own table and an index on a datetime field:

Sample output
[BLOCKING] shop/main table agg: view agg reads FROM its own table (view-reads-own-table)
    4.0:  Every write to a table the view reads fails with `Cannot maintain the view: it reads itself`.
    fix:  Define the view again with DEFINE TABLE OVERWRITE over the tables other than its own, or remove it.
    docs: https://surrealdb.com/docs/build/migrating/from-old-surrealdb-versions/3x-to-4x#views-that-read-their-own-table
[warning] shop/main table ev ev_at: index keys at, which is typed datetime (index-on-datetime)
    4.0:  An index built by 3.x keeps the text order of datetimes, in which a whole second sorts after its fractions, so ORDER BY and ranges over the field can return records out of order or leave some out.
    fix:  Run REBUILD INDEX on this index once every node runs 4.0.
    docs: https://surrealdb.com/docs/build/migrating/from-old-surrealdb-versions/3x-to-4x#datetimes-in-an-index
Not detectable from stored state:
  - 4.0 refuses CBOR tags 0, 9 and 13 (datetimes, UUIDs and durations as text), which some SDK releases send. Upgrade every SDK to a release that supports 4.0 before upgrading the server. (https://surrealdb.com/docs/build/migrating/from-old-surrealdb-versions/3x-to-4x#cbor-text-forms-of-datetimes-uuids-and-durations)
  - The 3.x Rust SDK, the SDKs built on it and JavaScript SDK releases before 2.1 refuse a 4.0 server. The 4.0 SDKs connect to 3.x servers as well, so upgrade the SDKs first. (https://surrealdb.com/docs/build/migrating/from-old-surrealdb-versions/3x-to-4x#sdk-version-checks)
  - Schema scripts, not stored definitions: 4.0 refuses a clause repeated in DEFINE TABLE, a DEFINE INDEX with two kinds, and a dec literal with more than 28 decimal places. The stored form of each is unaffected. (https://surrealdb.com/docs/build/migrating/from-old-surrealdb-versions/3x-to-4x#a-clause-repeated-in-define-table)
  - Queries sent by applications are not stored, so the check cannot see them. Read the behaviour changes, such as results without ORDER BY and float to decimal comparisons. (https://surrealdb.com/docs/build/migrating/from-old-surrealdb-versions/3x-to-4x#behaviour-changes)
Verdict: blocking. 1 namespace(s), 1 database(s), 5 definition(s): 1 blocking, 1 warning(s), 0 info, 0 unreadable scope(s). Checked by 3.3.6.

The notes at the end are in every report. They name changes that the stored state cannot show, such as the queries an application sends.

To check one database with a database user, and to read up to 500 records of each table as well:

surreal db upgrade-check -e http://localhost:8000 -u app -p hunter123 --auth-level database --ns shop --db main --scan-records 500

To check a datastore with no server running, give its path. The command opens the datastore itself and runs the check as the root owner, so stop the server first:

surreal db upgrade-check --endpoint surrealkv://path/to/data

The command reaches the same rules in three ways:

EndpointHow the check runs
http://, https://, ws:// or wss://The command calls the server's /upgrade-check route with your credentials, and the server reads its own catalog.
A server without the /upgrade-check route, or --client-sideA server from an earlier 3.3 release answers the route with 404, and the command then reads each definition with INFO statements, and records with SELECT, and runs the check itself. The report's checked_by ends with (client-side, through INFO).
A local path, such as surrealkv:// or rocksdb://The command opens the datastore in its own process.

Over a gRPC endpoint, the command always uses INFO statements, because the route is served over HTTP only.

The check covers the scope of the user who signs in. A root user sees every namespace, and the report names the storage engine only for a root user. A namespace or database user sees only its own namespace or database, and naming another one with --namespace or --database is refused. A record user is refused.

Every finding has one of three severities:

SeverityMeaning
blocking4.0 refuses or fails on this definition or record, so change it before the upgrade.
warning4.0 keeps working, but gives different results or needs an action, such as REBUILD INDEX, a change to a schema script, or room on the disk.
infoNo action is needed.

The verdict is blocking when there is a blocking finding, needs changes (needs_changes in JSON) when there is a warning, and compatible otherwise. The command exits with a non-zero status when the verdict is blocking, or when it could not read a namespace, a database or a table, so a script can stop before the upgrade:

Error output
1 blocking issue(s) found; resolve them before upgrading to 4.0

The rules, and what each finds, are listed under Checking a datastore before the upgrade.

Most rules read definitions only. Two rules read records, record-table-value and record-not-object, so they run only with --scan-records. The server limits the scan to 1,000,000 records of each table, 10,000,000 records in all and 600 seconds, whatever the options ask for. When a limit stops the scan, the summary line says (scan cut short by its budget), and the JSON report has "complete": false.

Was this page helpful?