Version 2.0.1
Cursors

Common operations in WiredTiger are performed using WT_CURSOR handles.

A cursor includes:

  • a position within a data source
  • getter/setters for key and value fields
  • encoding of fields to store in the data source
  • methods to navigate within and iterate through the data

See Cursor operations for a description of how to use cursors.

Cursors and Transactions

If there is a transaction active in a session, cursors operate in the context of that transaction. Reads performed while a transaction is active inherit the isolation level of the transaction, and updates performed within a transaction are made durable by calling WT_SESSION::commit_transaction, or discarded by calling WT_SESSION::rollback_transaction.

If no transaction is active, cursor reads are performed at the isolation level of the session, set with the isolation configuration key to WT_CONNECTION::open_session and successful updates are automatically committed before the update operation completes.

Any operation that consists of multiple related updates should be enclosed in an explicit transaction to ensure that the updates are applied atomically.

At read-committed (the default) or snapshot isolation levels, committed changes from concurrent transactions become visible when no cursor is positioned. In other words, at these isolation levels, all cursors in a session read from a stable snapshot while any cursor in the session remains positioned.

Cursor positions do not survive transaction boundaries. When a transaction is started with the WT_SESSION::begin_transaction or ended with either WT_SESSION::commit_transaction or WT_SESSION::rollback_transaction, all open cursors are reset, as if the WT_CURSOR::reset method was called. The cursor reset discards any cursor position as well as the key and value.

Applications that need to continue an operation across a transaction boundary must make a copy of the cursor's key, and re-position the cursor with WT_CURSOR::search to continue the operation, dealing with cases where the record may no longer be available due to a WT_CURSOR::remove or WT_SESSION::rollback_transaction.

See Transactions for more information.

Cursor types

The following are some of the common builtin cursor types:

URITypeNotes
backup:hot backup cursorSee also: Hot backup
colgroup:<table name>:<column group name>column group cursor
index:<table name>:<index name>index cursor (key=index key, value=table value)
metadata:metadata cursorSee also: Reading WiredTiger Metadata
statistics:[<data source URI>]database or file statistics (key=(int), value=(string)description, (string)value, (uint64_t)value)
table:<table name>table cursor (key=table key, value=table value)

It is also possible to open cursors on the following low-level types:

file:<file name>file cursor (key=file key, value=file value)
lsm:<name>LSM cursor (key=LSM key, value=LSM value)See also: Log-Structured Merge Trees

See Data Sources for the full list.

Projections

Cursors on tables and indices can return a subset of columns. This is done by listing the column names in parenthesis in the uri parameter to WT_SESSION::open_cursor. Only the fields from the listed columns are returned by WT_CURSOR::get_value.

The ex_schema.c example creates a table where the value format is "5sHq", where the initial string is the country, the short is a year, and the long is a population. The following example lists just the country and year columns from the table record values:

/*
* Use a projection to return just the table's country and year
* columns.
*/
ret = session->open_cursor(session,
"table:poptable(country,year)", NULL, NULL, &cursor);
while ((ret = cursor->next(cursor)) == 0) {
ret = cursor->get_value(cursor, &country, &year);
printf("country %s, year %u\n", country, year);
}

This is particularly useful with index cursors, because if all columns in the projection are available in the index (including primary key columns, which are the values of the index), the data can be read from the index without accessing any column groups. See Index cursor projections for more information.

Raw mode

Cursors can be configured for raw mode by specifying the "raw" config keyword to WT_SESSION::open_cursor. In this mode, the methods WT_CURSOR::get_key, WT_CURSOR::get_value, WT_CURSOR::set_key and WT_CURSOR::set_value all take a single WT_ITEM in the variable-length argument list instead of a separate argument for each column.

WT_ITEM structures do not need to be cleared before use.

For WT_CURSOR::get_key and WT_CURSOR::get_value in raw mode, the WT_ITEM can be split into columns by calling WT_EXTENSION_API::struct_unpack with the cursor's key_format or value_format, respectively. For WT_CURSOR::set_key and WT_CURSOR::set_value in raw mode, the WT_ITEM should be equivalent to calling WT_EXTENSION_API::struct_pack for the cursor's key_format or value_format, respectively.

The ex_schema.c example creates a table where the value format is "5sHq", where the initial string is the country, the short is a year, and the long is a population. The following example lists the table record values, using raw mode:

/* List the records in the table using raw mode. */
ret = session->open_cursor(session,
"table:poptable", NULL, "raw", &cursor);
while ((ret = cursor->next(cursor)) == 0) {
WT_ITEM key, value;
ret = cursor->get_key(cursor, &key);
ret = wiredtiger_struct_unpack(session,
key.data, key.size, "r", &recno);
printf("ID %" PRIu64, recno);
ret = cursor->get_value(cursor, &value);
ret = wiredtiger_struct_unpack(session,
value.data, value.size,
"5sHQ", &country, &year, &population);
printf(": country %s, year %u, population %" PRIu64 "\n",
country, year, population);
}

Raw mode can be used in combination with projections. The following example lists just the country and year columns from the table record values, using raw mode:

/*
* Use a projection to return just the table's country and year
* columns, using raw mode.
*/
ret = session->open_cursor(session,
"table:poptable(country,year)", NULL, "raw", &cursor);
while ((ret = cursor->next(cursor)) == 0) {
WT_ITEM value;
ret = cursor->get_value(cursor, &value);
session, value.data, value.size, "5sH", &country, &year);
printf("country %s, year %u\n", country, year);
}

Reading WiredTiger Metadata

WiredTiger cursors provide access to data from a variety of sources. One of these sources is the list of objects in the database.

To retrieve the list of database objects, open a cursor on the uri metadata:. Each returned key will be a database object and each returned value will be the information stored in the metadata for object named by the key.

For example:

ret = session->open_cursor(
session, "metadata:", NULL, NULL, &cursor);