diff options
author | Michael Cahill <michael.cahill@mongodb.com> | 2015-10-19 16:31:47 +1100 |
---|---|---|
committer | David Hows <howsdav@gmail.com> | 2015-12-23 14:19:15 +1100 |
commit | deadcdaf1bfe3ba73243e1b5f1a83b3af80deb91 (patch) | |
tree | b0f0dcd0d661b84dd593384da85407cce74067bb | |
parent | 27d0cbdf8046565dba6902f4e6ee93b2642f0d19 (diff) | |
download | mongo-deadcdaf1bfe3ba73243e1b5f1a83b3af80deb91.tar.gz |
Merge pull request #2256 from wiredtiger/stat-fast-no-table-lock
(cherry picked from commit 497b744d6)
WT-2174 Backport - Enhance size statistics to not wait for the table lock
-rw-r--r-- | src/schema/schema_stat.c | 68 |
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( |