Version 10.0.0
Performance monitoring with statistics

WiredTiger optionally maintains a variety of statistics, when the statistics configuration string is specified to wiredtiger_open; see Statistics for general information about statistics, and Statistics Data for information about accessing the statistics.

Note that maintaining run-time statistics involves updating shared-memory data structures and may decrease application performance.

The statistics gathered by WiredTiger can be combined to derive information about the system's behavior. For example, a cursor can be opened on the statistics for a table:

error_check(session->open_cursor(session, "statistics:table:access", NULL, NULL, &cursor));

Then this code calculates the "fragmentation" of a table, defined here as the percentage of the table that is not part of the current checkpoint:

int64_t ckpt_size, file_size, percent;
get_stat(cursor, WT_STAT_DSRC_BLOCK_CHECKPOINT_SIZE, &ckpt_size);
get_stat(cursor, WT_STAT_DSRC_BLOCK_SIZE, &file_size);
percent = 0;
if (file_size != 0)
percent = 100 * ((file_size - ckpt_size) / file_size);
printf("Table is %" PRId64 "%% fragmented\n", percent);

The following example calculates the "write amplification", defined here as the ratio of bytes written to the filesystem versus the total bytes inserted, updated and removed by the application.

int64_t app_insert, app_remove, app_update, fs_writes;
get_stat(cursor, WT_STAT_DSRC_CURSOR_INSERT_BYTES, &app_insert);
get_stat(cursor, WT_STAT_DSRC_CURSOR_REMOVE_BYTES, &app_remove);
get_stat(cursor, WT_STAT_DSRC_CURSOR_UPDATE_BYTES, &app_update);
get_stat(cursor, WT_STAT_DSRC_CACHE_BYTES_WRITE, &fs_writes);
if (app_insert + app_remove + app_update != 0)
printf("Write amplification is %.2lf\n",
(double)fs_writes / (app_insert + app_remove + app_update));

Both examples use this helper function to retrieve statistics values from a cursor:

void
get_stat(WT_CURSOR *cursor, int stat_field, int64_t *valuep)
{
const char *desc, *pvalue;
cursor->set_key(cursor, stat_field);
error_check(cursor->search(cursor));
error_check(cursor->get_value(cursor, &desc, &pvalue, valuep));
}