diff options
author | Michael Cahill <michael.cahill@mongodb.com> | 2017-08-03 15:29:53 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-03 15:29:53 +1000 |
commit | 74510affecfd4c274988a3f7b8e71448492f2103 (patch) | |
tree | 52c1f497ac75db4a65fc4cf495f45030781793d5 | |
parent | d2f2eae6d7718a53ac5bacf7141773ee0696f3c6 (diff) | |
download | mongo-74510affecfd4c274988a3f7b8e71448492f2103.tar.gz |
WT-3471 Sweep the table cache after schema changes. (#3551)
During WT_SESSION::reset, if there has been a schema change (such as a WT_SESSION::drop operation) since the last sweep, do a pass through the table cache and remove any obsolete table handles.
-rw-r--r-- | src/include/extern.h | 1 | ||||
-rw-r--r-- | src/include/session.h | 6 | ||||
-rw-r--r-- | src/schema/schema_list.c | 31 | ||||
-rw-r--r-- | src/session/session_api.c | 2 |
4 files changed, 40 insertions, 0 deletions
diff --git a/src/include/extern.h b/src/include/extern.h index bf3279d0f94..dfd2d03707f 100644 --- a/src/include/extern.h +++ b/src/include/extern.h @@ -570,6 +570,7 @@ extern int __wt_schema_destroy_index(WT_SESSION_IMPL *session, WT_INDEX **idxp) extern int __wt_schema_destroy_table(WT_SESSION_IMPL *session, WT_TABLE **tablep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_schema_remove_table(WT_SESSION_IMPL *session, WT_TABLE *table) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_schema_close_tables(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_sweep_tables(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_schema_colgroup_name(WT_SESSION_IMPL *session, WT_TABLE *table, const char *cgname, size_t len, WT_ITEM *buf) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_schema_open_colgroups(WT_SESSION_IMPL *session, WT_TABLE *table) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_schema_open_index(WT_SESSION_IMPL *session, WT_TABLE *table, const char *idxname, size_t len, WT_INDEX **indexp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); diff --git a/src/include/session.h b/src/include/session.h index 0074b4a9d43..d05dee68641 100644 --- a/src/include/session.h +++ b/src/include/session.h @@ -98,6 +98,12 @@ struct __wt_session_impl { */ TAILQ_HEAD(__tables, __wt_table) tables; + /* + * Updated when the table cache is swept of all tables older than the + * current schema generation. + */ + uint64_t table_sweep_gen; + /* Current rwlock for callback. */ WT_RWLOCK *current_rwlock; uint8_t current_rwticket; diff --git a/src/schema/schema_list.c b/src/schema/schema_list.c index 74ef5135a4a..3dc51b6cb43 100644 --- a/src/schema/schema_list.c +++ b/src/schema/schema_list.c @@ -249,3 +249,34 @@ __wt_schema_close_tables(WT_SESSION_IMPL *session) WT_TRET(__wt_schema_remove_table(session, table)); return (ret); } + +/* + * __wt_schema_sweep_tables -- + * Close all idle, obsolete tables in a session. + */ +int +__wt_schema_sweep_tables(WT_SESSION_IMPL *session) +{ + WT_TABLE *table, *next; + uint64_t schema_gen; + bool old_table_busy; + + WT_ORDERED_READ(schema_gen, S2C(session)->schema_gen); + if (schema_gen == session->table_sweep_gen) + return (0); + + old_table_busy = false; + TAILQ_FOREACH_SAFE(table, &session->tables, q, next) + if (table->schema_gen != schema_gen) { + if (table->refcnt == 0) + WT_RET(__wt_schema_remove_table( + session, table)); + else + old_table_busy = true; + } + + if (!old_table_busy) + session->table_sweep_gen = schema_gen; + + return (0); +} diff --git a/src/session/session_api.c b/src/session/session_api.c index 89a5a2c633d..5ce6135cfca 100644 --- a/src/session/session_api.c +++ b/src/session/session_api.c @@ -818,6 +818,8 @@ __session_reset(WT_SESSION *wt_session) WT_TRET(__wt_session_reset_cursors(session, true)); + WT_TRET(__wt_schema_sweep_tables(session)); + /* Release common session resources. */ WT_TRET(__wt_session_release_resources(session)); |