diff options
author | Chenhao Qu <chenhao.qu@mongodb.com> | 2022-04-19 23:39:07 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-04-20 00:10:46 +0000 |
commit | 9fd24287e684e18f2aae8d0b24c9acf6ebcbbfea (patch) | |
tree | 61af8af12ef75042af1288ba9db8830647d64b52 /src/third_party | |
parent | e916372674aa762557c9e30141b277e019d8039f (diff) | |
download | mongo-9fd24287e684e18f2aae8d0b24c9acf6ebcbbfea.tar.gz |
Import wiredtiger: 12f6c1c6976e1bff7cc4b7a5041498ff94767358 from branch mongodb-master
ref: ad0b418109..12f6c1c697
for: 6.1.0-rc0
WT-8973 Define semantics of zero timestamp in our APIs
Diffstat (limited to 'src/third_party')
23 files changed, 236 insertions, 247 deletions
diff --git a/src/third_party/wiredtiger/dist/api_data.py b/src/third_party/wiredtiger/dist/api_data.py index f67c6deed59..45dd064ec35 100644 --- a/src/third_party/wiredtiger/dist/api_data.py +++ b/src/third_party/wiredtiger/dist/api_data.py @@ -1644,11 +1644,11 @@ methods = { 'WT_SESSION.query_timestamp' : Method([ Config('get', 'read', r''' - specify which timestamp to query: \c commit returns the most recently - set commit_timestamp; \c first_commit returns the first set - commit_timestamp; \c prepare returns the timestamp used in preparing a - transaction; \c read returns the timestamp at which the transaction is - reading at. See @ref timestamp_txn_api''', + specify which timestamp to query: \c commit returns the most + recently set commit_timestamp; \c first_commit returns the first set + commit_timestamp; \c prepare returns the timestamp used in preparing + a transaction; \c read returns the timestamp at which the transaction + is reading. See @ref timestamp_txn_api''', choices=['commit', 'first_commit', 'prepare', 'read']), ]), @@ -1663,10 +1663,6 @@ methods = { ]), 'WT_SESSION.flush_tier' : Method([ - Config('flush_timestamp', '', r''' - flush objects to all storage sources using the specified timestamp. - The value must not be older than the current oldest timestamp and it must - not be newer than the stable timestamp'''), Config('force', 'false', r''' force sharing of all data''', type='boolean'), @@ -1820,6 +1816,7 @@ methods = { be newer than the current stable timestamp. See @ref timestamp_prepare'''), ]), +'WT_SESSION.timestamp_transaction_uint' : Method([]), 'WT_SESSION.timestamp_transaction' : Method([ Config('commit_timestamp', '', r''' set the commit timestamp for the current transaction. For non-prepared transactions, @@ -1959,8 +1956,8 @@ methods = { recent \c oldest_timestamp set with WT_CONNECTION::set_timestamp; \c oldest_reader returns the minimum of the read timestamps of all active readers; \c pinned returns the minimum of the \c oldest_timestamp and the read timestamps of all active readers; - \c recovery returns the timestamp of the most recent stable checkpoint taken prior to a - shutdown; \c stable_timestamp returns the most recent \c stable_timestamp set with + \c recovery returns the timestamp of the most recent stable checkpoint taken prior + to a shutdown; \c stable_timestamp returns the most recent \c stable_timestamp set with WT_CONNECTION::set_timestamp. (The \c oldest and \c stable arguments are deprecated short-hand for \c oldest_timestamp and \c stable_timestamp, respectively.) See @ref timestamp_global_api''', diff --git a/src/third_party/wiredtiger/examples/c/ex_all.c b/src/third_party/wiredtiger/examples/c/ex_all.c index e4c49e2f9a0..f76d57b40fd 100644 --- a/src/third_party/wiredtiger/examples/c/ex_all.c +++ b/src/third_party/wiredtiger/examples/c/ex_all.c @@ -896,6 +896,7 @@ transaction_ops(WT_SESSION *session_arg) { /*! [hexadecimal timestamp] */ uint64_t ts; + /* 2 bytes for each byte converted to hexadecimal; sizeof includes the trailing nul byte */ char timestamp_buf[sizeof("commit_timestamp=") + 2 * sizeof(uint64_t)]; @@ -920,6 +921,12 @@ transaction_ops(WT_SESSION *session_arg) error_check(conn->query_timestamp(conn, timestamp_buf, "get=all_durable")); /*! [query timestamp] */ + + error_check(session->begin_transaction(session, NULL)); + /*! [transaction timestamp_uint] */ + error_check(session->timestamp_transaction_uint(session, WT_TS_TXN_TYPE_COMMIT, 42)); + /*! [transaction timestamp_uint] */ + error_check(session->commit_transaction(session, NULL)); } /*! [set durable timestamp] */ diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data index f054921907c..6562455c74d 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": "ad0b418109f05284ecdc343683988388a1a7fd39" + "commit": "12f6c1c6976e1bff7cc4b7a5041498ff94767358" } diff --git a/src/third_party/wiredtiger/src/config/config_def.c b/src/third_party/wiredtiger/src/config/config_def.c index bc1a7a93990..8c3e008201e 100644 --- a/src/third_party/wiredtiger/src/config/config_def.c +++ b/src/third_party/wiredtiger/src/config/config_def.c @@ -355,8 +355,7 @@ static const WT_CONFIG_CHECK confchk_WT_SESSION_drop[] = { {NULL, NULL, NULL, NULL, NULL, 0}}; static const WT_CONFIG_CHECK confchk_WT_SESSION_flush_tier[] = { - {"flush_timestamp", "string", NULL, NULL, NULL, 0}, {"force", "boolean", NULL, NULL, NULL, 0}, - {"lock_wait", "boolean", NULL, NULL, NULL, 0}, + {"force", "boolean", NULL, NULL, NULL, 0}, {"lock_wait", "boolean", NULL, NULL, NULL, 0}, {"sync", "string", NULL, "choices=[\"off\",\"on\"]", NULL, 0}, {"timeout", "int", NULL, NULL, NULL, 0}, {NULL, NULL, NULL, NULL, NULL, 0}}; @@ -1278,8 +1277,8 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator", "checkpoint_wait=true,force=false,lock_wait=true," "remove_files=true", confchk_WT_SESSION_drop, 4}, - {"WT_SESSION.flush_tier", "flush_timestamp=,force=false,lock_wait=true,sync=on,timeout=0", - confchk_WT_SESSION_flush_tier, 5}, + {"WT_SESSION.flush_tier", "force=false,lock_wait=true,sync=on,timeout=0", + confchk_WT_SESSION_flush_tier, 4}, {"WT_SESSION.join", "bloom_bit_count=16,bloom_false_positives=false," "bloom_hash_count=8,compare=\"eq\",count=,operation=\"and\"," @@ -1314,7 +1313,8 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator", "commit_timestamp=,durable_timestamp=,prepare_timestamp=," "read_timestamp=", confchk_WT_SESSION_timestamp_transaction, 4}, - {"WT_SESSION.truncate", "", NULL, 0}, {"WT_SESSION.upgrade", "", NULL, 0}, + {"WT_SESSION.timestamp_transaction_uint", "", NULL, 0}, {"WT_SESSION.truncate", "", NULL, 0}, + {"WT_SESSION.upgrade", "", NULL, 0}, {"WT_SESSION.verify", "do_not_clear_txn_id=false,dump_address=false,dump_blocks=false," "dump_layout=false,dump_offsets=,dump_pages=false," diff --git a/src/third_party/wiredtiger/src/docs/timestamp-global.dox b/src/third_party/wiredtiger/src/docs/timestamp-global.dox index 7bddc1c4345..df708687c29 100644 --- a/src/third_party/wiredtiger/src/docs/timestamp-global.dox +++ b/src/third_party/wiredtiger/src/docs/timestamp-global.dox @@ -127,20 +127,21 @@ USING THE FORCE FLAG NEEDS MOTIVATION AND DISCUSSION. --> @section timestamp_global_querying_timestamps Querying global timestamps The following table lists the global timestamps an application can query using -the WT_CONNECTION::set_timestamp method, including constraints. +the WT_CONNECTION::set_timestamp method, including constraints. In all cases, +a timestamp of 0 is returned if the timestamp is not available or has not been +set, for example, the \c last_checkpoint timestamp if no checkpoints have run, +or \c oldest_reader if there are no active transactions. | Timestamp | Constraints | Description | |-----------|-------------|-------------| | all_durable | None | The largest timestamp such that all timestamps up to that value have been made durable (see @ref timestamp_prepare for discussion of the durable timestamp). | -| last_checkpoint | <= stable | The stable timestamp at which the last checkpoint ran (or 0 if no checkpoints have run). | +| last_checkpoint | <= stable | The stable timestamp at which the last checkpoint ran. | | oldest_reader | None | The timestamp of the oldest currently active read transaction. | | oldest_timestamp | <= stable | The current application-set \c oldest_timestamp value. | | pinned | <= oldest | The minimum of the \c oldest_timestamp and the oldest active reader. | -| recovery | <= stable | The stable timestamp used in the most recent checkpoint prior to the last shutdown (or 0 if none available). | +| recovery | <= stable | The stable timestamp used in the most recent checkpoint prior to the last shutdown. | | stable_timestamp | None | The current application-set \c stable_timestamp value. | -In all cases, ::WT_NOTFOUND is returned if there is no matching timestamp. - @subsection timestamp_global_query_api_all_durable Reading the "all_durable" timestamp <!-- diff --git a/src/third_party/wiredtiger/src/docs/timestamp-model.dox b/src/third_party/wiredtiger/src/docs/timestamp-model.dox index a87a87d4a89..e6c7310c12e 100644 --- a/src/third_party/wiredtiger/src/docs/timestamp-model.dox +++ b/src/third_party/wiredtiger/src/docs/timestamp-model.dox @@ -31,20 +31,26 @@ timestamp_txn_api for a full explanation. @section timestamps_format Timestamp format Timestamps are 64-bit unsigned integers naming a point in application time. -WiredTiger does not interpret timestamps other than expecting larger timestamps -to correspond to later times. Timestamp 0 is reserved, so timestamps must -start at 1 or greater. It is not necessary for timestamp values to be clock time -of any kind; an expected timestamp source is a global counter shared by -instances of an application distributed across a network, individually running -local WiredTiger databases. - -Timestamps are read from and written to the WiredTiger API as hexadecimal -strings without any leading prefix like "0x". Applications using timestamps -must format those time values as hexadecimal when querying or setting -timestamps in WiredTiger: +WiredTiger does not interpret timestamps other than expecting larger +timestamps to correspond to later times. The timestamp value of zero is +reserved, timestamps must be non-zero. It is not necessary for timestamp +values to be clock time of any kind; an expected timestamp source is a global +counter shared by instances of an application distributed across a network, +individually running local WiredTiger databases. + +Timestamps can be read from and written to the WiredTiger API as hexadecimal +strings without any leading prefix like "0x". Applications using timestamps +must format those values as hexadecimal when querying or setting timestamps +in WiredTiger: @snippet ex_all.c hexadecimal timestamp +Also, timestamps can be written to the WiredTiger API as 64-bit unsigned +integers in one fast-path case (where handling hexadecimal strings has shown +itself to be a bottle-neck): + +@snippet ex_all.c transaction timestamp_uint + @section timestamps_durability_commit Logged objects, commit-level durability and timestamps \warning diff --git a/src/third_party/wiredtiger/src/docs/timestamp-txn.dox b/src/third_party/wiredtiger/src/docs/timestamp-txn.dox index fe929fdb7be..ba66ce3dc0c 100644 --- a/src/third_party/wiredtiger/src/docs/timestamp-txn.dox +++ b/src/third_party/wiredtiger/src/docs/timestamp-txn.dox @@ -73,7 +73,9 @@ application misbehavior will not be detected. @section timestamp_txn_api_query Querying transaction timestamp information The following table lists the timestamps that can be queried using -WT_SESSION::query_timestamp: +WT_SESSION::query_timestamp. In all cases, a timestamp of 0 is returned +if the timestamp is not available or has not been set, for example, the +\c commit timestamp if no commit timestamp has been set. | Timestamp | Description | |-----------|-------------| @@ -82,8 +84,6 @@ WT_SESSION::query_timestamp: | prepare | the timestamp used to prepare the transaction | | read | the timestamp at which the transaction is reading | -In all cases, ::WT_NOTFOUND is returned if there is no matching timestamp. - @section timestamp_txn_api_begin Configuring transaction timestamp information with WT_SESSION::begin_transaction The following table lists the transaction's timestamps and behaviors that can be set when the transaction begins, using WT_SESSION::begin_transaction: diff --git a/src/third_party/wiredtiger/src/include/config.h b/src/third_party/wiredtiger/src/include/config.h index 29c576defd8..95d30c2f304 100644 --- a/src/third_party/wiredtiger/src/include/config.h +++ b/src/third_party/wiredtiger/src/include/config.h @@ -91,22 +91,23 @@ struct __wt_config_parser_impl { #define WT_CONFIG_ENTRY_WT_SESSION_salvage 37 #define WT_CONFIG_ENTRY_WT_SESSION_strerror 38 #define WT_CONFIG_ENTRY_WT_SESSION_timestamp_transaction 39 -#define WT_CONFIG_ENTRY_WT_SESSION_truncate 40 -#define WT_CONFIG_ENTRY_WT_SESSION_upgrade 41 -#define WT_CONFIG_ENTRY_WT_SESSION_verify 42 -#define WT_CONFIG_ENTRY_colgroup_meta 43 -#define WT_CONFIG_ENTRY_file_config 44 -#define WT_CONFIG_ENTRY_file_meta 45 -#define WT_CONFIG_ENTRY_index_meta 46 -#define WT_CONFIG_ENTRY_lsm_meta 47 -#define WT_CONFIG_ENTRY_object_meta 48 -#define WT_CONFIG_ENTRY_table_meta 49 -#define WT_CONFIG_ENTRY_tier_meta 50 -#define WT_CONFIG_ENTRY_tiered_meta 51 -#define WT_CONFIG_ENTRY_wiredtiger_open 52 -#define WT_CONFIG_ENTRY_wiredtiger_open_all 53 -#define WT_CONFIG_ENTRY_wiredtiger_open_basecfg 54 -#define WT_CONFIG_ENTRY_wiredtiger_open_usercfg 55 +#define WT_CONFIG_ENTRY_WT_SESSION_timestamp_transaction_uint 40 +#define WT_CONFIG_ENTRY_WT_SESSION_truncate 41 +#define WT_CONFIG_ENTRY_WT_SESSION_upgrade 42 +#define WT_CONFIG_ENTRY_WT_SESSION_verify 43 +#define WT_CONFIG_ENTRY_colgroup_meta 44 +#define WT_CONFIG_ENTRY_file_config 45 +#define WT_CONFIG_ENTRY_file_meta 46 +#define WT_CONFIG_ENTRY_index_meta 47 +#define WT_CONFIG_ENTRY_lsm_meta 48 +#define WT_CONFIG_ENTRY_object_meta 49 +#define WT_CONFIG_ENTRY_table_meta 50 +#define WT_CONFIG_ENTRY_tier_meta 51 +#define WT_CONFIG_ENTRY_tiered_meta 52 +#define WT_CONFIG_ENTRY_wiredtiger_open 53 +#define WT_CONFIG_ENTRY_wiredtiger_open_all 54 +#define WT_CONFIG_ENTRY_wiredtiger_open_basecfg 55 +#define WT_CONFIG_ENTRY_wiredtiger_open_usercfg 56 /* * configuration section: END * DO NOT EDIT: automatically built by dist/flags.py. diff --git a/src/third_party/wiredtiger/src/include/extern.h b/src/third_party/wiredtiger/src/include/extern.h index e8ac5790016..5f6482b7b2d 100644 --- a/src/third_party/wiredtiger/src/include/extern.h +++ b/src/third_party/wiredtiger/src/include/extern.h @@ -1543,8 +1543,6 @@ extern int __wt_txn_commit(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_txn_config(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); -extern int __wt_txn_get_pinned_timestamp(WT_SESSION_IMPL *session, wt_timestamp_t *tsp, - uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_txn_global_init(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_txn_global_set_timestamp(WT_SESSION_IMPL *session, const char *cfg[]) @@ -1598,8 +1596,6 @@ extern int __wt_txn_ts_log(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_txn_update_oldest(WT_SESSION_IMPL *session, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); -extern int __wt_txn_update_pinned_timestamp(WT_SESSION_IMPL *session, bool force) - WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_txn_validate_commit_timestamp(WT_SESSION_IMPL *session, wt_timestamp_t *commit_tsp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_txn_validate_durable_timestamp(WT_SESSION_IMPL *session, wt_timestamp_t durable_ts) @@ -1863,6 +1859,8 @@ extern void __wt_txn_bump_snapshot(WT_SESSION_IMPL *session); extern void __wt_txn_clear_durable_timestamp(WT_SESSION_IMPL *session); extern void __wt_txn_clear_read_timestamp(WT_SESSION_IMPL *session); extern void __wt_txn_destroy(WT_SESSION_IMPL *session); +extern void __wt_txn_get_pinned_timestamp( + WT_SESSION_IMPL *session, wt_timestamp_t *tsp, uint32_t flags); extern void __wt_txn_get_snapshot(WT_SESSION_IMPL *session); extern void __wt_txn_global_destroy(WT_SESSION_IMPL *session); extern void __wt_txn_op_free(WT_SESSION_IMPL *session, WT_TXN_OP *op); @@ -1872,6 +1870,7 @@ extern void __wt_txn_release_resources(WT_SESSION_IMPL *session); extern void __wt_txn_release_snapshot(WT_SESSION_IMPL *session); extern void __wt_txn_stats_update(WT_SESSION_IMPL *session); extern void __wt_txn_truncate_end(WT_SESSION_IMPL *session); +extern void __wt_txn_update_pinned_timestamp(WT_SESSION_IMPL *session, bool force); extern void __wt_update_vector_clear(WT_UPDATE_VECTOR *updates); extern void __wt_update_vector_free(WT_UPDATE_VECTOR *updates); extern void __wt_update_vector_init(WT_SESSION_IMPL *session, WT_UPDATE_VECTOR *updates); diff --git a/src/third_party/wiredtiger/src/include/wiredtiger.in b/src/third_party/wiredtiger/src/include/wiredtiger.in index 90cd59194d0..c4314e56d3e 100644 --- a/src/third_party/wiredtiger/src/include/wiredtiger.in +++ b/src/third_party/wiredtiger/src/include/wiredtiger.in @@ -823,9 +823,6 @@ struct __wt_session { * * @param session the session handle * @configstart{WT_SESSION.flush_tier, see dist/api_data.py} - * @config{flush_timestamp, flush objects to all storage sources using the specified - * timestamp. The value must not be older than the current oldest timestamp and it must not - * be newer than the stable timestamp., a string; default empty.} * @config{force, force sharing of all data., a boolean flag; default \c false.} * @config{lock_wait, wait for locks\, if \c lock_wait=false\, fail if any required locks * are not available immediately., a boolean flag; default \c true.} @@ -1829,13 +1826,13 @@ struct __wt_session { * @config{get, specify which timestamp to query: \c commit returns the most recently set * commit_timestamp; \c first_commit returns the first set commit_timestamp; \c prepare * returns the timestamp used in preparing a transaction; \c read returns the timestamp at - * which the transaction is reading at. See @ref timestamp_txn_api., a string\, chosen from + * which the transaction is reading. See @ref timestamp_txn_api., a string\, chosen from * the following options: \c "commit"\, \c "first_commit"\, \c "prepare"\, \c "read"; * default \c read.} * @configend + * + * A timestamp of 0 is returned if the timestamp is not available or has not been set. * @errors - * ::WT_NOTFOUND is returned if the session is not in a transaction or there is no matching - * timestamp. */ int __F(query_timestamp)( WT_SESSION *session, char *hex_timestamp, const char *config); @@ -1879,18 +1876,19 @@ struct __wt_session { int __F(timestamp_transaction)(WT_SESSION *session, const char *config); /*! - * Set a timestamp on a transaction numerically. Prefer this over @ref - * timestamp_transaction when the string parsing done in that method becomes a bottleneck. + * Set a timestamp on a transaction numerically. Prefer this method over + * WT_SESSION::timestamp_transaction if the hexadecimal string parsing done in that method + * becomes a bottleneck. + * + * The WT_SESSION.timestamp_transaction_uint method can only be used at snapshot isolation. * - * The WT_SESSION.timestamp_transaction_uint method can only be used at snapshot - * isolation. + * @snippet ex_all.c transaction timestamp_uint * * @requires_transaction * * @param session the session handle - * @param which the timestamp you wish to set. See @ref WT_TS_TXN_TYPE for available - * options, and @ref timestamp_transaction for constraints on when timestamps can be - * set. + * @param which the timestamp being set (see ::WT_TS_TXN_TYPE for available options, and + * WT_SESSION::timestamp_transaction for constraints on the timestamps). * @param ts the timestamp. * @errors */ @@ -2506,8 +2504,9 @@ struct __wt_connection { * "oldest_reader"\, \c "oldest_timestamp"\, \c "pinned"\, \c "recovery"\, \c "stable"\, \c * "stable_timestamp"; default \c all_durable.} * @configend + * + * A timestamp of 0 is returned if the timestamp is not available or has not been set. * @errors - * ::WT_NOTFOUND is returned if there is no matching timestamp. */ int __F(query_timestamp)( WT_CONNECTION *connection, char *hex_timestamp, const char *config); diff --git a/src/third_party/wiredtiger/src/txn/txn.c b/src/third_party/wiredtiger/src/txn/txn.c index 048935d3192..d6d01b1bdad 100644 --- a/src/third_party/wiredtiger/src/txn/txn.c +++ b/src/third_party/wiredtiger/src/txn/txn.c @@ -429,7 +429,7 @@ __wt_txn_update_oldest(WT_SESSION_IMPL *session, uint32_t flags) /* Try to move the pinned timestamp forward. */ if (strict) - WT_RET(__wt_txn_update_pinned_timestamp(session, false)); + __wt_txn_update_pinned_timestamp(session, false); /* * For pure read-only workloads, or if the update isn't forced and the oldest ID isn't too far @@ -2099,13 +2099,14 @@ __wt_txn_stats_update(WT_SESSION_IMPL *session) WT_STAT_SET(session, stats, txn_pinned_timestamp_oldest, durable_timestamp - txn_global->oldest_timestamp); - if (__wt_txn_get_pinned_timestamp(session, &oldest_active_read_timestamp, 0) == 0) { + __wt_txn_get_pinned_timestamp(session, &oldest_active_read_timestamp, 0); + if (oldest_active_read_timestamp == 0) { + WT_STAT_SET(session, stats, txn_timestamp_oldest_active_read, 0); + WT_STAT_SET(session, stats, txn_pinned_timestamp_reader, 0); + } else { WT_STAT_SET(session, stats, txn_timestamp_oldest_active_read, oldest_active_read_timestamp); WT_STAT_SET(session, stats, txn_pinned_timestamp_reader, durable_timestamp - oldest_active_read_timestamp); - } else { - WT_STAT_SET(session, stats, txn_timestamp_oldest_active_read, 0); - WT_STAT_SET(session, stats, txn_pinned_timestamp_reader, 0); } WT_STAT_SET(session, stats, txn_pinned_checkpoint_range, diff --git a/src/third_party/wiredtiger/src/txn/txn_timestamp.c b/src/third_party/wiredtiger/src/txn/txn_timestamp.c index 86df5e4339d..4e957a1bfb6 100644 --- a/src/third_party/wiredtiger/src/txn/txn_timestamp.c +++ b/src/third_party/wiredtiger/src/txn/txn_timestamp.c @@ -61,7 +61,7 @@ __wt_txn_parse_timestamp( { WT_RET(__wt_txn_parse_timestamp_raw(session, name, timestamp, cval)); if (cval->len != 0 && *timestamp == WT_TS_NONE) - WT_RET_MSG(session, EINVAL, "Failed to parse %s timestamp '%.*s': zero not permitted", name, + WT_RET_MSG(session, EINVAL, "illegal %s timestamp '%.*s': zero not permitted", name, (int)cval->len, cval->str); return (0); @@ -81,7 +81,7 @@ __txn_get_read_timestamp(WT_TXN_SHARED *txn_shared, wt_timestamp_t *read_timesta * __wt_txn_get_pinned_timestamp -- * Calculate the current pinned timestamp. */ -int +void __wt_txn_get_pinned_timestamp(WT_SESSION_IMPL *session, wt_timestamp_t *tsp, uint32_t flags) { WT_CONNECTION_IMPL *conn; @@ -96,8 +96,11 @@ __wt_txn_get_pinned_timestamp(WT_SESSION_IMPL *session, wt_timestamp_t *tsp, uin include_oldest = LF_ISSET(WT_TXN_TS_INCLUDE_OLDEST); txn_has_write_lock = LF_ISSET(WT_TXN_TS_ALREADY_LOCKED); - if (include_oldest && !txn_global->has_oldest_timestamp) - return (WT_NOTFOUND); + /* If including oldest and there's none set, we're done, nothing else matters. */ + if (include_oldest && !txn_global->has_oldest_timestamp) { + *tsp = 0; + return; + } if (!txn_has_write_lock) __wt_readlock(session, &txn_global->rwlock); @@ -111,9 +114,7 @@ __wt_txn_get_pinned_timestamp(WT_SESSION_IMPL *session, wt_timestamp_t *tsp, uin /* Walk the array of concurrent transactions. */ WT_ORDERED_READ(session_cnt, conn->session_cnt); - WT_STAT_CONN_INCR(session, txn_walk_sessions); for (i = 0, s = txn_global->txn_shared_list; i < session_cnt; i++, s++) { - WT_STAT_CONN_INCR(session, txn_sessions_walked); __txn_get_read_timestamp(s, &tmp_read_ts); /* * A zero timestamp is possible here only when the oldest timestamp is not accounted for. @@ -125,11 +126,10 @@ __wt_txn_get_pinned_timestamp(WT_SESSION_IMPL *session, wt_timestamp_t *tsp, uin if (!txn_has_write_lock) __wt_readunlock(session, &txn_global->rwlock); - if (!include_oldest && tmp_ts == 0) - return (WT_NOTFOUND); - *tsp = tmp_ts; + WT_STAT_CONN_INCR(session, txn_walk_sessions); + WT_STAT_CONN_INCRV(session, txn_sessions_walked, i); - return (0); + *tsp = tmp_ts; } /* @@ -162,53 +162,40 @@ __txn_global_query_timestamp(WT_SESSION_IMPL *session, wt_timestamp_t *tsp, cons WT_STAT_CONN_INCR(session, txn_query_ts); WT_RET(__wt_config_gets(session, cfg, "get", &cval)); if (WT_STRING_MATCH("all_durable", cval.str, cval.len)) { - if (!txn_global->has_durable_timestamp) - return (WT_NOTFOUND); - ts = txn_global->durable_timestamp; - WT_ASSERT(session, ts != WT_TS_NONE); + ts = txn_global->has_durable_timestamp ? txn_global->durable_timestamp : 0; __wt_readlock(session, &txn_global->rwlock); /* Walk the array of concurrent transactions. */ WT_ORDERED_READ(session_cnt, conn->session_cnt); - WT_STAT_CONN_INCR(session, txn_walk_sessions); for (i = 0, s = txn_global->txn_shared_list; i < session_cnt; i++, s++) { - WT_STAT_CONN_INCR(session, txn_sessions_walked); __txn_get_durable_timestamp(s, &tmpts); - if (tmpts != WT_TS_NONE && --tmpts < ts) + if (tmpts != 0 && (ts == 0 || --tmpts < ts)) ts = tmpts; } __wt_readunlock(session, &txn_global->rwlock); - /* - * If a transaction is committing with a durable timestamp of 1, we could return zero here, - * which is unexpected. Fail instead. - */ - if (ts == WT_TS_NONE) - return (WT_NOTFOUND); + WT_STAT_CONN_INCR(session, txn_walk_sessions); + WT_STAT_CONN_INCRV(session, txn_sessions_walked, i); } else if (WT_STRING_MATCH("last_checkpoint", cval.str, cval.len)) { /* Read-only value forever. Make sure we don't used a cached version. */ WT_BARRIER(); ts = txn_global->last_ckpt_timestamp; } else if (WT_STRING_MATCH("oldest_timestamp", cval.str, cval.len) || WT_STRING_MATCH("oldest", cval.str, cval.len)) { - if (!txn_global->has_oldest_timestamp) - return (WT_NOTFOUND); - ts = txn_global->oldest_timestamp; + ts = txn_global->has_oldest_timestamp ? txn_global->oldest_timestamp : 0; } else if (WT_STRING_MATCH("oldest_reader", cval.str, cval.len)) - WT_RET(__wt_txn_get_pinned_timestamp(session, &ts, WT_TXN_TS_INCLUDE_CKPT)); + __wt_txn_get_pinned_timestamp(session, &ts, WT_TXN_TS_INCLUDE_CKPT); else if (WT_STRING_MATCH("pinned", cval.str, cval.len)) - WT_RET(__wt_txn_get_pinned_timestamp( - session, &ts, WT_TXN_TS_INCLUDE_CKPT | WT_TXN_TS_INCLUDE_OLDEST)); + __wt_txn_get_pinned_timestamp( + session, &ts, WT_TXN_TS_INCLUDE_CKPT | WT_TXN_TS_INCLUDE_OLDEST); else if (WT_STRING_MATCH("recovery", cval.str, cval.len)) /* Read-only value forever. No lock needed. */ ts = txn_global->recovery_timestamp; else if (WT_STRING_MATCH("stable_timestamp", cval.str, cval.len) || WT_STRING_MATCH("stable", cval.str, cval.len)) { - if (!txn_global->has_stable_timestamp) - return (WT_NOTFOUND); - ts = txn_global->stable_timestamp; + ts = txn_global->has_stable_timestamp ? txn_global->stable_timestamp : 0; } else WT_RET_MSG(session, EINVAL, "unknown timestamp query %.*s", (int)cval.len, cval.str); @@ -231,8 +218,6 @@ __txn_query_timestamp(WT_SESSION_IMPL *session, wt_timestamp_t *tsp, const char txn_shared = WT_SESSION_TXN_SHARED(session); WT_STAT_CONN_INCR(session, session_query_ts); - if (!F_ISSET(txn, WT_TXN_RUNNING)) - return (WT_NOTFOUND); WT_RET(__wt_config_gets(session, cfg, "get", &cval)); if (WT_STRING_MATCH("commit", cval.str, cval.len)) @@ -273,10 +258,9 @@ __wt_txn_query_timestamp( * Update the pinned timestamp (the oldest timestamp that has to be maintained for current or * future readers). */ -int +void __wt_txn_update_pinned_timestamp(WT_SESSION_IMPL *session, bool force) { - WT_DECL_RET; WT_TXN_GLOBAL *txn_global; wt_timestamp_t last_pinned_timestamp, pinned_timestamp; @@ -284,18 +268,18 @@ __wt_txn_update_pinned_timestamp(WT_SESSION_IMPL *session, bool force) /* Skip locking and scanning when the oldest timestamp is pinned. */ if (txn_global->oldest_is_pinned) - return (0); + return; /* Scan to find the global pinned timestamp. */ - if ((ret = __wt_txn_get_pinned_timestamp( - session, &pinned_timestamp, WT_TXN_TS_INCLUDE_OLDEST)) != 0) - return (ret == WT_NOTFOUND ? 0 : ret); + __wt_txn_get_pinned_timestamp(session, &pinned_timestamp, WT_TXN_TS_INCLUDE_OLDEST); + if (pinned_timestamp == 0) + return; if (txn_global->has_pinned_timestamp && !force) { last_pinned_timestamp = txn_global->pinned_timestamp; if (pinned_timestamp <= last_pinned_timestamp) - return (0); + return; } __wt_writelock(session, &txn_global->rwlock); @@ -303,14 +287,12 @@ __wt_txn_update_pinned_timestamp(WT_SESSION_IMPL *session, bool force) * Scan the global pinned timestamp again, it's possible that it got changed after the previous * scan. */ - if ((ret = __wt_txn_get_pinned_timestamp( - session, &pinned_timestamp, WT_TXN_TS_ALREADY_LOCKED | WT_TXN_TS_INCLUDE_OLDEST)) != 0) { - __wt_writeunlock(session, &txn_global->rwlock); - return (ret == WT_NOTFOUND ? 0 : ret); - } + __wt_txn_get_pinned_timestamp( + session, &pinned_timestamp, WT_TXN_TS_ALREADY_LOCKED | WT_TXN_TS_INCLUDE_OLDEST); - if (!txn_global->has_pinned_timestamp || force || - txn_global->pinned_timestamp < pinned_timestamp) { + if (pinned_timestamp != 0 && + (!txn_global->has_pinned_timestamp || force || + txn_global->pinned_timestamp < pinned_timestamp)) { txn_global->pinned_timestamp = pinned_timestamp; txn_global->has_pinned_timestamp = true; txn_global->oldest_is_pinned = txn_global->pinned_timestamp == txn_global->oldest_timestamp; @@ -318,8 +300,6 @@ __wt_txn_update_pinned_timestamp(WT_SESSION_IMPL *session, bool force) __wt_verbose_timestamp(session, pinned_timestamp, "Updated pinned timestamp"); } __wt_writeunlock(session, &txn_global->rwlock); - - return (0); } /* @@ -472,7 +452,7 @@ set: __wt_writeunlock(session, &txn_global->rwlock); if (has_oldest || has_stable) - WT_RET(__wt_txn_update_pinned_timestamp(session, force)); + __wt_txn_update_pinned_timestamp(session, force); return (0); } @@ -996,11 +976,31 @@ int __wt_txn_set_timestamp_uint(WT_SESSION_IMPL *session, WT_TS_TXN_TYPE which, wt_timestamp_t ts) { WT_CONNECTION_IMPL *conn; + const char *name; WT_RET(__wt_txn_context_check(session, true)); conn = S2C(session); + if (ts == 0) { + name = "unknown"; + switch (which) { + case WT_TS_TXN_TYPE_COMMIT: + name = "commit"; + break; + case WT_TS_TXN_TYPE_DURABLE: + name = "durable"; + break; + case WT_TS_TXN_TYPE_PREPARE: + name = "prepare"; + break; + case WT_TS_TXN_TYPE_READ: + name = "read"; + break; + } + WT_RET_MSG(session, EINVAL, "illegal %s timestamp: zero not permitted", name); + } + switch (which) { case WT_TS_TXN_TYPE_COMMIT: WT_RET(__wt_txn_set_commit_timestamp(session, ts)); @@ -1008,12 +1008,12 @@ __wt_txn_set_timestamp_uint(WT_SESSION_IMPL *session, WT_TS_TXN_TYPE which, wt_t case WT_TS_TXN_TYPE_DURABLE: WT_RET(__wt_txn_set_durable_timestamp(session, ts)); break; - case WT_TS_TXN_TYPE_READ: - WT_RET(__wt_txn_set_read_timestamp(session, ts)); - break; case WT_TS_TXN_TYPE_PREPARE: WT_RET(__wt_txn_set_prepare_timestamp(session, ts)); break; + case WT_TS_TXN_TYPE_READ: + WT_RET(__wt_txn_set_read_timestamp(session, ts)); + break; } __wt_txn_publish_durable_timestamp(session); diff --git a/src/third_party/wiredtiger/test/checkpoint/checkpointer.c b/src/third_party/wiredtiger/test/checkpoint/checkpointer.c index 2a98774eaef..4d8fa97c0f2 100644 --- a/src/third_party/wiredtiger/test/checkpoint/checkpointer.c +++ b/src/third_party/wiredtiger/test/checkpoint/checkpointer.c @@ -197,7 +197,7 @@ real_checkpointer(void) if (g.use_timestamps) { testutil_check(g.conn->query_timestamp(g.conn, timestamp_buf, "get=stable_timestamp")); - testutil_timestamp_parse(timestamp_buf, &stable_ts); + stable_ts = testutil_timestamp_parse(timestamp_buf); oldest_ts = g.ts_oldest; if (stable_ts <= oldest_ts) verify_ts = stable_ts; diff --git a/src/third_party/wiredtiger/test/csuite/tiered_abort/main.c b/src/third_party/wiredtiger/test/csuite/tiered_abort/main.c index 3bcaf067094..a3ac29ccf5a 100644 --- a/src/third_party/wiredtiger/test/csuite/tiered_abort/main.c +++ b/src/third_party/wiredtiger/test/csuite/tiered_abort/main.c @@ -165,25 +165,26 @@ thread_ts_run(void *arg) testutil_check(td->conn->open_session(td->conn, NULL, NULL, &session)); /* Update the oldest timestamp every 1 millisecond. */ - for (;;) { + for (;; __wt_sleep(0, 1000)) { /* * We get the last committed timestamp periodically in order to update the oldest timestamp, - * that requires locking out transactional ops that set or query a timestamp. + * that requires locking out transactional ops that set or query a timestamp. If there is no + * work to do, all-durable will be 0 and we just wait. */ testutil_check(pthread_rwlock_wrlock(&ts_lock)); ret = td->conn->query_timestamp(td->conn, ts_string, "get=all_durable"); testutil_check(pthread_rwlock_unlock(&ts_lock)); - testutil_assert(ret == 0 || ret == WT_NOTFOUND); - if (ret == 0) { - /* - * Set both the oldest and stable timestamp so that we don't need to maintain read - * availability at older timestamps. - */ - testutil_check(__wt_snprintf(tscfg, sizeof(tscfg), - "oldest_timestamp=%s,stable_timestamp=%s", ts_string, ts_string)); - testutil_check(td->conn->set_timestamp(td->conn, tscfg)); - } - __wt_sleep(0, 1000); + testutil_assert(ret == 0); + if (testutil_timestamp_parse(ts_string) == 0) + continue; + + /* + * Set both the oldest and stable timestamp so that we don't need to maintain read + * availability at older timestamps. + */ + testutil_check(__wt_snprintf( + tscfg, sizeof(tscfg), "oldest_timestamp=%s,stable_timestamp=%s", ts_string, ts_string)); + testutil_check(td->conn->set_timestamp(td->conn, tscfg)); } /* NOTREACHED */ } diff --git a/src/third_party/wiredtiger/test/csuite/timestamp_abort/main.c b/src/third_party/wiredtiger/test/csuite/timestamp_abort/main.c index 02fe9ae2793..7ba89f2d72a 100644 --- a/src/third_party/wiredtiger/test/csuite/timestamp_abort/main.c +++ b/src/third_party/wiredtiger/test/csuite/timestamp_abort/main.c @@ -168,62 +168,57 @@ thread_ts_run(void *arg) testutil_check(td->conn->open_session(td->conn, NULL, NULL, &session)); first = true; /* Update the oldest timestamp every 1 millisecond. */ - for (;;) { + for (;; __wt_sleep(0, 1000)) { /* * We get the last committed timestamp periodically in order to update the oldest timestamp, - * that requires locking out transactional ops that set or query a timestamp. + * that requires locking out transactional ops that set or query a timestamp. If there is no + * work to do, all-durable will be 0 and we just wait. */ testutil_check(pthread_rwlock_wrlock(&ts_lock)); ret = td->conn->query_timestamp(td->conn, ts_string, "get=all_durable"); testutil_check(pthread_rwlock_unlock(&ts_lock)); - testutil_assert(ret == 0 || ret == WT_NOTFOUND); + testutil_assert(ret == 0); /* * All durable can intermittently move backwards, we do not want to set stable and the * oldest timestamps backwards. */ - all_dur_ts = strtoul(ts_string, NULL, 16); - if (!first && all_dur_ts < prev_all_dur_ts) { - __wt_sleep(0, 1000); + all_dur_ts = testutil_timestamp_parse(ts_string); + if (all_dur_ts == 0 || all_dur_ts < prev_all_dur_ts) continue; - } - if (ret == 0) { - rand_op = __wt_random(&rnd) % 4; - /* - * Periodically let the oldest timestamp lag. Other times set the stable and oldest - * timestamps as separate API calls. The rest of the time set them both as one call. - */ - if (rand_op == 0) { + prev_all_dur_ts = all_dur_ts; + + rand_op = __wt_random(&rnd) % 4; + /* + * Periodically let the oldest timestamp lag. Other times set the stable and oldest + * timestamps as separate API calls. The rest of the time set them both as one call. + */ + if (rand_op == 0) { + testutil_check(__wt_snprintf(tscfg, sizeof(tscfg), "stable_timestamp=%s", ts_string)); + testutil_check(td->conn->set_timestamp(td->conn, tscfg)); + testutil_check(__wt_snprintf(tscfg, sizeof(tscfg), "oldest_timestamp=%s", ts_string)); + testutil_check(td->conn->set_timestamp(td->conn, tscfg)); + } else { + if (!first && rand_op == 1) testutil_check( __wt_snprintf(tscfg, sizeof(tscfg), "stable_timestamp=%s", ts_string)); - testutil_check(td->conn->set_timestamp(td->conn, tscfg)); - testutil_check( - __wt_snprintf(tscfg, sizeof(tscfg), "oldest_timestamp=%s", ts_string)); - testutil_check(td->conn->set_timestamp(td->conn, tscfg)); - } else { - if (!first && rand_op == 1) - testutil_check( - __wt_snprintf(tscfg, sizeof(tscfg), "stable_timestamp=%s", ts_string)); - else - testutil_check(__wt_snprintf(tscfg, sizeof(tscfg), - "oldest_timestamp=%s,stable_timestamp=%s", ts_string, ts_string)); - testutil_check(td->conn->set_timestamp(td->conn, tscfg)); - } - prev_all_dur_ts = all_dur_ts; - first = false; - /* - * Set and reset the checkpoint retention setting on a regular basis. We want to test - * racing with the internal log removal thread while we're here. - */ - dbg = __wt_random(&rnd) % 2; - if (dbg == 0) - testutil_check( - __wt_snprintf(tscfg, sizeof(tscfg), "debug_mode=(checkpoint_retention=0)")); else - testutil_check( - __wt_snprintf(tscfg, sizeof(tscfg), "debug_mode=(checkpoint_retention=5)")); - testutil_check(td->conn->reconfigure(td->conn, tscfg)); + testutil_check(__wt_snprintf(tscfg, sizeof(tscfg), + "oldest_timestamp=%s,stable_timestamp=%s", ts_string, ts_string)); + testutil_check(td->conn->set_timestamp(td->conn, tscfg)); } - __wt_sleep(0, 1000); + first = false; + /* + * Set and reset the checkpoint retention setting on a regular basis. We want to test racing + * with the internal log removal thread while we're here. + */ + dbg = __wt_random(&rnd) % 2; + if (dbg == 0) + testutil_check( + __wt_snprintf(tscfg, sizeof(tscfg), "debug_mode=(checkpoint_retention=0)")); + else + testutil_check( + __wt_snprintf(tscfg, sizeof(tscfg), "debug_mode=(checkpoint_retention=5)")); + testutil_check(td->conn->reconfigure(td->conn, tscfg)); } /* NOTREACHED */ } diff --git a/src/third_party/wiredtiger/test/csuite/wt6616_checkpoint_oldest_ts/main.c b/src/third_party/wiredtiger/test/csuite/wt6616_checkpoint_oldest_ts/main.c index e6091f2b3dd..d38ed37417c 100644 --- a/src/third_party/wiredtiger/test/csuite/wt6616_checkpoint_oldest_ts/main.c +++ b/src/third_party/wiredtiger/test/csuite/wt6616_checkpoint_oldest_ts/main.c @@ -372,11 +372,11 @@ main(int argc, char *argv[]) /* Get the stable timestamp from the stable timestamp of the last successful checkpoint. */ testutil_check(conn->query_timestamp(conn, ts_string, "get=stable_timestamp")); - testutil_timestamp_parse(ts_string, &stable_ts); + stable_ts = testutil_timestamp_parse(ts_string); /* Get the oldest timestamp from the oldest timestamp of the last successful checkpoint. */ testutil_check(conn->query_timestamp(conn, ts_string, "get=oldest_timestamp")); - testutil_timestamp_parse(ts_string, &oldest_ts); + oldest_ts = testutil_timestamp_parse(ts_string); printf("Verify data from oldest timestamp %" PRIu64 " to stable timestamp %" PRIu64 "\n", oldest_ts, stable_ts); diff --git a/src/third_party/wiredtiger/test/csuite/wt8246_compact_rts_data_correctness/main.c b/src/third_party/wiredtiger/test/csuite/wt8246_compact_rts_data_correctness/main.c index b055edf8fbb..68467dd9468 100644 --- a/src/third_party/wiredtiger/test/csuite/wt8246_compact_rts_data_correctness/main.c +++ b/src/third_party/wiredtiger/test/csuite/wt8246_compact_rts_data_correctness/main.c @@ -130,11 +130,8 @@ run_test(bool column_store, const char *uri, bool preserve) WT_CONNECTION *conn; WT_SESSION *session; pid_t pid; - uint64_t oldest_ts, stable_ts; int status; - char compact_file[2048]; - char home[1024]; - char ts_string[WT_TS_HEX_STRING_SIZE]; + char compact_file[2048], home[1024]; testutil_work_dir_from_path( home, sizeof(home), column_store ? working_dir_col : working_dir_row); @@ -187,14 +184,6 @@ run_test(bool column_store, const char *uri, bool preserve) testutil_check(wiredtiger_open(home, NULL, ENV_CONFIG_REC, &conn)); testutil_check(conn->open_session(conn, NULL, NULL, &session)); - /* Get the stable timestamp from the stable timestamp of the last successful checkpoint. */ - testutil_check(conn->query_timestamp(conn, ts_string, "get=stable_timestamp")); - testutil_timestamp_parse(ts_string, &stable_ts); - - /* Get the oldest timestamp from the oldest timestamp of the last successful checkpoint. */ - testutil_check(conn->query_timestamp(conn, ts_string, "get=oldest_timestamp")); - testutil_timestamp_parse(ts_string, &oldest_ts); - /* * Verify data is visible and correct after compact operation was killed and RTS is performed in * recovery. Stable timestamp is used to check the visibility of data, stable timestamp is diff --git a/src/third_party/wiredtiger/test/format/util.c b/src/third_party/wiredtiger/test/format/util.c index d0566e456a4..b7f7e533dd1 100644 --- a/src/third_party/wiredtiger/test/format/util.c +++ b/src/third_party/wiredtiger/test/format/util.c @@ -295,7 +295,7 @@ timestamp_once(WT_SESSION *session, bool allow_lag, bool final) g.oldest_timestamp = g.stable_timestamp = ++g.timestamp; else { if ((ret = conn->query_timestamp(conn, buf, "get=all_durable")) == 0) - testutil_timestamp_parse(buf, &all_durable); + all_durable = testutil_timestamp_parse(buf); else { testutil_assert(ret == WT_NOTFOUND); lock_writeunlock(session, &g.ts_lock); @@ -385,7 +385,7 @@ set_oldest_timestamp(void) conn = g.wts_conn; if ((ret = conn->query_timestamp(conn, tsbuf, "get=oldest_timestamp")) == 0) { - testutil_timestamp_parse(tsbuf, &oldest_ts); + oldest_ts = testutil_timestamp_parse(tsbuf); g.timestamp = oldest_ts; testutil_check( __wt_snprintf(buf, sizeof(buf), "%s%" PRIx64, oldest_timestamp_str, g.oldest_timestamp)); diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp08.py b/src/third_party/wiredtiger/test/suite/test_timestamp08.py index 844aba62362..01ff424bb99 100644 --- a/src/third_party/wiredtiger/test/suite/test_timestamp08.py +++ b/src/third_party/wiredtiger/test/suite/test_timestamp08.py @@ -47,10 +47,14 @@ class test_timestamp08(wttest.WiredTigerTestCase, suite_subprocess): self.session.commit_transaction( 'commit_timestamp=' + self.timestamp_str(1)) - # Can set a zero timestamp. These calls shouldn't raise any errors. + # Cannot set a zero timestamp. self.session.begin_transaction() - self.session.timestamp_transaction_uint(wiredtiger.WT_TS_TXN_TYPE_COMMIT, 0) - self.session.timestamp_transaction_uint(wiredtiger.WT_TS_TXN_TYPE_READ, 0) + self.assertRaisesWithMessage(wiredtiger.WiredTigerError, + lambda: self.session.timestamp_transaction_uint(wiredtiger.WT_TS_TXN_TYPE_COMMIT, 0), + '/zero not permitted/') + self.assertRaisesWithMessage(wiredtiger.WiredTigerError, + lambda: self.session.timestamp_transaction_uint(wiredtiger.WT_TS_TXN_TYPE_READ, 0), + '/zero not permitted/') self.session.rollback_transaction() # In a single transaction it is illegal to set a commit timestamp diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp13.py b/src/third_party/wiredtiger/test/suite/test_timestamp13.py index ae4898c75bb..81a9b6d1671 100644 --- a/src/third_party/wiredtiger/test/suite/test_timestamp13.py +++ b/src/third_party/wiredtiger/test/suite/test_timestamp13.py @@ -50,11 +50,9 @@ class test_timestamp13(wttest.WiredTigerTestCase, suite_subprocess): 'key_format=i,value_format=i' + self.extra_config) query_choices = ['commit', 'first_commit', 'prepare', 'read'] - # Querying a session's timestamps will error when not in a transaction. + # Querying a session's timestamps when not in a transaction returns not-set values. for query in query_choices: - self.assertRaises( - wiredtiger.WiredTigerError, - lambda: self.session.query_timestamp('get=' + query)) + self.assertEqual(self.session.query_timestamp('get=' + query), "0") self.session.begin_transaction() # Nothing has been set, all queries will return timestamp 0. @@ -68,11 +66,9 @@ class test_timestamp13(wttest.WiredTigerTestCase, suite_subprocess): '/not a permitted choice for key/') self.session.rollback_transaction() - # Querying a session's timestamps will error when not in a transaction. + # Querying a session's timestamps when not in a transaction will return 0. for query in query_choices: - self.assertRaises( - wiredtiger.WiredTigerError, - lambda: self.session.query_timestamp('get=' + query)) + self.assertEqual(self.session.query_timestamp('get=' + query), '0') def test_query_read_commit_timestamps(self): self.session.create(self.uri, diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp14.py b/src/third_party/wiredtiger/test/suite/test_timestamp14.py index 27f428d9b9e..bf1e57d7639 100644 --- a/src/third_party/wiredtiger/test/suite/test_timestamp14.py +++ b/src/third_party/wiredtiger/test/suite/test_timestamp14.py @@ -63,8 +63,7 @@ class test_timestamp14(wttest.WiredTigerTestCase, suite_subprocess): cur1 = session1.open_cursor(all_durable_uri) cur1[1]=1 session1.commit_transaction() - self.assertRaisesException(wiredtiger.WiredTigerError, - lambda: self.conn.query_timestamp('get=all_durable')) + self.assertEquals(self.conn.query_timestamp('get=all_durable'), "0") # Scenario 1: A single transaction with a commit timestamp, will # result in the all_durable timestamp being set. @@ -143,8 +142,7 @@ class test_timestamp14(wttest.WiredTigerTestCase, suite_subprocess): session2.create(oldest_reader_uri, format) # Nothing is reading so there is no oldest reader. - self.assertRaisesException(wiredtiger.WiredTigerError, - lambda: self.conn.query_timestamp('get=oldest_reader')) + self.assertEquals(self.conn.query_timestamp('get=oldest_reader'), "0") # Write some data for reading. session1.begin_transaction() @@ -153,8 +151,7 @@ class test_timestamp14(wttest.WiredTigerTestCase, suite_subprocess): session1.commit_transaction('commit_timestamp=5') # No active sessions so no oldest reader. - self.assertRaisesException(wiredtiger.WiredTigerError, - lambda: self.conn.query_timestamp('get=oldest_reader')) + self.assertEquals(self.conn.query_timestamp('get=oldest_reader'), "0") # Create an active read session. session1.begin_transaction('read_timestamp=5') @@ -191,8 +188,7 @@ class test_timestamp14(wttest.WiredTigerTestCase, suite_subprocess): # Now that all read transactions have completed we will be back # to having no oldest reader. - self.assertRaisesException(wiredtiger.WiredTigerError, - lambda: self.conn.query_timestamp('get=oldest_reader')) + self.assertEquals(self.conn.query_timestamp('get=oldest_reader'), "0") def test_pinned_oldest(self): pinned_oldest_uri = self.uri + 'pinned_oldest' @@ -200,12 +196,10 @@ class test_timestamp14(wttest.WiredTigerTestCase, suite_subprocess): format = 'key_format={},value_format={}'.format(self.key_format, self.value_format) session1.create(pinned_oldest_uri, format) # Confirm no oldest timestamp exists. - self.assertRaisesException(wiredtiger.WiredTigerError, - lambda: self.conn.query_timestamp('get=oldest_timestamp')) + self.assertEquals(self.conn.query_timestamp('get=oldest_timestamp'), "0") # Confirm no pinned timestamp exists. - self.assertRaisesException(wiredtiger.WiredTigerError, - lambda: self.conn.query_timestamp('get=pinned')) + self.assertEquals(self.conn.query_timestamp('get=pinned'), "0") # Write some data for reading. session1.begin_transaction() @@ -214,12 +208,10 @@ class test_timestamp14(wttest.WiredTigerTestCase, suite_subprocess): session1.commit_transaction('commit_timestamp=5') # Confirm no oldest timestamp exists. - self.assertRaisesException(wiredtiger.WiredTigerError, - lambda: self.conn.query_timestamp('get=oldest_timestamp')) + self.assertEquals(self.conn.query_timestamp('get=oldest_timestamp'), "0") # Confirm no pinned timestamp exists. - self.assertRaisesException(wiredtiger.WiredTigerError, - lambda: self.conn.query_timestamp('get=pinned')) + self.assertEquals(self.conn.query_timestamp('get=pinned'), "0") self.conn.set_timestamp('oldest_timestamp=5') diff --git a/src/third_party/wiredtiger/test/utility/misc.c b/src/third_party/wiredtiger/test/utility/misc.c index 9e9c11e0a3c..ea808e14c41 100644 --- a/src/third_party/wiredtiger/test/utility/misc.c +++ b/src/third_party/wiredtiger/test/utility/misc.c @@ -261,19 +261,6 @@ testutil_clean_test_artifacts(const char *dir) } /* - * testutil_timestamp_parse -- - * Parse a timestamp to an integral value. - */ -void -testutil_timestamp_parse(const char *str, uint64_t *tsp) -{ - char *p; - - *tsp = __wt_strtouq(str, &p, 16); - testutil_assert(p - str <= 16); -} - -/* * testutil_create_backup_directory -- * TODO: Add a comment describing this function. */ diff --git a/src/third_party/wiredtiger/test/utility/test_util.h b/src/third_party/wiredtiger/test/utility/test_util.h index 38457022191..7c45587358a 100644 --- a/src/third_party/wiredtiger/test/utility/test_util.h +++ b/src/third_party/wiredtiger/test/utility/test_util.h @@ -234,6 +234,12 @@ typedef struct { */ #define scan_end_check(a) testutil_assert(a) +#ifdef _WIN32 +__declspec(noreturn) +#endif + void testutil_die(int, const char *, ...) WT_GCC_FUNC_ATTRIBUTE((cold)) + WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); + /* * u64_to_string -- * Convert a uint64_t to a text string. Algorithm from Andrei Alexandrescu's talk: "Three @@ -289,15 +295,24 @@ u64_to_string_zf(uint64_t n, char *buf, size_t len) *--p = '0'; } +/* + * testutil_timestamp_parse -- + * Parse a timestamp to an integral value. + */ +static inline uint64_t +testutil_timestamp_parse(const char *str) +{ + uint64_t ts; + char *p; + + ts = __wt_strtouq(str, &p, 16); + testutil_assert((size_t)(p - str) <= WT_TS_HEX_STRING_SIZE); + return (ts); +} + /* Allow tests to add their own death handling. */ extern void (*custom_die)(void); -#ifdef _WIN32 -__declspec(noreturn) -#endif - void testutil_die(int, const char *, ...) WT_GCC_FUNC_ATTRIBUTE((cold)) - WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); - void *dcalloc(size_t, size_t); void *dmalloc(size_t); void *drealloc(void *, size_t); @@ -333,7 +348,6 @@ void testutil_progress(TEST_OPTS *, const char *); #ifndef _WIN32 void testutil_sleep_wait(uint32_t, pid_t); #endif -void testutil_timestamp_parse(const char *, uint64_t *); void testutil_work_dir_from_path(char *, size_t, const char *); WT_THREAD_RET thread_append(void *); |