diff options
-rw-r--r-- | dist/stat.py | 16 | ||||
-rw-r--r-- | src/conn/conn_dhandle.c | 33 | ||||
-rw-r--r-- | src/conn/conn_handle.c | 3 | ||||
-rw-r--r-- | src/include/connection.h | 2 | ||||
-rw-r--r-- | src/include/dhandle.h | 2 | ||||
-rw-r--r-- | src/include/extern.h | 6 | ||||
-rw-r--r-- | src/include/meta.h | 5 | ||||
-rw-r--r-- | src/include/stat.h | 9 | ||||
-rw-r--r-- | src/support/stat.c | 32 |
9 files changed, 78 insertions, 30 deletions
diff --git a/dist/stat.py b/dist/stat.py index e42585c1b8c..d04a0514c49 100644 --- a/dist/stat.py +++ b/dist/stat.py @@ -138,15 +138,27 @@ __wt_stat_''' + name + '_init_single(WT_' + name.upper() + '''_STATS *stats) if handle != None: f.write(''' -void -__wt_stat_''' + name + '_init(' + handle + ''' *handle) +int +__wt_stat_''' + name + '''_init( + WT_SESSION_IMPL *session, ''' + handle + ''' *handle) { \tint i; +\tWT_RET(__wt_calloc(session, (size_t)WT_COUNTER_SLOTS, +\t sizeof(*handle->stat_array), &handle->stat_array)); + \tfor (i = 0; i < WT_COUNTER_SLOTS; ++i) { \t\thandle->stats[i] = &handle->stat_array[i]; \t\t__wt_stat_''' + name + '''_init_single(handle->stats[i]); \t} +\treturn (0); +} + +void +__wt_stat_''' + name + '''_discard( + WT_SESSION_IMPL *session, ''' + handle + ''' *handle) +{ +\t__wt_free(session, handle->stat_array); } ''') diff --git a/src/conn/conn_dhandle.c b/src/conn/conn_dhandle.c index ec850c793cc..30d901c9b64 100644 --- a/src/conn/conn_dhandle.c +++ b/src/conn/conn_dhandle.c @@ -20,6 +20,7 @@ __conn_dhandle_destroy(WT_SESSION_IMPL *session, WT_DATA_HANDLE *dhandle) __wt_free(session, dhandle->checkpoint); __wt_free(session, dhandle->handle); __wt_spin_destroy(session, &dhandle->close_lock); + __wt_stat_dsrc_discard(session, dhandle); __wt_overwrite_and_free(session, dhandle); } @@ -54,8 +55,6 @@ __conn_dhandle_alloc(WT_SESSION_IMPL *session, WT_ERR(__wt_spin_init( session, &dhandle->close_lock, "data handle close")); - __wt_stat_dsrc_init(dhandle); - if (strcmp(uri, WT_METAFILE_URI) == 0) F_SET(dhandle, WT_DHANDLE_IS_METADATA); @@ -310,16 +309,15 @@ __wt_conn_btree_open( WT_ASSERT(session, !F_ISSET(S2C(session), WT_CONN_CLOSING)); /* - * If the handle is already open, it has to be closed so it can - * be reopened with a new configuration. + * If the handle is already open, it has to be closed so it can be + * reopened with a new configuration. * - * This call can return EBUSY if there's an update in the - * object that's not yet globally visible. That's not a - * problem because it can only happen when we're switching from - * a normal handle to a "special" one, so we're returning EBUSY - * to an attempt to verify or do other special operations. The - * reverse won't happen because when the handle from a verify - * or other special operation is closed, there won't be updates + * This call can return EBUSY if there's an update in the object that's + * not yet globally visible. That's not a problem because it can only + * happen when we're switching from a normal handle to a "special" one, + * so we're returning EBUSY to an attempt to verify or do other special + * operations. The reverse won't happen because when the handle from a + * verify or other special operation is closed, there won't be updates * in the tree that can block the close. */ if (F_ISSET(dhandle, WT_DHANDLE_OPEN)) @@ -332,6 +330,16 @@ __wt_conn_btree_open( /* Set any special flags on the handle. */ F_SET(btree, LF_MASK(WT_BTREE_SPECIAL_FLAGS)); + /* + * Allocate data-source statistics memory. We don't allocate that memory + * when allocating the data-handle because not all data handles need + * statistics (for example, handles used for checkpoint locking). If we + * are reopening the handle, then it may already have statistics memory, + * check to avoid the leak. + */ + if (!F_ISSET(dhandle, WT_DHANDLE_OPEN)) + WT_ERR(__wt_stat_dsrc_init(session, dhandle)); + WT_ERR(__wt_btree_open(session, cfg)); /* @@ -554,8 +562,7 @@ __wt_conn_dhandle_discard_single( dhandle = session->dhandle; - if (F_ISSET(dhandle, WT_DHANDLE_OPEN) || - (final && F_ISSET(dhandle, WT_DHANDLE_DEAD))) { + if (F_ISSET(dhandle, WT_DHANDLE_OPEN)) { tret = __wt_conn_btree_sync_and_close(session, final, force); if (final && tret != 0) { __wt_err(session, tret, diff --git a/src/conn/conn_handle.c b/src/conn/conn_handle.c index 5104624523b..3571cc60115 100644 --- a/src/conn/conn_handle.c +++ b/src/conn/conn_handle.c @@ -48,7 +48,7 @@ __wt_connection_init(WT_CONNECTION_IMPL *conn) WT_RET(__wt_conn_config_init(session)); /* Statistics. */ - __wt_stat_connection_init(conn); + WT_RET(__wt_stat_connection_init(session, conn)); /* Spinlocks. */ WT_RET(__wt_spin_init(session, &conn->api_lock, "api")); @@ -161,6 +161,7 @@ __wt_connection_destroy(WT_CONNECTION_IMPL *conn) __wt_free(session, conn->home); __wt_free(session, conn->error_prefix); __wt_free(session, conn->sessions); + __wt_stat_connection_discard(session, conn); __wt_free(NULL, conn); return (ret); diff --git a/src/include/connection.h b/src/include/connection.h index 88c672ea49b..4e8e88bf6e4 100644 --- a/src/include/connection.h +++ b/src/include/connection.h @@ -290,7 +290,7 @@ struct __wt_connection_impl { /* Connection statistics */ WT_CONNECTION_STATS *stats[WT_COUNTER_SLOTS]; - WT_CONNECTION_STATS stat_array[WT_COUNTER_SLOTS]; + WT_CONNECTION_STATS *stat_array; WT_ASYNC *async; /* Async structure */ int async_cfg; /* Global async configuration */ diff --git a/src/include/dhandle.h b/src/include/dhandle.h index 9a11594c893..001eb268f86 100644 --- a/src/include/dhandle.h +++ b/src/include/dhandle.h @@ -75,7 +75,7 @@ struct __wt_data_handle { /* Data-source statistics */ WT_DSRC_STATS *stats[WT_COUNTER_SLOTS]; - WT_DSRC_STATS stat_array[WT_COUNTER_SLOTS]; + WT_DSRC_STATS *stat_array; /* Flags values over 0xff are reserved for WT_BTREE_* */ #define WT_DHANDLE_DEAD 0x01 /* Dead, awaiting discard */ diff --git a/src/include/extern.h b/src/include/extern.h index 84cd1b6aa8c..da5f78bb526 100644 --- a/src/include/extern.h +++ b/src/include/extern.h @@ -697,14 +697,16 @@ extern void *__wt_ext_scr_alloc( WT_EXTENSION_API *wt_api, WT_SESSION *wt_sessio extern void __wt_ext_scr_free(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, void *p); extern int __wt_stat_dsrc_desc(WT_CURSOR_STAT *cst, int slot, const char **p) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_stat_dsrc_init_single(WT_DSRC_STATS *stats); -extern void __wt_stat_dsrc_init(WT_DATA_HANDLE *handle); +extern int __wt_stat_dsrc_init( WT_SESSION_IMPL *session, WT_DATA_HANDLE *handle) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_stat_dsrc_discard( WT_SESSION_IMPL *session, WT_DATA_HANDLE *handle); extern void __wt_stat_dsrc_clear_single(WT_DSRC_STATS *stats); extern void __wt_stat_dsrc_clear_all(WT_DSRC_STATS **stats); extern void __wt_stat_dsrc_aggregate_single( WT_DSRC_STATS *from, WT_DSRC_STATS *to); extern void __wt_stat_dsrc_aggregate( WT_DSRC_STATS **from, WT_DSRC_STATS *to); extern int __wt_stat_connection_desc(WT_CURSOR_STAT *cst, int slot, const char **p) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_stat_connection_init_single(WT_CONNECTION_STATS *stats); -extern void __wt_stat_connection_init(WT_CONNECTION_IMPL *handle); +extern int __wt_stat_connection_init( WT_SESSION_IMPL *session, WT_CONNECTION_IMPL *handle) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_stat_connection_discard( WT_SESSION_IMPL *session, WT_CONNECTION_IMPL *handle); extern void __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats); extern void __wt_stat_connection_clear_all(WT_CONNECTION_STATS **stats); extern void __wt_stat_connection_aggregate( WT_CONNECTION_STATS **from, WT_CONNECTION_STATS *to); diff --git a/src/include/meta.h b/src/include/meta.h index 63c79dbc72e..6d4a167a8e5 100644 --- a/src/include/meta.h +++ b/src/include/meta.h @@ -29,9 +29,8 @@ #define WT_LAS_URI "file:WiredTigerLAS.wt" /* Lookaside table URI*/ /* - * Pre computed hash for the metadata file. Used to optimize comparisons - * against the metafile URI. The validity is checked on connection open - * when diagnostic is enabled. + * Optimize comparisons against the metafile URI, flag handles that reference + * the metadata file. */ #define WT_IS_METADATA(session, dh) \ F_ISSET((dh), WT_DHANDLE_IS_METADATA) diff --git a/src/include/stat.h b/src/include/stat.h index d0b0b60585a..e53414fc0c9 100644 --- a/src/include/stat.h +++ b/src/include/stat.h @@ -225,21 +225,24 @@ __wt_stats_clear(void *stats_arg, int slot) * necessary until everything is converted to using data-source handles. */ #define WT_STAT_DATA_DECRV(session, fld, value) do { \ - if ((session)->dhandle != NULL) \ + if ((session)->dhandle != NULL && \ + (session)->dhandle->stat_array != NULL) \ WT_STAT_DECRV( \ session, (session)->dhandle->stats, fld, value); \ } while (0) #define WT_STAT_DATA_DECR(session, fld) \ WT_STAT_DATA_DECRV(session, fld, 1) #define WT_STAT_DATA_INCRV(session, fld, value) do { \ - if ((session)->dhandle != NULL) \ + if ((session)->dhandle != NULL && \ + (session)->dhandle->stat_array != NULL) \ WT_STAT_INCRV( \ session, (session)->dhandle->stats, fld, value); \ } while (0) #define WT_STAT_DATA_INCR(session, fld) \ WT_STAT_DATA_INCRV(session, fld, 1) #define WT_STAT_DATA_SET(session, fld, value) do { \ - if ((session)->dhandle != NULL) \ + if ((session)->dhandle != NULL && \ + (session)->dhandle->stat_array != NULL) \ WT_STAT_SET( \ session, (session)->dhandle->stats, fld, value); \ } while (0) diff --git a/src/support/stat.c b/src/support/stat.c index 6e8e218a0db..5acd9fc713f 100644 --- a/src/support/stat.c +++ b/src/support/stat.c @@ -138,15 +138,27 @@ __wt_stat_dsrc_init_single(WT_DSRC_STATS *stats) memset(stats, 0, sizeof(*stats)); } -void -__wt_stat_dsrc_init(WT_DATA_HANDLE *handle) +int +__wt_stat_dsrc_init( + WT_SESSION_IMPL *session, WT_DATA_HANDLE *handle) { int i; + WT_RET(__wt_calloc(session, (size_t)WT_COUNTER_SLOTS, + sizeof(*handle->stat_array), &handle->stat_array)); + for (i = 0; i < WT_COUNTER_SLOTS; ++i) { handle->stats[i] = &handle->stat_array[i]; __wt_stat_dsrc_init_single(handle->stats[i]); } + return (0); +} + +void +__wt_stat_dsrc_discard( + WT_SESSION_IMPL *session, WT_DATA_HANDLE *handle) +{ + __wt_free(session, handle->stat_array); } void @@ -860,15 +872,27 @@ __wt_stat_connection_init_single(WT_CONNECTION_STATS *stats) memset(stats, 0, sizeof(*stats)); } -void -__wt_stat_connection_init(WT_CONNECTION_IMPL *handle) +int +__wt_stat_connection_init( + WT_SESSION_IMPL *session, WT_CONNECTION_IMPL *handle) { int i; + WT_RET(__wt_calloc(session, (size_t)WT_COUNTER_SLOTS, + sizeof(*handle->stat_array), &handle->stat_array)); + for (i = 0; i < WT_COUNTER_SLOTS; ++i) { handle->stats[i] = &handle->stat_array[i]; __wt_stat_connection_init_single(handle->stats[i]); } + return (0); +} + +void +__wt_stat_connection_discard( + WT_SESSION_IMPL *session, WT_CONNECTION_IMPL *handle) +{ + __wt_free(session, handle->stat_array); } void |