@SnapshotSave

Documentation

VoltDB Home » Documentation » Using VoltDB

@SnapshotSave

@SnapshotSave — Saves the current database contents to disk.

Synopsis

@SnapshotSave String directory-path, String unique-ID, Integer blocking-flag

@SnapshotSave String json-encoded-options

@SnapshotSave

Description

The @SnapshotSave system procedure saves the contents of the current in-memory database to disk. Each node of the database cluster saves its portion of the database locally.

There are three forms of the @SnapshotSave stored procedure: a procedure call with individual argument parameters, with all arguments in a single JSON-encoded string, or with no arguments. When you specify the arguments as individual parameters, VoltDB creates a native mode snapshot that can be used to recover or restore the database. When you specify the arguments as a JSON-encoded string, you can request a different format for the snapshot, including CSV (comma-separated value) files that can be used for import into other databases or utilities. When you specify no arguments a full, native snapshot is saved into the default snapshots directory in the database root directory.

Individual Arguments

When you specify the arguments as individual parameters, you must specify three arguments:

  1. The directory path where the snapshot files are stored

  2. An identifier that is included in the file names to uniquely identify the files that make up a single snapshot

  3. A flag value indicating whether the snapshot should block other transactions until it is complete or not

The resulting snapshot consists of multiple files saved to the directory specified by directory-path using unique-ID as a filename prefix. The third argument, blocking-flag, specifies whether the save is performed synchronously (thereby blocking any following transactions until the save completes) or asynchronously. If this parameter is set to any non-zero value, the save operation will block any following transactions. If it is zero, others transactions will be executed in parallel.

The files created using this invocation are in native VoltDB snapshot format and can be used to restore or recover the database at some later time. This is the same format used for automatic snapshots. See Chapter 13, Saving & Restoring a VoltDB Database for more information about saving and restoring VoltDB databases.

JSON-Encoded Arguments

When you specify the arguments as a JSON-encoded string, you can specify what snapshot format you want to create. Table G.1, “@SnapshotSave Options” describes all possible options when creating a snapshot using JSON-encoded arguments.

Table G.1. @SnapshotSave Options

OptionDescription
uripathSpecifies the path where the snapshot files are created. Note that, as a JSON-encoded argument, the path must be specified as a URI, not just a system directory path. Therefore, a local directory must be specified using the file:// identifier, such as "file:///tmp", and the path must exist on all nodes of the cluster.
nonceSpecifies the unique identifier for the snapshot.
blockSpecifies whether the snapshot should be synchronous (true) and block other transactions or asynchronous (false).
format

Specifies the format of the snapshot. Valid formats are "csv" and "native".

When you save a snapshot in CSV format, the resulting files are in standard comma-separated value format, with only one file for each table. In other words, duplicates (from replicated tables or duplicate partitions due to K-safety) are eliminated. CSV formatted snapshots are useful for import or reuse by other databases or utilities. However, they cannot be used to restore or recover a VoltDB database.

When you save a snapshot in native format, each node and partition saves its contents to separate files. These files can then be used to restore or recover the database. It is also possible to later convert native format snapshots to CSV using the snapshot utilities described in the VoltDB Administrator's Guide.

skiptables

Specifies tables to leave out of the snapshot. Use of tables or skiptables allows you to create a partial snapshot of the larger database. Specify the list of tables as a JSON array. For example, the following JSON argument excludes the Areacode and Country tables from the snapshot:

"skiptables":["areacode","country"]
tables

Specifies tables to include in the snapshot. Use of tables or skiptables allows you to create a partial snapshot of the larger database. Specify the list of tables as a JSON array. For example, the following JSON argument includes only the Employee and Company tables in the snapshot:

"tables":["employee","company"]

For example, the JSON-encoded arguments to synchronously save a CSV formatted snapshot to /tmp using the unique identifier "mydb" is the following:

{uripath:"file:///tmp",nonce:"mydb",block:true,format:"csv"}

The block and format arguments are optional. If you do not specify them they default to block:false and format:"native". The arguments uripath and nonce are required. The tables and skiptables arguments are mutually exclusive.

Because the unique identifier is used in the resulting filenames, the identifier can contain only characters that are valid for Linux file names. In addition, hyphens ("-") and commas (",") are not permitted.

Note that it is normal to perform manual saves synchronously, to ensure the snapshot represents a known state of the database. However, automatic snapshots are performed asynchronously to reduce the impact on ongoing database activity.

Return Values

The @SnapshotSave system procedure returns two different VoltTables, depending on the outcome of the request.

Option #1: one VoltTable with a row for every execution site. (That is, the number of hosts multiplied by the number of sites per host.).

NameDatatypeDescription
HOST_IDINTEGERNumeric ID for the host node.
HOSTNAMESTRINGServer name of the host node.
SITE_IDINTEGERNumeric ID of the execution site on the host node.
RESULTSTRINGString value indicating the success ("SUCCESS") or failure ("FAILURE") of the request.
ERR_MSGSTRINGIf the result is FAILURE, this column contains a message explaining the cause of the failure.

Option #2: one VoltTable with a variable number of rows.

NameDatatypeDescription
HOST_IDINTEGERNumeric ID for the host node.
HOSTNAMESTRINGServer name of the host node.
TABLESTRINGThe name of the database table. The contents of each table is saved to a separate file. Therefore it is possible for the snapshot of each table to succeed or fail independently.
RESULTSTRINGString value indicating the success ("SUCCESS") or failure ("FAILURE") of the request.
ERR_MSGSTRINGIf the result is FAILURE, this column contains a message explaining the cause of the failure.

Examples

The following example uses @SnapshotSave to save the current database content in native snapshot format to the path /tmp/voltdb/backup/ using the unique identifier flight on each node of the cluster.

$ sqlcmd
1> exec @SnapshotSave '/tmp/voltdb/backup/', 'flight', 1;

Alternately, you can use the voltadmin save command to perform the same function. When using the voltadmin save command, you use the --blocking flag instead of a third parameter to request a blocking save:

$ voltadmin save --blocking /tmp/voltdb/backup/ flight 

Note that the procedure call will return successfully even if the save was not entirely successful. The information returned in the VoltTable array tells you what parts of the operation were successful or not. For example, save may succeed on one node but not on another.

The following code sample performs the same function, but also checks the return values and notifies the operator when portions of the save operation are not successful.

VoltTable[] results = null;

try { results = client.callProcedure("@SnapshotSave",
                                     "/tmp/voltdb/backup/",
                                     "flight", 1).getResults(); }
catch (Exception e) { e.printStackTrace(); }

for (int table=0; table<results.length; table++) {
    for (int r=0;r<results[table].getRowCount();r++) {
        VoltTableRow row = results[table].fetchRow(r);
        if (row.getString("RESULT").compareTo("SUCCESS") != 0) {
            System.out.printf("Site %s failed to write " +
                   "table %s because %s.\n",
                   row.getString("HOSTNAME"), row.getString("TABLE"),
                   row.getString("ERR_MSG"));
        }
    }
}