From cf64a5f2c0f959e648c3611c7bc77bb45da1de21 Mon Sep 17 00:00:00 2001 From: Siddhartha Mahajan Date: Fri, 15 Jul 2022 01:44:04 +0000 Subject: Import wiredtiger: 22879bd37a0dd16ac10ff45ca24f75da3075ed4b from branch mongodb-master ref: 3a4fa07414..22879bd37a for: 6.1.0-rc0 WT-8201 Add rwlock flags to dhandle (#8078) --- src/third_party/wiredtiger/import.data | 2 +- src/third_party/wiredtiger/src/conn/conn_dhandle.c | 2 +- src/third_party/wiredtiger/src/conn/conn_sweep.c | 65 +++++++++++-------- src/third_party/wiredtiger/src/include/dhandle.h | 22 ++++++- src/third_party/wiredtiger/src/include/extern.h | 5 ++ .../wiredtiger/src/include/txn_inline.h | 2 +- .../wiredtiger/src/session/session_dhandle.c | 72 +++++++++++++++++++--- src/third_party/wiredtiger/src/txn/txn.c | 2 +- 8 files changed, 129 insertions(+), 43 deletions(-) diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data index dc02ce94aab..654ed5bffed 100644 --- a/src/third_party/wiredtiger/import.data +++ b/src/third_party/wiredtiger/import.data @@ -2,5 +2,5 @@ "vendor": "wiredtiger", "github": "wiredtiger/wiredtiger.git", "branch": "mongodb-master", - "commit": "3a4fa07414894dec4fcda9da00bd8af6b7fc4b95" + "commit": "22879bd37a0dd16ac10ff45ca24f75da3075ed4b" } diff --git a/src/third_party/wiredtiger/src/conn/conn_dhandle.c b/src/third_party/wiredtiger/src/conn/conn_dhandle.c index ff6cf27a8c6..bb53b870980 100644 --- a/src/third_party/wiredtiger/src/conn/conn_dhandle.c +++ b/src/third_party/wiredtiger/src/conn/conn_dhandle.c @@ -465,7 +465,7 @@ __conn_dhandle_config_parse_ts(WT_SESSION_IMPL *session) { WT_CONFIG_ITEM cval; WT_DATA_HANDLE *dhandle; - uint32_t flags; + uint16_t flags; const char **cfg; dhandle = session->dhandle; diff --git a/src/third_party/wiredtiger/src/conn/conn_sweep.c b/src/third_party/wiredtiger/src/conn/conn_sweep.c index d68d3641666..7de1aff89fd 100644 --- a/src/third_party/wiredtiger/src/conn/conn_sweep.c +++ b/src/third_party/wiredtiger/src/conn/conn_sweep.c @@ -50,19 +50,43 @@ __sweep_mark(WT_SESSION_IMPL *session, uint64_t now) } /* - * __sweep_expire_one -- - * Mark a single handle dead. + * __sweep_close_dhandle_locked -- + * Close write-locked dhandle. */ static int -__sweep_expire_one(WT_SESSION_IMPL *session) +__sweep_close_dhandle_locked(WT_SESSION_IMPL *session) { WT_BTREE *btree; WT_DATA_HANDLE *dhandle; - WT_DECL_RET; dhandle = session->dhandle; btree = WT_DHANDLE_BTREE(dhandle) ? dhandle->handle : NULL; + /* This method expects dhandle write lock. */ + WT_ASSERT(session, FLD_ISSET(dhandle->lock_flags, WT_DHANDLE_LOCK_WRITE)); + + /* Only sweep clean trees. */ + if (btree != NULL && btree->modified) + return (0); + + /* + * Mark the handle dead and close the underlying handle. + * + * For btree handles, closing the handle decrements the open file count, meaning the close loop + * won't overrun the configured minimum. + */ + return (__wt_conn_dhandle_close(session, false, true)); +} + +/* + * __sweep_expire_one -- + * Mark a single handle dead. + */ +static int +__sweep_expire_one(WT_SESSION_IMPL *session) +{ + WT_DECL_RET; + /* * Acquire an exclusive lock on the handle and mark it dead. * @@ -75,22 +99,7 @@ __sweep_expire_one(WT_SESSION_IMPL *session) * rather than returning an EBUSY error to the application. This is done holding the handle list * lock so that connection-level handle searches never need to retry. */ - WT_RET(__wt_try_writelock(session, &dhandle->rwlock)); - - /* Only sweep clean trees. */ - if (btree != NULL && btree->modified) - goto err; - - /* - * Mark the handle dead and close the underlying handle. - * - * For btree handles, closing the handle decrements the open file count, meaning the close loop - * won't overrun the configured minimum. - */ - ret = __wt_conn_dhandle_close(session, false, true); - -err: - __wt_writeunlock(session, &dhandle->rwlock); + WT_WITH_DHANDLE_WRITE_LOCK_NOWAIT(session, ret, ret = __sweep_close_dhandle_locked(session)); return (ret); } @@ -178,20 +187,20 @@ __sweep_discard_trees(WT_SESSION_IMPL *session, u_int *dead_handlesp) * Remove a closed handle from the connection list. */ static int -__sweep_remove_one(WT_SESSION_IMPL *session, WT_DATA_HANDLE *dhandle) +__sweep_remove_one(WT_SESSION_IMPL *session) { WT_DECL_RET; /* Try to get exclusive access. */ - WT_RET(__wt_try_writelock(session, &dhandle->rwlock)); + WT_RET(__wt_session_dhandle_try_writelock(session)); /* * If there are no longer any references to the handle in any sessions, attempt to discard it. */ - if (!WT_DHANDLE_CAN_DISCARD(dhandle)) + if (!WT_DHANDLE_CAN_DISCARD(session->dhandle)) WT_ERR(EBUSY); - WT_WITH_DHANDLE(session, dhandle, ret = __wt_conn_dhandle_discard_single(session, false, true)); + ret = __wt_conn_dhandle_discard_single(session, false, true); /* * If the handle was not successfully discarded, unlock it and don't retry the discard until it @@ -199,7 +208,7 @@ __sweep_remove_one(WT_SESSION_IMPL *session, WT_DATA_HANDLE *dhandle) */ if (ret != 0) { err: - __wt_writeunlock(session, &dhandle->rwlock); + __wt_session_dhandle_writeunlock(session); } return (ret); @@ -227,9 +236,11 @@ __sweep_remove_handles(WT_SESSION_IMPL *session) if (dhandle->type == WT_DHANDLE_TYPE_TABLE) WT_WITH_TABLE_WRITE_LOCK(session, - WT_WITH_HANDLE_LIST_WRITE_LOCK(session, ret = __sweep_remove_one(session, dhandle))); + WT_WITH_HANDLE_LIST_WRITE_LOCK( + session, WT_WITH_DHANDLE(session, dhandle, ret = __sweep_remove_one(session)))); else - WT_WITH_HANDLE_LIST_WRITE_LOCK(session, ret = __sweep_remove_one(session, dhandle)); + WT_WITH_HANDLE_LIST_WRITE_LOCK( + session, WT_WITH_DHANDLE(session, dhandle, ret = __sweep_remove_one(session))); if (ret == 0) WT_STAT_CONN_INCR(session, dh_sweep_remove); else diff --git a/src/third_party/wiredtiger/src/include/dhandle.h b/src/third_party/wiredtiger/src/include/dhandle.h index 8bbae1539a0..865ea0d9568 100644 --- a/src/third_party/wiredtiger/src/include/dhandle.h +++ b/src/third_party/wiredtiger/src/include/dhandle.h @@ -57,6 +57,19 @@ #define WT_DHANDLE_IS_CHECKPOINT(dhandle) ((dhandle)->checkpoint != NULL) +/* + * WT_WITH_DHANDLE_WRITE_LOCK_NOWAIT -- + * Try to acquire write lock for the session's current dhandle, perform an operation, drop the + * lock. + */ +#define WT_WITH_DHANDLE_WRITE_LOCK_NOWAIT(session, ret, op) \ + do { \ + if (((ret) = __wt_session_dhandle_try_writelock(session)) == 0) { \ + op; \ + __wt_session_dhandle_writeunlock(session); \ + } \ + } while (0) + /* * WT_DATA_HANDLE -- * A handle for a generic named data source. @@ -137,6 +150,11 @@ struct __wt_data_handle { #define WT_DHANDLE_TS_MIXED_MODE 0x04u /* Handle using mixed mode timestamps checking. */ #define WT_DHANDLE_TS_NEVER 0x08u /* Handle never using timestamps checking. */ #define WT_DHANDLE_TS_ORDERED 0x10u /* Handle using ordered timestamps checking. */ - /* AUTOMATIC FLAG VALUE GENERATION STOP 32 */ - uint32_t ts_flags; + /* AUTOMATIC FLAG VALUE GENERATION STOP 16 */ + uint16_t ts_flags; + +/* AUTOMATIC FLAG VALUE GENERATION START 0 */ +#define WT_DHANDLE_LOCK_WRITE 0x1u /* Write lock is acquired. */ + /* AUTOMATIC FLAG VALUE GENERATION STOP 16 */ + uint16_t lock_flags; }; diff --git a/src/third_party/wiredtiger/src/include/extern.h b/src/third_party/wiredtiger/src/include/extern.h index ae1cce21b49..73f3d2632ed 100644 --- a/src/third_party/wiredtiger/src/include/extern.h +++ b/src/third_party/wiredtiger/src/include/extern.h @@ -1409,6 +1409,8 @@ extern int __wt_session_create(WT_SESSION_IMPL *session, const char *uri, const WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_session_cursor_cache_sweep(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_session_dhandle_try_writelock(WT_SESSION_IMPL *session) + WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_session_get_btree_ckpt(WT_SESSION_IMPL *session, const char *uri, const char *cfg[], uint32_t flags, WT_DATA_HANDLE **hs_dhandlep, WT_CKPT_SNAPSHOT *ckpt_snapshot) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); @@ -1863,6 +1865,9 @@ extern void __wt_rwlock_destroy(WT_SESSION_IMPL *session, WT_RWLOCK *l); extern void __wt_schema_destroy_colgroup(WT_SESSION_IMPL *session, WT_COLGROUP **colgroupp); extern void __wt_scr_discard(WT_SESSION_IMPL *session); extern void __wt_session_close_cache(WT_SESSION_IMPL *session); +extern void __wt_session_dhandle_readlock(WT_SESSION_IMPL *session); +extern void __wt_session_dhandle_readunlock(WT_SESSION_IMPL *session); +extern void __wt_session_dhandle_writeunlock(WT_SESSION_IMPL *session); extern void __wt_session_gen_enter(WT_SESSION_IMPL *session, int which); extern void __wt_session_gen_leave(WT_SESSION_IMPL *session, int which); extern void __wt_stash_discard(WT_SESSION_IMPL *session); diff --git a/src/third_party/wiredtiger/src/include/txn_inline.h b/src/third_party/wiredtiger/src/include/txn_inline.h index ce2f47ca5d6..8e09926193a 100644 --- a/src/third_party/wiredtiger/src/include/txn_inline.h +++ b/src/third_party/wiredtiger/src/include/txn_inline.h @@ -1352,7 +1352,7 @@ static inline int __wt_txn_search_check(WT_SESSION_IMPL *session) { WT_TXN *txn; - uint32_t flags; + uint16_t flags; const char *name; txn = session->txn; diff --git a/src/third_party/wiredtiger/src/session/session_dhandle.c b/src/third_party/wiredtiger/src/session/session_dhandle.c index c8f39c28273..f9e3c52c850 100644 --- a/src/third_party/wiredtiger/src/session/session_dhandle.c +++ b/src/third_party/wiredtiger/src/session/session_dhandle.c @@ -161,17 +161,17 @@ __wt_session_lock_dhandle(WT_SESSION_IMPL *session, uint32_t flags, bool *is_dea * thread has it locked for real. */ if (F_ISSET(dhandle, WT_DHANDLE_OPEN) && (!want_exclusive || lock_busy)) { - __wt_readlock(session, &dhandle->rwlock); + WT_WITH_DHANDLE(session, dhandle, __wt_session_dhandle_readlock(session)); if (F_ISSET(dhandle, WT_DHANDLE_DEAD)) { *is_deadp = true; - __wt_readunlock(session, &dhandle->rwlock); + WT_WITH_DHANDLE(session, dhandle, __wt_session_dhandle_readunlock(session)); return (0); } is_open = F_ISSET(dhandle, WT_DHANDLE_OPEN); if (is_open && !want_exclusive) return (0); - __wt_readunlock(session, &dhandle->rwlock); + WT_WITH_DHANDLE(session, dhandle, __wt_session_dhandle_readunlock(session)); } else is_open = false; @@ -180,10 +180,11 @@ __wt_session_lock_dhandle(WT_SESSION_IMPL *session, uint32_t flags, bool *is_dea * subtlety here: if we race with another thread that successfully opens the file, we don't * want to block waiting to get exclusive access. */ - if ((ret = __wt_try_writelock(session, &dhandle->rwlock)) == 0) { + WT_WITH_DHANDLE(session, dhandle, ret = __wt_session_dhandle_try_writelock(session)); + if (ret == 0) { if (F_ISSET(dhandle, WT_DHANDLE_DEAD)) { *is_deadp = true; - __wt_writeunlock(session, &dhandle->rwlock); + WT_WITH_DHANDLE(session, dhandle, __wt_session_dhandle_writeunlock(session)); return (0); } @@ -192,7 +193,7 @@ __wt_session_lock_dhandle(WT_SESSION_IMPL *session, uint32_t flags, bool *is_dea */ if (F_ISSET(dhandle, WT_DHANDLE_OPEN) && !want_exclusive) { lock_busy = false; - __wt_writeunlock(session, &dhandle->rwlock); + WT_WITH_DHANDLE(session, dhandle, __wt_session_dhandle_writeunlock(session)); continue; } @@ -273,9 +274,9 @@ __wt_session_release_dhandle(WT_SESSION_IMPL *session) if (locked) { if (write_locked) { F_CLR(dhandle, WT_DHANDLE_EXCLUSIVE); - __wt_writeunlock(session, &dhandle->rwlock); + WT_WITH_DHANDLE(session, dhandle, __wt_session_dhandle_writeunlock(session)); } else - __wt_readunlock(session, &dhandle->rwlock); + WT_WITH_DHANDLE(session, dhandle, __wt_session_dhandle_readunlock(session)); } session->dhandle = NULL; @@ -755,6 +756,57 @@ __session_get_dhandle(WT_SESSION_IMPL *session, const char *uri, const char *che return (ret); } +/* + * __wt_session_dhandle_readlock -- + * Acquire read lock for the session's current dhandle. + */ +void +__wt_session_dhandle_readlock(WT_SESSION_IMPL *session) +{ + WT_ASSERT(session, session->dhandle != NULL); + __wt_readlock(session, &session->dhandle->rwlock); +} + +/* + * __wt_session_dhandle_readunlock -- + * Release read lock for the session's current dhandle. + */ +void +__wt_session_dhandle_readunlock(WT_SESSION_IMPL *session) +{ + WT_ASSERT(session, session->dhandle != NULL); + __wt_readunlock(session, &session->dhandle->rwlock); +} + +/* + * __wt_session_dhandle_writeunlock -- + * Release write lock for the session's current dhandle. + */ +void +__wt_session_dhandle_writeunlock(WT_SESSION_IMPL *session) +{ + WT_ASSERT(session, session->dhandle != NULL); + WT_ASSERT(session, FLD_ISSET(session->dhandle->lock_flags, WT_DHANDLE_LOCK_WRITE)); + FLD_CLR(session->dhandle->lock_flags, WT_DHANDLE_LOCK_WRITE); + __wt_writeunlock(session, &session->dhandle->rwlock); +} + +/* + * __wt_session_dhandle_try_writelock -- + * Try to acquire write lock for the session's current dhandle. + */ +int +__wt_session_dhandle_try_writelock(WT_SESSION_IMPL *session) +{ + WT_DECL_RET; + + WT_ASSERT(session, session->dhandle != NULL); + if ((ret = __wt_try_writelock(session, &session->dhandle->rwlock)) == 0) + FLD_SET(session->dhandle->lock_flags, WT_DHANDLE_LOCK_WRITE); + + return (ret); +} + /* * __wt_session_get_dhandle -- * Get a data handle for the given name, set session->dhandle. Optionally if we opened a @@ -798,7 +850,7 @@ __wt_session_get_dhandle(WT_SESSION_IMPL *session, const char *uri, const char * dhandle->excl_session = NULL; dhandle->excl_ref = 0; F_CLR(dhandle, WT_DHANDLE_EXCLUSIVE); - __wt_writeunlock(session, &dhandle->rwlock); + WT_WITH_DHANDLE(session, dhandle, __wt_session_dhandle_writeunlock(session)); WT_WITH_SCHEMA_LOCK( session, ret = __wt_session_get_dhandle(session, uri, checkpoint, cfg, flags)); @@ -818,7 +870,7 @@ __wt_session_get_dhandle(WT_SESSION_IMPL *session, const char *uri, const char * dhandle->excl_session = NULL; dhandle->excl_ref = 0; F_CLR(dhandle, WT_DHANDLE_EXCLUSIVE); - __wt_writeunlock(session, &dhandle->rwlock); + WT_WITH_DHANDLE(session, dhandle, __wt_session_dhandle_writeunlock(session)); WT_RET(ret); } diff --git a/src/third_party/wiredtiger/src/txn/txn.c b/src/third_party/wiredtiger/src/txn/txn.c index 48b58b20c71..201584c1e50 100644 --- a/src/third_party/wiredtiger/src/txn/txn.c +++ b/src/third_party/wiredtiger/src/txn/txn.c @@ -846,7 +846,7 @@ __txn_timestamp_usage_check(WT_SESSION_IMPL *session, WT_TXN_OP *op, WT_UPDATE * WT_BTREE *btree; WT_TXN *txn; wt_timestamp_t op_ts, prev_op_durable_ts; - uint32_t flags; + uint16_t flags; char ts_string[2][WT_TS_INT_STRING_SIZE]; const char *name; bool no_ts_ok, txn_has_ts; -- cgit v1.2.1