Version 2.4.1
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:

if ((ret = session->open_cursor(session,
"statistics:table:access", NULL, NULL, &cursor)) != 0)
return (ret);

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:

uint64_t ckpt_size, file_size;
ret = get_stat(cursor, WT_STAT_DSRC_BLOCK_CHECKPOINT_SIZE, &ckpt_size);
ret = get_stat(cursor, WT_STAT_DSRC_BLOCK_SIZE, &file_size);
printf("File is %d%% fragmented\n",
(int)(100 * (file_size - ckpt_size) / file_size));

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.

uint64_t app_insert, app_remove, app_update, fs_writes;
ret = get_stat(cursor, WT_STAT_DSRC_CURSOR_INSERT_BYTES, &app_insert);
ret = get_stat(cursor, WT_STAT_DSRC_CURSOR_REMOVE_BYTES, &app_remove);
ret = get_stat(cursor, WT_STAT_DSRC_CURSOR_UPDATE_BYTES, &app_update);
ret = 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:

int
get_stat(WT_CURSOR *cursor, int stat_field, uint64_t *valuep)
{
const char *desc, *pvalue;
int ret;
cursor->set_key(cursor, stat_field);
if ((ret = cursor->search(cursor)) != 0)
return (ret);
return (cursor->get_value(cursor, &desc, &pvalue, valuep));
}