summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/schema/schema_stat.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/schema/schema_stat.c b/src/schema/schema_stat.c
index df8e23eb604..dba1dfe5f55 100644
--- a/src/schema/schema_stat.c
+++ b/src/schema/schema_stat.c
@@ -53,6 +53,63 @@ err: __wt_scr_free(session, &buf);
}
/*
+ * __curstat_size_only --
+ * For very simple tables we can avoid getting table handles if
+ * configured to only retrieve the size. It's worthwhile because
+ * workloads that create and drop a lot of tables can put a lot of
+ * pressure on the table list lock.
+ */
+static int
+__curstat_size_only(WT_SESSION_IMPL *session,
+ const char *uri, bool *was_fast,WT_CURSOR_STAT *cst)
+{
+ WT_CONFIG cparser;
+ WT_CONFIG_ITEM ckey, colconf, cval;
+ WT_DECL_RET;
+ WT_ITEM namebuf;
+ wt_off_t filesize;
+ char *tableconf;
+
+ WT_CLEAR(namebuf);
+ *was_fast = false;
+
+ /* Retrieve the metadata for this table. */
+ WT_RET(__wt_metadata_search(session, uri, &tableconf));
+
+ /*
+ * The fast path only works if the table consists of a single file
+ * and does not have any indexes. The absence of named columns is how
+ * we determine that neither of those conditions can be satisfied.
+ */
+ WT_ERR(__wt_config_getones(session, tableconf, "columns", &colconf));
+ WT_ERR(__wt_config_subinit(session, &cparser, &colconf));
+ if ((ret = __wt_config_next(&cparser, &ckey, &cval)) == 0)
+ goto err;
+
+ /* Build up the file name from the table URI. */
+ WT_ERR(__wt_buf_fmt(
+ session, &namebuf, "%s.wt", uri + strlen("table:")));
+ /*
+ * Get the size of the underlying file. There is nothing stopping a
+ * race with schema level table operations (for example drop) if there
+ * is a race there will be an error message generated.
+ */
+ WT_ERR(__wt_filesize_name(session, namebuf.data, &filesize));
+
+ /* Setup and populate the statistics structure */
+ __wt_stat_init_dsrc_stats(&cst->u.dsrc_stats);
+ WT_STAT_SET(&cst->u.dsrc_stats, block_size, filesize);
+ __wt_curstat_dsrc_final(cst);
+
+ *was_fast = true;
+
+err: __wt_free(session, tableconf);
+ __wt_buf_free(session, &namebuf);
+
+ return (ret);
+}
+
+/*
* __wt_curstat_table_init --
* Initialize the statistics for a table.
*/
@@ -67,6 +124,17 @@ __wt_curstat_table_init(WT_SESSION_IMPL *session,
WT_TABLE *table;
u_int i;
const char *name;
+ bool was_fast;
+
+ /*
+ * If only gathering table size statistics, try a fast path that
+ * avoids the schema and table list locks.
+ */
+ if (F_ISSET(cst, WT_CONN_STAT_SIZE)) {
+ WT_RET(__curstat_size_only(session, uri, &was_fast, cst));
+ if (was_fast)
+ return (0);
+ }
name = uri + strlen("table:");
WT_RET(__wt_schema_get_table(