summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Chen <luke.chen@mongodb.com>2021-01-27 13:28:13 +1100
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-01-27 03:07:52 +0000
commit77d134c7a2bab846aaaa056b0883888a8219da2a (patch)
tree8caac27a3573139d221fdf93ba9c99b3e042bc78
parent5fad1f69662696c5b789392622aa34d370fb4825 (diff)
downloadmongo-77d134c7a2bab846aaaa056b0883888a8219da2a.tar.gz
Import wiredtiger: a52cd5a47a7e9af9e2c341e66f0ffdd9bc977930 from branch mongodb-4.4
ref: ef1f2937c3..a52cd5a47a for: 4.4.4 WT-6309 Add support for start/stop arguments to wt printlog command WT-6866 Refactor python backup tests initial base class WT-6924 Queue history store pages for urgent eviction when cache pressure is high WT-6946 Adding test tags to an initial set of test programs WT-7068 Add column store support to test_hs03 WT-7084 Fix assert in test code and a comment error WT-7109 Retain no longer supported configuration options for backward compatibility WT-7113 Integrate prototype tiered storage code into WT WT-7114 Revert Makefile code to always run the prototype script
-rw-r--r--src/third_party/wiredtiger/dist/api_data.py49
-rw-r--r--src/third_party/wiredtiger/dist/filelist2
-rw-r--r--src/third_party/wiredtiger/dist/s_string.ok2
-rw-r--r--src/third_party/wiredtiger/dist/stat_data.py2
-rw-r--r--src/third_party/wiredtiger/import.data2
-rw-r--r--src/third_party/wiredtiger/src/block/block_addr.c81
-rw-r--r--src/third_party/wiredtiger/src/block/block_ckpt.c51
-rw-r--r--src/third_party/wiredtiger/src/block/block_ckpt_scan.c7
-rw-r--r--src/third_party/wiredtiger/src/block/block_compact.c4
-rw-r--r--src/third_party/wiredtiger/src/block/block_ext.c36
-rw-r--r--src/third_party/wiredtiger/src/block/block_open.c15
-rw-r--r--src/third_party/wiredtiger/src/block/block_read.c91
-rw-r--r--src/third_party/wiredtiger/src/block/block_slvg.c17
-rw-r--r--src/third_party/wiredtiger/src/block/block_vrfy.c4
-rw-r--r--src/third_party/wiredtiger/src/block/block_write.c26
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_debug.c4
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_handle.c5
-rw-r--r--src/third_party/wiredtiger/src/config/config_def.c170
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_api.c2
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_dhandle.c17
-rw-r--r--src/third_party/wiredtiger/src/cursor/cur_backup.c3
-rw-r--r--src/third_party/wiredtiger/src/cursor/cur_log.c4
-rw-r--r--src/third_party/wiredtiger/src/evict/evict_lru.c35
-rw-r--r--src/third_party/wiredtiger/src/include/block.h8
-rw-r--r--src/third_party/wiredtiger/src/include/cache.h8
-rw-r--r--src/third_party/wiredtiger/src/include/cache_inline.h18
-rw-r--r--src/third_party/wiredtiger/src/include/config.h9
-rw-r--r--src/third_party/wiredtiger/src/include/connection.h11
-rw-r--r--src/third_party/wiredtiger/src/include/dhandle.h2
-rw-r--r--src/third_party/wiredtiger/src/include/extern.h55
-rw-r--r--src/third_party/wiredtiger/src/include/stat.h3
-rw-r--r--src/third_party/wiredtiger/src/include/tiered.h44
-rw-r--r--src/third_party/wiredtiger/src/include/wiredtiger.in982
-rw-r--r--src/third_party/wiredtiger/src/include/wt_internal.h5
-rw-r--r--src/third_party/wiredtiger/src/log/log.c30
-rw-r--r--src/third_party/wiredtiger/src/schema/schema_alter.c2
-rw-r--r--src/third_party/wiredtiger/src/schema/schema_create.c2
-rw-r--r--src/third_party/wiredtiger/src/schema/schema_drop.c2
-rw-r--r--src/third_party/wiredtiger/src/schema/schema_rename.c2
-rw-r--r--src/third_party/wiredtiger/src/schema/schema_truncate.c2
-rw-r--r--src/third_party/wiredtiger/src/schema/schema_worker.c2
-rw-r--r--src/third_party/wiredtiger/src/session/session_api.c5
-rw-r--r--src/third_party/wiredtiger/src/session/session_compact.c4
-rw-r--r--src/third_party/wiredtiger/src/support/err.c2
-rw-r--r--src/third_party/wiredtiger/src/support/stat.c13
-rw-r--r--src/third_party/wiredtiger/src/tiered/tiered_cursor.c1186
-rw-r--r--src/third_party/wiredtiger/src/tiered/tiered_schema.c255
-rw-r--r--src/third_party/wiredtiger/src/txn/txn_log.c6
-rw-r--r--src/third_party/wiredtiger/src/txn/txn_recover.c10
-rw-r--r--src/third_party/wiredtiger/src/utilities/util_list.c33
-rw-r--r--src/third_party/wiredtiger/src/utilities/util_load.c5
-rw-r--r--src/third_party/wiredtiger/src/utilities/util_printlog.c37
-rw-r--r--src/third_party/wiredtiger/test/csuite/wt3363_checkpoint_op_races/main.c7
-rwxr-xr-xsrc/third_party/wiredtiger/test/suite/suite_subprocess.py31
-rw-r--r--src/third_party/wiredtiger/test/suite/test_backup01.py47
-rw-r--r--src/third_party/wiredtiger/test/suite/test_backup03.py44
-rwxr-xr-xsrc/third_party/wiredtiger/test/suite/test_backup04.py41
-rw-r--r--src/third_party/wiredtiger/test/suite/test_backup06.py17
-rw-r--r--src/third_party/wiredtiger/test/suite/test_backup07.py22
-rw-r--r--src/third_party/wiredtiger/test/suite/test_backup10.py22
-rw-r--r--src/third_party/wiredtiger/test/suite/test_backup11.py24
-rw-r--r--src/third_party/wiredtiger/test/suite/test_backup12.py31
-rw-r--r--src/third_party/wiredtiger/test/suite/test_backup13.py43
-rw-r--r--src/third_party/wiredtiger/test/suite/test_backup14.py107
-rw-r--r--src/third_party/wiredtiger/test/suite/test_backup15.py51
-rw-r--r--src/third_party/wiredtiger/test/suite/test_backup16.py37
-rw-r--r--src/third_party/wiredtiger/test/suite/test_backup17.py30
-rw-r--r--src/third_party/wiredtiger/test/suite/test_backup18.py19
-rw-r--r--src/third_party/wiredtiger/test/suite/test_backup19.py52
-rw-r--r--src/third_party/wiredtiger/test/suite/test_base01.py4
-rwxr-xr-xsrc/third_party/wiredtiger/test/suite/test_checkpoint02.py5
-rw-r--r--src/third_party/wiredtiger/test/suite/test_checkpoint03.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_hs03.py9
-rw-r--r--src/third_party/wiredtiger/test/suite/test_lsm01.py2
-rw-r--r--src/third_party/wiredtiger/test/suite/test_tiered01.py75
-rw-r--r--src/third_party/wiredtiger/test/suite/test_txn08.py41
-rw-r--r--src/third_party/wiredtiger/test/suite/wtbackup.py149
77 files changed, 3103 insertions, 1183 deletions
diff --git a/src/third_party/wiredtiger/dist/api_data.py b/src/third_party/wiredtiger/dist/api_data.py
index 247a4777d29..738d53d32a1 100644
--- a/src/third_party/wiredtiger/dist/api_data.py
+++ b/src/third_party/wiredtiger/dist/api_data.py
@@ -48,6 +48,14 @@ common_runtime_config = [
Config('assert', '', r'''
enable enhanced checking. ''',
type='category', subconfig= [
+ Config('commit_timestamp', 'none', r'''
+ This option is no longer supported. Retained for backward
+ compatibility. Use \c write_timestamp option instead.''',
+ choices=['always', 'key_consistent', 'never', 'none']),
+ Config('durable_timestamp', 'none', r'''
+ This option is no longer supported. Retained for backward
+ compatibility. Use \c write_timestamp option instead.''',
+ choices=['always', 'key_consistent', 'never', 'none']),
Config('write_timestamp', 'off', r'''
verify that commit timestamps are used per the configured
\c write_timestamp_usage option for this table''',
@@ -197,6 +205,20 @@ lsm_config = [
]),
]
+tiered_config = common_runtime_config + [
+ Config('tiered', '', r'''
+ options only relevant for tiered data sources''',
+ type='category', subconfig=[
+ Config('chunk_size', '1GB', r'''
+ the maximum size of the hot chunk of tiered tree. This
+ limit is soft - it is possible for chunks to be temporarily
+ larger than this value''',
+ min='1M'),
+ Config('tiers', '', r'''
+ list of data sources to combine into a tiered storage structure''', type='list')
+ ]),
+]
+
file_runtime_config = common_runtime_config + [
Config('access_pattern_hint', 'none', r'''
It is recommended that workloads that consist primarily of
@@ -229,16 +251,20 @@ file_runtime_config = common_runtime_config + [
system buffer cache after that many bytes from this object are
written into the buffer cache''',
min=0),
+ Config('readonly', 'false', r'''
+ the file is read-only. All methods that may modify a file are
+ disabled. See @ref readonly for more information''',
+ type='boolean'),
]
# Per-file configuration
file_config = format_meta + file_runtime_config + [
Config('block_allocation', 'best', r'''
- configure block allocation. Permitted values are \c "first" or
- \c "best"; the \c "first" configuration uses a first-available
- algorithm during block allocation, the \c "best" configuration
- uses a best-fit algorithm''',
- choices=['first', 'best',]),
+ configure block allocation. Permitted values are \c "best" or \c "first";
+ the \c "best" configuration uses a best-fit algorithm,
+ the \c "first" configuration uses a first-available algorithm during block allocation,
+ the \c "log-structure" configuration allocates a new file for each checkpoint''',
+ choices=['best', 'first', 'log-structured',]),
Config('allocation_size', '4KB', r'''
the file unit allocation size, in bytes, must a power-of-two;
smaller values decrease the file space required by overflow
@@ -284,6 +310,9 @@ file_config = format_meta + file_runtime_config + [
Config('format', 'btree', r'''
the file format''',
choices=['btree']),
+ Config('huffman_key', 'none', r'''
+ This option is no longer supported. Retained for backward
+ compatibility. See @ref huffman for more information'''),
Config('huffman_value', 'none', r'''
configure Huffman encoding for values. Permitted values are
\c "none", \c "english", \c "utf8<file>" or \c "utf16<file>".
@@ -409,6 +438,8 @@ lsm_meta = file_config + lsm_config + [
obsolete chunks in the LSM tree'''),
]
+tiered_meta = tiered_config
+
table_only_config = [
Config('colgroups', '', r'''
comma-separated list of names of column groups. Each column
@@ -1141,11 +1172,15 @@ methods = {
'table.meta' : Method(table_meta),
+'tiered.meta' : Method(tiered_meta),
+
'WT_CURSOR.close' : Method([]),
'WT_CURSOR.reconfigure' : Method(cursor_runtime_config),
'WT_SESSION.alter' : Method(file_runtime_config + [
+ Config('checkpoint', '', r'''
+ the file checkpoint entries''', undoc=True),
Config('exclusive_refreshed', 'true', r'''
refresh the in memory state and flush the metadata change to disk,
disabling this flag is dangerous - it will only re-write the
@@ -1165,8 +1200,8 @@ methods = {
type='int'),
]),
-'WT_SESSION.create' : Method(file_config + lsm_config + source_meta +
- index_only_config + table_only_config + [
+'WT_SESSION.create' : Method(file_config + lsm_config + tiered_config +
+ source_meta + index_only_config + table_only_config + [
Config('exclusive', 'false', r'''
fail if the object exists. When false (the default), if the
object exists, check that its settings match the specified
diff --git a/src/third_party/wiredtiger/dist/filelist b/src/third_party/wiredtiger/dist/filelist
index 00ce38d68ef..7bbc5e5596a 100644
--- a/src/third_party/wiredtiger/dist/filelist
+++ b/src/third_party/wiredtiger/dist/filelist
@@ -206,6 +206,8 @@ src/support/scratch.c
src/support/stat.c
src/support/thread_group.c
src/support/timestamp.c
+src/tiered/tiered_cursor.c
+src/tiered/tiered_schema.c
src/txn/txn.c
src/txn/txn_ckpt.c
src/txn/txn_ext.c
diff --git a/src/third_party/wiredtiger/dist/s_string.ok b/src/third_party/wiredtiger/dist/s_string.ok
index 9fe47b19315..a60c3165259 100644
--- a/src/third_party/wiredtiger/dist/s_string.ok
+++ b/src/third_party/wiredtiger/dist/s_string.ok
@@ -645,6 +645,7 @@ cursoring
cursorp
curstat
curtable
+curtiered
cust
customp
cv
@@ -954,6 +955,7 @@ libs
libtool
libwiredtiger
linkers
+liveness
llll
llu
llvm
diff --git a/src/third_party/wiredtiger/dist/stat_data.py b/src/third_party/wiredtiger/dist/stat_data.py
index d2c1ee31e96..997337c7896 100644
--- a/src/third_party/wiredtiger/dist/stat_data.py
+++ b/src/third_party/wiredtiger/dist/stat_data.py
@@ -231,6 +231,7 @@ connection_stats = [
CacheStat('cache_eviction_pages_queued_oldest', 'pages queued for urgent eviction during walk'),
CacheStat('cache_eviction_pages_queued_post_lru', 'pages queued for eviction post lru sorting'),
CacheStat('cache_eviction_pages_queued_urgent', 'pages queued for urgent eviction'),
+ CacheStat('cache_eviction_pages_queued_urgent_hs_dirty', 'pages queued for urgent eviction from history store due to high dirty content'),
CacheStat('cache_eviction_pages_already_queued', 'pages seen by eviction walk that are already queued'),
CacheStat('cache_eviction_pages_in_parallel_with_checkpoint', 'pages evicted in parallel with checkpoint'),
CacheStat('cache_eviction_queue_empty', 'eviction server candidate queue empty when topping up'),
@@ -764,6 +765,7 @@ conn_dsrc_stats = [
CacheStat('cache_eviction_target_page_lt128', 'eviction walk target pages histogram - 64-128'),
CacheStat('cache_eviction_target_page_lt32', 'eviction walk target pages histogram - 10-31'),
CacheStat('cache_eviction_target_page_lt64', 'eviction walk target pages histogram - 32-63'),
+ CacheStat('cache_eviction_target_page_reduced', 'eviction walk target pages reduced due to history store cache pressure'),
CacheStat('cache_eviction_walk_from_root', 'eviction walks started from root of tree'),
CacheStat('cache_eviction_walk_restart', 'eviction walks restarted'),
CacheStat('cache_eviction_walk_saved_pos', 'eviction walks started from saved location in tree'),
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data
index 67302efc1b0..eb0dde936e8 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-4.4",
- "commit": "ef1f2937c3939dea0e251b8c7c499eb8c1506483"
+ "commit": "a52cd5a47a7e9af9e2c341e66f0ffdd9bc977930"
}
diff --git a/src/third_party/wiredtiger/src/block/block_addr.c b/src/third_party/wiredtiger/src/block/block_addr.c
index f9bd4248642..312db74a24c 100644
--- a/src/third_party/wiredtiger/src/block/block_addr.c
+++ b/src/third_party/wiredtiger/src/block/block_addr.c
@@ -14,11 +14,15 @@
* reference so it can be called repeatedly to load a buffer.
*/
static int
-__block_buffer_to_addr(
- uint32_t allocsize, const uint8_t **pp, wt_off_t *offsetp, uint32_t *sizep, uint32_t *checksump)
+__block_buffer_to_addr(WT_BLOCK *block, const uint8_t **pp, uint32_t *logidp, wt_off_t *offsetp,
+ uint32_t *sizep, uint32_t *checksump)
{
- uint64_t o, s, c;
+ uint64_t l, o, s, c;
+ if (block->log_structured)
+ WT_RET(__wt_vunpack_uint(pp, 0, &l));
+ else
+ l = 0;
WT_RET(__wt_vunpack_uint(pp, 0, &o));
WT_RET(__wt_vunpack_uint(pp, 0, &s));
WT_RET(__wt_vunpack_uint(pp, 0, &c));
@@ -37,10 +41,11 @@ __block_buffer_to_addr(
*/
if (s == 0) {
*offsetp = 0;
- *sizep = *checksump = 0;
+ *logidp = *sizep = *checksump = 0;
} else {
- *offsetp = (wt_off_t)(o + 1) * allocsize;
- *sizep = (uint32_t)s * allocsize;
+ *logidp = (uint32_t)l;
+ *offsetp = (wt_off_t)(o + 1) * block->allocsize;
+ *sizep = (uint32_t)s * block->allocsize;
*checksump = (uint32_t)c;
}
return (0);
@@ -52,19 +57,22 @@ __block_buffer_to_addr(
*/
int
__wt_block_addr_to_buffer(
- WT_BLOCK *block, uint8_t **pp, wt_off_t offset, uint32_t size, uint32_t checksum)
+ WT_BLOCK *block, uint8_t **pp, uint32_t logid, wt_off_t offset, uint32_t size, uint32_t checksum)
{
- uint64_t o, s, c;
+ uint64_t l, o, s, c;
/* See the comment above: this is the reverse operation. */
if (size == 0) {
o = WT_BLOCK_INVALID_OFFSET;
- s = c = 0;
+ l = s = c = 0;
} else {
+ l = logid;
o = (uint64_t)offset / block->allocsize - 1;
s = size / block->allocsize;
c = checksum;
}
+ if (block->log_structured)
+ WT_RET(__wt_vpack_uint(pp, 0, l));
WT_RET(__wt_vpack_uint(pp, 0, o));
WT_RET(__wt_vpack_uint(pp, 0, s));
WT_RET(__wt_vpack_uint(pp, 0, c));
@@ -77,10 +85,10 @@ __wt_block_addr_to_buffer(
* reference.
*/
int
-__wt_block_buffer_to_addr(
- WT_BLOCK *block, const uint8_t *p, wt_off_t *offsetp, uint32_t *sizep, uint32_t *checksump)
+__wt_block_buffer_to_addr(WT_BLOCK *block, const uint8_t *p, uint32_t *logidp, wt_off_t *offsetp,
+ uint32_t *sizep, uint32_t *checksump)
{
- return (__block_buffer_to_addr(block->allocsize, &p, offsetp, sizep, checksump));
+ return (__block_buffer_to_addr(block, &p, logidp, offsetp, sizep, checksump));
}
/*
@@ -92,14 +100,14 @@ __wt_block_addr_invalid(
WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr, size_t addr_size, bool live)
{
wt_off_t offset;
- uint32_t checksum, size;
+ uint32_t checksum, logid, size;
WT_UNUSED(session);
WT_UNUSED(addr_size);
WT_UNUSED(live);
/* Crack the cookie. */
- WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum));
+ WT_RET(__wt_block_buffer_to_addr(block, addr, &logid, &offset, &size, &checksum));
#ifdef HAVE_DIAGNOSTIC
/*
@@ -111,7 +119,7 @@ __wt_block_addr_invalid(
#endif
/* Check if the address is past the end of the file. */
- return (offset + size > block->size ? EINVAL : 0);
+ return (logid == block->logid && offset + size > block->size ? EINVAL : 0);
}
/*
@@ -123,15 +131,16 @@ __wt_block_addr_string(
WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, const uint8_t *addr, size_t addr_size)
{
wt_off_t offset;
- uint32_t checksum, size;
+ uint32_t checksum, logid, size;
WT_UNUSED(addr_size);
/* Crack the cookie. */
- WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum));
+ WT_RET(__wt_block_buffer_to_addr(block, addr, &logid, &offset, &size, &checksum));
/* Printable representation. */
- WT_RET(__wt_buf_fmt(session, buf, "[%" PRIuMAX "-%" PRIuMAX ", %" PRIu32 ", %" PRIu32 "]",
+ WT_RET(__wt_buf_fmt(session, buf,
+ "[%" PRIu32 ": %" PRIuMAX "-%" PRIuMAX ", %" PRIu32 ", %" PRIu32 "]", logid,
(uintmax_t)offset, (uintmax_t)offset + size, size, checksum));
return (0);
@@ -143,7 +152,7 @@ __wt_block_addr_string(
*/
static int
__block_buffer_to_ckpt(
- WT_SESSION_IMPL *session, uint32_t allocsize, const uint8_t *p, WT_BLOCK_CKPT *ci)
+ WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *p, WT_BLOCK_CKPT *ci)
{
uint64_t a;
const uint8_t **pp;
@@ -153,14 +162,14 @@ __block_buffer_to_ckpt(
WT_RET_MSG(session, WT_ERROR, "unsupported checkpoint version");
pp = &p;
- WT_RET(
- __block_buffer_to_addr(allocsize, pp, &ci->root_offset, &ci->root_size, &ci->root_checksum));
WT_RET(__block_buffer_to_addr(
- allocsize, pp, &ci->alloc.offset, &ci->alloc.size, &ci->alloc.checksum));
+ block, pp, &ci->root_logid, &ci->root_offset, &ci->root_size, &ci->root_checksum));
WT_RET(__block_buffer_to_addr(
- allocsize, pp, &ci->avail.offset, &ci->avail.size, &ci->avail.checksum));
+ block, pp, &ci->alloc.logid, &ci->alloc.offset, &ci->alloc.size, &ci->alloc.checksum));
WT_RET(__block_buffer_to_addr(
- allocsize, pp, &ci->discard.offset, &ci->discard.size, &ci->discard.checksum));
+ block, pp, &ci->avail.logid, &ci->avail.offset, &ci->avail.size, &ci->avail.checksum));
+ WT_RET(__block_buffer_to_addr(block, pp, &ci->discard.logid, &ci->discard.offset,
+ &ci->discard.size, &ci->discard.checksum));
WT_RET(__wt_vunpack_uint(pp, 0, &a));
ci->file_size = (wt_off_t)a;
WT_RET(__wt_vunpack_uint(pp, 0, &a));
@@ -177,7 +186,7 @@ int
__wt_block_buffer_to_ckpt(
WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *p, WT_BLOCK_CKPT *ci)
{
- return (__block_buffer_to_ckpt(session, block->allocsize, p, ci));
+ return (__block_buffer_to_ckpt(session, block, p, ci));
}
/*
@@ -185,13 +194,13 @@ __wt_block_buffer_to_ckpt(
* Convert a checkpoint cookie into its components, external utility version.
*/
int
-__wt_block_ckpt_decode(WT_SESSION *wt_session, size_t allocsize, const uint8_t *p,
- WT_BLOCK_CKPT *ci) WT_GCC_FUNC_ATTRIBUTE((visibility("default")))
+__wt_block_ckpt_decode(WT_SESSION *wt_session, WT_BLOCK *block, const uint8_t *p, WT_BLOCK_CKPT *ci)
+ WT_GCC_FUNC_ATTRIBUTE((visibility("default")))
{
WT_SESSION_IMPL *session;
session = (WT_SESSION_IMPL *)wt_session;
- return (__block_buffer_to_ckpt(session, (uint32_t)allocsize, p, ci));
+ return (__block_buffer_to_ckpt(session, block, p, ci));
}
/*
@@ -203,6 +212,9 @@ __wt_block_ckpt_to_buffer(
WT_SESSION_IMPL *session, WT_BLOCK *block, uint8_t **pp, WT_BLOCK_CKPT *ci, bool skip_avail)
{
uint64_t a;
+ uint32_t logid;
+
+ logid = block->logid;
if (ci->version != WT_BM_CHECKPOINT_VERSION)
WT_RET_MSG(session, WT_ERROR, "unsupported checkpoint version");
@@ -210,16 +222,17 @@ __wt_block_ckpt_to_buffer(
(*pp)[0] = ci->version;
(*pp)++;
- WT_RET(__wt_block_addr_to_buffer(block, pp, ci->root_offset, ci->root_size, ci->root_checksum));
- WT_RET(
- __wt_block_addr_to_buffer(block, pp, ci->alloc.offset, ci->alloc.size, ci->alloc.checksum));
+ WT_RET(__wt_block_addr_to_buffer(
+ block, pp, logid, ci->root_offset, ci->root_size, ci->root_checksum));
+ WT_RET(__wt_block_addr_to_buffer(
+ block, pp, logid, ci->alloc.offset, ci->alloc.size, ci->alloc.checksum));
if (skip_avail)
- WT_RET(__wt_block_addr_to_buffer(block, pp, 0, 0, 0));
+ WT_RET(__wt_block_addr_to_buffer(block, pp, 0, 0, 0, 0));
else
WT_RET(__wt_block_addr_to_buffer(
- block, pp, ci->avail.offset, ci->avail.size, ci->avail.checksum));
+ block, pp, logid, ci->avail.offset, ci->avail.size, ci->avail.checksum));
WT_RET(__wt_block_addr_to_buffer(
- block, pp, ci->discard.offset, ci->discard.size, ci->discard.checksum));
+ block, pp, logid, ci->discard.offset, ci->discard.size, ci->discard.checksum));
a = (uint64_t)ci->file_size;
WT_RET(__wt_vpack_uint(pp, 0, a));
a = ci->ckpt_size;
diff --git a/src/third_party/wiredtiger/src/block/block_ckpt.c b/src/third_party/wiredtiger/src/block/block_ckpt.c
index cdabd131e40..ceb9cf39262 100644
--- a/src/third_party/wiredtiger/src/block/block_ckpt.c
+++ b/src/third_party/wiredtiger/src/block/block_ckpt.c
@@ -95,8 +95,13 @@ __wt_block_checkpoint_load(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint
if (ci->root_offset != WT_BLOCK_INVALID_OFFSET) {
endp = root_addr;
WT_ERR(__wt_block_addr_to_buffer(
- block, &endp, ci->root_offset, ci->root_size, ci->root_checksum));
+ block, &endp, ci->root_logid, ci->root_offset, ci->root_size, ci->root_checksum));
*root_addr_sizep = WT_PTRDIFF(endp, root_addr);
+
+ if (block->log_structured) {
+ block->logid = ci->root_logid;
+ WT_ERR(__wt_block_newfile(session, block));
+ }
}
/*
@@ -113,7 +118,7 @@ __wt_block_checkpoint_load(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint
* the end of the file, that was done when the checkpoint was first written (re-writing the
* checkpoint might possibly make it relevant here, but it's unlikely enough I don't bother).
*/
- if (!checkpoint)
+ if (!checkpoint && !block->log_structured)
WT_ERR(__wt_block_truncate(session, block, ci->file_size));
if (0) {
@@ -237,10 +242,10 @@ __wt_block_checkpoint(
*/
if (buf == NULL) {
ci->root_offset = WT_BLOCK_INVALID_OFFSET;
- ci->root_size = ci->root_checksum = 0;
+ ci->root_logid = ci->root_size = ci->root_checksum = 0;
} else
- WT_ERR(__wt_block_write_off(session, block, buf, &ci->root_offset, &ci->root_size,
- &ci->root_checksum, data_checksum, true, false));
+ WT_ERR(__wt_block_write_off(session, block, buf, &ci->root_logid, &ci->root_offset,
+ &ci->root_size, &ci->root_checksum, data_checksum, true, false));
/*
* Checkpoints are potentially reading/writing/merging lots of blocks, pre-allocate structures
@@ -463,6 +468,37 @@ __ckpt_add_blk_mods_ext(WT_SESSION_IMPL *session, WT_CKPT *ckptbase, WT_BLOCK_CK
}
/*
+ * __wt_block_newfile --
+ * Switch a log-structured block object to a new file.
+ */
+int
+__wt_block_newfile(WT_SESSION_IMPL *session, WT_BLOCK *block)
+{
+ WT_DECL_ITEM(tmp);
+ WT_DECL_RET;
+ const char *filename;
+
+ /* Bump to a new file ID. */
+ ++block->logid;
+
+ WT_ERR(__wt_scr_alloc(session, 0, &tmp));
+ WT_ERR(__wt_buf_fmt(session, tmp, "%s.%08" PRIu32, block->name, block->logid));
+ filename = tmp->data;
+ WT_ERR(__wt_close(session, &block->fh));
+ WT_ERR(__wt_open(session, filename, WT_FS_OPEN_FILE_TYPE_DATA,
+ WT_FS_OPEN_CREATE | block->file_flags, &block->fh));
+ WT_ERR(__wt_desc_write(session, block->fh, block->allocsize));
+
+ block->size = block->allocsize;
+ __wt_block_ckpt_destroy(session, &block->live);
+ WT_ERR(__wt_block_ckpt_init(session, &block->live, "live"));
+
+err:
+ __wt_scr_free(session, &tmp);
+ return (ret);
+}
+
+/*
* __ckpt_process --
* Process the list of checkpoints.
*/
@@ -610,7 +646,7 @@ __ckpt_process(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_CKPT *ckptbase)
* lists, and the freed blocks will then be included when writing the live extent lists.
*/
WT_CKPT_FOREACH (ckptbase, ckpt) {
- if (F_ISSET(ckpt, WT_CKPT_FAKE) || !F_ISSET(ckpt, WT_CKPT_DELETE))
+ if (F_ISSET(ckpt, WT_CKPT_FAKE) || !F_ISSET(ckpt, WT_CKPT_DELETE) || block->log_structured)
continue;
if (WT_VERBOSE_ISSET(session, WT_VERB_CHECKPOINT))
@@ -744,6 +780,9 @@ live_update:
ci->ckpt_discard = ci->discard;
WT_ERR(__wt_block_extlist_init(session, &ci->discard, "live", "discard", false));
+ if (block->log_structured)
+ WT_ERR(__wt_block_newfile(session, block));
+
#ifdef HAVE_DIAGNOSTIC
/*
* The first checkpoint in the system should always have an empty discard list. If we've read
diff --git a/src/third_party/wiredtiger/src/block/block_ckpt_scan.c b/src/third_party/wiredtiger/src/block/block_ckpt_scan.c
index 4d47c4301b2..2320076752a 100644
--- a/src/third_party/wiredtiger/src/block/block_ckpt_scan.c
+++ b/src/third_party/wiredtiger/src/block/block_ckpt_scan.c
@@ -220,13 +220,16 @@ __wt_block_checkpoint_last(WT_SESSION_IMPL *session, WT_BLOCK *block, char **met
const WT_PAGE_HEADER *dsk;
wt_off_t ext_off, ext_size, offset;
uint64_t len, nblocks, write_gen;
- uint32_t checksum, size;
+ uint32_t checksum, logid, size;
const uint8_t *p, *t;
bool found;
*metadatap = *checkpoint_listp = NULL;
WT_RET(__wt_buf_init(session, checkpoint, WT_BLOCK_CHECKPOINT_BUFFER));
+ /* TODO: scan all log IDs. */
+ logid = 0;
+
/*
* Initialize a pair of structures that track the best and current checkpoints found so far.
* This is a little trickier than normal because we don't want to start saving a checkpoint only
@@ -279,7 +282,7 @@ __wt_block_checkpoint_last(WT_SESSION_IMPL *session, WT_BLOCK *block, char **met
* block isn't valid, skip to the next possible block.
*/
if (__wt_block_offset_invalid(block, offset, size) ||
- __wt_block_read_off(session, block, tmp, offset, size, checksum) != 0) {
+ __wt_block_read_off(session, block, tmp, logid, offset, size, checksum) != 0) {
size = WT_BTREE_MIN_ALLOC_SIZE;
continue;
}
diff --git a/src/third_party/wiredtiger/src/block/block_compact.c b/src/third_party/wiredtiger/src/block/block_compact.c
index 19ee0b664f6..6615d4e192d 100644
--- a/src/third_party/wiredtiger/src/block/block_compact.c
+++ b/src/third_party/wiredtiger/src/block/block_compact.c
@@ -136,13 +136,13 @@ __wt_block_compact_page_skip(
WT_EXT *ext;
WT_EXTLIST *el;
wt_off_t limit, offset;
- uint32_t size, checksum;
+ uint32_t checksum, logid, size;
WT_UNUSED(addr_size);
*skipp = true; /* Return a default skip. */
/* Crack the cookie. */
- WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum));
+ WT_RET(__wt_block_buffer_to_addr(block, addr, &logid, &offset, &size, &checksum));
/*
* If this block is in the chosen percentage of the file and there's a block on the available
diff --git a/src/third_party/wiredtiger/src/block/block_ext.c b/src/third_party/wiredtiger/src/block/block_ext.c
index 06c44680f1a..d0dbfa97646 100644
--- a/src/third_party/wiredtiger/src/block/block_ext.c
+++ b/src/third_party/wiredtiger/src/block/block_ext.c
@@ -380,7 +380,7 @@ corrupt:
/*
* __wt_block_off_remove_overlap --
- * Remove a range from an extent list, where the range may be part of a overlapping entry.
+ * Remove a range from an extent list, where the range may be part of an overlapping entry.
*/
int
__wt_block_off_remove_overlap(
@@ -565,24 +565,28 @@ __wt_block_free(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr,
{
WT_DECL_RET;
wt_off_t offset;
- uint32_t checksum, size;
+ uint32_t checksum, logid, size;
WT_UNUSED(addr_size);
WT_STAT_DATA_INCR(session, block_free);
/* Crack the cookie. */
- WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum));
+ WT_RET(__wt_block_buffer_to_addr(block, addr, &logid, &offset, &size, &checksum));
- __wt_verbose(
- session, WT_VERB_BLOCK, "free %" PRIdMAX "/%" PRIdMAX, (intmax_t)offset, (intmax_t)size);
+ __wt_verbose(session, WT_VERB_BLOCK, "free %" PRIu32 ": %" PRIdMAX "/%" PRIdMAX, logid,
+ (intmax_t)offset, (intmax_t)size);
#ifdef HAVE_DIAGNOSTIC
WT_RET(__wt_block_misplaced(session, block, "free", offset, size, true, __func__, __LINE__));
#endif
- WT_RET(__wt_block_ext_prealloc(session, 5));
- __wt_spin_lock(session, &block->live_lock);
- ret = __wt_block_off_free(session, block, offset, (wt_off_t)size);
- __wt_spin_unlock(session, &block->live_lock);
+ if (logid == block->logid) {
+ WT_RET(__wt_block_ext_prealloc(session, 5));
+ __wt_spin_lock(session, &block->live_lock);
+ ret = __wt_block_off_free(session, block, logid, offset, (wt_off_t)size);
+ __wt_spin_unlock(session, &block->live_lock);
+ } else {
+ /* TODO: update stats about older files to drive garbage collection. */
+ }
return (ret);
}
@@ -592,13 +596,18 @@ __wt_block_free(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr,
* Free a file range to the underlying file.
*/
int
-__wt_block_off_free(WT_SESSION_IMPL *session, WT_BLOCK *block, wt_off_t offset, wt_off_t size)
+__wt_block_off_free(
+ WT_SESSION_IMPL *session, WT_BLOCK *block, uint32_t logid, wt_off_t offset, wt_off_t size)
{
WT_DECL_RET;
/* If a sync is running, no other sessions can free blocks. */
WT_ASSERT(session, WT_SESSION_BTREE_SYNC_SAFE(session, S2BT(session)));
+ /* TODO: track stats for old files to drive garbage collection. */
+ if (logid != block->logid)
+ return (0);
+
/*
* Callers of this function are expected to have already acquired any locks required to
* manipulate the extent lists.
@@ -1096,7 +1105,7 @@ __wt_block_extlist_read(
return (0);
WT_RET(__wt_scr_alloc(session, el->size, &tmp));
- WT_ERR(__wt_block_read_off(session, block, tmp, el->offset, el->size, el->checksum));
+ WT_ERR(__wt_block_read_off(session, block, tmp, el->logid, el->offset, el->size, el->checksum));
p = WT_BLOCK_HEADER_BYTE(tmp->mem);
WT_ERR(__wt_extlist_read_pair(&p, &off, &size));
@@ -1156,7 +1165,7 @@ __wt_block_extlist_write(
WT_EXT *ext;
WT_PAGE_HEADER *dsk;
size_t size;
- uint32_t entries;
+ uint32_t logid, entries;
uint8_t *p;
WT_RET(__block_extlist_dump(session, block, el, "write"));
@@ -1214,7 +1223,8 @@ __wt_block_extlist_write(
/* Write the extent list to disk. */
WT_ERR(__wt_block_write_off(
- session, block, tmp, &el->offset, &el->size, &el->checksum, true, true, true));
+ session, block, tmp, &logid, &el->offset, &el->size, &el->checksum, true, true, true));
+ WT_UNUSED(logid); /* TODO check */
/*
* Remove the allocated blocks from the system's allocation list, extent blocks never appear on
diff --git a/src/third_party/wiredtiger/src/block/block_open.c b/src/third_party/wiredtiger/src/block/block_open.c
index d97f3a86f7d..5eba665ea8d 100644
--- a/src/third_party/wiredtiger/src/block/block_open.c
+++ b/src/third_party/wiredtiger/src/block/block_open.c
@@ -33,6 +33,8 @@ __wt_block_manager_create(WT_SESSION_IMPL *session, const char *filename, uint32
int suffix;
bool exists;
+ WT_ERR(__wt_scr_alloc(session, 0, &tmp));
+
/*
* Create the underlying file and open a handle.
*
@@ -46,8 +48,6 @@ __wt_block_manager_create(WT_SESSION_IMPL *session, const char *filename, uint32
break;
WT_ERR_TEST(ret != EEXIST, ret, false);
- if (tmp == NULL)
- WT_ERR(__wt_scr_alloc(session, 0, &tmp));
for (suffix = 1;; ++suffix) {
WT_ERR(__wt_buf_fmt(session, tmp, "%s.%d", filename, suffix));
WT_ERR(__wt_fs_exist(session, tmp->data, &exists));
@@ -91,6 +91,7 @@ __block_destroy(WT_SESSION_IMPL *session, WT_BLOCK *block)
WT_CONNECTION_IMPL *conn;
WT_DECL_RET;
uint64_t bucket;
+ u_int i;
conn = S2C(session);
bucket = block->name_hash & (conn->hash_size - 1);
@@ -98,6 +99,12 @@ __block_destroy(WT_SESSION_IMPL *session, WT_BLOCK *block)
__wt_free(session, block->name);
+ if (block->log_structured && block->lfh != NULL) {
+ for (i = 0; i < block->max_logid; i++)
+ WT_TRET(__wt_close(session, &block->lfh[i]));
+ __wt_free(session, block->lfh);
+ }
+
if (block->fh != NULL)
WT_TRET(__wt_close(session, &block->fh));
@@ -175,6 +182,7 @@ __wt_block_open(WT_SESSION_IMPL *session, const char *filename, const char *cfg[
WT_ERR(__wt_config_gets(session, cfg, "block_allocation", &cval));
block->allocfirst = WT_STRING_MATCH("first", cval.str, cval.len);
+ block->log_structured = WT_STRING_MATCH("log-structured", cval.str, cval.len);
/* Configuration: optional OS buffer cache maximum size. */
WT_ERR(__wt_config_gets(session, cfg, "os_cache_max", &cval));
@@ -203,7 +211,8 @@ __wt_block_open(WT_SESSION_IMPL *session, const char *filename, const char *cfg[
LF_SET(WT_FS_OPEN_DIRECTIO);
if (!readonly && FLD_ISSET(conn->direct_io, WT_DIRECT_IO_DATA))
LF_SET(WT_FS_OPEN_DIRECTIO);
- WT_ERR(__wt_open(session, filename, WT_FS_OPEN_FILE_TYPE_DATA, flags, &block->fh));
+ block->file_flags = flags;
+ WT_ERR(__wt_open(session, filename, WT_FS_OPEN_FILE_TYPE_DATA, block->file_flags, &block->fh));
/* Set the file's size. */
WT_ERR(__wt_filesize(session, block->fh, &block->size));
diff --git a/src/third_party/wiredtiger/src/block/block_read.c b/src/third_party/wiredtiger/src/block/block_read.c
index 8680f1f90f8..c5e3a1c193c 100644
--- a/src/third_party/wiredtiger/src/block/block_read.c
+++ b/src/third_party/wiredtiger/src/block/block_read.c
@@ -18,9 +18,10 @@ __wt_bm_preload(WT_BM *bm, WT_SESSION_IMPL *session, const uint8_t *addr, size_t
WT_BLOCK *block;
WT_DECL_ITEM(tmp);
WT_DECL_RET;
+ WT_FH *fh;
WT_FILE_HANDLE *handle;
wt_off_t offset;
- uint32_t checksum, size;
+ uint32_t checksum, logid, size;
bool mapped;
block = bm->block;
@@ -28,9 +29,10 @@ __wt_bm_preload(WT_BM *bm, WT_SESSION_IMPL *session, const uint8_t *addr, size_t
WT_STAT_CONN_INCR(session, block_preload);
/* Crack the cookie. */
- WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum));
+ WT_RET(__wt_block_buffer_to_addr(block, addr, &logid, &offset, &size, &checksum));
- handle = block->fh->handle;
+ WT_RET(__wt_block_fh(session, block, logid, &fh));
+ handle = fh->handle;
mapped = bm->map != NULL && offset + size <= (wt_off_t)bm->maplen;
if (mapped && handle->fh_map_preload != NULL)
ret = handle->fh_map_preload(
@@ -59,21 +61,23 @@ __wt_bm_read(
{
WT_BLOCK *block;
WT_DECL_RET;
+ WT_FH *fh;
WT_FILE_HANDLE *handle;
wt_off_t offset;
- uint32_t checksum, size;
+ uint32_t checksum, logid, size;
bool mapped;
WT_UNUSED(addr_size);
block = bm->block;
/* Crack the cookie. */
- WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum));
+ WT_RET(__wt_block_buffer_to_addr(block, addr, &logid, &offset, &size, &checksum));
/*
* Map the block if it's possible.
*/
- handle = block->fh->handle;
+ WT_RET(__wt_block_fh(session, block, logid, &fh));
+ handle = fh->handle;
mapped = bm->map != NULL && offset + size <= (wt_off_t)bm->maplen;
if (mapped && handle->fh_map_preload != NULL) {
buf->data = (uint8_t *)bm->map + offset;
@@ -96,7 +100,7 @@ __wt_bm_read(
#endif
/* Read the block. */
__wt_capacity_throttle(session, size, WT_THROTTLE_READ);
- WT_RET(__wt_block_read_off(session, block, buf, offset, size, checksum));
+ WT_RET(__wt_block_read_off(session, block, buf, logid, offset, size, checksum));
/* Optionally discard blocks from the system's buffer cache. */
WT_RET(__wt_block_discard(session, block, (size_t)size));
@@ -109,17 +113,17 @@ __wt_bm_read(
* Dump a block into the log in 1KB chunks.
*/
static int
-__wt_bm_corrupt_dump(WT_SESSION_IMPL *session, WT_ITEM *buf, wt_off_t offset, uint32_t size,
- uint32_t checksum) WT_GCC_FUNC_ATTRIBUTE((cold))
+__wt_bm_corrupt_dump(WT_SESSION_IMPL *session, WT_ITEM *buf, uint32_t logid, wt_off_t offset,
+ uint32_t size, uint32_t checksum) WT_GCC_FUNC_ATTRIBUTE((cold))
{
WT_DECL_ITEM(tmp);
WT_DECL_RET;
size_t chunk, i, nchunks;
-#define WT_CORRUPT_FMT "{%" PRIuMAX ", %" PRIu32 ", %#" PRIx32 "}"
+#define WT_CORRUPT_FMT "{%" PRIu32 ": %" PRIuMAX ", %" PRIu32 ", %#" PRIx32 "}"
if (buf->size == 0) {
- __wt_errx(session, WT_CORRUPT_FMT ": empty buffer, no dump available", (uintmax_t)offset,
- size, checksum);
+ __wt_errx(session, WT_CORRUPT_FMT ": empty buffer, no dump available", logid,
+ (uintmax_t)offset, size, checksum);
return (0);
}
@@ -130,7 +134,7 @@ __wt_bm_corrupt_dump(WT_SESSION_IMPL *session, WT_ITEM *buf, wt_off_t offset, ui
WT_ERR(__wt_buf_catfmt(session, tmp, "%02x ", ((uint8_t *)buf->data)[i]));
if (++i == buf->size || i % 1024 == 0) {
__wt_errx(session,
- WT_CORRUPT_FMT ": (chunk %" WT_SIZET_FMT " of %" WT_SIZET_FMT "): %.*s",
+ WT_CORRUPT_FMT ": (chunk %" WT_SIZET_FMT " of %" WT_SIZET_FMT "): %.*s", logid,
(uintmax_t)offset, size, checksum, ++chunk, nchunks, (int)tmp->size,
(char *)tmp->data);
if (i == buf->size)
@@ -154,15 +158,15 @@ __wt_bm_corrupt(WT_BM *bm, WT_SESSION_IMPL *session, const uint8_t *addr, size_t
WT_DECL_ITEM(tmp);
WT_DECL_RET;
wt_off_t offset;
- uint32_t checksum, size;
+ uint32_t checksum, logid, size;
/* Read the block. */
WT_RET(__wt_scr_alloc(session, 0, &tmp));
WT_ERR(__wt_bm_read(bm, session, tmp, addr, addr_size));
/* Crack the cookie, dump the block. */
- WT_ERR(__wt_block_buffer_to_addr(bm->block, addr, &offset, &size, &checksum));
- WT_ERR(__wt_bm_corrupt_dump(session, tmp, offset, size, checksum));
+ WT_ERR(__wt_block_buffer_to_addr(bm->block, addr, &logid, &offset, &size, &checksum));
+ WT_ERR(__wt_bm_corrupt_dump(session, tmp, logid, offset, size, checksum));
err:
__wt_scr_free(session, &tmp);
@@ -203,14 +207,60 @@ err:
#endif
/*
+ * __wt_block_fh --
+ * Get a block file handle.
+ */
+int
+__wt_block_fh(WT_SESSION_IMPL *session, WT_BLOCK *block, uint32_t logid, WT_FH **fhp)
+{
+ WT_DECL_ITEM(tmp);
+ WT_DECL_RET;
+ const char *filename;
+
+ if (!block->log_structured || logid == block->logid) {
+ *fhp = block->fh;
+ return (0);
+ }
+
+ /* TODO: fh readlock */
+ if (logid * sizeof(WT_FILE_HANDLE *) < block->lfh_alloc && (*fhp = block->lfh[logid]) != NULL)
+ return (0);
+
+ /* TODO: fh writelock */
+ /* Ensure the array goes far enough. */
+ WT_RET(__wt_realloc_def(session, &block->lfh_alloc, logid + 1, &block->lfh));
+ if (logid >= block->max_logid)
+ block->max_logid = logid + 1;
+ if ((*fhp = block->lfh[logid]) != NULL)
+ return (0);
+
+ WT_RET(__wt_scr_alloc(session, 0, &tmp));
+ if (logid == 0)
+ filename = block->name;
+ else {
+ WT_ERR(__wt_buf_fmt(session, tmp, "%s.%08" PRIu32, block->name, logid));
+ filename = tmp->data;
+ }
+ WT_ERR(__wt_open(session, filename, WT_FS_OPEN_FILE_TYPE_DATA,
+ WT_FS_OPEN_READONLY | block->file_flags, &block->lfh[logid]));
+ *fhp = block->lfh[logid];
+ WT_ASSERT(session, *fhp != NULL);
+
+err:
+ __wt_scr_free(session, &tmp);
+ return (ret);
+}
+
+/*
* __wt_block_read_off --
* Read an addr/size pair referenced block into a buffer.
*/
int
-__wt_block_read_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_off_t offset,
- uint32_t size, uint32_t checksum)
+__wt_block_read_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, uint32_t logid,
+ wt_off_t offset, uint32_t size, uint32_t checksum)
{
WT_BLOCK_HEADER *blk, swap;
+ WT_FH *fh;
size_t bufsize;
__wt_verbose(session, WT_VERB_READ, "off %" PRIuMAX ", size %" PRIu32 ", checksum %#" PRIx32,
@@ -243,7 +293,8 @@ __wt_block_read_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_
block->name, size, block->allocsize);
WT_RET(__wt_buf_init(session, buf, bufsize));
- WT_RET(__wt_read(session, block->fh, offset, size, buf->mem));
+ WT_RET(__wt_block_fh(session, block, logid, &fh));
+ WT_RET(__wt_read(session, fh, offset, size, buf->mem));
buf->size = size;
/*
@@ -276,7 +327,7 @@ __wt_block_read_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_
block->name, size, (uintmax_t)offset, swap.checksum, checksum);
if (!F_ISSET(session, WT_SESSION_QUIET_CORRUPT_FILE))
- WT_IGNORE_RET(__wt_bm_corrupt_dump(session, buf, offset, size, checksum));
+ WT_IGNORE_RET(__wt_bm_corrupt_dump(session, buf, logid, offset, size, checksum));
/* Panic if a checksum fails during an ordinary read. */
F_SET(S2C(session), WT_CONN_DATA_CORRUPTION);
diff --git a/src/third_party/wiredtiger/src/block/block_slvg.c b/src/third_party/wiredtiger/src/block/block_slvg.c
index 8a632e892b4..857f15d7848 100644
--- a/src/third_party/wiredtiger/src/block/block_slvg.c
+++ b/src/third_party/wiredtiger/src/block/block_slvg.c
@@ -104,11 +104,14 @@ __wt_block_salvage_next(
WT_DECL_RET;
WT_FH *fh;
wt_off_t max, offset;
- uint32_t allocsize, checksum, size;
+ uint32_t allocsize, checksum, logid, size;
uint8_t *endp;
*eofp = 0;
+ /* FIXME: salvage across all chunks in a log-structured tree. */
+ logid = 0;
+
fh = block->fh;
allocsize = block->allocsize;
WT_ERR(__wt_scr_alloc(session, allocsize, &tmp));
@@ -137,19 +140,19 @@ __wt_block_salvage_next(
* otherwise, move past it.
*/
if (!__wt_block_offset_invalid(block, offset, size) &&
- __wt_block_read_off(session, block, tmp, offset, size, checksum) == 0)
+ __wt_block_read_off(session, block, tmp, logid, offset, size, checksum) == 0)
break;
/* Free the allocation-size block. */
__wt_verbose(session, WT_VERB_SALVAGE, "skipping %" PRIu32 "B at file offset %" PRIuMAX,
allocsize, (uintmax_t)offset);
- WT_ERR(__wt_block_off_free(session, block, offset, (wt_off_t)allocsize));
+ WT_ERR(__wt_block_off_free(session, block, logid, offset, (wt_off_t)allocsize));
block->slvg_off += allocsize;
}
/* Re-create the address cookie that should reference this block. */
endp = addr;
- WT_ERR(__wt_block_addr_to_buffer(block, &endp, offset, size, checksum));
+ WT_ERR(__wt_block_addr_to_buffer(block, &endp, logid, offset, size, checksum));
*addr_sizep = WT_PTRDIFF(endp, addr);
done:
@@ -167,7 +170,7 @@ __wt_block_salvage_valid(
WT_SESSION_IMPL *session, WT_BLOCK *block, uint8_t *addr, size_t addr_size, bool valid)
{
wt_off_t offset;
- uint32_t size, checksum;
+ uint32_t size, logid, checksum;
WT_UNUSED(addr_size);
@@ -175,11 +178,11 @@ __wt_block_salvage_valid(
* Crack the cookie. If the upper layer took the block, move past it; if the upper layer
* rejected the block, move past an allocation size chunk and free it.
*/
- WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum));
+ WT_RET(__wt_block_buffer_to_addr(block, addr, &logid, &offset, &size, &checksum));
if (valid)
block->slvg_off = offset + size;
else {
- WT_RET(__wt_block_off_free(session, block, offset, (wt_off_t)block->allocsize));
+ WT_RET(__wt_block_off_free(session, block, logid, offset, (wt_off_t)block->allocsize));
block->slvg_off = offset + block->allocsize;
}
diff --git a/src/third_party/wiredtiger/src/block/block_vrfy.c b/src/third_party/wiredtiger/src/block/block_vrfy.c
index 57bba04e5da..0a434aebfce 100644
--- a/src/third_party/wiredtiger/src/block/block_vrfy.c
+++ b/src/third_party/wiredtiger/src/block/block_vrfy.c
@@ -316,12 +316,12 @@ __wt_block_verify_addr(
WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr, size_t addr_size)
{
wt_off_t offset;
- uint32_t checksum, size;
+ uint32_t checksum, logid, size;
WT_UNUSED(addr_size);
/* Crack the cookie. */
- WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum));
+ WT_RET(__wt_block_buffer_to_addr(block, addr, &logid, &offset, &size, &checksum));
/* Add to the per-file list. */
WT_RET(__verify_filefrag_add(session, block, NULL, offset, size, false));
diff --git a/src/third_party/wiredtiger/src/block/block_write.c b/src/third_party/wiredtiger/src/block/block_write.c
index c5890efd038..bafee786c5b 100644
--- a/src/third_party/wiredtiger/src/block/block_write.c
+++ b/src/third_party/wiredtiger/src/block/block_write.c
@@ -189,14 +189,14 @@ __wt_block_write(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, uint8_
size_t *addr_sizep, bool data_checksum, bool checkpoint_io)
{
wt_off_t offset;
- uint32_t checksum, size;
+ uint32_t checksum, logid, size;
uint8_t *endp;
WT_RET(__wt_block_write_off(
- session, block, buf, &offset, &size, &checksum, data_checksum, checkpoint_io, false));
+ session, block, buf, &logid, &offset, &size, &checksum, data_checksum, checkpoint_io, false));
endp = addr;
- WT_RET(__wt_block_addr_to_buffer(block, &endp, offset, size, checksum));
+ WT_RET(__wt_block_addr_to_buffer(block, &endp, logid, offset, size, checksum));
*addr_sizep = WT_PTRDIFF(endp, addr);
return (0);
@@ -207,15 +207,16 @@ __wt_block_write(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, uint8_
* Write a buffer into a block, returning the block's offset, size and checksum.
*/
static int
-__block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_off_t *offsetp,
- uint32_t *sizep, uint32_t *checksump, bool data_checksum, bool checkpoint_io, bool caller_locked)
+__block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, uint32_t *logidp,
+ wt_off_t *offsetp, uint32_t *sizep, uint32_t *checksump, bool data_checksum, bool checkpoint_io,
+ bool caller_locked)
{
WT_BLOCK_HEADER *blk;
WT_DECL_RET;
WT_FH *fh;
wt_off_t offset;
size_t align_size;
- uint32_t checksum;
+ uint32_t checksum, logid;
uint8_t *file_sizep;
bool local_locked;
@@ -224,6 +225,7 @@ __block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_of
*checksump = 0; /* -Werror=maybe-uninitialized */
fh = block->fh;
+ logid = block->logid;
/* Buffers should be aligned for writing. */
if (!F_ISSET(buf, WT_ITEM_ALIGNED)) {
@@ -325,7 +327,7 @@ __block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_of
if ((ret = __wt_write(session, fh, offset, align_size, buf->mem)) != 0) {
if (!caller_locked)
__wt_spin_lock(session, &block->live_lock);
- WT_TRET(__wt_block_off_free(session, block, offset, (wt_off_t)align_size));
+ WT_TRET(__wt_block_off_free(session, block, logid, offset, (wt_off_t)align_size));
if (!caller_locked)
__wt_spin_unlock(session, &block->live_lock);
WT_RET(ret);
@@ -359,6 +361,7 @@ __block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_of
__wt_verbose(session, WT_VERB_WRITE, "off %" PRIuMAX ", size %" PRIuMAX ", checksum %#" PRIx32,
(uintmax_t)offset, (uintmax_t)align_size, checksum);
+ *logidp = logid;
*offsetp = offset;
*sizep = WT_STORE_SIZE(align_size);
*checksump = checksum;
@@ -371,8 +374,9 @@ __block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_of
* Write a buffer into a block, returning the block's offset, size and checksum.
*/
int
-__wt_block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_off_t *offsetp,
- uint32_t *sizep, uint32_t *checksump, bool data_checksum, bool checkpoint_io, bool caller_locked)
+__wt_block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, uint32_t *logidp,
+ wt_off_t *offsetp, uint32_t *sizep, uint32_t *checksump, bool data_checksum, bool checkpoint_io,
+ bool caller_locked)
{
WT_DECL_RET;
@@ -382,8 +386,8 @@ __wt_block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt
* never see anything other than their original content.
*/
__wt_page_header_byteswap(buf->mem);
- ret = __block_write_off(
- session, block, buf, offsetp, sizep, checksump, data_checksum, checkpoint_io, caller_locked);
+ ret = __block_write_off(session, block, buf, logidp, offsetp, sizep, checksump, data_checksum,
+ checkpoint_io, caller_locked);
__wt_page_header_byteswap(buf->mem);
return (ret);
}
diff --git a/src/third_party/wiredtiger/src/btree/bt_debug.c b/src/third_party/wiredtiger/src/btree/bt_debug.c
index fc68db0e1bb..2f93982a461 100644
--- a/src/third_party/wiredtiger/src/btree/bt_debug.c
+++ b/src/third_party/wiredtiger/src/btree/bt_debug.c
@@ -377,6 +377,7 @@ int
__wt_debug_offset(
WT_SESSION_IMPL *session, wt_off_t offset, uint32_t size, uint32_t checksum, const char *ofile)
{
+ WT_BLOCK *block;
WT_DECL_ITEM(buf);
WT_DECL_RET;
uint8_t addr[WT_BTREE_MAX_ADDR_COOKIE], *endp;
@@ -390,8 +391,9 @@ __wt_debug_offset(
*
* Convert the triplet into an address structure.
*/
+ block = S2BT(session)->bm->block;
endp = addr;
- WT_RET(__wt_block_addr_to_buffer(S2BT(session)->bm->block, &endp, offset, size, checksum));
+ WT_RET(__wt_block_addr_to_buffer(block, &endp, block->logid, offset, size, checksum));
/*
* Read the address through the btree I/O functions (so the block is decompressed as necessary).
diff --git a/src/third_party/wiredtiger/src/btree/bt_handle.c b/src/third_party/wiredtiger/src/btree/bt_handle.c
index c23b2e05240..2d26a1bf573 100644
--- a/src/third_party/wiredtiger/src/btree/bt_handle.c
+++ b/src/third_party/wiredtiger/src/btree/bt_handle.c
@@ -484,6 +484,11 @@ __btree_conf(WT_SESSION_IMPL *session, WT_CKPT *ckpt)
/* Configure encryption. */
WT_RET(__wt_btree_config_encryptor(session, cfg, &btree->kencryptor));
+ /* Configure read-only. */
+ WT_RET(__wt_config_gets(session, cfg, "readonly", &cval));
+ if (cval.val)
+ F_SET(btree, WT_BTREE_READONLY);
+
/* Initialize locks. */
WT_RET(__wt_rwlock_init(session, &btree->ovfl_lock));
WT_RET(__wt_spin_init(session, &btree->flush_lock, "btree flush"));
diff --git a/src/third_party/wiredtiger/src/config/config_def.c b/src/third_party/wiredtiger/src/config/config_def.c
index dde2b81aafa..bb87d9e3535 100644
--- a/src/third_party/wiredtiger/src/config/config_def.c
+++ b/src/third_party/wiredtiger/src/config/config_def.c
@@ -154,6 +154,14 @@ static const WT_CONFIG_CHECK confchk_WT_CURSOR_reconfigure[] = {
{NULL, NULL, NULL, NULL, NULL, 0}};
static const WT_CONFIG_CHECK confchk_assert_subconfigs[] = {
+ {"commit_timestamp", "string", NULL,
+ "choices=[\"always\",\"key_consistent\",\"never\","
+ "\"none\"]",
+ NULL, 0},
+ {"durable_timestamp", "string", NULL,
+ "choices=[\"always\",\"key_consistent\",\"never\","
+ "\"none\"]",
+ NULL, 0},
{"read_timestamp", "string", NULL, "choices=[\"always\",\"never\",\"none\"]", NULL, 0},
{"write_timestamp", "string", NULL, "choices=[\"off\",\"on\"]", NULL, 0},
{NULL, NULL, NULL, NULL, NULL, 0}};
@@ -164,12 +172,12 @@ static const WT_CONFIG_CHECK confchk_WT_SESSION_create_log_subconfigs[] = {
static const WT_CONFIG_CHECK confchk_WT_SESSION_alter[] = {
{"access_pattern_hint", "string", NULL, "choices=[\"none\",\"random\",\"sequential\"]", NULL, 0},
{"app_metadata", "string", NULL, NULL, NULL, 0},
- {"assert", "category", NULL, NULL, confchk_assert_subconfigs, 2},
- {"cache_resident", "boolean", NULL, NULL, NULL, 0},
+ {"assert", "category", NULL, NULL, confchk_assert_subconfigs, 4},
+ {"cache_resident", "boolean", NULL, NULL, NULL, 0}, {"checkpoint", "string", NULL, NULL, NULL, 0},
{"exclusive_refreshed", "boolean", NULL, NULL, NULL, 0},
{"log", "category", NULL, NULL, confchk_WT_SESSION_create_log_subconfigs, 1},
{"os_cache_dirty_max", "int", NULL, "min=0", NULL, 0},
- {"os_cache_max", "int", NULL, "min=0", NULL, 0},
+ {"os_cache_max", "int", NULL, "min=0", NULL, 0}, {"readonly", "boolean", NULL, NULL, NULL, 0},
{"verbose", "list", NULL, "choices=[\"write_timestamp\"]", NULL, 0},
{"write_timestamp_usage", "string", NULL,
"choices=[\"always\",\"key_consistent\",\"mixed_mode\","
@@ -236,12 +244,16 @@ static const WT_CONFIG_CHECK confchk_WT_SESSION_create_lsm_subconfigs[] = {
{"merge_max", "int", NULL, "min=2,max=100", NULL, 0},
{"merge_min", "int", NULL, "max=100", NULL, 0}, {NULL, NULL, NULL, NULL, NULL, 0}};
+static const WT_CONFIG_CHECK confchk_WT_SESSION_create_tiered_subconfigs[] = {
+ {"chunk_size", "int", NULL, "min=1M", NULL, 0}, {"tiers", "list", NULL, NULL, NULL, 0},
+ {NULL, NULL, NULL, NULL, NULL, 0}};
+
static const WT_CONFIG_CHECK confchk_WT_SESSION_create[] = {
{"access_pattern_hint", "string", NULL, "choices=[\"none\",\"random\",\"sequential\"]", NULL, 0},
{"allocation_size", "int", NULL, "min=512B,max=128MB", NULL, 0},
{"app_metadata", "string", NULL, NULL, NULL, 0},
- {"assert", "category", NULL, NULL, confchk_assert_subconfigs, 2},
- {"block_allocation", "string", NULL, "choices=[\"first\",\"best\"]", NULL, 0},
+ {"assert", "category", NULL, NULL, confchk_assert_subconfigs, 4},
+ {"block_allocation", "string", NULL, "choices=[\"best\",\"first\",\"log-structured\"]", NULL, 0},
{"block_compressor", "string", NULL, NULL, NULL, 0},
{"cache_resident", "boolean", NULL, NULL, NULL, 0},
{"checksum", "string", NULL, "choices=[\"on\",\"off\",\"uncompressed\"]", NULL, 0},
@@ -250,7 +262,7 @@ static const WT_CONFIG_CHECK confchk_WT_SESSION_create[] = {
{"encryption", "category", NULL, NULL, confchk_WT_SESSION_create_encryption_subconfigs, 2},
{"exclusive", "boolean", NULL, NULL, NULL, 0}, {"extractor", "string", NULL, NULL, NULL, 0},
{"format", "string", NULL, "choices=[\"btree\"]", NULL, 0},
- {"huffman_value", "string", NULL, NULL, NULL, 0},
+ {"huffman_key", "string", NULL, NULL, NULL, 0}, {"huffman_value", "string", NULL, NULL, NULL, 0},
{"ignore_in_memory_cache_size", "boolean", NULL, NULL, NULL, 0},
{"immutable", "boolean", NULL, NULL, NULL, 0},
{"import", "category", NULL, NULL, confchk_WT_SESSION_create_import_subconfigs, 3},
@@ -271,9 +283,12 @@ static const WT_CONFIG_CHECK confchk_WT_SESSION_create[] = {
{"os_cache_max", "int", NULL, "min=0", NULL, 0},
{"prefix_compression", "boolean", NULL, NULL, NULL, 0},
{"prefix_compression_min", "int", NULL, "min=0", NULL, 0},
- {"source", "string", NULL, NULL, NULL, 0}, {"split_deepen_min_child", "int", NULL, NULL, NULL, 0},
+ {"readonly", "boolean", NULL, NULL, NULL, 0}, {"source", "string", NULL, NULL, NULL, 0},
+ {"split_deepen_min_child", "int", NULL, NULL, NULL, 0},
{"split_deepen_per_child", "int", NULL, NULL, NULL, 0},
- {"split_pct", "int", NULL, "min=50,max=100", NULL, 0}, {"type", "string", NULL, NULL, NULL, 0},
+ {"split_pct", "int", NULL, "min=50,max=100", NULL, 0},
+ {"tiered", "category", NULL, NULL, confchk_WT_SESSION_create_tiered_subconfigs, 2},
+ {"type", "string", NULL, NULL, NULL, 0},
{"value_format", "format", __wt_struct_confchk, NULL, NULL, 0},
{"verbose", "list", NULL, "choices=[\"write_timestamp\"]", NULL, 0},
{"write_timestamp_usage", "string", NULL,
@@ -372,7 +387,7 @@ static const WT_CONFIG_CHECK confchk_WT_SESSION_verify[] = {
static const WT_CONFIG_CHECK confchk_colgroup_meta[] = {
{"app_metadata", "string", NULL, NULL, NULL, 0},
- {"assert", "category", NULL, NULL, confchk_assert_subconfigs, 2},
+ {"assert", "category", NULL, NULL, confchk_assert_subconfigs, 4},
{"collator", "string", NULL, NULL, NULL, 0}, {"columns", "list", NULL, NULL, NULL, 0},
{"source", "string", NULL, NULL, NULL, 0}, {"type", "string", NULL, NULL, NULL, 0},
{"verbose", "list", NULL, "choices=[\"write_timestamp\"]", NULL, 0},
@@ -386,8 +401,8 @@ static const WT_CONFIG_CHECK confchk_file_config[] = {
{"access_pattern_hint", "string", NULL, "choices=[\"none\",\"random\",\"sequential\"]", NULL, 0},
{"allocation_size", "int", NULL, "min=512B,max=128MB", NULL, 0},
{"app_metadata", "string", NULL, NULL, NULL, 0},
- {"assert", "category", NULL, NULL, confchk_assert_subconfigs, 2},
- {"block_allocation", "string", NULL, "choices=[\"first\",\"best\"]", NULL, 0},
+ {"assert", "category", NULL, NULL, confchk_assert_subconfigs, 4},
+ {"block_allocation", "string", NULL, "choices=[\"best\",\"first\",\"log-structured\"]", NULL, 0},
{"block_compressor", "string", NULL, NULL, NULL, 0},
{"cache_resident", "boolean", NULL, NULL, NULL, 0},
{"checksum", "string", NULL, "choices=[\"on\",\"off\",\"uncompressed\"]", NULL, 0},
@@ -395,7 +410,7 @@ static const WT_CONFIG_CHECK confchk_file_config[] = {
{"dictionary", "int", NULL, "min=0", NULL, 0},
{"encryption", "category", NULL, NULL, confchk_WT_SESSION_create_encryption_subconfigs, 2},
{"format", "string", NULL, "choices=[\"btree\"]", NULL, 0},
- {"huffman_value", "string", NULL, NULL, NULL, 0},
+ {"huffman_key", "string", NULL, NULL, NULL, 0}, {"huffman_value", "string", NULL, NULL, NULL, 0},
{"ignore_in_memory_cache_size", "boolean", NULL, NULL, NULL, 0},
{"internal_item_max", "int", NULL, "min=0", NULL, 0},
{"internal_key_max", "int", NULL, "min=0", NULL, 0},
@@ -413,6 +428,7 @@ static const WT_CONFIG_CHECK confchk_file_config[] = {
{"os_cache_max", "int", NULL, "min=0", NULL, 0},
{"prefix_compression", "boolean", NULL, NULL, NULL, 0},
{"prefix_compression_min", "int", NULL, "min=0", NULL, 0},
+ {"readonly", "boolean", NULL, NULL, NULL, 0},
{"split_deepen_min_child", "int", NULL, NULL, NULL, 0},
{"split_deepen_per_child", "int", NULL, NULL, NULL, 0},
{"split_pct", "int", NULL, "min=50,max=100", NULL, 0},
@@ -428,8 +444,8 @@ static const WT_CONFIG_CHECK confchk_file_meta[] = {
{"access_pattern_hint", "string", NULL, "choices=[\"none\",\"random\",\"sequential\"]", NULL, 0},
{"allocation_size", "int", NULL, "min=512B,max=128MB", NULL, 0},
{"app_metadata", "string", NULL, NULL, NULL, 0},
- {"assert", "category", NULL, NULL, confchk_assert_subconfigs, 2},
- {"block_allocation", "string", NULL, "choices=[\"first\",\"best\"]", NULL, 0},
+ {"assert", "category", NULL, NULL, confchk_assert_subconfigs, 4},
+ {"block_allocation", "string", NULL, "choices=[\"best\",\"first\",\"log-structured\"]", NULL, 0},
{"block_compressor", "string", NULL, NULL, NULL, 0},
{"cache_resident", "boolean", NULL, NULL, NULL, 0}, {"checkpoint", "string", NULL, NULL, NULL, 0},
{"checkpoint_backup_info", "string", NULL, NULL, NULL, 0},
@@ -439,7 +455,8 @@ static const WT_CONFIG_CHECK confchk_file_meta[] = {
{"dictionary", "int", NULL, "min=0", NULL, 0},
{"encryption", "category", NULL, NULL, confchk_WT_SESSION_create_encryption_subconfigs, 2},
{"format", "string", NULL, "choices=[\"btree\"]", NULL, 0},
- {"huffman_value", "string", NULL, NULL, NULL, 0}, {"id", "string", NULL, NULL, NULL, 0},
+ {"huffman_key", "string", NULL, NULL, NULL, 0}, {"huffman_value", "string", NULL, NULL, NULL, 0},
+ {"id", "string", NULL, NULL, NULL, 0},
{"ignore_in_memory_cache_size", "boolean", NULL, NULL, NULL, 0},
{"internal_item_max", "int", NULL, "min=0", NULL, 0},
{"internal_key_max", "int", NULL, "min=0", NULL, 0},
@@ -457,6 +474,7 @@ static const WT_CONFIG_CHECK confchk_file_meta[] = {
{"os_cache_max", "int", NULL, "min=0", NULL, 0},
{"prefix_compression", "boolean", NULL, NULL, NULL, 0},
{"prefix_compression_min", "int", NULL, "min=0", NULL, 0},
+ {"readonly", "boolean", NULL, NULL, NULL, 0},
{"split_deepen_min_child", "int", NULL, NULL, NULL, 0},
{"split_deepen_per_child", "int", NULL, NULL, NULL, 0},
{"split_pct", "int", NULL, "min=50,max=100", NULL, 0},
@@ -471,7 +489,7 @@ static const WT_CONFIG_CHECK confchk_file_meta[] = {
static const WT_CONFIG_CHECK confchk_index_meta[] = {
{"app_metadata", "string", NULL, NULL, NULL, 0},
- {"assert", "category", NULL, NULL, confchk_assert_subconfigs, 2},
+ {"assert", "category", NULL, NULL, confchk_assert_subconfigs, 4},
{"collator", "string", NULL, NULL, NULL, 0}, {"columns", "list", NULL, NULL, NULL, 0},
{"extractor", "string", NULL, NULL, NULL, 0}, {"immutable", "boolean", NULL, NULL, NULL, 0},
{"index_key_columns", "int", NULL, NULL, NULL, 0},
@@ -489,8 +507,8 @@ static const WT_CONFIG_CHECK confchk_lsm_meta[] = {
{"access_pattern_hint", "string", NULL, "choices=[\"none\",\"random\",\"sequential\"]", NULL, 0},
{"allocation_size", "int", NULL, "min=512B,max=128MB", NULL, 0},
{"app_metadata", "string", NULL, NULL, NULL, 0},
- {"assert", "category", NULL, NULL, confchk_assert_subconfigs, 2},
- {"block_allocation", "string", NULL, "choices=[\"first\",\"best\"]", NULL, 0},
+ {"assert", "category", NULL, NULL, confchk_assert_subconfigs, 4},
+ {"block_allocation", "string", NULL, "choices=[\"best\",\"first\",\"log-structured\"]", NULL, 0},
{"block_compressor", "string", NULL, NULL, NULL, 0},
{"cache_resident", "boolean", NULL, NULL, NULL, 0},
{"checksum", "string", NULL, "choices=[\"on\",\"off\",\"uncompressed\"]", NULL, 0},
@@ -498,7 +516,7 @@ static const WT_CONFIG_CHECK confchk_lsm_meta[] = {
{"columns", "list", NULL, NULL, NULL, 0}, {"dictionary", "int", NULL, "min=0", NULL, 0},
{"encryption", "category", NULL, NULL, confchk_WT_SESSION_create_encryption_subconfigs, 2},
{"format", "string", NULL, "choices=[\"btree\"]", NULL, 0},
- {"huffman_value", "string", NULL, NULL, NULL, 0},
+ {"huffman_key", "string", NULL, NULL, NULL, 0}, {"huffman_value", "string", NULL, NULL, NULL, 0},
{"ignore_in_memory_cache_size", "boolean", NULL, NULL, NULL, 0},
{"internal_item_max", "int", NULL, "min=0", NULL, 0},
{"internal_key_max", "int", NULL, "min=0", NULL, 0},
@@ -518,6 +536,7 @@ static const WT_CONFIG_CHECK confchk_lsm_meta[] = {
{"os_cache_max", "int", NULL, "min=0", NULL, 0},
{"prefix_compression", "boolean", NULL, NULL, NULL, 0},
{"prefix_compression_min", "int", NULL, "min=0", NULL, 0},
+ {"readonly", "boolean", NULL, NULL, NULL, 0},
{"split_deepen_min_child", "int", NULL, NULL, NULL, 0},
{"split_deepen_per_child", "int", NULL, NULL, NULL, 0},
{"split_pct", "int", NULL, "min=50,max=100", NULL, 0},
@@ -531,7 +550,7 @@ static const WT_CONFIG_CHECK confchk_lsm_meta[] = {
static const WT_CONFIG_CHECK confchk_table_meta[] = {
{"app_metadata", "string", NULL, NULL, NULL, 0},
- {"assert", "category", NULL, NULL, confchk_assert_subconfigs, 2},
+ {"assert", "category", NULL, NULL, confchk_assert_subconfigs, 4},
{"colgroups", "list", NULL, NULL, NULL, 0}, {"collator", "string", NULL, NULL, NULL, 0},
{"columns", "list", NULL, NULL, NULL, 0},
{"key_format", "format", __wt_struct_confchk, NULL, NULL, 0},
@@ -543,6 +562,17 @@ static const WT_CONFIG_CHECK confchk_table_meta[] = {
NULL, 0},
{NULL, NULL, NULL, NULL, NULL, 0}};
+static const WT_CONFIG_CHECK confchk_tiered_meta[] = {
+ {"app_metadata", "string", NULL, NULL, NULL, 0},
+ {"assert", "category", NULL, NULL, confchk_assert_subconfigs, 4},
+ {"tiered", "category", NULL, NULL, confchk_WT_SESSION_create_tiered_subconfigs, 2},
+ {"verbose", "list", NULL, "choices=[\"write_timestamp\"]", NULL, 0},
+ {"write_timestamp_usage", "string", NULL,
+ "choices=[\"always\",\"key_consistent\",\"mixed_mode\","
+ "\"never\",\"none\",\"ordered\"]",
+ NULL, 0},
+ {NULL, NULL, NULL, NULL, NULL, 0}};
+
static const WT_CONFIG_CHECK confchk_wiredtiger_open_compatibility_subconfigs[] = {
{"release", "string", NULL, NULL, NULL, 0}, {"require_max", "string", NULL, NULL, NULL, 0},
{"require_min", "string", NULL, NULL, NULL, 0}, {NULL, NULL, NULL, NULL, NULL, 0}};
@@ -915,11 +945,12 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
{"WT_CURSOR.reconfigure", "append=false,overwrite=true", confchk_WT_CURSOR_reconfigure, 2},
{"WT_SESSION.alter",
"access_pattern_hint=none,app_metadata=,"
- "assert=(read_timestamp=none,write_timestamp=off),"
- "cache_resident=false,exclusive_refreshed=true,log=(enabled=true)"
- ",os_cache_dirty_max=0,os_cache_max=0,verbose=[],"
+ "assert=(commit_timestamp=none,durable_timestamp=none,"
+ "read_timestamp=none,write_timestamp=off),cache_resident=false,"
+ "checkpoint=,exclusive_refreshed=true,log=(enabled=true),"
+ "os_cache_dirty_max=0,os_cache_max=0,readonly=false,verbose=[],"
"write_timestamp_usage=none",
- confchk_WT_SESSION_alter, 10},
+ confchk_WT_SESSION_alter, 12},
{"WT_SESSION.begin_transaction",
"ignore_prepare=false,isolation=,name=,operation_timeout_ms=0,"
"priority=0,read_before_oldest=false,read_timestamp=,"
@@ -935,13 +966,14 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
{"WT_SESSION.compact", "timeout=1200", confchk_WT_SESSION_compact, 1},
{"WT_SESSION.create",
"access_pattern_hint=none,allocation_size=4KB,app_metadata=,"
- "assert=(read_timestamp=none,write_timestamp=off),"
- "block_allocation=best,block_compressor=,cache_resident=false,"
- "checksum=uncompressed,colgroups=,collator=,columns=,dictionary=0"
- ",encryption=(keyid=,name=),exclusive=false,extractor=,"
- "format=btree,huffman_value=,ignore_in_memory_cache_size=false,"
- "immutable=false,import=(enabled=false,file_metadata=,"
- "repair=false),internal_item_max=0,internal_key_max=0,"
+ "assert=(commit_timestamp=none,durable_timestamp=none,"
+ "read_timestamp=none,write_timestamp=off),block_allocation=best,"
+ "block_compressor=,cache_resident=false,checksum=uncompressed,"
+ "colgroups=,collator=,columns=,dictionary=0,encryption=(keyid=,"
+ "name=),exclusive=false,extractor=,format=btree,huffman_key=,"
+ "huffman_value=,ignore_in_memory_cache_size=false,immutable=false"
+ ",import=(enabled=false,file_metadata=,repair=false),"
+ "internal_item_max=0,internal_key_max=0,"
"internal_key_truncate=true,internal_page_max=4KB,key_format=u,"
"key_gap=10,leaf_item_max=0,leaf_key_max=0,leaf_page_max=32KB,"
"leaf_value_max=0,log=(enabled=true),lsm=(auto_throttle=true,"
@@ -950,10 +982,11 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
"chunk_size=10MB,merge_custom=(prefix=,start_generation=0,"
"suffix=),merge_max=15,merge_min=0),memory_page_image_max=0,"
"memory_page_max=5MB,os_cache_dirty_max=0,os_cache_max=0,"
- "prefix_compression=false,prefix_compression_min=4,source=,"
- "split_deepen_min_child=0,split_deepen_per_child=0,split_pct=90,"
- "type=file,value_format=u,verbose=[],write_timestamp_usage=none",
- confchk_WT_SESSION_create, 46},
+ "prefix_compression=false,prefix_compression_min=4,readonly=false"
+ ",source=,split_deepen_min_child=0,split_deepen_per_child=0,"
+ "split_pct=90,tiered=(chunk_size=1GB,tiers=),type=file,"
+ "value_format=u,verbose=[],write_timestamp_usage=none",
+ confchk_WT_SESSION_create, 49},
{"WT_SESSION.drop",
"checkpoint_wait=true,force=false,lock_wait=true,"
"remove_files=true",
@@ -996,55 +1029,60 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
"strict=false",
confchk_WT_SESSION_verify, 7},
{"colgroup.meta",
- "app_metadata=,assert=(read_timestamp=none,write_timestamp=off),"
+ "app_metadata=,assert=(commit_timestamp=none,"
+ "durable_timestamp=none,read_timestamp=none,write_timestamp=off),"
"collator=,columns=,source=,type=file,verbose=[],"
"write_timestamp_usage=none",
confchk_colgroup_meta, 8},
{"file.config",
"access_pattern_hint=none,allocation_size=4KB,app_metadata=,"
- "assert=(read_timestamp=none,write_timestamp=off),"
- "block_allocation=best,block_compressor=,cache_resident=false,"
- "checksum=uncompressed,collator=,columns=,dictionary=0,"
- "encryption=(keyid=,name=),format=btree,huffman_value=,"
+ "assert=(commit_timestamp=none,durable_timestamp=none,"
+ "read_timestamp=none,write_timestamp=off),block_allocation=best,"
+ "block_compressor=,cache_resident=false,checksum=uncompressed,"
+ "collator=,columns=,dictionary=0,encryption=(keyid=,name=),"
+ "format=btree,huffman_key=,huffman_value=,"
"ignore_in_memory_cache_size=false,internal_item_max=0,"
"internal_key_max=0,internal_key_truncate=true,"
"internal_page_max=4KB,key_format=u,key_gap=10,leaf_item_max=0,"
"leaf_key_max=0,leaf_page_max=32KB,leaf_value_max=0,"
"log=(enabled=true),memory_page_image_max=0,memory_page_max=5MB,"
"os_cache_dirty_max=0,os_cache_max=0,prefix_compression=false,"
- "prefix_compression_min=4,split_deepen_min_child=0,"
- "split_deepen_per_child=0,split_pct=90,value_format=u,verbose=[],"
- "write_timestamp_usage=none",
- confchk_file_config, 38},
+ "prefix_compression_min=4,readonly=false,split_deepen_min_child=0"
+ ",split_deepen_per_child=0,split_pct=90,value_format=u,verbose=[]"
+ ",write_timestamp_usage=none",
+ confchk_file_config, 40},
{"file.meta",
"access_pattern_hint=none,allocation_size=4KB,app_metadata=,"
- "assert=(read_timestamp=none,write_timestamp=off),"
- "block_allocation=best,block_compressor=,cache_resident=false,"
- "checkpoint=,checkpoint_backup_info=,checkpoint_lsn=,"
- "checksum=uncompressed,collator=,columns=,dictionary=0,"
- "encryption=(keyid=,name=),format=btree,huffman_value=,id=,"
+ "assert=(commit_timestamp=none,durable_timestamp=none,"
+ "read_timestamp=none,write_timestamp=off),block_allocation=best,"
+ "block_compressor=,cache_resident=false,checkpoint=,"
+ "checkpoint_backup_info=,checkpoint_lsn=,checksum=uncompressed,"
+ "collator=,columns=,dictionary=0,encryption=(keyid=,name=),"
+ "format=btree,huffman_key=,huffman_value=,id=,"
"ignore_in_memory_cache_size=false,internal_item_max=0,"
"internal_key_max=0,internal_key_truncate=true,"
"internal_page_max=4KB,key_format=u,key_gap=10,leaf_item_max=0,"
"leaf_key_max=0,leaf_page_max=32KB,leaf_value_max=0,"
"log=(enabled=true),memory_page_image_max=0,memory_page_max=5MB,"
"os_cache_dirty_max=0,os_cache_max=0,prefix_compression=false,"
- "prefix_compression_min=4,split_deepen_min_child=0,"
- "split_deepen_per_child=0,split_pct=90,value_format=u,verbose=[],"
- "version=(major=0,minor=0),write_timestamp_usage=none",
- confchk_file_meta, 43},
+ "prefix_compression_min=4,readonly=false,split_deepen_min_child=0"
+ ",split_deepen_per_child=0,split_pct=90,value_format=u,verbose=[]"
+ ",version=(major=0,minor=0),write_timestamp_usage=none",
+ confchk_file_meta, 45},
{"index.meta",
- "app_metadata=,assert=(read_timestamp=none,write_timestamp=off),"
+ "app_metadata=,assert=(commit_timestamp=none,"
+ "durable_timestamp=none,read_timestamp=none,write_timestamp=off),"
"collator=,columns=,extractor=,immutable=false,index_key_columns="
",key_format=u,source=,type=file,value_format=u,verbose=[],"
"write_timestamp_usage=none",
confchk_index_meta, 13},
{"lsm.meta",
"access_pattern_hint=none,allocation_size=4KB,app_metadata=,"
- "assert=(read_timestamp=none,write_timestamp=off),"
- "block_allocation=best,block_compressor=,cache_resident=false,"
- "checksum=uncompressed,chunks=,collator=,columns=,dictionary=0,"
- "encryption=(keyid=,name=),format=btree,huffman_value=,"
+ "assert=(commit_timestamp=none,durable_timestamp=none,"
+ "read_timestamp=none,write_timestamp=off),block_allocation=best,"
+ "block_compressor=,cache_resident=false,checksum=uncompressed,"
+ "chunks=,collator=,columns=,dictionary=0,encryption=(keyid=,"
+ "name=),format=btree,huffman_key=,huffman_value=,"
"ignore_in_memory_cache_size=false,internal_item_max=0,"
"internal_key_max=0,internal_key_truncate=true,"
"internal_page_max=4KB,key_format=u,key_gap=10,last=,"
@@ -1056,14 +1094,22 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
"suffix=),merge_max=15,merge_min=0),memory_page_image_max=0,"
"memory_page_max=5MB,old_chunks=,os_cache_dirty_max=0,"
"os_cache_max=0,prefix_compression=false,prefix_compression_min=4"
- ",split_deepen_min_child=0,split_deepen_per_child=0,split_pct=90,"
- "value_format=u,verbose=[],write_timestamp_usage=none",
- confchk_lsm_meta, 42},
+ ",readonly=false,split_deepen_min_child=0,"
+ "split_deepen_per_child=0,split_pct=90,value_format=u,verbose=[],"
+ "write_timestamp_usage=none",
+ confchk_lsm_meta, 44},
{"table.meta",
- "app_metadata=,assert=(read_timestamp=none,write_timestamp=off),"
+ "app_metadata=,assert=(commit_timestamp=none,"
+ "durable_timestamp=none,read_timestamp=none,write_timestamp=off),"
"colgroups=,collator=,columns=,key_format=u,value_format=u,"
"verbose=[],write_timestamp_usage=none",
confchk_table_meta, 9},
+ {"tiered.meta",
+ "app_metadata=,assert=(commit_timestamp=none,"
+ "durable_timestamp=none,read_timestamp=none,write_timestamp=off),"
+ "tiered=(chunk_size=1GB,tiers=),verbose=[],"
+ "write_timestamp_usage=none",
+ confchk_tiered_meta, 5},
{"wiredtiger_open",
"buffer_alignment=-1,builtin_extension_config=,cache_cursors=true"
",cache_max_wait_ms=0,cache_overhead=8,cache_size=100MB,"
diff --git a/src/third_party/wiredtiger/src/conn/conn_api.c b/src/third_party/wiredtiger/src/conn/conn_api.c
index 613c71a8d05..420494d985c 100644
--- a/src/third_party/wiredtiger/src/conn/conn_api.c
+++ b/src/third_party/wiredtiger/src/conn/conn_api.c
@@ -1857,7 +1857,7 @@ __wt_verbose_config(WT_SESSION_IMPL *session, const char *cfg[])
{"salvage", WT_VERB_SALVAGE}, {"shared_cache", WT_VERB_SHARED_CACHE},
{"split", WT_VERB_SPLIT}, {"temporary", WT_VERB_TEMPORARY},
{"thread_group", WT_VERB_THREAD_GROUP}, {"timestamp", WT_VERB_TIMESTAMP},
- {"transaction", WT_VERB_TRANSACTION}, {"verify", WT_VERB_VERIFY},
+ {"tiered", WT_VERB_TIERED}, {"transaction", WT_VERB_TRANSACTION}, {"verify", WT_VERB_VERIFY},
{"version", WT_VERB_VERSION}, {"write", WT_VERB_WRITE}, {NULL, 0}};
WT_CONFIG_ITEM cval, sval;
WT_CONNECTION_IMPL *conn;
diff --git a/src/third_party/wiredtiger/src/conn/conn_dhandle.c b/src/third_party/wiredtiger/src/conn/conn_dhandle.c
index 44b2d86f7c5..b9302ccb602 100644
--- a/src/third_party/wiredtiger/src/conn/conn_dhandle.c
+++ b/src/third_party/wiredtiger/src/conn/conn_dhandle.c
@@ -99,6 +99,9 @@ __conn_dhandle_config_set(WT_SESSION_IMPL *session)
case WT_DHANDLE_TYPE_TABLE:
WT_ERR(__wt_strdup(session, WT_CONFIG_BASE(session, table_meta), &dhandle->cfg[0]));
break;
+ case WT_DHANDLE_TYPE_TIERED:
+ WT_ERR(__wt_strdup(session, WT_CONFIG_BASE(session, tiered_meta), &dhandle->cfg[0]));
+ break;
}
dhandle->cfg[1] = metaconf;
dhandle->meta_base = base;
@@ -127,6 +130,9 @@ __conn_dhandle_destroy(WT_SESSION_IMPL *session, WT_DATA_HANDLE *dhandle)
case WT_DHANDLE_TYPE_TABLE:
ret = __wt_schema_close_table(session, (WT_TABLE *)dhandle);
break;
+ case WT_DHANDLE_TYPE_TIERED:
+ ret = __wt_tiered_close(session, (WT_TIERED *)dhandle);
+ break;
}
__wt_rwlock_destroy(session, &dhandle->rwlock);
@@ -150,6 +156,7 @@ __wt_conn_dhandle_alloc(WT_SESSION_IMPL *session, const char *uri, const char *c
WT_DATA_HANDLE *dhandle;
WT_DECL_RET;
WT_TABLE *table;
+ WT_TIERED *tiered;
uint64_t bucket;
/*
@@ -165,6 +172,10 @@ __wt_conn_dhandle_alloc(WT_SESSION_IMPL *session, const char *uri, const char *c
WT_RET(__wt_calloc_one(session, &table));
dhandle = (WT_DATA_HANDLE *)table;
dhandle->type = WT_DHANDLE_TYPE_TABLE;
+ } else if (WT_PREFIX_MATCH(uri, "tiered:")) {
+ WT_RET(__wt_calloc_one(session, &tiered));
+ dhandle = (WT_DATA_HANDLE *)tiered;
+ dhandle->type = WT_DHANDLE_TYPE_TIERED;
} else
WT_RET_PANIC(session, EINVAL, "illegal handle allocation URI %s", uri);
@@ -364,6 +375,9 @@ __wt_conn_dhandle_close(WT_SESSION_IMPL *session, bool final, bool mark_dead)
case WT_DHANDLE_TYPE_TABLE:
WT_TRET(__wt_schema_close_table(session, (WT_TABLE *)dhandle));
break;
+ case WT_DHANDLE_TYPE_TIERED:
+ WT_TRET(__wt_tiered_close(session, (WT_TIERED *)dhandle));
+ break;
}
/*
@@ -519,6 +533,9 @@ __wt_conn_dhandle_open(WT_SESSION_IMPL *session, const char *cfg[], uint32_t fla
case WT_DHANDLE_TYPE_TABLE:
WT_ERR(__wt_schema_open_table(session));
break;
+ case WT_DHANDLE_TYPE_TIERED:
+ WT_ERR(__wt_tiered_open(session, cfg));
+ break;
}
/*
diff --git a/src/third_party/wiredtiger/src/cursor/cur_backup.c b/src/third_party/wiredtiger/src/cursor/cur_backup.c
index 274786c2866..f576a3ffa12 100644
--- a/src/third_party/wiredtiger/src/cursor/cur_backup.c
+++ b/src/third_party/wiredtiger/src/cursor/cur_backup.c
@@ -883,7 +883,8 @@ __backup_list_uri_append(WT_SESSION_IMPL *session, const char *name, bool *skip)
*/
if (!WT_PREFIX_MATCH(name, "file:") && !WT_PREFIX_MATCH(name, "colgroup:") &&
!WT_PREFIX_MATCH(name, "index:") && !WT_PREFIX_MATCH(name, "lsm:") &&
- !WT_PREFIX_MATCH(name, WT_SYSTEM_PREFIX) && !WT_PREFIX_MATCH(name, "table:"))
+ !WT_PREFIX_MATCH(name, WT_SYSTEM_PREFIX) && !WT_PREFIX_MATCH(name, "table:") &&
+ !WT_PREFIX_MATCH(name, "tiered:"))
WT_RET_MSG(session, ENOTSUP, "hot backup is not supported for objects of type %s", name);
/* Add the metadata entry to the backup file. */
diff --git a/src/third_party/wiredtiger/src/cursor/cur_log.c b/src/third_party/wiredtiger/src/cursor/cur_log.c
index 84c7e15c30c..03956a1fc36 100644
--- a/src/third_party/wiredtiger/src/cursor/cur_log.c
+++ b/src/third_party/wiredtiger/src/cursor/cur_log.c
@@ -208,7 +208,7 @@ __curlog_next(WT_CURSOR *cursor)
*/
if (cl->stepp == NULL || cl->stepp >= cl->stepp_end || !*cl->stepp) {
cl->txnid = 0;
- ret = __wt_log_scan(session, cl->next_lsn, WT_LOGSCAN_ONE, __curlog_logrec, cl);
+ ret = __wt_log_scan(session, cl->next_lsn, NULL, WT_LOGSCAN_ONE, __curlog_logrec, cl);
if (ret == ENOENT)
ret = WT_NOTFOUND;
WT_ERR(ret);
@@ -246,7 +246,7 @@ __curlog_search(WT_CURSOR *cursor)
*/
WT_ERR(__wt_cursor_get_key(cursor, &key_file, &key_offset, &counter));
WT_SET_LSN(&key, key_file, key_offset);
- ret = __wt_log_scan(session, &key, WT_LOGSCAN_ONE, __curlog_logrec, cl);
+ ret = __wt_log_scan(session, &key, NULL, WT_LOGSCAN_ONE, __curlog_logrec, cl);
if (ret == ENOENT)
ret = WT_NOTFOUND;
WT_ERR(ret);
diff --git a/src/third_party/wiredtiger/src/evict/evict_lru.c b/src/third_party/wiredtiger/src/evict/evict_lru.c
index 99a560fbe19..2cf014137a7 100644
--- a/src/third_party/wiredtiger/src/evict/evict_lru.c
+++ b/src/third_party/wiredtiger/src/evict/evict_lru.c
@@ -584,8 +584,15 @@ __evict_update_work(WT_SESSION_IMPL *session)
if (!__evict_queue_empty(cache->evict_urgent_queue, false))
LF_SET(WT_CACHE_EVICT_URGENT);
- if (F_ISSET(conn, WT_CONN_HS_OPEN) && __wt_hs_get_btree(session, &hs_tree) == 0)
+ /*
+ * TODO: We are caching the cache usage values associated with the history store because the
+ * history store dhandle isn't always available to eviction. Keeping potentially out-of-date
+ * values could lead to surprising bugs in the future.
+ */
+ if (F_ISSET(conn, WT_CONN_HS_OPEN) && __wt_hs_get_btree(session, &hs_tree) == 0) {
cache->bytes_hs = hs_tree->bytes_inmem;
+ cache->bytes_hs_dirty = hs_tree->bytes_dirty_intl + hs_tree->bytes_dirty_leaf;
+ }
/*
* If we need space in the cache, try to find clean pages to evict.
@@ -1726,6 +1733,19 @@ __evict_walk_tree(WT_SESSION_IMPL *session, WT_EVICT_QUEUE *queue, u_int max_ent
if (target_pages > remaining_slots)
target_pages = remaining_slots;
+ /*
+ * Reduce the number of pages to be selected from btrees other than the history store (HS) if
+ * the cache pressure is high and HS content dominates the cache. Evicting unclean non-HS pages
+ * can generate even more HS content and will not help with the cache pressure, and will
+ * probably just amplify it further.
+ */
+ if (!WT_IS_HS(btree->dhandle) && __wt_cache_hs_dirty(session)) {
+ /* If target pages are less than 10, keep it like that. */
+ target_pages = target_pages < 10 ? target_pages : target_pages / 10;
+ WT_STAT_CONN_INCR(session, cache_eviction_target_page_reduced);
+ WT_STAT_DATA_INCR(session, cache_eviction_target_page_reduced);
+ }
+
/* If we don't want any pages from this tree, move on. */
if (target_pages == 0)
return (0);
@@ -1930,6 +1950,19 @@ __evict_walk_tree(WT_SESSION_IMPL *session, WT_EVICT_QUEUE *queue, u_int max_ent
continue;
}
+ /*
+ * If history store dirty content is dominating the cache, we want to prioritize evicting
+ * history store pages over other btree pages. This helps in keeping cache contents below
+ * the configured cache size during checkpoints where reconciling non-HS pages can generate
+ * significant amount of HS dirty content very quickly.
+ */
+ if (WT_IS_HS(btree->dhandle) && __wt_cache_hs_dirty(session)) {
+ WT_STAT_CONN_INCR(session, cache_eviction_pages_queued_urgent_hs_dirty);
+ if (__wt_page_evict_urgent(session, ref))
+ urgent_queued = true;
+ continue;
+ }
+
/* Pages that are empty or from dead trees are fast-tracked. */
if (__wt_page_is_empty(page) || F_ISSET(session->dhandle, WT_DHANDLE_DEAD))
goto fast;
diff --git a/src/third_party/wiredtiger/src/include/block.h b/src/third_party/wiredtiger/src/include/block.h
index f35d09f05f3..74b677b6cd0 100644
--- a/src/third_party/wiredtiger/src/include/block.h
+++ b/src/third_party/wiredtiger/src/include/block.h
@@ -51,6 +51,7 @@ struct __wt_extlist {
uint64_t bytes; /* Byte count */
uint32_t entries; /* Entry count */
+ uint32_t logid; /* Written log ID */
wt_off_t offset; /* Written extent offset */
uint32_t checksum; /* Written extent checksum */
uint32_t size; /* Written extent size */
@@ -140,6 +141,7 @@ struct __wt_size {
struct __wt_block_ckpt {
uint8_t version; /* Version */
+ uint32_t root_logid;
wt_off_t root_offset; /* The root */
uint32_t root_checksum, root_size;
@@ -236,12 +238,18 @@ struct __wt_block {
/* Configuration information, set when the file is opened. */
uint32_t allocfirst; /* Allocation is first-fit */
uint32_t allocsize; /* Allocation size */
+ bool log_structured; /* Write checkpoint as separate files */
size_t os_cache; /* System buffer cache flush max */
size_t os_cache_max;
size_t os_cache_dirty_max;
u_int block_header; /* Header length */
+ /* Log-structured tracking. */
+ uint32_t file_flags, logid, max_logid;
+ WT_FH **lfh;
+ size_t lfh_alloc;
+
/*
* There is only a single checkpoint in a file that can be written. The information could
* logically live in the WT_BM structure, but then we would be re-creating it every time we
diff --git a/src/third_party/wiredtiger/src/include/cache.h b/src/third_party/wiredtiger/src/include/cache.h
index 16bad36997b..85b3ab35f83 100644
--- a/src/third_party/wiredtiger/src/include/cache.h
+++ b/src/third_party/wiredtiger/src/include/cache.h
@@ -71,7 +71,6 @@ struct __wt_cache {
uint64_t bytes_dirty_leaf;
uint64_t bytes_dirty_total;
uint64_t bytes_evict; /* Bytes/pages discarded by eviction */
- uint64_t bytes_hs; /* History store bytes inmem */
uint64_t bytes_image_intl; /* Bytes of disk images (internal) */
uint64_t bytes_image_leaf; /* Bytes of disk images (leaf) */
uint64_t bytes_inmem; /* Bytes/pages in memory */
@@ -80,6 +79,13 @@ struct __wt_cache {
uint64_t bytes_updates; /* Bytes of updates to pages */
uint64_t bytes_written;
+ /*
+ * History store cache usage. TODO: The values for these variables are cached and potentially
+ * outdated.
+ */
+ uint64_t bytes_hs; /* History store bytes inmem */
+ uint64_t bytes_hs_dirty; /* History store bytes inmem dirty */
+
uint64_t pages_dirty_intl;
uint64_t pages_dirty_leaf;
uint64_t pages_evicted;
diff --git a/src/third_party/wiredtiger/src/include/cache_inline.h b/src/third_party/wiredtiger/src/include/cache_inline.h
index 4061d5b52f6..4015196fd6d 100644
--- a/src/third_party/wiredtiger/src/include/cache_inline.h
+++ b/src/third_party/wiredtiger/src/include/cache_inline.h
@@ -446,6 +446,24 @@ __wt_cache_full(WT_SESSION_IMPL *session)
}
/*
+ * __wt_cache_hs_dirty --
+ * Return if a major portion of the cache is dirty due to history store content.
+ */
+static inline bool
+__wt_cache_hs_dirty(WT_SESSION_IMPL *session)
+{
+ WT_CACHE *cache;
+ WT_CONNECTION_IMPL *conn;
+ uint64_t bytes_max;
+ conn = S2C(session);
+ cache = conn->cache;
+ bytes_max = S2C(session)->cache_size;
+
+ return (__wt_cache_bytes_plus_overhead(cache, cache->bytes_hs_dirty) >=
+ ((uint64_t)(cache->eviction_dirty_trigger * bytes_max) / 100));
+}
+
+/*
* __wt_cache_eviction_check --
* Evict pages if the cache crosses its boundaries.
*/
diff --git a/src/third_party/wiredtiger/src/include/config.h b/src/third_party/wiredtiger/src/include/config.h
index 70f4fdef9a6..8b405657f28 100644
--- a/src/third_party/wiredtiger/src/include/config.h
+++ b/src/third_party/wiredtiger/src/include/config.h
@@ -99,10 +99,11 @@ struct __wt_config_parser_impl {
#define WT_CONFIG_ENTRY_index_meta 45
#define WT_CONFIG_ENTRY_lsm_meta 46
#define WT_CONFIG_ENTRY_table_meta 47
-#define WT_CONFIG_ENTRY_wiredtiger_open 48
-#define WT_CONFIG_ENTRY_wiredtiger_open_all 49
-#define WT_CONFIG_ENTRY_wiredtiger_open_basecfg 50
-#define WT_CONFIG_ENTRY_wiredtiger_open_usercfg 51
+#define WT_CONFIG_ENTRY_tiered_meta 48
+#define WT_CONFIG_ENTRY_wiredtiger_open 49
+#define WT_CONFIG_ENTRY_wiredtiger_open_all 50
+#define WT_CONFIG_ENTRY_wiredtiger_open_basecfg 51
+#define WT_CONFIG_ENTRY_wiredtiger_open_usercfg 52
/*
* configuration section: END
* DO NOT EDIT: automatically built by dist/flags.py.
diff --git a/src/third_party/wiredtiger/src/include/connection.h b/src/third_party/wiredtiger/src/include/connection.h
index d52fe680d81..f62570a8041 100644
--- a/src/third_party/wiredtiger/src/include/connection.h
+++ b/src/third_party/wiredtiger/src/include/connection.h
@@ -508,11 +508,12 @@ struct __wt_connection_impl {
#define WT_VERB_SPLIT 0x0020000000u
#define WT_VERB_TEMPORARY 0x0040000000u
#define WT_VERB_THREAD_GROUP 0x0080000000u
-#define WT_VERB_TIMESTAMP 0x0100000000u
-#define WT_VERB_TRANSACTION 0x0200000000u
-#define WT_VERB_VERIFY 0x0400000000u
-#define WT_VERB_VERSION 0x0800000000u
-#define WT_VERB_WRITE 0x1000000000u
+#define WT_VERB_TIERED 0x0100000000u
+#define WT_VERB_TIMESTAMP 0x0200000000u
+#define WT_VERB_TRANSACTION 0x0400000000u
+#define WT_VERB_VERIFY 0x0800000000u
+#define WT_VERB_VERSION 0x1000000000u
+#define WT_VERB_WRITE 0x2000000000u
/* AUTOMATIC FLAG VALUE GENERATION STOP */
uint64_t verbose;
diff --git a/src/third_party/wiredtiger/src/include/dhandle.h b/src/third_party/wiredtiger/src/include/dhandle.h
index 9f98cf87e3f..12f173d3802 100644
--- a/src/third_party/wiredtiger/src/include/dhandle.h
+++ b/src/third_party/wiredtiger/src/include/dhandle.h
@@ -85,7 +85,7 @@ struct __wt_data_handle {
WT_DATA_SOURCE *dsrc; /* Data source for this handle */
void *handle; /* Generic handle */
- enum { WT_DHANDLE_TYPE_BTREE, WT_DHANDLE_TYPE_TABLE } type;
+ enum { WT_DHANDLE_TYPE_BTREE, WT_DHANDLE_TYPE_TABLE, WT_DHANDLE_TYPE_TIERED } type;
bool compact_skip; /* If the handle failed to compact */
diff --git a/src/third_party/wiredtiger/src/include/extern.h b/src/third_party/wiredtiger/src/include/extern.h
index 83327b021ee..68e636cdebf 100644
--- a/src/third_party/wiredtiger/src/include/extern.h
+++ b/src/third_party/wiredtiger/src/include/extern.h
@@ -85,12 +85,13 @@ extern int __wt_block_addr_invalid(WT_SESSION_IMPL *session, WT_BLOCK *block, co
size_t addr_size, bool live) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_block_addr_string(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf,
const uint8_t *addr, size_t addr_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
-extern int __wt_block_addr_to_buffer(WT_BLOCK *block, uint8_t **pp, wt_off_t offset, uint32_t size,
- uint32_t checksum) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+extern int __wt_block_addr_to_buffer(WT_BLOCK *block, uint8_t **pp, uint32_t logid, wt_off_t offset,
+ uint32_t size, uint32_t checksum) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_block_alloc(WT_SESSION_IMPL *session, WT_BLOCK *block, wt_off_t *offp,
wt_off_t size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
-extern int __wt_block_buffer_to_addr(WT_BLOCK *block, const uint8_t *p, wt_off_t *offsetp,
- uint32_t *sizep, uint32_t *checksump) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+extern int __wt_block_buffer_to_addr(WT_BLOCK *block, const uint8_t *p, uint32_t *logidp,
+ wt_off_t *offsetp, uint32_t *sizep, uint32_t *checksump)
+ WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_block_buffer_to_ckpt(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *p,
WT_BLOCK_CKPT *ci) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_block_checkpoint(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf,
@@ -108,7 +109,7 @@ extern int __wt_block_checkpoint_start(WT_SESSION_IMPL *session, WT_BLOCK *block
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_block_checkpoint_unload(WT_SESSION_IMPL *session, WT_BLOCK *block, bool checkpoint)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
-extern int __wt_block_ckpt_decode(WT_SESSION *wt_session, size_t allocsize, const uint8_t *p,
+extern int __wt_block_ckpt_decode(WT_SESSION *wt_session, WT_BLOCK *block, const uint8_t *p,
WT_BLOCK_CKPT *ci) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")))
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_block_ckpt_init(WT_SESSION_IMPL *session, WT_BLOCK_CKPT *ci, const char *name)
@@ -150,6 +151,8 @@ extern int __wt_block_extlist_truncate(WT_SESSION_IMPL *session, WT_BLOCK *block
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_block_extlist_write(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_EXTLIST *el,
WT_EXTLIST *additional) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+extern int __wt_block_fh(WT_SESSION_IMPL *session, WT_BLOCK *block, uint32_t logid, WT_FH **fhp)
+ WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_block_free(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr,
size_t addr_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_block_insert_ext(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_EXTLIST *el,
@@ -170,15 +173,17 @@ extern int __wt_block_map(WT_SESSION_IMPL *session, WT_BLOCK *block, void *mappe
extern int __wt_block_misplaced(WT_SESSION_IMPL *session, WT_BLOCK *block, const char *list,
wt_off_t offset, uint32_t size, bool live, const char *func, int line)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
-extern int __wt_block_off_free(WT_SESSION_IMPL *session, WT_BLOCK *block, wt_off_t offset,
- wt_off_t size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+extern int __wt_block_newfile(WT_SESSION_IMPL *session, WT_BLOCK *block)
+ WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+extern int __wt_block_off_free(WT_SESSION_IMPL *session, WT_BLOCK *block, uint32_t logid,
+ wt_off_t offset, wt_off_t size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_block_off_remove_overlap(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_EXTLIST *el,
wt_off_t off, wt_off_t size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_block_open(WT_SESSION_IMPL *session, const char *filename, const char *cfg[],
bool forced_salvage, bool readonly, uint32_t allocsize, WT_BLOCK **blockp)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_block_read_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf,
- wt_off_t offset, uint32_t size, uint32_t checksum)
+ uint32_t logid, wt_off_t offset, uint32_t size, uint32_t checksum)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_block_read_off_blind(WT_SESSION_IMPL *session, WT_BLOCK *block, wt_off_t offset,
uint32_t *sizep, uint32_t *checksump) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
@@ -206,8 +211,8 @@ extern int __wt_block_write(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *
size_t *addr_sizep, bool data_checksum, bool checkpoint_io)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf,
- wt_off_t *offsetp, uint32_t *sizep, uint32_t *checksump, bool data_checksum, bool checkpoint_io,
- bool caller_locked) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+ uint32_t *logidp, wt_off_t *offsetp, uint32_t *sizep, uint32_t *checksump, bool data_checksum,
+ bool checkpoint_io, bool caller_locked) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_block_write_size(WT_SESSION_IMPL *session, WT_BLOCK *block, size_t *sizep)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_bloom_close(WT_BLOOM *bloom) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")))
@@ -578,6 +583,9 @@ extern int __wt_curtable_get_value(WT_CURSOR *cursor, ...)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_curtable_open(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner,
const char *cfg[], WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+extern int __wt_curtiered_close(WT_CURSOR *cursor) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+extern int __wt_curtiered_open(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner,
+ const char *cfg[], WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_debug_addr(WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size,
const char *ofile) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_debug_addr_print(WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size)
@@ -834,7 +842,8 @@ extern int __wt_log_remove(WT_SESSION_IMPL *session, const char *file_prefix, ui
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_log_reset(WT_SESSION_IMPL *session, uint32_t lognum)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
-extern int __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags,
+extern int __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *start_lsnp, WT_LSN *end_lsnp,
+ uint32_t flags,
int (*func)(WT_SESSION_IMPL *session, WT_ITEM *record, WT_LSN *lsnp, WT_LSN *next_lsnp,
void *cookie, int firstrecord),
void *cookie) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
@@ -1432,6 +1441,22 @@ extern int __wt_thread_group_destroy(WT_SESSION_IMPL *session, WT_THREAD_GROUP *
extern int __wt_thread_group_resize(WT_SESSION_IMPL *session, WT_THREAD_GROUP *group,
uint32_t new_min, uint32_t new_max, uint32_t flags)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+extern int __wt_tiered_close(WT_SESSION_IMPL *session, WT_TIERED *tiered)
+ WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+extern int __wt_tiered_create(WT_SESSION_IMPL *session, const char *uri, bool exclusive,
+ const char *config) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+extern int __wt_tiered_drop(WT_SESSION_IMPL *session, const char *uri, const char *cfg[])
+ WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+extern int __wt_tiered_open(WT_SESSION_IMPL *session, const char *cfg[])
+ WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+extern int __wt_tiered_rename(WT_SESSION_IMPL *session, const char *olduri, const char *newuri,
+ const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+extern int __wt_tiered_truncate(WT_SESSION_IMPL *session, const char *uri, const char *cfg[])
+ WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+extern int __wt_tiered_worker(WT_SESSION_IMPL *session, const char *uri,
+ int (*file_func)(WT_SESSION_IMPL *, const char *[]),
+ int (*name_func)(WT_SESSION_IMPL *, const char *, bool *), const char *cfg[], uint32_t open_flags)
+ WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_time_aggregate_validate(WT_SESSION_IMPL *session, WT_TIME_AGGREGATE *ta,
WT_TIME_AGGREGATE *parent, bool silent) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_time_value_validate(WT_SESSION_IMPL *session, WT_TIME_WINDOW *tw,
@@ -1497,9 +1522,9 @@ extern int __wt_txn_parse_timestamp_raw(WT_SESSION_IMPL *session, const char *na
wt_timestamp_t *timestamp, WT_CONFIG_ITEM *cval) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_txn_prepare(WT_SESSION_IMPL *session, const char *cfg[])
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
-extern int __wt_txn_printlog(WT_SESSION *wt_session, const char *ofile, uint32_t flags)
- WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")))
- WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+extern int __wt_txn_printlog(WT_SESSION *wt_session, const char *ofile, uint32_t flags,
+ WT_LSN *start_lsn, WT_LSN *end_lsn) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")))
+ WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_txn_query_timestamp(WT_SESSION_IMPL *session, char *hex_timestamp,
const char *cfg[], bool global_txn) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_txn_reconfigure(WT_SESSION_IMPL *session, const char *config)
@@ -1800,6 +1825,8 @@ static inline bool __wt_cache_aggressive(WT_SESSION_IMPL *session)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
static inline bool __wt_cache_full(WT_SESSION_IMPL *session)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+static inline bool __wt_cache_hs_dirty(WT_SESSION_IMPL *session)
+ WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
static inline bool __wt_cache_stuck(WT_SESSION_IMPL *session)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
static inline bool __wt_checksum_match(const void *chunk, size_t len, uint32_t v)
diff --git a/src/third_party/wiredtiger/src/include/stat.h b/src/third_party/wiredtiger/src/include/stat.h
index dcac8f3e569..e1c6cea488a 100644
--- a/src/third_party/wiredtiger/src/include/stat.h
+++ b/src/third_party/wiredtiger/src/include/stat.h
@@ -400,6 +400,7 @@ struct __wt_connection_stats {
int64_t cache_eviction_pages_queued_post_lru;
int64_t cache_eviction_pages_queued_urgent;
int64_t cache_eviction_pages_queued_oldest;
+ int64_t cache_eviction_pages_queued_urgent_hs_dirty;
int64_t cache_eviction_pages_already_queued;
int64_t cache_eviction_fail;
int64_t cache_eviction_fail_parent_has_overflow_items;
@@ -697,6 +698,7 @@ struct __wt_connection_stats {
int64_t cache_eviction_target_page_ge128;
int64_t cache_eviction_target_page_lt64;
int64_t cache_eviction_target_page_lt128;
+ int64_t cache_eviction_target_page_reduced;
int64_t cache_eviction_walks_abandoned;
int64_t cache_eviction_walks_stopped;
int64_t cache_eviction_walks_gave_up_no_targets;
@@ -909,6 +911,7 @@ struct __wt_dsrc_stats {
int64_t cache_eviction_target_page_ge128;
int64_t cache_eviction_target_page_lt64;
int64_t cache_eviction_target_page_lt128;
+ int64_t cache_eviction_target_page_reduced;
int64_t cache_eviction_walks_abandoned;
int64_t cache_eviction_walks_stopped;
int64_t cache_eviction_walks_gave_up_no_targets;
diff --git a/src/third_party/wiredtiger/src/include/tiered.h b/src/third_party/wiredtiger/src/include/tiered.h
new file mode 100644
index 00000000000..ac4343661c5
--- /dev/null
+++ b/src/third_party/wiredtiger/src/include/tiered.h
@@ -0,0 +1,44 @@
+/*-
+ * Copyright (c) 2014-2020 MongoDB, Inc.
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+/*
+ * WT_CURSOR_TIERED --
+ * An tiered cursor.
+ */
+struct __wt_cursor_tiered {
+ WT_CURSOR iface;
+
+ WT_TIERED *tiered;
+
+ WT_CURSOR **cursors;
+ WT_CURSOR *current; /* The current cursor for iteration */
+ WT_CURSOR *primary; /* The current primary */
+
+/* AUTOMATIC FLAG VALUE GENERATION START */
+#define WT_CURTIERED_ACTIVE 0x1u /* Incremented the session count */
+#define WT_CURTIERED_ITERATE_NEXT 0x2u /* Forward iteration */
+#define WT_CURTIERED_ITERATE_PREV 0x4u /* Backward iteration */
+ /* AUTOMATIC FLAG VALUE GENERATION STOP */
+ uint32_t flags;
+};
+
+/*
+ * WT_TIERED --
+ * Handle for a tiered data source.
+ */
+struct __wt_tiered {
+ WT_DATA_HANDLE iface;
+
+ const char *name, *config, *filename;
+ const char *key_format, *value_format;
+
+ WT_DATA_HANDLE **tiers;
+ u_int ntiers;
+
+ WT_COLLATOR *collator; /* TODO: handle custom collation */
+};
diff --git a/src/third_party/wiredtiger/src/include/wiredtiger.in b/src/third_party/wiredtiger/src/include/wiredtiger.in
index 40d7f5ea6a5..d59138e1bb0 100644
--- a/src/third_party/wiredtiger/src/include/wiredtiger.in
+++ b/src/third_party/wiredtiger/src/include/wiredtiger.in
@@ -1002,6 +1002,8 @@ struct __wt_session {
* object blocks from the system buffer cache after that many bytes from this object are
* read or written into the buffer cache., an integer greater than or equal to 0; default \c
* 0.}
+ * @config{readonly, the file is read-only. All methods that may modify a file are
+ * disabled. See @ref readonly for more information., a boolean flag; default \c false.}
* @config{verbose, enable messages for various events. Options are given as a list\, such
* as <code>"verbose=[write_timestamp]"</code>., a list\, with values chosen from the
* following options: \c "write_timestamp"; default \c [].}
@@ -1050,10 +1052,12 @@ struct __wt_session {
* an integer between 512B and 128MB; default \c 4KB.}
* @config{app_metadata, application-owned metadata for this object., a string; default
* empty.}
- * @config{block_allocation, configure block allocation. Permitted values are \c "first" or
- * \c "best"; the \c "first" configuration uses a first-available algorithm during block
- * allocation\, the \c "best" configuration uses a best-fit algorithm., a string\, chosen
- * from the following options: \c "first"\, \c "best"; default \c best.}
+ * @config{block_allocation, configure block allocation. Permitted values are \c "best" or
+ * \c "first"; the \c "best" configuration uses a best-fit algorithm\, the \c "first"
+ * configuration uses a first-available algorithm during block allocation\, the \c
+ * "log-structure" configuration allocates a new file for each checkpoint., a string\,
+ * chosen from the following options: \c "best"\, \c "first"\, \c "log-structured"; default
+ * \c best.}
* @config{block_compressor, configure a compressor for file blocks. Permitted values are
* \c "none" or custom compression engine name created with WT_CONNECTION::add_compressor.
* If WiredTiger has builtin support for \c "lz4"\, \c "snappy"\, \c "zlib" or \c "zstd"
@@ -1104,6 +1108,8 @@ struct __wt_session {
* \c none.}
* @config{format, the file format., a string\, chosen from the following options: \c
* "btree"; default \c btree.}
+ * @config{huffman_key, This option is no longer supported. Retained for backward
+ * compatibility. See @ref huffman for more information., a string; default \c none.}
* @config{huffman_value, configure Huffman encoding for values. Permitted values are \c
* "none"\, \c "english"\, \c "utf8<file>" or \c "utf16<file>". See @ref huffman for more
* information., a string; default \c none.}
@@ -1230,10 +1236,21 @@ struct __wt_session {
* boolean flag; default \c false.}
* @config{prefix_compression_min, minimum gain before prefix compression will be used on
* row-store leaf pages., an integer greater than or equal to 0; default \c 4.}
+ * @config{readonly, the file is read-only. All methods that may modify a file are
+ * disabled. See @ref readonly for more information., a boolean flag; default \c false.}
* @config{split_pct, the Btree page split size as a percentage of the maximum Btree page
* size\, that is\, when a Btree page is split\, it will be split into smaller pages\, where
* each page is the specified percentage of the maximum Btree page size., an integer between
* 50 and 100; default \c 90.}
+ * @config{tiered = (, options only relevant for tiered data sources., a set of related
+ * configuration options defined below.}
+ * @config{&nbsp;&nbsp;&nbsp;&nbsp;chunk_size, the
+ * maximum size of the hot chunk of tiered tree. This limit is soft - it is possible for
+ * chunks to be temporarily larger than this value., an integer greater than or equal to 1M;
+ * default \c 1GB.}
+ * @config{&nbsp;&nbsp;&nbsp;&nbsp;tiers, list of data sources to combine
+ * into a tiered storage structure., a list of strings; default empty.}
+ * @config{ ),,}
* @config{type, set the type of data source used to store a column group\, index or simple
* table. By default\, a \c "file:" URI is derived from the object name. The \c type
* configuration can be used to switch to a different data source\, such as LSM or an
@@ -4930,930 +4947,940 @@ extern int wiredtiger_extension_terminate(WT_CONNECTION *connection);
#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED_URGENT 1085
/*! cache: pages queued for urgent eviction during walk */
#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED_OLDEST 1086
+/*!
+ * cache: pages queued for urgent eviction from history store due to high
+ * dirty content
+ */
+#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED_URGENT_HS_DIRTY 1087
/*! cache: pages seen by eviction walk that are already queued */
-#define WT_STAT_CONN_CACHE_EVICTION_PAGES_ALREADY_QUEUED 1087
+#define WT_STAT_CONN_CACHE_EVICTION_PAGES_ALREADY_QUEUED 1088
/*! cache: pages selected for eviction unable to be evicted */
-#define WT_STAT_CONN_CACHE_EVICTION_FAIL 1088
+#define WT_STAT_CONN_CACHE_EVICTION_FAIL 1089
/*!
* cache: pages selected for eviction unable to be evicted as the parent
* page has overflow items
*/
-#define WT_STAT_CONN_CACHE_EVICTION_FAIL_PARENT_HAS_OVERFLOW_ITEMS 1089
+#define WT_STAT_CONN_CACHE_EVICTION_FAIL_PARENT_HAS_OVERFLOW_ITEMS 1090
/*!
* cache: pages selected for eviction unable to be evicted because of
* active children on an internal page
*/
-#define WT_STAT_CONN_CACHE_EVICTION_FAIL_ACTIVE_CHILDREN_ON_AN_INTERNAL_PAGE 1090
+#define WT_STAT_CONN_CACHE_EVICTION_FAIL_ACTIVE_CHILDREN_ON_AN_INTERNAL_PAGE 1091
/*!
* cache: pages selected for eviction unable to be evicted because of
* failure in reconciliation
*/
-#define WT_STAT_CONN_CACHE_EVICTION_FAIL_IN_RECONCILIATION 1091
+#define WT_STAT_CONN_CACHE_EVICTION_FAIL_IN_RECONCILIATION 1092
/*! cache: pages walked for eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_WALK 1092
+#define WT_STAT_CONN_CACHE_EVICTION_WALK 1093
/*! cache: percentage overhead */
-#define WT_STAT_CONN_CACHE_OVERHEAD 1093
+#define WT_STAT_CONN_CACHE_OVERHEAD 1094
/*! cache: tracked bytes belonging to internal pages in the cache */
-#define WT_STAT_CONN_CACHE_BYTES_INTERNAL 1094
+#define WT_STAT_CONN_CACHE_BYTES_INTERNAL 1095
/*! cache: tracked bytes belonging to leaf pages in the cache */
-#define WT_STAT_CONN_CACHE_BYTES_LEAF 1095
+#define WT_STAT_CONN_CACHE_BYTES_LEAF 1096
/*! cache: tracked dirty pages in the cache */
-#define WT_STAT_CONN_CACHE_PAGES_DIRTY 1096
+#define WT_STAT_CONN_CACHE_PAGES_DIRTY 1097
/*! capacity: background fsync file handles considered */
-#define WT_STAT_CONN_FSYNC_ALL_FH_TOTAL 1097
+#define WT_STAT_CONN_FSYNC_ALL_FH_TOTAL 1098
/*! capacity: background fsync file handles synced */
-#define WT_STAT_CONN_FSYNC_ALL_FH 1098
+#define WT_STAT_CONN_FSYNC_ALL_FH 1099
/*! capacity: background fsync time (msecs) */
-#define WT_STAT_CONN_FSYNC_ALL_TIME 1099
+#define WT_STAT_CONN_FSYNC_ALL_TIME 1100
/*! capacity: bytes read */
-#define WT_STAT_CONN_CAPACITY_BYTES_READ 1100
+#define WT_STAT_CONN_CAPACITY_BYTES_READ 1101
/*! capacity: bytes written for checkpoint */
-#define WT_STAT_CONN_CAPACITY_BYTES_CKPT 1101
+#define WT_STAT_CONN_CAPACITY_BYTES_CKPT 1102
/*! capacity: bytes written for eviction */
-#define WT_STAT_CONN_CAPACITY_BYTES_EVICT 1102
+#define WT_STAT_CONN_CAPACITY_BYTES_EVICT 1103
/*! capacity: bytes written for log */
-#define WT_STAT_CONN_CAPACITY_BYTES_LOG 1103
+#define WT_STAT_CONN_CAPACITY_BYTES_LOG 1104
/*! capacity: bytes written total */
-#define WT_STAT_CONN_CAPACITY_BYTES_WRITTEN 1104
+#define WT_STAT_CONN_CAPACITY_BYTES_WRITTEN 1105
/*! capacity: threshold to call fsync */
-#define WT_STAT_CONN_CAPACITY_THRESHOLD 1105
+#define WT_STAT_CONN_CAPACITY_THRESHOLD 1106
/*! capacity: time waiting due to total capacity (usecs) */
-#define WT_STAT_CONN_CAPACITY_TIME_TOTAL 1106
+#define WT_STAT_CONN_CAPACITY_TIME_TOTAL 1107
/*! capacity: time waiting during checkpoint (usecs) */
-#define WT_STAT_CONN_CAPACITY_TIME_CKPT 1107
+#define WT_STAT_CONN_CAPACITY_TIME_CKPT 1108
/*! capacity: time waiting during eviction (usecs) */
-#define WT_STAT_CONN_CAPACITY_TIME_EVICT 1108
+#define WT_STAT_CONN_CAPACITY_TIME_EVICT 1109
/*! capacity: time waiting during logging (usecs) */
-#define WT_STAT_CONN_CAPACITY_TIME_LOG 1109
+#define WT_STAT_CONN_CAPACITY_TIME_LOG 1110
/*! capacity: time waiting during read (usecs) */
-#define WT_STAT_CONN_CAPACITY_TIME_READ 1110
+#define WT_STAT_CONN_CAPACITY_TIME_READ 1111
/*! connection: auto adjusting condition resets */
-#define WT_STAT_CONN_COND_AUTO_WAIT_RESET 1111
+#define WT_STAT_CONN_COND_AUTO_WAIT_RESET 1112
/*! connection: auto adjusting condition wait calls */
-#define WT_STAT_CONN_COND_AUTO_WAIT 1112
+#define WT_STAT_CONN_COND_AUTO_WAIT 1113
/*!
* connection: auto adjusting condition wait raced to update timeout and
* skipped updating
*/
-#define WT_STAT_CONN_COND_AUTO_WAIT_SKIPPED 1113
+#define WT_STAT_CONN_COND_AUTO_WAIT_SKIPPED 1114
/*! connection: detected system time went backwards */
-#define WT_STAT_CONN_TIME_TRAVEL 1114
+#define WT_STAT_CONN_TIME_TRAVEL 1115
/*! connection: files currently open */
-#define WT_STAT_CONN_FILE_OPEN 1115
+#define WT_STAT_CONN_FILE_OPEN 1116
/*! connection: hash bucket array size for data handles */
-#define WT_STAT_CONN_BUCKETS_DH 1116
+#define WT_STAT_CONN_BUCKETS_DH 1117
/*! connection: hash bucket array size general */
-#define WT_STAT_CONN_BUCKETS 1117
+#define WT_STAT_CONN_BUCKETS 1118
/*! connection: memory allocations */
-#define WT_STAT_CONN_MEMORY_ALLOCATION 1118
+#define WT_STAT_CONN_MEMORY_ALLOCATION 1119
/*! connection: memory frees */
-#define WT_STAT_CONN_MEMORY_FREE 1119
+#define WT_STAT_CONN_MEMORY_FREE 1120
/*! connection: memory re-allocations */
-#define WT_STAT_CONN_MEMORY_GROW 1120
+#define WT_STAT_CONN_MEMORY_GROW 1121
/*! connection: pthread mutex condition wait calls */
-#define WT_STAT_CONN_COND_WAIT 1121
+#define WT_STAT_CONN_COND_WAIT 1122
/*! connection: pthread mutex shared lock read-lock calls */
-#define WT_STAT_CONN_RWLOCK_READ 1122
+#define WT_STAT_CONN_RWLOCK_READ 1123
/*! connection: pthread mutex shared lock write-lock calls */
-#define WT_STAT_CONN_RWLOCK_WRITE 1123
+#define WT_STAT_CONN_RWLOCK_WRITE 1124
/*! connection: total fsync I/Os */
-#define WT_STAT_CONN_FSYNC_IO 1124
+#define WT_STAT_CONN_FSYNC_IO 1125
/*! connection: total read I/Os */
-#define WT_STAT_CONN_READ_IO 1125
+#define WT_STAT_CONN_READ_IO 1126
/*! connection: total write I/Os */
-#define WT_STAT_CONN_WRITE_IO 1126
+#define WT_STAT_CONN_WRITE_IO 1127
/*! cursor: cached cursor count */
-#define WT_STAT_CONN_CURSOR_CACHED_COUNT 1127
+#define WT_STAT_CONN_CURSOR_CACHED_COUNT 1128
/*! cursor: cursor bulk loaded cursor insert calls */
-#define WT_STAT_CONN_CURSOR_INSERT_BULK 1128
+#define WT_STAT_CONN_CURSOR_INSERT_BULK 1129
/*! cursor: cursor close calls that result in cache */
-#define WT_STAT_CONN_CURSOR_CACHE 1129
+#define WT_STAT_CONN_CURSOR_CACHE 1130
/*! cursor: cursor create calls */
-#define WT_STAT_CONN_CURSOR_CREATE 1130
+#define WT_STAT_CONN_CURSOR_CREATE 1131
/*! cursor: cursor insert calls */
-#define WT_STAT_CONN_CURSOR_INSERT 1131
+#define WT_STAT_CONN_CURSOR_INSERT 1132
/*! cursor: cursor insert key and value bytes */
-#define WT_STAT_CONN_CURSOR_INSERT_BYTES 1132
+#define WT_STAT_CONN_CURSOR_INSERT_BYTES 1133
/*! cursor: cursor modify calls */
-#define WT_STAT_CONN_CURSOR_MODIFY 1133
+#define WT_STAT_CONN_CURSOR_MODIFY 1134
/*! cursor: cursor modify key and value bytes affected */
-#define WT_STAT_CONN_CURSOR_MODIFY_BYTES 1134
+#define WT_STAT_CONN_CURSOR_MODIFY_BYTES 1135
/*! cursor: cursor modify value bytes modified */
-#define WT_STAT_CONN_CURSOR_MODIFY_BYTES_TOUCH 1135
+#define WT_STAT_CONN_CURSOR_MODIFY_BYTES_TOUCH 1136
/*! cursor: cursor next calls */
-#define WT_STAT_CONN_CURSOR_NEXT 1136
+#define WT_STAT_CONN_CURSOR_NEXT 1137
/*!
* cursor: cursor next calls that skip due to a globally visible history
* store tombstone in rollback to stable
*/
-#define WT_STAT_CONN_CURSOR_NEXT_HS_TOMBSTONE_RTS 1137
+#define WT_STAT_CONN_CURSOR_NEXT_HS_TOMBSTONE_RTS 1138
/*! cursor: cursor operation restarted */
-#define WT_STAT_CONN_CURSOR_RESTART 1138
+#define WT_STAT_CONN_CURSOR_RESTART 1139
/*! cursor: cursor prev calls */
-#define WT_STAT_CONN_CURSOR_PREV 1139
+#define WT_STAT_CONN_CURSOR_PREV 1140
/*!
* cursor: cursor prev calls that skip due to a globally visible history
* store tombstone in rollback to stable
*/
-#define WT_STAT_CONN_CURSOR_PREV_HS_TOMBSTONE_RTS 1140
+#define WT_STAT_CONN_CURSOR_PREV_HS_TOMBSTONE_RTS 1141
/*! cursor: cursor remove calls */
-#define WT_STAT_CONN_CURSOR_REMOVE 1141
+#define WT_STAT_CONN_CURSOR_REMOVE 1142
/*! cursor: cursor remove key bytes removed */
-#define WT_STAT_CONN_CURSOR_REMOVE_BYTES 1142
+#define WT_STAT_CONN_CURSOR_REMOVE_BYTES 1143
/*! cursor: cursor reserve calls */
-#define WT_STAT_CONN_CURSOR_RESERVE 1143
+#define WT_STAT_CONN_CURSOR_RESERVE 1144
/*! cursor: cursor reset calls */
-#define WT_STAT_CONN_CURSOR_RESET 1144
+#define WT_STAT_CONN_CURSOR_RESET 1145
/*! cursor: cursor search calls */
-#define WT_STAT_CONN_CURSOR_SEARCH 1145
+#define WT_STAT_CONN_CURSOR_SEARCH 1146
/*! cursor: cursor search history store calls */
-#define WT_STAT_CONN_CURSOR_SEARCH_HS 1146
+#define WT_STAT_CONN_CURSOR_SEARCH_HS 1147
/*! cursor: cursor search near calls */
-#define WT_STAT_CONN_CURSOR_SEARCH_NEAR 1147
+#define WT_STAT_CONN_CURSOR_SEARCH_NEAR 1148
/*! cursor: cursor sweep buckets */
-#define WT_STAT_CONN_CURSOR_SWEEP_BUCKETS 1148
+#define WT_STAT_CONN_CURSOR_SWEEP_BUCKETS 1149
/*! cursor: cursor sweep cursors closed */
-#define WT_STAT_CONN_CURSOR_SWEEP_CLOSED 1149
+#define WT_STAT_CONN_CURSOR_SWEEP_CLOSED 1150
/*! cursor: cursor sweep cursors examined */
-#define WT_STAT_CONN_CURSOR_SWEEP_EXAMINED 1150
+#define WT_STAT_CONN_CURSOR_SWEEP_EXAMINED 1151
/*! cursor: cursor sweeps */
-#define WT_STAT_CONN_CURSOR_SWEEP 1151
+#define WT_STAT_CONN_CURSOR_SWEEP 1152
/*! cursor: cursor truncate calls */
-#define WT_STAT_CONN_CURSOR_TRUNCATE 1152
+#define WT_STAT_CONN_CURSOR_TRUNCATE 1153
/*! cursor: cursor update calls */
-#define WT_STAT_CONN_CURSOR_UPDATE 1153
+#define WT_STAT_CONN_CURSOR_UPDATE 1154
/*! cursor: cursor update key and value bytes */
-#define WT_STAT_CONN_CURSOR_UPDATE_BYTES 1154
+#define WT_STAT_CONN_CURSOR_UPDATE_BYTES 1155
/*! cursor: cursor update value size change */
-#define WT_STAT_CONN_CURSOR_UPDATE_BYTES_CHANGED 1155
+#define WT_STAT_CONN_CURSOR_UPDATE_BYTES_CHANGED 1156
/*! cursor: cursors reused from cache */
-#define WT_STAT_CONN_CURSOR_REOPEN 1156
+#define WT_STAT_CONN_CURSOR_REOPEN 1157
/*! data-handle: connection data handle size */
-#define WT_STAT_CONN_DH_CONN_HANDLE_SIZE 1157
+#define WT_STAT_CONN_DH_CONN_HANDLE_SIZE 1158
/*! data-handle: connection data handles currently active */
-#define WT_STAT_CONN_DH_CONN_HANDLE_COUNT 1158
+#define WT_STAT_CONN_DH_CONN_HANDLE_COUNT 1159
/*! data-handle: connection sweep candidate became referenced */
-#define WT_STAT_CONN_DH_SWEEP_REF 1159
+#define WT_STAT_CONN_DH_SWEEP_REF 1160
/*! data-handle: connection sweep dhandles closed */
-#define WT_STAT_CONN_DH_SWEEP_CLOSE 1160
+#define WT_STAT_CONN_DH_SWEEP_CLOSE 1161
/*! data-handle: connection sweep dhandles removed from hash list */
-#define WT_STAT_CONN_DH_SWEEP_REMOVE 1161
+#define WT_STAT_CONN_DH_SWEEP_REMOVE 1162
/*! data-handle: connection sweep time-of-death sets */
-#define WT_STAT_CONN_DH_SWEEP_TOD 1162
+#define WT_STAT_CONN_DH_SWEEP_TOD 1163
/*! data-handle: connection sweeps */
-#define WT_STAT_CONN_DH_SWEEPS 1163
+#define WT_STAT_CONN_DH_SWEEPS 1164
/*! data-handle: session dhandles swept */
-#define WT_STAT_CONN_DH_SESSION_HANDLES 1164
+#define WT_STAT_CONN_DH_SESSION_HANDLES 1165
/*! data-handle: session sweep attempts */
-#define WT_STAT_CONN_DH_SESSION_SWEEPS 1165
+#define WT_STAT_CONN_DH_SESSION_SWEEPS 1166
/*! lock: checkpoint lock acquisitions */
-#define WT_STAT_CONN_LOCK_CHECKPOINT_COUNT 1166
+#define WT_STAT_CONN_LOCK_CHECKPOINT_COUNT 1167
/*! lock: checkpoint lock application thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_CHECKPOINT_WAIT_APPLICATION 1167
+#define WT_STAT_CONN_LOCK_CHECKPOINT_WAIT_APPLICATION 1168
/*! lock: checkpoint lock internal thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_CHECKPOINT_WAIT_INTERNAL 1168
+#define WT_STAT_CONN_LOCK_CHECKPOINT_WAIT_INTERNAL 1169
/*! lock: dhandle lock application thread time waiting (usecs) */
-#define WT_STAT_CONN_LOCK_DHANDLE_WAIT_APPLICATION 1169
+#define WT_STAT_CONN_LOCK_DHANDLE_WAIT_APPLICATION 1170
/*! lock: dhandle lock internal thread time waiting (usecs) */
-#define WT_STAT_CONN_LOCK_DHANDLE_WAIT_INTERNAL 1170
+#define WT_STAT_CONN_LOCK_DHANDLE_WAIT_INTERNAL 1171
/*! lock: dhandle read lock acquisitions */
-#define WT_STAT_CONN_LOCK_DHANDLE_READ_COUNT 1171
+#define WT_STAT_CONN_LOCK_DHANDLE_READ_COUNT 1172
/*! lock: dhandle write lock acquisitions */
-#define WT_STAT_CONN_LOCK_DHANDLE_WRITE_COUNT 1172
+#define WT_STAT_CONN_LOCK_DHANDLE_WRITE_COUNT 1173
/*!
* lock: durable timestamp queue lock application thread time waiting
* (usecs)
*/
-#define WT_STAT_CONN_LOCK_DURABLE_TIMESTAMP_WAIT_APPLICATION 1173
+#define WT_STAT_CONN_LOCK_DURABLE_TIMESTAMP_WAIT_APPLICATION 1174
/*!
* lock: durable timestamp queue lock internal thread time waiting
* (usecs)
*/
-#define WT_STAT_CONN_LOCK_DURABLE_TIMESTAMP_WAIT_INTERNAL 1174
+#define WT_STAT_CONN_LOCK_DURABLE_TIMESTAMP_WAIT_INTERNAL 1175
/*! lock: durable timestamp queue read lock acquisitions */
-#define WT_STAT_CONN_LOCK_DURABLE_TIMESTAMP_READ_COUNT 1175
+#define WT_STAT_CONN_LOCK_DURABLE_TIMESTAMP_READ_COUNT 1176
/*! lock: durable timestamp queue write lock acquisitions */
-#define WT_STAT_CONN_LOCK_DURABLE_TIMESTAMP_WRITE_COUNT 1176
+#define WT_STAT_CONN_LOCK_DURABLE_TIMESTAMP_WRITE_COUNT 1177
/*! lock: metadata lock acquisitions */
-#define WT_STAT_CONN_LOCK_METADATA_COUNT 1177
+#define WT_STAT_CONN_LOCK_METADATA_COUNT 1178
/*! lock: metadata lock application thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_METADATA_WAIT_APPLICATION 1178
+#define WT_STAT_CONN_LOCK_METADATA_WAIT_APPLICATION 1179
/*! lock: metadata lock internal thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_METADATA_WAIT_INTERNAL 1179
+#define WT_STAT_CONN_LOCK_METADATA_WAIT_INTERNAL 1180
/*!
* lock: read timestamp queue lock application thread time waiting
* (usecs)
*/
-#define WT_STAT_CONN_LOCK_READ_TIMESTAMP_WAIT_APPLICATION 1180
+#define WT_STAT_CONN_LOCK_READ_TIMESTAMP_WAIT_APPLICATION 1181
/*! lock: read timestamp queue lock internal thread time waiting (usecs) */
-#define WT_STAT_CONN_LOCK_READ_TIMESTAMP_WAIT_INTERNAL 1181
+#define WT_STAT_CONN_LOCK_READ_TIMESTAMP_WAIT_INTERNAL 1182
/*! lock: read timestamp queue read lock acquisitions */
-#define WT_STAT_CONN_LOCK_READ_TIMESTAMP_READ_COUNT 1182
+#define WT_STAT_CONN_LOCK_READ_TIMESTAMP_READ_COUNT 1183
/*! lock: read timestamp queue write lock acquisitions */
-#define WT_STAT_CONN_LOCK_READ_TIMESTAMP_WRITE_COUNT 1183
+#define WT_STAT_CONN_LOCK_READ_TIMESTAMP_WRITE_COUNT 1184
/*! lock: schema lock acquisitions */
-#define WT_STAT_CONN_LOCK_SCHEMA_COUNT 1184
+#define WT_STAT_CONN_LOCK_SCHEMA_COUNT 1185
/*! lock: schema lock application thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_SCHEMA_WAIT_APPLICATION 1185
+#define WT_STAT_CONN_LOCK_SCHEMA_WAIT_APPLICATION 1186
/*! lock: schema lock internal thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_SCHEMA_WAIT_INTERNAL 1186
+#define WT_STAT_CONN_LOCK_SCHEMA_WAIT_INTERNAL 1187
/*!
* lock: table lock application thread time waiting for the table lock
* (usecs)
*/
-#define WT_STAT_CONN_LOCK_TABLE_WAIT_APPLICATION 1187
+#define WT_STAT_CONN_LOCK_TABLE_WAIT_APPLICATION 1188
/*!
* lock: table lock internal thread time waiting for the table lock
* (usecs)
*/
-#define WT_STAT_CONN_LOCK_TABLE_WAIT_INTERNAL 1188
+#define WT_STAT_CONN_LOCK_TABLE_WAIT_INTERNAL 1189
/*! lock: table read lock acquisitions */
-#define WT_STAT_CONN_LOCK_TABLE_READ_COUNT 1189
+#define WT_STAT_CONN_LOCK_TABLE_READ_COUNT 1190
/*! lock: table write lock acquisitions */
-#define WT_STAT_CONN_LOCK_TABLE_WRITE_COUNT 1190
+#define WT_STAT_CONN_LOCK_TABLE_WRITE_COUNT 1191
/*! lock: txn global lock application thread time waiting (usecs) */
-#define WT_STAT_CONN_LOCK_TXN_GLOBAL_WAIT_APPLICATION 1191
+#define WT_STAT_CONN_LOCK_TXN_GLOBAL_WAIT_APPLICATION 1192
/*! lock: txn global lock internal thread time waiting (usecs) */
-#define WT_STAT_CONN_LOCK_TXN_GLOBAL_WAIT_INTERNAL 1192
+#define WT_STAT_CONN_LOCK_TXN_GLOBAL_WAIT_INTERNAL 1193
/*! lock: txn global read lock acquisitions */
-#define WT_STAT_CONN_LOCK_TXN_GLOBAL_READ_COUNT 1193
+#define WT_STAT_CONN_LOCK_TXN_GLOBAL_READ_COUNT 1194
/*! lock: txn global write lock acquisitions */
-#define WT_STAT_CONN_LOCK_TXN_GLOBAL_WRITE_COUNT 1194
+#define WT_STAT_CONN_LOCK_TXN_GLOBAL_WRITE_COUNT 1195
/*! log: busy returns attempting to switch slots */
-#define WT_STAT_CONN_LOG_SLOT_SWITCH_BUSY 1195
+#define WT_STAT_CONN_LOG_SLOT_SWITCH_BUSY 1196
/*! log: force archive time sleeping (usecs) */
-#define WT_STAT_CONN_LOG_FORCE_ARCHIVE_SLEEP 1196
+#define WT_STAT_CONN_LOG_FORCE_ARCHIVE_SLEEP 1197
/*! log: log bytes of payload data */
-#define WT_STAT_CONN_LOG_BYTES_PAYLOAD 1197
+#define WT_STAT_CONN_LOG_BYTES_PAYLOAD 1198
/*! log: log bytes written */
-#define WT_STAT_CONN_LOG_BYTES_WRITTEN 1198
+#define WT_STAT_CONN_LOG_BYTES_WRITTEN 1199
/*! log: log files manually zero-filled */
-#define WT_STAT_CONN_LOG_ZERO_FILLS 1199
+#define WT_STAT_CONN_LOG_ZERO_FILLS 1200
/*! log: log flush operations */
-#define WT_STAT_CONN_LOG_FLUSH 1200
+#define WT_STAT_CONN_LOG_FLUSH 1201
/*! log: log force write operations */
-#define WT_STAT_CONN_LOG_FORCE_WRITE 1201
+#define WT_STAT_CONN_LOG_FORCE_WRITE 1202
/*! log: log force write operations skipped */
-#define WT_STAT_CONN_LOG_FORCE_WRITE_SKIP 1202
+#define WT_STAT_CONN_LOG_FORCE_WRITE_SKIP 1203
/*! log: log records compressed */
-#define WT_STAT_CONN_LOG_COMPRESS_WRITES 1203
+#define WT_STAT_CONN_LOG_COMPRESS_WRITES 1204
/*! log: log records not compressed */
-#define WT_STAT_CONN_LOG_COMPRESS_WRITE_FAILS 1204
+#define WT_STAT_CONN_LOG_COMPRESS_WRITE_FAILS 1205
/*! log: log records too small to compress */
-#define WT_STAT_CONN_LOG_COMPRESS_SMALL 1205
+#define WT_STAT_CONN_LOG_COMPRESS_SMALL 1206
/*! log: log release advances write LSN */
-#define WT_STAT_CONN_LOG_RELEASE_WRITE_LSN 1206
+#define WT_STAT_CONN_LOG_RELEASE_WRITE_LSN 1207
/*! log: log scan operations */
-#define WT_STAT_CONN_LOG_SCANS 1207
+#define WT_STAT_CONN_LOG_SCANS 1208
/*! log: log scan records requiring two reads */
-#define WT_STAT_CONN_LOG_SCAN_REREADS 1208
+#define WT_STAT_CONN_LOG_SCAN_REREADS 1209
/*! log: log server thread advances write LSN */
-#define WT_STAT_CONN_LOG_WRITE_LSN 1209
+#define WT_STAT_CONN_LOG_WRITE_LSN 1210
/*! log: log server thread write LSN walk skipped */
-#define WT_STAT_CONN_LOG_WRITE_LSN_SKIP 1210
+#define WT_STAT_CONN_LOG_WRITE_LSN_SKIP 1211
/*! log: log sync operations */
-#define WT_STAT_CONN_LOG_SYNC 1211
+#define WT_STAT_CONN_LOG_SYNC 1212
/*! log: log sync time duration (usecs) */
-#define WT_STAT_CONN_LOG_SYNC_DURATION 1212
+#define WT_STAT_CONN_LOG_SYNC_DURATION 1213
/*! log: log sync_dir operations */
-#define WT_STAT_CONN_LOG_SYNC_DIR 1213
+#define WT_STAT_CONN_LOG_SYNC_DIR 1214
/*! log: log sync_dir time duration (usecs) */
-#define WT_STAT_CONN_LOG_SYNC_DIR_DURATION 1214
+#define WT_STAT_CONN_LOG_SYNC_DIR_DURATION 1215
/*! log: log write operations */
-#define WT_STAT_CONN_LOG_WRITES 1215
+#define WT_STAT_CONN_LOG_WRITES 1216
/*! log: logging bytes consolidated */
-#define WT_STAT_CONN_LOG_SLOT_CONSOLIDATED 1216
+#define WT_STAT_CONN_LOG_SLOT_CONSOLIDATED 1217
/*! log: maximum log file size */
-#define WT_STAT_CONN_LOG_MAX_FILESIZE 1217
+#define WT_STAT_CONN_LOG_MAX_FILESIZE 1218
/*! log: number of pre-allocated log files to create */
-#define WT_STAT_CONN_LOG_PREALLOC_MAX 1218
+#define WT_STAT_CONN_LOG_PREALLOC_MAX 1219
/*! log: pre-allocated log files not ready and missed */
-#define WT_STAT_CONN_LOG_PREALLOC_MISSED 1219
+#define WT_STAT_CONN_LOG_PREALLOC_MISSED 1220
/*! log: pre-allocated log files prepared */
-#define WT_STAT_CONN_LOG_PREALLOC_FILES 1220
+#define WT_STAT_CONN_LOG_PREALLOC_FILES 1221
/*! log: pre-allocated log files used */
-#define WT_STAT_CONN_LOG_PREALLOC_USED 1221
+#define WT_STAT_CONN_LOG_PREALLOC_USED 1222
/*! log: records processed by log scan */
-#define WT_STAT_CONN_LOG_SCAN_RECORDS 1222
+#define WT_STAT_CONN_LOG_SCAN_RECORDS 1223
/*! log: slot close lost race */
-#define WT_STAT_CONN_LOG_SLOT_CLOSE_RACE 1223
+#define WT_STAT_CONN_LOG_SLOT_CLOSE_RACE 1224
/*! log: slot close unbuffered waits */
-#define WT_STAT_CONN_LOG_SLOT_CLOSE_UNBUF 1224
+#define WT_STAT_CONN_LOG_SLOT_CLOSE_UNBUF 1225
/*! log: slot closures */
-#define WT_STAT_CONN_LOG_SLOT_CLOSES 1225
+#define WT_STAT_CONN_LOG_SLOT_CLOSES 1226
/*! log: slot join atomic update races */
-#define WT_STAT_CONN_LOG_SLOT_RACES 1226
+#define WT_STAT_CONN_LOG_SLOT_RACES 1227
/*! log: slot join calls atomic updates raced */
-#define WT_STAT_CONN_LOG_SLOT_YIELD_RACE 1227
+#define WT_STAT_CONN_LOG_SLOT_YIELD_RACE 1228
/*! log: slot join calls did not yield */
-#define WT_STAT_CONN_LOG_SLOT_IMMEDIATE 1228
+#define WT_STAT_CONN_LOG_SLOT_IMMEDIATE 1229
/*! log: slot join calls found active slot closed */
-#define WT_STAT_CONN_LOG_SLOT_YIELD_CLOSE 1229
+#define WT_STAT_CONN_LOG_SLOT_YIELD_CLOSE 1230
/*! log: slot join calls slept */
-#define WT_STAT_CONN_LOG_SLOT_YIELD_SLEEP 1230
+#define WT_STAT_CONN_LOG_SLOT_YIELD_SLEEP 1231
/*! log: slot join calls yielded */
-#define WT_STAT_CONN_LOG_SLOT_YIELD 1231
+#define WT_STAT_CONN_LOG_SLOT_YIELD 1232
/*! log: slot join found active slot closed */
-#define WT_STAT_CONN_LOG_SLOT_ACTIVE_CLOSED 1232
+#define WT_STAT_CONN_LOG_SLOT_ACTIVE_CLOSED 1233
/*! log: slot joins yield time (usecs) */
-#define WT_STAT_CONN_LOG_SLOT_YIELD_DURATION 1233
+#define WT_STAT_CONN_LOG_SLOT_YIELD_DURATION 1234
/*! log: slot transitions unable to find free slot */
-#define WT_STAT_CONN_LOG_SLOT_NO_FREE_SLOTS 1234
+#define WT_STAT_CONN_LOG_SLOT_NO_FREE_SLOTS 1235
/*! log: slot unbuffered writes */
-#define WT_STAT_CONN_LOG_SLOT_UNBUFFERED 1235
+#define WT_STAT_CONN_LOG_SLOT_UNBUFFERED 1236
/*! log: total in-memory size of compressed records */
-#define WT_STAT_CONN_LOG_COMPRESS_MEM 1236
+#define WT_STAT_CONN_LOG_COMPRESS_MEM 1237
/*! log: total log buffer size */
-#define WT_STAT_CONN_LOG_BUFFER_SIZE 1237
+#define WT_STAT_CONN_LOG_BUFFER_SIZE 1238
/*! log: total size of compressed records */
-#define WT_STAT_CONN_LOG_COMPRESS_LEN 1238
+#define WT_STAT_CONN_LOG_COMPRESS_LEN 1239
/*! log: written slots coalesced */
-#define WT_STAT_CONN_LOG_SLOT_COALESCED 1239
+#define WT_STAT_CONN_LOG_SLOT_COALESCED 1240
/*! log: yields waiting for previous log file close */
-#define WT_STAT_CONN_LOG_CLOSE_YIELDS 1240
+#define WT_STAT_CONN_LOG_CLOSE_YIELDS 1241
/*! perf: file system read latency histogram (bucket 1) - 10-49ms */
-#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT50 1241
+#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT50 1242
/*! perf: file system read latency histogram (bucket 2) - 50-99ms */
-#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT100 1242
+#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT100 1243
/*! perf: file system read latency histogram (bucket 3) - 100-249ms */
-#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT250 1243
+#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT250 1244
/*! perf: file system read latency histogram (bucket 4) - 250-499ms */
-#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT500 1244
+#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT500 1245
/*! perf: file system read latency histogram (bucket 5) - 500-999ms */
-#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT1000 1245
+#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT1000 1246
/*! perf: file system read latency histogram (bucket 6) - 1000ms+ */
-#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_GT1000 1246
+#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_GT1000 1247
/*! perf: file system write latency histogram (bucket 1) - 10-49ms */
-#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT50 1247
+#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT50 1248
/*! perf: file system write latency histogram (bucket 2) - 50-99ms */
-#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT100 1248
+#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT100 1249
/*! perf: file system write latency histogram (bucket 3) - 100-249ms */
-#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT250 1249
+#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT250 1250
/*! perf: file system write latency histogram (bucket 4) - 250-499ms */
-#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT500 1250
+#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT500 1251
/*! perf: file system write latency histogram (bucket 5) - 500-999ms */
-#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT1000 1251
+#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT1000 1252
/*! perf: file system write latency histogram (bucket 6) - 1000ms+ */
-#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_GT1000 1252
+#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_GT1000 1253
/*! perf: operation read latency histogram (bucket 1) - 100-249us */
-#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT250 1253
+#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT250 1254
/*! perf: operation read latency histogram (bucket 2) - 250-499us */
-#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT500 1254
+#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT500 1255
/*! perf: operation read latency histogram (bucket 3) - 500-999us */
-#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT1000 1255
+#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT1000 1256
/*! perf: operation read latency histogram (bucket 4) - 1000-9999us */
-#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT10000 1256
+#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT10000 1257
/*! perf: operation read latency histogram (bucket 5) - 10000us+ */
-#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_GT10000 1257
+#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_GT10000 1258
/*! perf: operation write latency histogram (bucket 1) - 100-249us */
-#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT250 1258
+#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT250 1259
/*! perf: operation write latency histogram (bucket 2) - 250-499us */
-#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT500 1259
+#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT500 1260
/*! perf: operation write latency histogram (bucket 3) - 500-999us */
-#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT1000 1260
+#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT1000 1261
/*! perf: operation write latency histogram (bucket 4) - 1000-9999us */
-#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT10000 1261
+#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT10000 1262
/*! perf: operation write latency histogram (bucket 5) - 10000us+ */
-#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_GT10000 1262
+#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_GT10000 1263
/*! reconciliation: maximum seconds spent in a reconciliation call */
-#define WT_STAT_CONN_REC_MAXIMUM_SECONDS 1263
+#define WT_STAT_CONN_REC_MAXIMUM_SECONDS 1264
/*!
* reconciliation: page reconciliation calls that resulted in values with
* prepared transaction metadata
*/
-#define WT_STAT_CONN_REC_PAGES_WITH_PREPARE 1264
+#define WT_STAT_CONN_REC_PAGES_WITH_PREPARE 1265
/*!
* reconciliation: page reconciliation calls that resulted in values with
* timestamps
*/
-#define WT_STAT_CONN_REC_PAGES_WITH_TS 1265
+#define WT_STAT_CONN_REC_PAGES_WITH_TS 1266
/*!
* reconciliation: page reconciliation calls that resulted in values with
* transaction ids
*/
-#define WT_STAT_CONN_REC_PAGES_WITH_TXN 1266
+#define WT_STAT_CONN_REC_PAGES_WITH_TXN 1267
/*! reconciliation: pages written including at least one prepare state */
-#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_PREPARED 1267
+#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_PREPARED 1268
/*! reconciliation: pages written including at least one start timestamp */
-#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_START_TS 1268
+#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_START_TS 1269
/*! reconciliation: records written including a prepare state */
-#define WT_STAT_CONN_REC_TIME_WINDOW_PREPARED 1269
+#define WT_STAT_CONN_REC_TIME_WINDOW_PREPARED 1270
/*! reconciliation: split bytes currently awaiting free */
-#define WT_STAT_CONN_REC_SPLIT_STASHED_BYTES 1270
+#define WT_STAT_CONN_REC_SPLIT_STASHED_BYTES 1271
/*! reconciliation: split objects currently awaiting free */
-#define WT_STAT_CONN_REC_SPLIT_STASHED_OBJECTS 1271
+#define WT_STAT_CONN_REC_SPLIT_STASHED_OBJECTS 1272
/*! session: open session count */
-#define WT_STAT_CONN_SESSION_OPEN 1272
+#define WT_STAT_CONN_SESSION_OPEN 1273
/*! session: session query timestamp calls */
-#define WT_STAT_CONN_SESSION_QUERY_TS 1273
+#define WT_STAT_CONN_SESSION_QUERY_TS 1274
/*! session: table alter failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_ALTER_FAIL 1274
+#define WT_STAT_CONN_SESSION_TABLE_ALTER_FAIL 1275
/*! session: table alter successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_ALTER_SUCCESS 1275
+#define WT_STAT_CONN_SESSION_TABLE_ALTER_SUCCESS 1276
/*! session: table alter unchanged and skipped */
-#define WT_STAT_CONN_SESSION_TABLE_ALTER_SKIP 1276
+#define WT_STAT_CONN_SESSION_TABLE_ALTER_SKIP 1277
/*! session: table compact failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_COMPACT_FAIL 1277
+#define WT_STAT_CONN_SESSION_TABLE_COMPACT_FAIL 1278
/*! session: table compact successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_COMPACT_SUCCESS 1278
+#define WT_STAT_CONN_SESSION_TABLE_COMPACT_SUCCESS 1279
/*! session: table create failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_CREATE_FAIL 1279
+#define WT_STAT_CONN_SESSION_TABLE_CREATE_FAIL 1280
/*! session: table create successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_CREATE_SUCCESS 1280
+#define WT_STAT_CONN_SESSION_TABLE_CREATE_SUCCESS 1281
/*! session: table drop failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_DROP_FAIL 1281
+#define WT_STAT_CONN_SESSION_TABLE_DROP_FAIL 1282
/*! session: table drop successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_DROP_SUCCESS 1282
+#define WT_STAT_CONN_SESSION_TABLE_DROP_SUCCESS 1283
/*! session: table rename failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_RENAME_FAIL 1283
+#define WT_STAT_CONN_SESSION_TABLE_RENAME_FAIL 1284
/*! session: table rename successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_RENAME_SUCCESS 1284
+#define WT_STAT_CONN_SESSION_TABLE_RENAME_SUCCESS 1285
/*! session: table salvage failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_FAIL 1285
+#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_FAIL 1286
/*! session: table salvage successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_SUCCESS 1286
+#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_SUCCESS 1287
/*! session: table truncate failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_FAIL 1287
+#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_FAIL 1288
/*! session: table truncate successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_SUCCESS 1288
+#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_SUCCESS 1289
/*! session: table verify failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_VERIFY_FAIL 1289
+#define WT_STAT_CONN_SESSION_TABLE_VERIFY_FAIL 1290
/*! session: table verify successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_VERIFY_SUCCESS 1290
+#define WT_STAT_CONN_SESSION_TABLE_VERIFY_SUCCESS 1291
/*! thread-state: active filesystem fsync calls */
-#define WT_STAT_CONN_THREAD_FSYNC_ACTIVE 1291
+#define WT_STAT_CONN_THREAD_FSYNC_ACTIVE 1292
/*! thread-state: active filesystem read calls */
-#define WT_STAT_CONN_THREAD_READ_ACTIVE 1292
+#define WT_STAT_CONN_THREAD_READ_ACTIVE 1293
/*! thread-state: active filesystem write calls */
-#define WT_STAT_CONN_THREAD_WRITE_ACTIVE 1293
+#define WT_STAT_CONN_THREAD_WRITE_ACTIVE 1294
/*! thread-yield: application thread time evicting (usecs) */
-#define WT_STAT_CONN_APPLICATION_EVICT_TIME 1294
+#define WT_STAT_CONN_APPLICATION_EVICT_TIME 1295
/*! thread-yield: application thread time waiting for cache (usecs) */
-#define WT_STAT_CONN_APPLICATION_CACHE_TIME 1295
+#define WT_STAT_CONN_APPLICATION_CACHE_TIME 1296
/*!
* thread-yield: connection close blocked waiting for transaction state
* stabilization
*/
-#define WT_STAT_CONN_TXN_RELEASE_BLOCKED 1296
+#define WT_STAT_CONN_TXN_RELEASE_BLOCKED 1297
/*! thread-yield: connection close yielded for lsm manager shutdown */
-#define WT_STAT_CONN_CONN_CLOSE_BLOCKED_LSM 1297
+#define WT_STAT_CONN_CONN_CLOSE_BLOCKED_LSM 1298
/*! thread-yield: data handle lock yielded */
-#define WT_STAT_CONN_DHANDLE_LOCK_BLOCKED 1298
+#define WT_STAT_CONN_DHANDLE_LOCK_BLOCKED 1299
/*!
* thread-yield: get reference for page index and slot time sleeping
* (usecs)
*/
-#define WT_STAT_CONN_PAGE_INDEX_SLOT_REF_BLOCKED 1299
+#define WT_STAT_CONN_PAGE_INDEX_SLOT_REF_BLOCKED 1300
/*! thread-yield: log server sync yielded for log write */
-#define WT_STAT_CONN_LOG_SERVER_SYNC_BLOCKED 1300
+#define WT_STAT_CONN_LOG_SERVER_SYNC_BLOCKED 1301
/*! thread-yield: page access yielded due to prepare state change */
-#define WT_STAT_CONN_PREPARED_TRANSITION_BLOCKED_PAGE 1301
+#define WT_STAT_CONN_PREPARED_TRANSITION_BLOCKED_PAGE 1302
/*! thread-yield: page acquire busy blocked */
-#define WT_STAT_CONN_PAGE_BUSY_BLOCKED 1302
+#define WT_STAT_CONN_PAGE_BUSY_BLOCKED 1303
/*! thread-yield: page acquire eviction blocked */
-#define WT_STAT_CONN_PAGE_FORCIBLE_EVICT_BLOCKED 1303
+#define WT_STAT_CONN_PAGE_FORCIBLE_EVICT_BLOCKED 1304
/*! thread-yield: page acquire locked blocked */
-#define WT_STAT_CONN_PAGE_LOCKED_BLOCKED 1304
+#define WT_STAT_CONN_PAGE_LOCKED_BLOCKED 1305
/*! thread-yield: page acquire read blocked */
-#define WT_STAT_CONN_PAGE_READ_BLOCKED 1305
+#define WT_STAT_CONN_PAGE_READ_BLOCKED 1306
/*! thread-yield: page acquire time sleeping (usecs) */
-#define WT_STAT_CONN_PAGE_SLEEP 1306
+#define WT_STAT_CONN_PAGE_SLEEP 1307
/*!
* thread-yield: page delete rollback time sleeping for state change
* (usecs)
*/
-#define WT_STAT_CONN_PAGE_DEL_ROLLBACK_BLOCKED 1307
+#define WT_STAT_CONN_PAGE_DEL_ROLLBACK_BLOCKED 1308
/*! thread-yield: page reconciliation yielded due to child modification */
-#define WT_STAT_CONN_CHILD_MODIFY_BLOCKED_PAGE 1308
+#define WT_STAT_CONN_CHILD_MODIFY_BLOCKED_PAGE 1309
/*! transaction: Number of prepared updates */
-#define WT_STAT_CONN_TXN_PREPARED_UPDATES_COUNT 1309
+#define WT_STAT_CONN_TXN_PREPARED_UPDATES_COUNT 1310
/*! transaction: durable timestamp queue entries walked */
-#define WT_STAT_CONN_TXN_DURABLE_QUEUE_WALKED 1310
+#define WT_STAT_CONN_TXN_DURABLE_QUEUE_WALKED 1311
/*! transaction: durable timestamp queue insert to empty */
-#define WT_STAT_CONN_TXN_DURABLE_QUEUE_EMPTY 1311
+#define WT_STAT_CONN_TXN_DURABLE_QUEUE_EMPTY 1312
/*! transaction: durable timestamp queue inserts to head */
-#define WT_STAT_CONN_TXN_DURABLE_QUEUE_HEAD 1312
+#define WT_STAT_CONN_TXN_DURABLE_QUEUE_HEAD 1313
/*! transaction: durable timestamp queue inserts total */
-#define WT_STAT_CONN_TXN_DURABLE_QUEUE_INSERTS 1313
+#define WT_STAT_CONN_TXN_DURABLE_QUEUE_INSERTS 1314
/*! transaction: durable timestamp queue length */
-#define WT_STAT_CONN_TXN_DURABLE_QUEUE_LEN 1314
+#define WT_STAT_CONN_TXN_DURABLE_QUEUE_LEN 1315
/*! transaction: prepared transactions */
-#define WT_STAT_CONN_TXN_PREPARE 1315
+#define WT_STAT_CONN_TXN_PREPARE 1316
/*! transaction: prepared transactions committed */
-#define WT_STAT_CONN_TXN_PREPARE_COMMIT 1316
+#define WT_STAT_CONN_TXN_PREPARE_COMMIT 1317
/*! transaction: prepared transactions currently active */
-#define WT_STAT_CONN_TXN_PREPARE_ACTIVE 1317
+#define WT_STAT_CONN_TXN_PREPARE_ACTIVE 1318
/*! transaction: prepared transactions rolled back */
-#define WT_STAT_CONN_TXN_PREPARE_ROLLBACK 1318
+#define WT_STAT_CONN_TXN_PREPARE_ROLLBACK 1319
/*! transaction: query timestamp calls */
-#define WT_STAT_CONN_TXN_QUERY_TS 1319
+#define WT_STAT_CONN_TXN_QUERY_TS 1320
/*! transaction: read timestamp queue entries walked */
-#define WT_STAT_CONN_TXN_READ_QUEUE_WALKED 1320
+#define WT_STAT_CONN_TXN_READ_QUEUE_WALKED 1321
/*! transaction: read timestamp queue insert to empty */
-#define WT_STAT_CONN_TXN_READ_QUEUE_EMPTY 1321
+#define WT_STAT_CONN_TXN_READ_QUEUE_EMPTY 1322
/*! transaction: read timestamp queue inserts to head */
-#define WT_STAT_CONN_TXN_READ_QUEUE_HEAD 1322
+#define WT_STAT_CONN_TXN_READ_QUEUE_HEAD 1323
/*! transaction: read timestamp queue inserts total */
-#define WT_STAT_CONN_TXN_READ_QUEUE_INSERTS 1323
+#define WT_STAT_CONN_TXN_READ_QUEUE_INSERTS 1324
/*! transaction: read timestamp queue length */
-#define WT_STAT_CONN_TXN_READ_QUEUE_LEN 1324
+#define WT_STAT_CONN_TXN_READ_QUEUE_LEN 1325
/*! transaction: rollback to stable calls */
-#define WT_STAT_CONN_TXN_RTS 1325
+#define WT_STAT_CONN_TXN_RTS 1326
/*! transaction: rollback to stable pages visited */
-#define WT_STAT_CONN_TXN_RTS_PAGES_VISITED 1326
+#define WT_STAT_CONN_TXN_RTS_PAGES_VISITED 1327
/*! transaction: rollback to stable tree walk skipping pages */
-#define WT_STAT_CONN_TXN_RTS_TREE_WALK_SKIP_PAGES 1327
+#define WT_STAT_CONN_TXN_RTS_TREE_WALK_SKIP_PAGES 1328
/*! transaction: rollback to stable updates aborted */
-#define WT_STAT_CONN_TXN_RTS_UPD_ABORTED 1328
+#define WT_STAT_CONN_TXN_RTS_UPD_ABORTED 1329
/*! transaction: set timestamp calls */
-#define WT_STAT_CONN_TXN_SET_TS 1329
+#define WT_STAT_CONN_TXN_SET_TS 1330
/*! transaction: set timestamp durable calls */
-#define WT_STAT_CONN_TXN_SET_TS_DURABLE 1330
+#define WT_STAT_CONN_TXN_SET_TS_DURABLE 1331
/*! transaction: set timestamp durable updates */
-#define WT_STAT_CONN_TXN_SET_TS_DURABLE_UPD 1331
+#define WT_STAT_CONN_TXN_SET_TS_DURABLE_UPD 1332
/*! transaction: set timestamp oldest calls */
-#define WT_STAT_CONN_TXN_SET_TS_OLDEST 1332
+#define WT_STAT_CONN_TXN_SET_TS_OLDEST 1333
/*! transaction: set timestamp oldest updates */
-#define WT_STAT_CONN_TXN_SET_TS_OLDEST_UPD 1333
+#define WT_STAT_CONN_TXN_SET_TS_OLDEST_UPD 1334
/*! transaction: set timestamp stable calls */
-#define WT_STAT_CONN_TXN_SET_TS_STABLE 1334
+#define WT_STAT_CONN_TXN_SET_TS_STABLE 1335
/*! transaction: set timestamp stable updates */
-#define WT_STAT_CONN_TXN_SET_TS_STABLE_UPD 1335
+#define WT_STAT_CONN_TXN_SET_TS_STABLE_UPD 1336
/*! transaction: transaction begins */
-#define WT_STAT_CONN_TXN_BEGIN 1336
+#define WT_STAT_CONN_TXN_BEGIN 1337
/*! transaction: transaction checkpoint currently running */
-#define WT_STAT_CONN_TXN_CHECKPOINT_RUNNING 1337
+#define WT_STAT_CONN_TXN_CHECKPOINT_RUNNING 1338
/*! transaction: transaction checkpoint generation */
-#define WT_STAT_CONN_TXN_CHECKPOINT_GENERATION 1338
+#define WT_STAT_CONN_TXN_CHECKPOINT_GENERATION 1339
/*!
* transaction: transaction checkpoint history store file duration
* (usecs)
*/
-#define WT_STAT_CONN_TXN_HS_CKPT_DURATION 1339
+#define WT_STAT_CONN_TXN_HS_CKPT_DURATION 1340
/*! transaction: transaction checkpoint max time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MAX 1340
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MAX 1341
/*! transaction: transaction checkpoint min time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MIN 1341
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MIN 1342
/*!
* transaction: transaction checkpoint most recent duration for gathering
* all handles (usecs)
*/
-#define WT_STAT_CONN_TXN_CHECKPOINT_HANDLE_DURATION 1342
+#define WT_STAT_CONN_TXN_CHECKPOINT_HANDLE_DURATION 1343
/*!
* transaction: transaction checkpoint most recent duration for gathering
* applied handles (usecs)
*/
-#define WT_STAT_CONN_TXN_CHECKPOINT_HANDLE_DURATION_APPLY 1343
+#define WT_STAT_CONN_TXN_CHECKPOINT_HANDLE_DURATION_APPLY 1344
/*!
* transaction: transaction checkpoint most recent duration for gathering
* skipped handles (usecs)
*/
-#define WT_STAT_CONN_TXN_CHECKPOINT_HANDLE_DURATION_SKIP 1344
+#define WT_STAT_CONN_TXN_CHECKPOINT_HANDLE_DURATION_SKIP 1345
/*! transaction: transaction checkpoint most recent handles applied */
-#define WT_STAT_CONN_TXN_CHECKPOINT_HANDLE_APPLIED 1345
+#define WT_STAT_CONN_TXN_CHECKPOINT_HANDLE_APPLIED 1346
/*! transaction: transaction checkpoint most recent handles skipped */
-#define WT_STAT_CONN_TXN_CHECKPOINT_HANDLE_SKIPPED 1346
+#define WT_STAT_CONN_TXN_CHECKPOINT_HANDLE_SKIPPED 1347
/*! transaction: transaction checkpoint most recent handles walked */
-#define WT_STAT_CONN_TXN_CHECKPOINT_HANDLE_WALKED 1347
+#define WT_STAT_CONN_TXN_CHECKPOINT_HANDLE_WALKED 1348
/*! transaction: transaction checkpoint most recent time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_RECENT 1348
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_RECENT 1349
/*! transaction: transaction checkpoint prepare currently running */
-#define WT_STAT_CONN_TXN_CHECKPOINT_PREP_RUNNING 1349
+#define WT_STAT_CONN_TXN_CHECKPOINT_PREP_RUNNING 1350
/*! transaction: transaction checkpoint prepare max time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_PREP_MAX 1350
+#define WT_STAT_CONN_TXN_CHECKPOINT_PREP_MAX 1351
/*! transaction: transaction checkpoint prepare min time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_PREP_MIN 1351
+#define WT_STAT_CONN_TXN_CHECKPOINT_PREP_MIN 1352
/*! transaction: transaction checkpoint prepare most recent time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_PREP_RECENT 1352
+#define WT_STAT_CONN_TXN_CHECKPOINT_PREP_RECENT 1353
/*! transaction: transaction checkpoint prepare total time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_PREP_TOTAL 1353
+#define WT_STAT_CONN_TXN_CHECKPOINT_PREP_TOTAL 1354
/*! transaction: transaction checkpoint scrub dirty target */
-#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TARGET 1354
+#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TARGET 1355
/*! transaction: transaction checkpoint scrub time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TIME 1355
+#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TIME 1356
/*! transaction: transaction checkpoint total time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_TOTAL 1356
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_TOTAL 1357
/*! transaction: transaction checkpoints */
-#define WT_STAT_CONN_TXN_CHECKPOINT 1357
+#define WT_STAT_CONN_TXN_CHECKPOINT 1358
/*!
* transaction: transaction checkpoints skipped because database was
* clean
*/
-#define WT_STAT_CONN_TXN_CHECKPOINT_SKIPPED 1358
+#define WT_STAT_CONN_TXN_CHECKPOINT_SKIPPED 1359
/*! transaction: transaction failures due to history store */
-#define WT_STAT_CONN_TXN_FAIL_CACHE 1359
+#define WT_STAT_CONN_TXN_FAIL_CACHE 1360
/*!
* transaction: transaction fsync calls for checkpoint after allocating
* the transaction ID
*/
-#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST 1360
+#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST 1361
/*!
* transaction: transaction fsync duration for checkpoint after
* allocating the transaction ID (usecs)
*/
-#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST_DURATION 1361
+#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST_DURATION 1362
/*! transaction: transaction range of IDs currently pinned */
-#define WT_STAT_CONN_TXN_PINNED_RANGE 1362
+#define WT_STAT_CONN_TXN_PINNED_RANGE 1363
/*! transaction: transaction range of IDs currently pinned by a checkpoint */
-#define WT_STAT_CONN_TXN_PINNED_CHECKPOINT_RANGE 1363
+#define WT_STAT_CONN_TXN_PINNED_CHECKPOINT_RANGE 1364
/*! transaction: transaction range of timestamps currently pinned */
-#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP 1364
+#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP 1365
/*! transaction: transaction range of timestamps pinned by a checkpoint */
-#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP_CHECKPOINT 1365
+#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP_CHECKPOINT 1366
/*!
* transaction: transaction range of timestamps pinned by the oldest
* active read timestamp
*/
-#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP_READER 1366
+#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP_READER 1367
/*!
* transaction: transaction range of timestamps pinned by the oldest
* timestamp
*/
-#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP_OLDEST 1367
+#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP_OLDEST 1368
/*! transaction: transaction read timestamp of the oldest active reader */
-#define WT_STAT_CONN_TXN_TIMESTAMP_OLDEST_ACTIVE_READ 1368
+#define WT_STAT_CONN_TXN_TIMESTAMP_OLDEST_ACTIVE_READ 1369
/*! transaction: transaction sync calls */
-#define WT_STAT_CONN_TXN_SYNC 1369
+#define WT_STAT_CONN_TXN_SYNC 1370
/*! transaction: transactions committed */
-#define WT_STAT_CONN_TXN_COMMIT 1370
+#define WT_STAT_CONN_TXN_COMMIT 1371
/*! transaction: transactions rolled back */
-#define WT_STAT_CONN_TXN_ROLLBACK 1371
+#define WT_STAT_CONN_TXN_ROLLBACK 1372
/*! LSM: sleep for LSM checkpoint throttle */
-#define WT_STAT_CONN_LSM_CHECKPOINT_THROTTLE 1372
+#define WT_STAT_CONN_LSM_CHECKPOINT_THROTTLE 1373
/*! LSM: sleep for LSM merge throttle */
-#define WT_STAT_CONN_LSM_MERGE_THROTTLE 1373
+#define WT_STAT_CONN_LSM_MERGE_THROTTLE 1374
/*! cache: bytes currently in the cache */
-#define WT_STAT_CONN_CACHE_BYTES_INUSE 1374
+#define WT_STAT_CONN_CACHE_BYTES_INUSE 1375
/*! cache: bytes dirty in the cache cumulative */
-#define WT_STAT_CONN_CACHE_BYTES_DIRTY_TOTAL 1375
+#define WT_STAT_CONN_CACHE_BYTES_DIRTY_TOTAL 1376
/*! cache: bytes read into cache */
-#define WT_STAT_CONN_CACHE_BYTES_READ 1376
+#define WT_STAT_CONN_CACHE_BYTES_READ 1377
/*! cache: bytes written from cache */
-#define WT_STAT_CONN_CACHE_BYTES_WRITE 1377
+#define WT_STAT_CONN_CACHE_BYTES_WRITE 1378
/*! cache: checkpoint blocked page eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_CHECKPOINT 1378
+#define WT_STAT_CONN_CACHE_EVICTION_CHECKPOINT 1379
/*! cache: eviction walk target pages histogram - 0-9 */
-#define WT_STAT_CONN_CACHE_EVICTION_TARGET_PAGE_LT10 1379
+#define WT_STAT_CONN_CACHE_EVICTION_TARGET_PAGE_LT10 1380
/*! cache: eviction walk target pages histogram - 10-31 */
-#define WT_STAT_CONN_CACHE_EVICTION_TARGET_PAGE_LT32 1380
+#define WT_STAT_CONN_CACHE_EVICTION_TARGET_PAGE_LT32 1381
/*! cache: eviction walk target pages histogram - 128 and higher */
-#define WT_STAT_CONN_CACHE_EVICTION_TARGET_PAGE_GE128 1381
+#define WT_STAT_CONN_CACHE_EVICTION_TARGET_PAGE_GE128 1382
/*! cache: eviction walk target pages histogram - 32-63 */
-#define WT_STAT_CONN_CACHE_EVICTION_TARGET_PAGE_LT64 1382
+#define WT_STAT_CONN_CACHE_EVICTION_TARGET_PAGE_LT64 1383
/*! cache: eviction walk target pages histogram - 64-128 */
-#define WT_STAT_CONN_CACHE_EVICTION_TARGET_PAGE_LT128 1383
+#define WT_STAT_CONN_CACHE_EVICTION_TARGET_PAGE_LT128 1384
+/*!
+ * cache: eviction walk target pages reduced due to history store cache
+ * pressure
+ */
+#define WT_STAT_CONN_CACHE_EVICTION_TARGET_PAGE_REDUCED 1385
/*! cache: eviction walks abandoned */
-#define WT_STAT_CONN_CACHE_EVICTION_WALKS_ABANDONED 1384
+#define WT_STAT_CONN_CACHE_EVICTION_WALKS_ABANDONED 1386
/*! cache: eviction walks gave up because they restarted their walk twice */
-#define WT_STAT_CONN_CACHE_EVICTION_WALKS_STOPPED 1385
+#define WT_STAT_CONN_CACHE_EVICTION_WALKS_STOPPED 1387
/*!
* cache: eviction walks gave up because they saw too many pages and
* found no candidates
*/
-#define WT_STAT_CONN_CACHE_EVICTION_WALKS_GAVE_UP_NO_TARGETS 1386
+#define WT_STAT_CONN_CACHE_EVICTION_WALKS_GAVE_UP_NO_TARGETS 1388
/*!
* cache: eviction walks gave up because they saw too many pages and
* found too few candidates
*/
-#define WT_STAT_CONN_CACHE_EVICTION_WALKS_GAVE_UP_RATIO 1387
+#define WT_STAT_CONN_CACHE_EVICTION_WALKS_GAVE_UP_RATIO 1389
/*! cache: eviction walks reached end of tree */
-#define WT_STAT_CONN_CACHE_EVICTION_WALKS_ENDED 1388
+#define WT_STAT_CONN_CACHE_EVICTION_WALKS_ENDED 1390
/*! cache: eviction walks restarted */
-#define WT_STAT_CONN_CACHE_EVICTION_WALK_RESTART 1389
+#define WT_STAT_CONN_CACHE_EVICTION_WALK_RESTART 1391
/*! cache: eviction walks started from root of tree */
-#define WT_STAT_CONN_CACHE_EVICTION_WALK_FROM_ROOT 1390
+#define WT_STAT_CONN_CACHE_EVICTION_WALK_FROM_ROOT 1392
/*! cache: eviction walks started from saved location in tree */
-#define WT_STAT_CONN_CACHE_EVICTION_WALK_SAVED_POS 1391
+#define WT_STAT_CONN_CACHE_EVICTION_WALK_SAVED_POS 1393
/*! cache: hazard pointer blocked page eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_HAZARD 1392
+#define WT_STAT_CONN_CACHE_EVICTION_HAZARD 1394
/*! cache: history store table insert calls */
-#define WT_STAT_CONN_CACHE_HS_INSERT 1393
+#define WT_STAT_CONN_CACHE_HS_INSERT 1395
/*! cache: history store table insert calls that returned restart */
-#define WT_STAT_CONN_CACHE_HS_INSERT_RESTART 1394
+#define WT_STAT_CONN_CACHE_HS_INSERT_RESTART 1396
/*!
* cache: history store table out-of-order resolved updates that lose
* their durable timestamp
*/
-#define WT_STAT_CONN_CACHE_HS_ORDER_LOSE_DURABLE_TIMESTAMP 1395
+#define WT_STAT_CONN_CACHE_HS_ORDER_LOSE_DURABLE_TIMESTAMP 1397
/*!
* cache: history store table out-of-order updates that were fixed up by
* moving existing records
*/
-#define WT_STAT_CONN_CACHE_HS_ORDER_FIXUP_MOVE 1396
+#define WT_STAT_CONN_CACHE_HS_ORDER_FIXUP_MOVE 1398
/*!
* cache: history store table out-of-order updates that were fixed up
* during insertion
*/
-#define WT_STAT_CONN_CACHE_HS_ORDER_FIXUP_INSERT 1397
+#define WT_STAT_CONN_CACHE_HS_ORDER_FIXUP_INSERT 1399
/*! cache: history store table reads */
-#define WT_STAT_CONN_CACHE_HS_READ 1398
+#define WT_STAT_CONN_CACHE_HS_READ 1400
/*! cache: history store table reads missed */
-#define WT_STAT_CONN_CACHE_HS_READ_MISS 1399
+#define WT_STAT_CONN_CACHE_HS_READ_MISS 1401
/*! cache: history store table reads requiring squashed modifies */
-#define WT_STAT_CONN_CACHE_HS_READ_SQUASH 1400
+#define WT_STAT_CONN_CACHE_HS_READ_SQUASH 1402
/*!
* cache: history store table truncation by rollback to stable to remove
* an unstable update
*/
-#define WT_STAT_CONN_CACHE_HS_KEY_TRUNCATE_RTS_UNSTABLE 1401
+#define WT_STAT_CONN_CACHE_HS_KEY_TRUNCATE_RTS_UNSTABLE 1403
/*!
* cache: history store table truncation by rollback to stable to remove
* an update
*/
-#define WT_STAT_CONN_CACHE_HS_KEY_TRUNCATE_RTS 1402
+#define WT_STAT_CONN_CACHE_HS_KEY_TRUNCATE_RTS 1404
/*! cache: history store table truncation to remove an update */
-#define WT_STAT_CONN_CACHE_HS_KEY_TRUNCATE 1403
+#define WT_STAT_CONN_CACHE_HS_KEY_TRUNCATE 1405
/*!
* cache: history store table truncation to remove range of updates due
* to key being removed from the data page during reconciliation
*/
-#define WT_STAT_CONN_CACHE_HS_KEY_TRUNCATE_ONPAGE_REMOVAL 1404
+#define WT_STAT_CONN_CACHE_HS_KEY_TRUNCATE_ONPAGE_REMOVAL 1406
/*!
* cache: history store table truncation to remove range of updates due
* to non timestamped update on data page
*/
-#define WT_STAT_CONN_CACHE_HS_KEY_TRUNCATE_NON_TS 1405
+#define WT_STAT_CONN_CACHE_HS_KEY_TRUNCATE_NON_TS 1407
/*! cache: history store table writes requiring squashed modifies */
-#define WT_STAT_CONN_CACHE_HS_WRITE_SQUASH 1406
+#define WT_STAT_CONN_CACHE_HS_WRITE_SQUASH 1408
/*! cache: in-memory page passed criteria to be split */
-#define WT_STAT_CONN_CACHE_INMEM_SPLITTABLE 1407
+#define WT_STAT_CONN_CACHE_INMEM_SPLITTABLE 1409
/*! cache: in-memory page splits */
-#define WT_STAT_CONN_CACHE_INMEM_SPLIT 1408
+#define WT_STAT_CONN_CACHE_INMEM_SPLIT 1410
/*! cache: internal pages evicted */
-#define WT_STAT_CONN_CACHE_EVICTION_INTERNAL 1409
+#define WT_STAT_CONN_CACHE_EVICTION_INTERNAL 1411
/*! cache: internal pages split during eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_SPLIT_INTERNAL 1410
+#define WT_STAT_CONN_CACHE_EVICTION_SPLIT_INTERNAL 1412
/*! cache: leaf pages split during eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_SPLIT_LEAF 1411
+#define WT_STAT_CONN_CACHE_EVICTION_SPLIT_LEAF 1413
/*! cache: modified pages evicted */
-#define WT_STAT_CONN_CACHE_EVICTION_DIRTY 1412
+#define WT_STAT_CONN_CACHE_EVICTION_DIRTY 1414
/*! cache: overflow pages read into cache */
-#define WT_STAT_CONN_CACHE_READ_OVERFLOW 1413
+#define WT_STAT_CONN_CACHE_READ_OVERFLOW 1415
/*! cache: page split during eviction deepened the tree */
-#define WT_STAT_CONN_CACHE_EVICTION_DEEPEN 1414
+#define WT_STAT_CONN_CACHE_EVICTION_DEEPEN 1416
/*! cache: page written requiring history store records */
-#define WT_STAT_CONN_CACHE_WRITE_HS 1415
+#define WT_STAT_CONN_CACHE_WRITE_HS 1417
/*! cache: pages read into cache */
-#define WT_STAT_CONN_CACHE_READ 1416
+#define WT_STAT_CONN_CACHE_READ 1418
/*! cache: pages read into cache after truncate */
-#define WT_STAT_CONN_CACHE_READ_DELETED 1417
+#define WT_STAT_CONN_CACHE_READ_DELETED 1419
/*! cache: pages read into cache after truncate in prepare state */
-#define WT_STAT_CONN_CACHE_READ_DELETED_PREPARED 1418
+#define WT_STAT_CONN_CACHE_READ_DELETED_PREPARED 1420
/*! cache: pages requested from the cache */
-#define WT_STAT_CONN_CACHE_PAGES_REQUESTED 1419
+#define WT_STAT_CONN_CACHE_PAGES_REQUESTED 1421
/*! cache: pages seen by eviction walk */
-#define WT_STAT_CONN_CACHE_EVICTION_PAGES_SEEN 1420
+#define WT_STAT_CONN_CACHE_EVICTION_PAGES_SEEN 1422
/*! cache: pages written from cache */
-#define WT_STAT_CONN_CACHE_WRITE 1421
+#define WT_STAT_CONN_CACHE_WRITE 1423
/*! cache: pages written requiring in-memory restoration */
-#define WT_STAT_CONN_CACHE_WRITE_RESTORE 1422
+#define WT_STAT_CONN_CACHE_WRITE_RESTORE 1424
/*! cache: tracked dirty bytes in the cache */
-#define WT_STAT_CONN_CACHE_BYTES_DIRTY 1423
+#define WT_STAT_CONN_CACHE_BYTES_DIRTY 1425
/*! cache: unmodified pages evicted */
-#define WT_STAT_CONN_CACHE_EVICTION_CLEAN 1424
+#define WT_STAT_CONN_CACHE_EVICTION_CLEAN 1426
/*! checkpoint-cleanup: pages added for eviction */
-#define WT_STAT_CONN_CC_PAGES_EVICT 1425
+#define WT_STAT_CONN_CC_PAGES_EVICT 1427
/*! checkpoint-cleanup: pages removed */
-#define WT_STAT_CONN_CC_PAGES_REMOVED 1426
+#define WT_STAT_CONN_CC_PAGES_REMOVED 1428
/*! checkpoint-cleanup: pages skipped during tree walk */
-#define WT_STAT_CONN_CC_PAGES_WALK_SKIPPED 1427
+#define WT_STAT_CONN_CC_PAGES_WALK_SKIPPED 1429
/*! checkpoint-cleanup: pages visited */
-#define WT_STAT_CONN_CC_PAGES_VISITED 1428
+#define WT_STAT_CONN_CC_PAGES_VISITED 1430
/*! cursor: Total number of entries skipped by cursor next calls */
-#define WT_STAT_CONN_CURSOR_NEXT_SKIP_TOTAL 1429
+#define WT_STAT_CONN_CURSOR_NEXT_SKIP_TOTAL 1431
/*! cursor: Total number of entries skipped by cursor prev calls */
-#define WT_STAT_CONN_CURSOR_PREV_SKIP_TOTAL 1430
+#define WT_STAT_CONN_CURSOR_PREV_SKIP_TOTAL 1432
/*!
* cursor: Total number of entries skipped to position the history store
* cursor
*/
-#define WT_STAT_CONN_CURSOR_SKIP_HS_CUR_POSITION 1431
+#define WT_STAT_CONN_CURSOR_SKIP_HS_CUR_POSITION 1433
/*!
* cursor: cursor next calls that skip due to a globally visible history
* store tombstone
*/
-#define WT_STAT_CONN_CURSOR_NEXT_HS_TOMBSTONE 1432
+#define WT_STAT_CONN_CURSOR_NEXT_HS_TOMBSTONE 1434
/*!
* cursor: cursor next calls that skip greater than or equal to 100
* entries
*/
-#define WT_STAT_CONN_CURSOR_NEXT_SKIP_GE_100 1433
+#define WT_STAT_CONN_CURSOR_NEXT_SKIP_GE_100 1435
/*! cursor: cursor next calls that skip less than 100 entries */
-#define WT_STAT_CONN_CURSOR_NEXT_SKIP_LT_100 1434
+#define WT_STAT_CONN_CURSOR_NEXT_SKIP_LT_100 1436
/*!
* cursor: cursor prev calls that skip due to a globally visible history
* store tombstone
*/
-#define WT_STAT_CONN_CURSOR_PREV_HS_TOMBSTONE 1435
+#define WT_STAT_CONN_CURSOR_PREV_HS_TOMBSTONE 1437
/*!
* cursor: cursor prev calls that skip greater than or equal to 100
* entries
*/
-#define WT_STAT_CONN_CURSOR_PREV_SKIP_GE_100 1436
+#define WT_STAT_CONN_CURSOR_PREV_SKIP_GE_100 1438
/*! cursor: cursor prev calls that skip less than 100 entries */
-#define WT_STAT_CONN_CURSOR_PREV_SKIP_LT_100 1437
+#define WT_STAT_CONN_CURSOR_PREV_SKIP_LT_100 1439
/*! cursor: open cursor count */
-#define WT_STAT_CONN_CURSOR_OPEN_COUNT 1438
+#define WT_STAT_CONN_CURSOR_OPEN_COUNT 1440
/*! reconciliation: approximate byte size of timestamps in pages written */
-#define WT_STAT_CONN_REC_TIME_WINDOW_BYTES_TS 1439
+#define WT_STAT_CONN_REC_TIME_WINDOW_BYTES_TS 1441
/*!
* reconciliation: approximate byte size of transaction IDs in pages
* written
*/
-#define WT_STAT_CONN_REC_TIME_WINDOW_BYTES_TXN 1440
+#define WT_STAT_CONN_REC_TIME_WINDOW_BYTES_TXN 1442
/*! reconciliation: fast-path pages deleted */
-#define WT_STAT_CONN_REC_PAGE_DELETE_FAST 1441
+#define WT_STAT_CONN_REC_PAGE_DELETE_FAST 1443
/*! reconciliation: page reconciliation calls */
-#define WT_STAT_CONN_REC_PAGES 1442
+#define WT_STAT_CONN_REC_PAGES 1444
/*! reconciliation: page reconciliation calls for eviction */
-#define WT_STAT_CONN_REC_PAGES_EVICTION 1443
+#define WT_STAT_CONN_REC_PAGES_EVICTION 1445
/*! reconciliation: pages deleted */
-#define WT_STAT_CONN_REC_PAGE_DELETE 1444
+#define WT_STAT_CONN_REC_PAGE_DELETE 1446
/*!
* reconciliation: pages written including an aggregated newest start
* durable timestamp
*/
-#define WT_STAT_CONN_REC_TIME_AGGR_NEWEST_START_DURABLE_TS 1445
+#define WT_STAT_CONN_REC_TIME_AGGR_NEWEST_START_DURABLE_TS 1447
/*!
* reconciliation: pages written including an aggregated newest stop
* durable timestamp
*/
-#define WT_STAT_CONN_REC_TIME_AGGR_NEWEST_STOP_DURABLE_TS 1446
+#define WT_STAT_CONN_REC_TIME_AGGR_NEWEST_STOP_DURABLE_TS 1448
/*!
* reconciliation: pages written including an aggregated newest stop
* timestamp
*/
-#define WT_STAT_CONN_REC_TIME_AGGR_NEWEST_STOP_TS 1447
+#define WT_STAT_CONN_REC_TIME_AGGR_NEWEST_STOP_TS 1449
/*!
* reconciliation: pages written including an aggregated newest stop
* transaction ID
*/
-#define WT_STAT_CONN_REC_TIME_AGGR_NEWEST_STOP_TXN 1448
+#define WT_STAT_CONN_REC_TIME_AGGR_NEWEST_STOP_TXN 1450
/*!
* reconciliation: pages written including an aggregated newest
* transaction ID
*/
-#define WT_STAT_CONN_REC_TIME_AGGR_NEWEST_TXN 1449
+#define WT_STAT_CONN_REC_TIME_AGGR_NEWEST_TXN 1451
/*!
* reconciliation: pages written including an aggregated oldest start
* timestamp
*/
-#define WT_STAT_CONN_REC_TIME_AGGR_OLDEST_START_TS 1450
+#define WT_STAT_CONN_REC_TIME_AGGR_OLDEST_START_TS 1452
/*! reconciliation: pages written including an aggregated prepare */
-#define WT_STAT_CONN_REC_TIME_AGGR_PREPARED 1451
+#define WT_STAT_CONN_REC_TIME_AGGR_PREPARED 1453
/*!
* reconciliation: pages written including at least one start durable
* timestamp
*/
-#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_DURABLE_START_TS 1452
+#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_DURABLE_START_TS 1454
/*!
* reconciliation: pages written including at least one start transaction
* ID
*/
-#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_START_TXN 1453
+#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_START_TXN 1455
/*!
* reconciliation: pages written including at least one stop durable
* timestamp
*/
-#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_DURABLE_STOP_TS 1454
+#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_DURABLE_STOP_TS 1456
/*! reconciliation: pages written including at least one stop timestamp */
-#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_STOP_TS 1455
+#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_STOP_TS 1457
/*!
* reconciliation: pages written including at least one stop transaction
* ID
*/
-#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_STOP_TXN 1456
+#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_STOP_TXN 1458
/*! reconciliation: records written including a start durable timestamp */
-#define WT_STAT_CONN_REC_TIME_WINDOW_DURABLE_START_TS 1457
+#define WT_STAT_CONN_REC_TIME_WINDOW_DURABLE_START_TS 1459
/*! reconciliation: records written including a start timestamp */
-#define WT_STAT_CONN_REC_TIME_WINDOW_START_TS 1458
+#define WT_STAT_CONN_REC_TIME_WINDOW_START_TS 1460
/*! reconciliation: records written including a start transaction ID */
-#define WT_STAT_CONN_REC_TIME_WINDOW_START_TXN 1459
+#define WT_STAT_CONN_REC_TIME_WINDOW_START_TXN 1461
/*! reconciliation: records written including a stop durable timestamp */
-#define WT_STAT_CONN_REC_TIME_WINDOW_DURABLE_STOP_TS 1460
+#define WT_STAT_CONN_REC_TIME_WINDOW_DURABLE_STOP_TS 1462
/*! reconciliation: records written including a stop timestamp */
-#define WT_STAT_CONN_REC_TIME_WINDOW_STOP_TS 1461
+#define WT_STAT_CONN_REC_TIME_WINDOW_STOP_TS 1463
/*! reconciliation: records written including a stop transaction ID */
-#define WT_STAT_CONN_REC_TIME_WINDOW_STOP_TXN 1462
+#define WT_STAT_CONN_REC_TIME_WINDOW_STOP_TXN 1464
/*! transaction: race to read prepared update retry */
-#define WT_STAT_CONN_TXN_READ_RACE_PREPARE_UPDATE 1463
+#define WT_STAT_CONN_TXN_READ_RACE_PREPARE_UPDATE 1465
/*!
* transaction: rollback to stable hs records with stop timestamps older
* than newer records
*/
-#define WT_STAT_CONN_TXN_RTS_HS_STOP_OLDER_THAN_NEWER_START 1464
+#define WT_STAT_CONN_TXN_RTS_HS_STOP_OLDER_THAN_NEWER_START 1466
/*! transaction: rollback to stable keys removed */
-#define WT_STAT_CONN_TXN_RTS_KEYS_REMOVED 1465
+#define WT_STAT_CONN_TXN_RTS_KEYS_REMOVED 1467
/*! transaction: rollback to stable keys restored */
-#define WT_STAT_CONN_TXN_RTS_KEYS_RESTORED 1466
+#define WT_STAT_CONN_TXN_RTS_KEYS_RESTORED 1468
/*! transaction: rollback to stable restored tombstones from history store */
-#define WT_STAT_CONN_TXN_RTS_HS_RESTORE_TOMBSTONES 1467
+#define WT_STAT_CONN_TXN_RTS_HS_RESTORE_TOMBSTONES 1469
/*! transaction: rollback to stable sweeping history store keys */
-#define WT_STAT_CONN_TXN_RTS_SWEEP_HS_KEYS 1468
+#define WT_STAT_CONN_TXN_RTS_SWEEP_HS_KEYS 1470
/*! transaction: rollback to stable updates removed from history store */
-#define WT_STAT_CONN_TXN_RTS_HS_REMOVED 1469
+#define WT_STAT_CONN_TXN_RTS_HS_REMOVED 1471
/*! transaction: update conflicts */
-#define WT_STAT_CONN_TXN_UPDATE_CONFLICT 1470
+#define WT_STAT_CONN_TXN_UPDATE_CONFLICT 1472
/*!
* @}
@@ -6206,258 +6233,263 @@ extern int wiredtiger_extension_terminate(WT_CONNECTION *connection);
#define WT_STAT_DSRC_CACHE_EVICTION_TARGET_PAGE_LT64 2116
/*! cache: eviction walk target pages histogram - 64-128 */
#define WT_STAT_DSRC_CACHE_EVICTION_TARGET_PAGE_LT128 2117
+/*!
+ * cache: eviction walk target pages reduced due to history store cache
+ * pressure
+ */
+#define WT_STAT_DSRC_CACHE_EVICTION_TARGET_PAGE_REDUCED 2118
/*! cache: eviction walks abandoned */
-#define WT_STAT_DSRC_CACHE_EVICTION_WALKS_ABANDONED 2118
+#define WT_STAT_DSRC_CACHE_EVICTION_WALKS_ABANDONED 2119
/*! cache: eviction walks gave up because they restarted their walk twice */
-#define WT_STAT_DSRC_CACHE_EVICTION_WALKS_STOPPED 2119
+#define WT_STAT_DSRC_CACHE_EVICTION_WALKS_STOPPED 2120
/*!
* cache: eviction walks gave up because they saw too many pages and
* found no candidates
*/
-#define WT_STAT_DSRC_CACHE_EVICTION_WALKS_GAVE_UP_NO_TARGETS 2120
+#define WT_STAT_DSRC_CACHE_EVICTION_WALKS_GAVE_UP_NO_TARGETS 2121
/*!
* cache: eviction walks gave up because they saw too many pages and
* found too few candidates
*/
-#define WT_STAT_DSRC_CACHE_EVICTION_WALKS_GAVE_UP_RATIO 2121
+#define WT_STAT_DSRC_CACHE_EVICTION_WALKS_GAVE_UP_RATIO 2122
/*! cache: eviction walks reached end of tree */
-#define WT_STAT_DSRC_CACHE_EVICTION_WALKS_ENDED 2122
+#define WT_STAT_DSRC_CACHE_EVICTION_WALKS_ENDED 2123
/*! cache: eviction walks restarted */
-#define WT_STAT_DSRC_CACHE_EVICTION_WALK_RESTART 2123
+#define WT_STAT_DSRC_CACHE_EVICTION_WALK_RESTART 2124
/*! cache: eviction walks started from root of tree */
-#define WT_STAT_DSRC_CACHE_EVICTION_WALK_FROM_ROOT 2124
+#define WT_STAT_DSRC_CACHE_EVICTION_WALK_FROM_ROOT 2125
/*! cache: eviction walks started from saved location in tree */
-#define WT_STAT_DSRC_CACHE_EVICTION_WALK_SAVED_POS 2125
+#define WT_STAT_DSRC_CACHE_EVICTION_WALK_SAVED_POS 2126
/*! cache: hazard pointer blocked page eviction */
-#define WT_STAT_DSRC_CACHE_EVICTION_HAZARD 2126
+#define WT_STAT_DSRC_CACHE_EVICTION_HAZARD 2127
/*! cache: history store table insert calls */
-#define WT_STAT_DSRC_CACHE_HS_INSERT 2127
+#define WT_STAT_DSRC_CACHE_HS_INSERT 2128
/*! cache: history store table insert calls that returned restart */
-#define WT_STAT_DSRC_CACHE_HS_INSERT_RESTART 2128
+#define WT_STAT_DSRC_CACHE_HS_INSERT_RESTART 2129
/*!
* cache: history store table out-of-order resolved updates that lose
* their durable timestamp
*/
-#define WT_STAT_DSRC_CACHE_HS_ORDER_LOSE_DURABLE_TIMESTAMP 2129
+#define WT_STAT_DSRC_CACHE_HS_ORDER_LOSE_DURABLE_TIMESTAMP 2130
/*!
* cache: history store table out-of-order updates that were fixed up by
* moving existing records
*/
-#define WT_STAT_DSRC_CACHE_HS_ORDER_FIXUP_MOVE 2130
+#define WT_STAT_DSRC_CACHE_HS_ORDER_FIXUP_MOVE 2131
/*!
* cache: history store table out-of-order updates that were fixed up
* during insertion
*/
-#define WT_STAT_DSRC_CACHE_HS_ORDER_FIXUP_INSERT 2131
+#define WT_STAT_DSRC_CACHE_HS_ORDER_FIXUP_INSERT 2132
/*! cache: history store table reads */
-#define WT_STAT_DSRC_CACHE_HS_READ 2132
+#define WT_STAT_DSRC_CACHE_HS_READ 2133
/*! cache: history store table reads missed */
-#define WT_STAT_DSRC_CACHE_HS_READ_MISS 2133
+#define WT_STAT_DSRC_CACHE_HS_READ_MISS 2134
/*! cache: history store table reads requiring squashed modifies */
-#define WT_STAT_DSRC_CACHE_HS_READ_SQUASH 2134
+#define WT_STAT_DSRC_CACHE_HS_READ_SQUASH 2135
/*!
* cache: history store table truncation by rollback to stable to remove
* an unstable update
*/
-#define WT_STAT_DSRC_CACHE_HS_KEY_TRUNCATE_RTS_UNSTABLE 2135
+#define WT_STAT_DSRC_CACHE_HS_KEY_TRUNCATE_RTS_UNSTABLE 2136
/*!
* cache: history store table truncation by rollback to stable to remove
* an update
*/
-#define WT_STAT_DSRC_CACHE_HS_KEY_TRUNCATE_RTS 2136
+#define WT_STAT_DSRC_CACHE_HS_KEY_TRUNCATE_RTS 2137
/*! cache: history store table truncation to remove an update */
-#define WT_STAT_DSRC_CACHE_HS_KEY_TRUNCATE 2137
+#define WT_STAT_DSRC_CACHE_HS_KEY_TRUNCATE 2138
/*!
* cache: history store table truncation to remove range of updates due
* to key being removed from the data page during reconciliation
*/
-#define WT_STAT_DSRC_CACHE_HS_KEY_TRUNCATE_ONPAGE_REMOVAL 2138
+#define WT_STAT_DSRC_CACHE_HS_KEY_TRUNCATE_ONPAGE_REMOVAL 2139
/*!
* cache: history store table truncation to remove range of updates due
* to non timestamped update on data page
*/
-#define WT_STAT_DSRC_CACHE_HS_KEY_TRUNCATE_NON_TS 2139
+#define WT_STAT_DSRC_CACHE_HS_KEY_TRUNCATE_NON_TS 2140
/*! cache: history store table writes requiring squashed modifies */
-#define WT_STAT_DSRC_CACHE_HS_WRITE_SQUASH 2140
+#define WT_STAT_DSRC_CACHE_HS_WRITE_SQUASH 2141
/*! cache: in-memory page passed criteria to be split */
-#define WT_STAT_DSRC_CACHE_INMEM_SPLITTABLE 2141
+#define WT_STAT_DSRC_CACHE_INMEM_SPLITTABLE 2142
/*! cache: in-memory page splits */
-#define WT_STAT_DSRC_CACHE_INMEM_SPLIT 2142
+#define WT_STAT_DSRC_CACHE_INMEM_SPLIT 2143
/*! cache: internal pages evicted */
-#define WT_STAT_DSRC_CACHE_EVICTION_INTERNAL 2143
+#define WT_STAT_DSRC_CACHE_EVICTION_INTERNAL 2144
/*! cache: internal pages split during eviction */
-#define WT_STAT_DSRC_CACHE_EVICTION_SPLIT_INTERNAL 2144
+#define WT_STAT_DSRC_CACHE_EVICTION_SPLIT_INTERNAL 2145
/*! cache: leaf pages split during eviction */
-#define WT_STAT_DSRC_CACHE_EVICTION_SPLIT_LEAF 2145
+#define WT_STAT_DSRC_CACHE_EVICTION_SPLIT_LEAF 2146
/*! cache: modified pages evicted */
-#define WT_STAT_DSRC_CACHE_EVICTION_DIRTY 2146
+#define WT_STAT_DSRC_CACHE_EVICTION_DIRTY 2147
/*! cache: overflow pages read into cache */
-#define WT_STAT_DSRC_CACHE_READ_OVERFLOW 2147
+#define WT_STAT_DSRC_CACHE_READ_OVERFLOW 2148
/*! cache: page split during eviction deepened the tree */
-#define WT_STAT_DSRC_CACHE_EVICTION_DEEPEN 2148
+#define WT_STAT_DSRC_CACHE_EVICTION_DEEPEN 2149
/*! cache: page written requiring history store records */
-#define WT_STAT_DSRC_CACHE_WRITE_HS 2149
+#define WT_STAT_DSRC_CACHE_WRITE_HS 2150
/*! cache: pages read into cache */
-#define WT_STAT_DSRC_CACHE_READ 2150
+#define WT_STAT_DSRC_CACHE_READ 2151
/*! cache: pages read into cache after truncate */
-#define WT_STAT_DSRC_CACHE_READ_DELETED 2151
+#define WT_STAT_DSRC_CACHE_READ_DELETED 2152
/*! cache: pages read into cache after truncate in prepare state */
-#define WT_STAT_DSRC_CACHE_READ_DELETED_PREPARED 2152
+#define WT_STAT_DSRC_CACHE_READ_DELETED_PREPARED 2153
/*! cache: pages requested from the cache */
-#define WT_STAT_DSRC_CACHE_PAGES_REQUESTED 2153
+#define WT_STAT_DSRC_CACHE_PAGES_REQUESTED 2154
/*! cache: pages seen by eviction walk */
-#define WT_STAT_DSRC_CACHE_EVICTION_PAGES_SEEN 2154
+#define WT_STAT_DSRC_CACHE_EVICTION_PAGES_SEEN 2155
/*! cache: pages written from cache */
-#define WT_STAT_DSRC_CACHE_WRITE 2155
+#define WT_STAT_DSRC_CACHE_WRITE 2156
/*! cache: pages written requiring in-memory restoration */
-#define WT_STAT_DSRC_CACHE_WRITE_RESTORE 2156
+#define WT_STAT_DSRC_CACHE_WRITE_RESTORE 2157
/*! cache: tracked dirty bytes in the cache */
-#define WT_STAT_DSRC_CACHE_BYTES_DIRTY 2157
+#define WT_STAT_DSRC_CACHE_BYTES_DIRTY 2158
/*! cache: unmodified pages evicted */
-#define WT_STAT_DSRC_CACHE_EVICTION_CLEAN 2158
+#define WT_STAT_DSRC_CACHE_EVICTION_CLEAN 2159
/*! checkpoint-cleanup: pages added for eviction */
-#define WT_STAT_DSRC_CC_PAGES_EVICT 2159
+#define WT_STAT_DSRC_CC_PAGES_EVICT 2160
/*! checkpoint-cleanup: pages removed */
-#define WT_STAT_DSRC_CC_PAGES_REMOVED 2160
+#define WT_STAT_DSRC_CC_PAGES_REMOVED 2161
/*! checkpoint-cleanup: pages skipped during tree walk */
-#define WT_STAT_DSRC_CC_PAGES_WALK_SKIPPED 2161
+#define WT_STAT_DSRC_CC_PAGES_WALK_SKIPPED 2162
/*! checkpoint-cleanup: pages visited */
-#define WT_STAT_DSRC_CC_PAGES_VISITED 2162
+#define WT_STAT_DSRC_CC_PAGES_VISITED 2163
/*! cursor: Total number of entries skipped by cursor next calls */
-#define WT_STAT_DSRC_CURSOR_NEXT_SKIP_TOTAL 2163
+#define WT_STAT_DSRC_CURSOR_NEXT_SKIP_TOTAL 2164
/*! cursor: Total number of entries skipped by cursor prev calls */
-#define WT_STAT_DSRC_CURSOR_PREV_SKIP_TOTAL 2164
+#define WT_STAT_DSRC_CURSOR_PREV_SKIP_TOTAL 2165
/*!
* cursor: Total number of entries skipped to position the history store
* cursor
*/
-#define WT_STAT_DSRC_CURSOR_SKIP_HS_CUR_POSITION 2165
+#define WT_STAT_DSRC_CURSOR_SKIP_HS_CUR_POSITION 2166
/*!
* cursor: cursor next calls that skip due to a globally visible history
* store tombstone
*/
-#define WT_STAT_DSRC_CURSOR_NEXT_HS_TOMBSTONE 2166
+#define WT_STAT_DSRC_CURSOR_NEXT_HS_TOMBSTONE 2167
/*!
* cursor: cursor next calls that skip greater than or equal to 100
* entries
*/
-#define WT_STAT_DSRC_CURSOR_NEXT_SKIP_GE_100 2167
+#define WT_STAT_DSRC_CURSOR_NEXT_SKIP_GE_100 2168
/*! cursor: cursor next calls that skip less than 100 entries */
-#define WT_STAT_DSRC_CURSOR_NEXT_SKIP_LT_100 2168
+#define WT_STAT_DSRC_CURSOR_NEXT_SKIP_LT_100 2169
/*!
* cursor: cursor prev calls that skip due to a globally visible history
* store tombstone
*/
-#define WT_STAT_DSRC_CURSOR_PREV_HS_TOMBSTONE 2169
+#define WT_STAT_DSRC_CURSOR_PREV_HS_TOMBSTONE 2170
/*!
* cursor: cursor prev calls that skip greater than or equal to 100
* entries
*/
-#define WT_STAT_DSRC_CURSOR_PREV_SKIP_GE_100 2170
+#define WT_STAT_DSRC_CURSOR_PREV_SKIP_GE_100 2171
/*! cursor: cursor prev calls that skip less than 100 entries */
-#define WT_STAT_DSRC_CURSOR_PREV_SKIP_LT_100 2171
+#define WT_STAT_DSRC_CURSOR_PREV_SKIP_LT_100 2172
/*! cursor: open cursor count */
-#define WT_STAT_DSRC_CURSOR_OPEN_COUNT 2172
+#define WT_STAT_DSRC_CURSOR_OPEN_COUNT 2173
/*! reconciliation: approximate byte size of timestamps in pages written */
-#define WT_STAT_DSRC_REC_TIME_WINDOW_BYTES_TS 2173
+#define WT_STAT_DSRC_REC_TIME_WINDOW_BYTES_TS 2174
/*!
* reconciliation: approximate byte size of transaction IDs in pages
* written
*/
-#define WT_STAT_DSRC_REC_TIME_WINDOW_BYTES_TXN 2174
+#define WT_STAT_DSRC_REC_TIME_WINDOW_BYTES_TXN 2175
/*! reconciliation: fast-path pages deleted */
-#define WT_STAT_DSRC_REC_PAGE_DELETE_FAST 2175
+#define WT_STAT_DSRC_REC_PAGE_DELETE_FAST 2176
/*! reconciliation: page reconciliation calls */
-#define WT_STAT_DSRC_REC_PAGES 2176
+#define WT_STAT_DSRC_REC_PAGES 2177
/*! reconciliation: page reconciliation calls for eviction */
-#define WT_STAT_DSRC_REC_PAGES_EVICTION 2177
+#define WT_STAT_DSRC_REC_PAGES_EVICTION 2178
/*! reconciliation: pages deleted */
-#define WT_STAT_DSRC_REC_PAGE_DELETE 2178
+#define WT_STAT_DSRC_REC_PAGE_DELETE 2179
/*!
* reconciliation: pages written including an aggregated newest start
* durable timestamp
*/
-#define WT_STAT_DSRC_REC_TIME_AGGR_NEWEST_START_DURABLE_TS 2179
+#define WT_STAT_DSRC_REC_TIME_AGGR_NEWEST_START_DURABLE_TS 2180
/*!
* reconciliation: pages written including an aggregated newest stop
* durable timestamp
*/
-#define WT_STAT_DSRC_REC_TIME_AGGR_NEWEST_STOP_DURABLE_TS 2180
+#define WT_STAT_DSRC_REC_TIME_AGGR_NEWEST_STOP_DURABLE_TS 2181
/*!
* reconciliation: pages written including an aggregated newest stop
* timestamp
*/
-#define WT_STAT_DSRC_REC_TIME_AGGR_NEWEST_STOP_TS 2181
+#define WT_STAT_DSRC_REC_TIME_AGGR_NEWEST_STOP_TS 2182
/*!
* reconciliation: pages written including an aggregated newest stop
* transaction ID
*/
-#define WT_STAT_DSRC_REC_TIME_AGGR_NEWEST_STOP_TXN 2182
+#define WT_STAT_DSRC_REC_TIME_AGGR_NEWEST_STOP_TXN 2183
/*!
* reconciliation: pages written including an aggregated newest
* transaction ID
*/
-#define WT_STAT_DSRC_REC_TIME_AGGR_NEWEST_TXN 2183
+#define WT_STAT_DSRC_REC_TIME_AGGR_NEWEST_TXN 2184
/*!
* reconciliation: pages written including an aggregated oldest start
* timestamp
*/
-#define WT_STAT_DSRC_REC_TIME_AGGR_OLDEST_START_TS 2184
+#define WT_STAT_DSRC_REC_TIME_AGGR_OLDEST_START_TS 2185
/*! reconciliation: pages written including an aggregated prepare */
-#define WT_STAT_DSRC_REC_TIME_AGGR_PREPARED 2185
+#define WT_STAT_DSRC_REC_TIME_AGGR_PREPARED 2186
/*!
* reconciliation: pages written including at least one start durable
* timestamp
*/
-#define WT_STAT_DSRC_REC_TIME_WINDOW_PAGES_DURABLE_START_TS 2186
+#define WT_STAT_DSRC_REC_TIME_WINDOW_PAGES_DURABLE_START_TS 2187
/*!
* reconciliation: pages written including at least one start transaction
* ID
*/
-#define WT_STAT_DSRC_REC_TIME_WINDOW_PAGES_START_TXN 2187
+#define WT_STAT_DSRC_REC_TIME_WINDOW_PAGES_START_TXN 2188
/*!
* reconciliation: pages written including at least one stop durable
* timestamp
*/
-#define WT_STAT_DSRC_REC_TIME_WINDOW_PAGES_DURABLE_STOP_TS 2188
+#define WT_STAT_DSRC_REC_TIME_WINDOW_PAGES_DURABLE_STOP_TS 2189
/*! reconciliation: pages written including at least one stop timestamp */
-#define WT_STAT_DSRC_REC_TIME_WINDOW_PAGES_STOP_TS 2189
+#define WT_STAT_DSRC_REC_TIME_WINDOW_PAGES_STOP_TS 2190
/*!
* reconciliation: pages written including at least one stop transaction
* ID
*/
-#define WT_STAT_DSRC_REC_TIME_WINDOW_PAGES_STOP_TXN 2190
+#define WT_STAT_DSRC_REC_TIME_WINDOW_PAGES_STOP_TXN 2191
/*! reconciliation: records written including a start durable timestamp */
-#define WT_STAT_DSRC_REC_TIME_WINDOW_DURABLE_START_TS 2191
+#define WT_STAT_DSRC_REC_TIME_WINDOW_DURABLE_START_TS 2192
/*! reconciliation: records written including a start timestamp */
-#define WT_STAT_DSRC_REC_TIME_WINDOW_START_TS 2192
+#define WT_STAT_DSRC_REC_TIME_WINDOW_START_TS 2193
/*! reconciliation: records written including a start transaction ID */
-#define WT_STAT_DSRC_REC_TIME_WINDOW_START_TXN 2193
+#define WT_STAT_DSRC_REC_TIME_WINDOW_START_TXN 2194
/*! reconciliation: records written including a stop durable timestamp */
-#define WT_STAT_DSRC_REC_TIME_WINDOW_DURABLE_STOP_TS 2194
+#define WT_STAT_DSRC_REC_TIME_WINDOW_DURABLE_STOP_TS 2195
/*! reconciliation: records written including a stop timestamp */
-#define WT_STAT_DSRC_REC_TIME_WINDOW_STOP_TS 2195
+#define WT_STAT_DSRC_REC_TIME_WINDOW_STOP_TS 2196
/*! reconciliation: records written including a stop transaction ID */
-#define WT_STAT_DSRC_REC_TIME_WINDOW_STOP_TXN 2196
+#define WT_STAT_DSRC_REC_TIME_WINDOW_STOP_TXN 2197
/*! transaction: race to read prepared update retry */
-#define WT_STAT_DSRC_TXN_READ_RACE_PREPARE_UPDATE 2197
+#define WT_STAT_DSRC_TXN_READ_RACE_PREPARE_UPDATE 2198
/*!
* transaction: rollback to stable hs records with stop timestamps older
* than newer records
*/
-#define WT_STAT_DSRC_TXN_RTS_HS_STOP_OLDER_THAN_NEWER_START 2198
+#define WT_STAT_DSRC_TXN_RTS_HS_STOP_OLDER_THAN_NEWER_START 2199
/*! transaction: rollback to stable keys removed */
-#define WT_STAT_DSRC_TXN_RTS_KEYS_REMOVED 2199
+#define WT_STAT_DSRC_TXN_RTS_KEYS_REMOVED 2200
/*! transaction: rollback to stable keys restored */
-#define WT_STAT_DSRC_TXN_RTS_KEYS_RESTORED 2200
+#define WT_STAT_DSRC_TXN_RTS_KEYS_RESTORED 2201
/*! transaction: rollback to stable restored tombstones from history store */
-#define WT_STAT_DSRC_TXN_RTS_HS_RESTORE_TOMBSTONES 2201
+#define WT_STAT_DSRC_TXN_RTS_HS_RESTORE_TOMBSTONES 2202
/*! transaction: rollback to stable sweeping history store keys */
-#define WT_STAT_DSRC_TXN_RTS_SWEEP_HS_KEYS 2202
+#define WT_STAT_DSRC_TXN_RTS_SWEEP_HS_KEYS 2203
/*! transaction: rollback to stable updates removed from history store */
-#define WT_STAT_DSRC_TXN_RTS_HS_REMOVED 2203
+#define WT_STAT_DSRC_TXN_RTS_HS_REMOVED 2204
/*! transaction: update conflicts */
-#define WT_STAT_DSRC_TXN_UPDATE_CONFLICT 2204
+#define WT_STAT_DSRC_TXN_UPDATE_CONFLICT 2205
/*!
* @}
diff --git a/src/third_party/wiredtiger/src/include/wt_internal.h b/src/third_party/wiredtiger/src/include/wt_internal.h
index d3aa5905d4c..62b97d7e047 100644
--- a/src/third_party/wiredtiger/src/include/wt_internal.h
+++ b/src/third_party/wiredtiger/src/include/wt_internal.h
@@ -165,6 +165,8 @@ struct __wt_cursor_stat;
typedef struct __wt_cursor_stat WT_CURSOR_STAT;
struct __wt_cursor_table;
typedef struct __wt_cursor_table WT_CURSOR_TABLE;
+struct __wt_cursor_tiered;
+typedef struct __wt_cursor_tiered WT_CURSOR_TIERED;
struct __wt_data_handle;
typedef struct __wt_data_handle WT_DATA_HANDLE;
struct __wt_data_handle_cache;
@@ -313,6 +315,8 @@ struct __wt_thread;
typedef struct __wt_thread WT_THREAD;
struct __wt_thread_group;
typedef struct __wt_thread_group WT_THREAD_GROUP;
+struct __wt_tiered;
+typedef struct __wt_tiered WT_TIERED;
struct __wt_time_aggregate;
typedef struct __wt_time_aggregate WT_TIME_AGGREGATE;
struct __wt_time_window;
@@ -402,6 +406,7 @@ typedef uint64_t wt_timestamp_t;
#include "reconcile.h"
#include "schema.h"
#include "thread_group.h"
+#include "tiered.h"
#include "txn.h"
#include "session.h" /* required by connection.h */
diff --git a/src/third_party/wiredtiger/src/log/log.c b/src/third_party/wiredtiger/src/log/log.c
index 46dce80113c..6ba60e60129 100644
--- a/src/third_party/wiredtiger/src/log/log.c
+++ b/src/third_party/wiredtiger/src/log/log.c
@@ -2042,7 +2042,7 @@ __log_salvage_message(
* Scan the logs, calling a function on each record found.
*/
int
-__wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags,
+__wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *start_lsnp, WT_LSN *end_lsnp, uint32_t flags,
int (*func)(WT_SESSION_IMPL *session, WT_ITEM *record, WT_LSN *lsnp, WT_LSN *next_lsnp,
void *cookie, int firstrecord),
void *cookie)
@@ -2080,7 +2080,7 @@ __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags,
if (func == NULL)
return (0);
- if (lsnp != NULL && LF_ISSET(WT_LOGSCAN_FIRST | WT_LOGSCAN_FROM_CKP))
+ if (start_lsnp != NULL && LF_ISSET(WT_LOGSCAN_FIRST | WT_LOGSCAN_FROM_CKP))
WT_RET_MSG(session, WT_ERROR, "choose either a start LSN or a start flag");
/*
* Set up the allocation size, starting and ending LSNs. The values for those depend on whether
@@ -2091,7 +2091,7 @@ __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags,
allocsize = log->allocsize;
WT_ASSIGN_LSN(&end_lsn, &log->alloc_lsn);
WT_ASSIGN_LSN(&start_lsn, &log->first_lsn);
- if (lsnp == NULL) {
+ if (start_lsnp == NULL) {
if (LF_ISSET(WT_LOGSCAN_FROM_CKP))
WT_ASSIGN_LSN(&start_lsn, &log->ckpt_lsn);
else if (!LF_ISSET(WT_LOGSCAN_FIRST))
@@ -2121,16 +2121,17 @@ __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags,
WT_SET_LSN(&end_lsn, lastlog, 0);
WT_ERR(__wt_fs_directory_list_free(session, &logfiles, logcount));
}
- if (lsnp != NULL) {
+
+ if (start_lsnp != NULL) {
/*
* Offsets must be on allocation boundaries. An invalid LSN from a user should just return
* WT_NOTFOUND. It is not an error. But if it is from recovery, we expect valid LSNs so give
* more information about that.
*/
- if (lsnp->l.offset % allocsize != 0) {
+ if (start_lsnp->l.offset % allocsize != 0) {
if (LF_ISSET(WT_LOGSCAN_RECOVER | WT_LOGSCAN_RECOVER_METADATA))
WT_ERR_MSG(session, WT_NOTFOUND, "__wt_log_scan unaligned LSN %" PRIu32 "/%" PRIu32,
- lsnp->l.file, lsnp->l.offset);
+ start_lsnp->l.file, start_lsnp->l.offset);
else
WT_ERR(WT_NOTFOUND);
}
@@ -2139,11 +2140,11 @@ __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags,
* return WT_NOTFOUND. It is not an error. But if it is from recovery, we expect valid LSNs
* so give more information about that.
*/
- if (lsnp->l.file > lastlog) {
+ if (start_lsnp->l.file > lastlog) {
if (LF_ISSET(WT_LOGSCAN_RECOVER | WT_LOGSCAN_RECOVER_METADATA))
WT_ERR_MSG(session, WT_NOTFOUND,
"__wt_log_scan LSN %" PRIu32 "/%" PRIu32 " larger than biggest log file %" PRIu32,
- lsnp->l.file, lsnp->l.offset, lastlog);
+ start_lsnp->l.file, start_lsnp->l.offset, lastlog);
else
WT_ERR(WT_NOTFOUND);
}
@@ -2151,8 +2152,8 @@ __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags,
* Log cursors may not know the starting LSN. If an LSN is passed in that it is equal to the
* smallest LSN, start from the beginning of the log.
*/
- if (!WT_IS_INIT_LSN(lsnp))
- WT_ASSIGN_LSN(&start_lsn, lsnp);
+ if (!WT_IS_INIT_LSN(start_lsnp))
+ WT_ASSIGN_LSN(&start_lsn, start_lsnp);
}
WT_ERR(__log_open_verify(session, start_lsn.l.file, &log_fh, &prev_lsn, NULL, &need_salvage));
if (need_salvage)
@@ -2387,6 +2388,13 @@ advance:
if (LF_ISSET(WT_LOGSCAN_ONE))
break;
}
+
+ /*
+ * Exit the scanning loop if the next LSN seen is greater than our user set end range LSN.
+ */
+ if (end_lsnp != NULL && __wt_log_cmp(&next_lsn, end_lsnp) > 0)
+ break;
+
WT_ASSIGN_LSN(&rd_lsn, &next_lsn);
}
@@ -2687,7 +2695,7 @@ __log_write_internal(WT_SESSION_IMPL *session, WT_ITEM *record, WT_LSN *lsnp, ui
__wt_log_slot_free(session, myslot.slot);
} else if (force) {
/*
- * If we are going to wait for this slot to get written, signal the wrlsn thread.
+ * If we are going to wait for this slot to get written, signal the log server thread.
*
* XXX I've seen times when conditions are NULL.
*/
diff --git a/src/third_party/wiredtiger/src/schema/schema_alter.c b/src/third_party/wiredtiger/src/schema/schema_alter.c
index 49a78fa5784..667071df670 100644
--- a/src/third_party/wiredtiger/src/schema/schema_alter.c
+++ b/src/third_party/wiredtiger/src/schema/schema_alter.c
@@ -220,6 +220,8 @@ __schema_alter(WT_SESSION_IMPL *session, const char *uri, const char *newcfg[])
return (__wt_lsm_tree_worker(session, uri, __alter_file, NULL, newcfg, flags));
if (WT_PREFIX_MATCH(uri, "table:"))
return (__alter_table(session, uri, newcfg, exclusive_refreshed));
+ if (WT_PREFIX_MATCH(uri, "tiered:"))
+ return (__wt_tiered_worker(session, uri, __alter_file, NULL, newcfg, flags));
return (__wt_bad_object_type(session, uri));
}
diff --git a/src/third_party/wiredtiger/src/schema/schema_create.c b/src/third_party/wiredtiger/src/schema/schema_create.c
index f49bea7250e..35ae706ee1c 100644
--- a/src/third_party/wiredtiger/src/schema/schema_create.c
+++ b/src/third_party/wiredtiger/src/schema/schema_create.c
@@ -834,6 +834,8 @@ __schema_create(WT_SESSION_IMPL *session, const char *uri, const char *config)
ret = __create_index(session, uri, exclusive, config);
else if (WT_PREFIX_MATCH(uri, "table:"))
ret = __create_table(session, uri, exclusive, import, config);
+ else if (WT_PREFIX_MATCH(uri, "tiered:"))
+ ret = __wt_tiered_create(session, uri, exclusive, config);
else if ((dsrc = __wt_schema_get_source(session, uri)) != NULL)
ret = dsrc->create == NULL ? __wt_object_unsupported(session, uri) :
__create_data_source(session, uri, config, dsrc);
diff --git a/src/third_party/wiredtiger/src/schema/schema_drop.c b/src/third_party/wiredtiger/src/schema/schema_drop.c
index 21daf4b5b37..09ab32affcf 100644
--- a/src/third_party/wiredtiger/src/schema/schema_drop.c
+++ b/src/third_party/wiredtiger/src/schema/schema_drop.c
@@ -199,6 +199,8 @@ __schema_drop(WT_SESSION_IMPL *session, const char *uri, const char *cfg[])
ret = __wt_lsm_tree_drop(session, uri, cfg);
else if (WT_PREFIX_MATCH(uri, "table:"))
ret = __drop_table(session, uri, cfg);
+ else if (WT_PREFIX_MATCH(uri, "tiered:"))
+ ret = __wt_tiered_drop(session, uri, cfg);
else if ((dsrc = __wt_schema_get_source(session, uri)) != NULL)
ret = dsrc->drop == NULL ? __wt_object_unsupported(session, uri) :
dsrc->drop(dsrc, &session->iface, uri, (WT_CONFIG_ARG *)cfg);
diff --git a/src/third_party/wiredtiger/src/schema/schema_rename.c b/src/third_party/wiredtiger/src/schema/schema_rename.c
index 53c006ed226..6b5eb98d008 100644
--- a/src/third_party/wiredtiger/src/schema/schema_rename.c
+++ b/src/third_party/wiredtiger/src/schema/schema_rename.c
@@ -305,6 +305,8 @@ __schema_rename(WT_SESSION_IMPL *session, const char *uri, const char *newuri, c
ret = __wt_lsm_tree_rename(session, uri, newuri, cfg);
else if (WT_PREFIX_MATCH(uri, "table:"))
ret = __rename_table(session, uri, newuri, cfg);
+ else if (WT_PREFIX_MATCH(uri, "tiered:"))
+ ret = __wt_tiered_rename(session, uri, newuri, cfg);
else if ((dsrc = __wt_schema_get_source(session, uri)) != NULL)
ret = dsrc->rename == NULL ?
__wt_object_unsupported(session, uri) :
diff --git a/src/third_party/wiredtiger/src/schema/schema_truncate.c b/src/third_party/wiredtiger/src/schema/schema_truncate.c
index 390ecb0b5a8..27d8c78050f 100644
--- a/src/third_party/wiredtiger/src/schema/schema_truncate.c
+++ b/src/third_party/wiredtiger/src/schema/schema_truncate.c
@@ -83,6 +83,8 @@ __wt_schema_truncate(WT_SESSION_IMPL *session, const char *uri, const char *cfg[
ret = __wt_lsm_tree_truncate(session, uri, cfg);
else if (WT_PREFIX_SKIP(tablename, "table:"))
ret = __truncate_table(session, tablename, cfg);
+ else if (WT_PREFIX_MATCH(uri, "tiered:"))
+ ret = __wt_tiered_truncate(session, uri, cfg);
else if ((dsrc = __wt_schema_get_source(session, uri)) != NULL)
ret = dsrc->truncate == NULL ?
__truncate_dsrc(session, uri) :
diff --git a/src/third_party/wiredtiger/src/schema/schema_worker.c b/src/third_party/wiredtiger/src/schema/schema_worker.c
index e8beb10c670..37d069b8457 100644
--- a/src/third_party/wiredtiger/src/schema/schema_worker.c
+++ b/src/third_party/wiredtiger/src/schema/schema_worker.c
@@ -118,6 +118,8 @@ __wt_schema_worker(WT_SESSION_IMPL *session, const char *uri,
WT_ERR(
__wt_schema_worker(session, idx->source, file_func, name_func, cfg, open_flags));
}
+ } else if (WT_PREFIX_MATCH(uri, "tiered:")) {
+ WT_ERR(__wt_tiered_worker(session, uri, file_func, name_func, cfg, open_flags));
} else if ((dsrc = __wt_schema_get_source(session, uri)) != NULL) {
wt_session = (WT_SESSION *)session;
if (file_func == __wt_salvage && dsrc->salvage != NULL)
diff --git a/src/third_party/wiredtiger/src/session/session_api.c b/src/third_party/wiredtiger/src/session/session_api.c
index b221c7eb1f6..7ebdf736c2f 100644
--- a/src/third_party/wiredtiger/src/session/session_api.c
+++ b/src/third_party/wiredtiger/src/session/session_api.c
@@ -452,6 +452,8 @@ __session_open_cursor_int(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *
case 't':
if (WT_PREFIX_MATCH(uri, "table:"))
WT_RET(__wt_curtable_open(session, uri, owner, cfg, cursorp));
+ if (WT_PREFIX_MATCH(uri, "tiered:"))
+ WT_RET(__wt_curtiered_open(session, uri, owner, cfg, cursorp));
break;
case 'c':
if (WT_PREFIX_MATCH(uri, "colgroup:")) {
@@ -590,7 +592,8 @@ __session_open_cursor(WT_SESSION *wt_session, const char *uri, WT_CURSOR *to_dup
if (!WT_PREFIX_MATCH(uri, "backup:") && !WT_PREFIX_MATCH(uri, "colgroup:") &&
!WT_PREFIX_MATCH(uri, "index:") && !WT_PREFIX_MATCH(uri, "file:") &&
!WT_PREFIX_MATCH(uri, "lsm:") && !WT_PREFIX_MATCH(uri, WT_METADATA_URI) &&
- !WT_PREFIX_MATCH(uri, "table:") && __wt_schema_get_source(session, uri) == NULL)
+ !WT_PREFIX_MATCH(uri, "table:") && !WT_PREFIX_MATCH(uri, "tiered:") &&
+ __wt_schema_get_source(session, uri) == NULL)
WT_ERR(__wt_bad_object_type(session, uri));
}
}
diff --git a/src/third_party/wiredtiger/src/session/session_compact.c b/src/third_party/wiredtiger/src/session/session_compact.c
index 3184cdd579d..28eac90138e 100644
--- a/src/third_party/wiredtiger/src/session/session_compact.c
+++ b/src/third_party/wiredtiger/src/session/session_compact.c
@@ -142,6 +142,8 @@ __compact_uri_analyze(WT_SESSION_IMPL *session, const char *uri, bool *skipp)
*skipp = true;
} else if (WT_PREFIX_MATCH(uri, "file:"))
session->compact->file_count++;
+ if (WT_PREFIX_MATCH(uri, "tiered:"))
+ WT_RET(ENOTSUP);
return (0);
}
@@ -362,7 +364,7 @@ __wt_session_compact(WT_SESSION *wt_session, const char *uri, const char *config
if (!WT_PREFIX_MATCH(uri, "colgroup:") && !WT_PREFIX_MATCH(uri, "file:") &&
!WT_PREFIX_MATCH(uri, "index:") && !WT_PREFIX_MATCH(uri, "lsm:") &&
- !WT_PREFIX_MATCH(uri, "table:")) {
+ !WT_PREFIX_MATCH(uri, "table:") && !WT_PREFIX_MATCH(uri, "tiered:")) {
if ((dsrc = __wt_schema_get_source(session, uri)) != NULL)
ret = dsrc->compact == NULL ?
__wt_object_unsupported(session, uri) :
diff --git a/src/third_party/wiredtiger/src/support/err.c b/src/third_party/wiredtiger/src/support/err.c
index 2655b698a10..1a2c5d40add 100644
--- a/src/third_party/wiredtiger/src/support/err.c
+++ b/src/third_party/wiredtiger/src/support/err.c
@@ -574,7 +574,7 @@ __wt_bad_object_type(WT_SESSION_IMPL *session, const char *uri) WT_GCC_FUNC_ATTR
WT_PREFIX_MATCH(uri, "config:") || WT_PREFIX_MATCH(uri, "file:") ||
WT_PREFIX_MATCH(uri, "index:") || WT_PREFIX_MATCH(uri, "log:") ||
WT_PREFIX_MATCH(uri, "lsm:") || WT_PREFIX_MATCH(uri, "statistics:") ||
- WT_PREFIX_MATCH(uri, "table:"))
+ WT_PREFIX_MATCH(uri, "table:") || WT_PREFIX_MATCH(uri, "tiered:"))
return (__wt_object_unsupported(session, uri));
WT_RET_MSG(session, ENOTSUP, "unknown object type: %s", uri);
diff --git a/src/third_party/wiredtiger/src/support/stat.c b/src/third_party/wiredtiger/src/support/stat.c
index 83ad2859c54..1ee255be706 100644
--- a/src/third_party/wiredtiger/src/support/stat.c
+++ b/src/third_party/wiredtiger/src/support/stat.c
@@ -123,6 +123,7 @@ static const char *const __stats_dsrc_desc[] = {
"cache: eviction walk target pages histogram - 128 and higher",
"cache: eviction walk target pages histogram - 32-63",
"cache: eviction walk target pages histogram - 64-128",
+ "cache: eviction walk target pages reduced due to history store cache pressure",
"cache: eviction walks abandoned",
"cache: eviction walks gave up because they restarted their walk twice",
"cache: eviction walks gave up because they saw too many pages and found no candidates",
@@ -370,6 +371,7 @@ __wt_stat_dsrc_clear_single(WT_DSRC_STATS *stats)
stats->cache_eviction_target_page_ge128 = 0;
stats->cache_eviction_target_page_lt64 = 0;
stats->cache_eviction_target_page_lt128 = 0;
+ stats->cache_eviction_target_page_reduced = 0;
stats->cache_eviction_walks_abandoned = 0;
stats->cache_eviction_walks_stopped = 0;
stats->cache_eviction_walks_gave_up_no_targets = 0;
@@ -602,6 +604,7 @@ __wt_stat_dsrc_aggregate_single(WT_DSRC_STATS *from, WT_DSRC_STATS *to)
to->cache_eviction_target_page_ge128 += from->cache_eviction_target_page_ge128;
to->cache_eviction_target_page_lt64 += from->cache_eviction_target_page_lt64;
to->cache_eviction_target_page_lt128 += from->cache_eviction_target_page_lt128;
+ to->cache_eviction_target_page_reduced += from->cache_eviction_target_page_reduced;
to->cache_eviction_walks_abandoned += from->cache_eviction_walks_abandoned;
to->cache_eviction_walks_stopped += from->cache_eviction_walks_stopped;
to->cache_eviction_walks_gave_up_no_targets += from->cache_eviction_walks_gave_up_no_targets;
@@ -829,6 +832,8 @@ __wt_stat_dsrc_aggregate(WT_DSRC_STATS **from, WT_DSRC_STATS *to)
to->cache_eviction_target_page_ge128 += WT_STAT_READ(from, cache_eviction_target_page_ge128);
to->cache_eviction_target_page_lt64 += WT_STAT_READ(from, cache_eviction_target_page_lt64);
to->cache_eviction_target_page_lt128 += WT_STAT_READ(from, cache_eviction_target_page_lt128);
+ to->cache_eviction_target_page_reduced +=
+ WT_STAT_READ(from, cache_eviction_target_page_reduced);
to->cache_eviction_walks_abandoned += WT_STAT_READ(from, cache_eviction_walks_abandoned);
to->cache_eviction_walks_stopped += WT_STAT_READ(from, cache_eviction_walks_stopped);
to->cache_eviction_walks_gave_up_no_targets +=
@@ -1021,6 +1026,7 @@ static const char *const __stats_connection_desc[] = {
"cache: pages queued for eviction post lru sorting",
"cache: pages queued for urgent eviction",
"cache: pages queued for urgent eviction during walk",
+ "cache: pages queued for urgent eviction from history store due to high dirty content",
"cache: pages seen by eviction walk that are already queued",
"cache: pages selected for eviction unable to be evicted",
"cache: pages selected for eviction unable to be evicted as the parent page has overflow items",
@@ -1323,6 +1329,7 @@ static const char *const __stats_connection_desc[] = {
"cache: eviction walk target pages histogram - 128 and higher",
"cache: eviction walk target pages histogram - 32-63",
"cache: eviction walk target pages histogram - 64-128",
+ "cache: eviction walk target pages reduced due to history store cache pressure",
"cache: eviction walks abandoned",
"cache: eviction walks gave up because they restarted their walk twice",
"cache: eviction walks gave up because they saw too many pages and found no candidates",
@@ -1539,6 +1546,7 @@ __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats)
stats->cache_eviction_pages_queued_post_lru = 0;
stats->cache_eviction_pages_queued_urgent = 0;
stats->cache_eviction_pages_queued_oldest = 0;
+ stats->cache_eviction_pages_queued_urgent_hs_dirty = 0;
stats->cache_eviction_pages_already_queued = 0;
stats->cache_eviction_fail = 0;
stats->cache_eviction_fail_parent_has_overflow_items = 0;
@@ -1836,6 +1844,7 @@ __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats)
stats->cache_eviction_target_page_ge128 = 0;
stats->cache_eviction_target_page_lt64 = 0;
stats->cache_eviction_target_page_lt128 = 0;
+ stats->cache_eviction_target_page_reduced = 0;
stats->cache_eviction_walks_abandoned = 0;
stats->cache_eviction_walks_stopped = 0;
stats->cache_eviction_walks_gave_up_no_targets = 0;
@@ -2038,6 +2047,8 @@ __wt_stat_connection_aggregate(WT_CONNECTION_STATS **from, WT_CONNECTION_STATS *
WT_STAT_READ(from, cache_eviction_pages_queued_urgent);
to->cache_eviction_pages_queued_oldest +=
WT_STAT_READ(from, cache_eviction_pages_queued_oldest);
+ to->cache_eviction_pages_queued_urgent_hs_dirty +=
+ WT_STAT_READ(from, cache_eviction_pages_queued_urgent_hs_dirty);
to->cache_eviction_pages_already_queued +=
WT_STAT_READ(from, cache_eviction_pages_already_queued);
to->cache_eviction_fail += WT_STAT_READ(from, cache_eviction_fail);
@@ -2346,6 +2357,8 @@ __wt_stat_connection_aggregate(WT_CONNECTION_STATS **from, WT_CONNECTION_STATS *
to->cache_eviction_target_page_ge128 += WT_STAT_READ(from, cache_eviction_target_page_ge128);
to->cache_eviction_target_page_lt64 += WT_STAT_READ(from, cache_eviction_target_page_lt64);
to->cache_eviction_target_page_lt128 += WT_STAT_READ(from, cache_eviction_target_page_lt128);
+ to->cache_eviction_target_page_reduced +=
+ WT_STAT_READ(from, cache_eviction_target_page_reduced);
to->cache_eviction_walks_abandoned += WT_STAT_READ(from, cache_eviction_walks_abandoned);
to->cache_eviction_walks_stopped += WT_STAT_READ(from, cache_eviction_walks_stopped);
to->cache_eviction_walks_gave_up_no_targets +=
diff --git a/src/third_party/wiredtiger/src/tiered/tiered_cursor.c b/src/third_party/wiredtiger/src/tiered/tiered_cursor.c
new file mode 100644
index 00000000000..26c750fb496
--- /dev/null
+++ b/src/third_party/wiredtiger/src/tiered/tiered_cursor.c
@@ -0,0 +1,1186 @@
+/*-
+ * Copyright (c) 2014-2020 MongoDB, Inc.
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+#define WT_FORALL_CURSORS(curtiered, c, i) \
+ for ((i) = (curtiered)->tiered->ntiers; (i) > 0;) \
+ if (((c) = (curtiered)->cursors[--(i)]) != NULL)
+
+#define WT_TIERED_CURCMP(s, tiered, c1, c2, cmp) \
+ __wt_compare(s, (tiered)->collator, &(c1)->key, &(c2)->key, &(cmp))
+
+/*
+ * __curtiered_open_cursors --
+ * Open cursors for the current set of files.
+ */
+static int
+__curtiered_open_cursors(WT_CURSOR_TIERED *curtiered)
+{
+ WT_CURSOR *cursor;
+ WT_DATA_HANDLE *dhandle;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+ WT_TIERED *tiered;
+ u_int i;
+
+ cursor = &curtiered->iface;
+ session = CUR2S(curtiered);
+ dhandle = NULL;
+ tiered = curtiered->tiered;
+
+ if (tiered->ntiers == 0)
+ return (0);
+
+ /*
+ * If the key is pointing to memory that is pinned by a chunk cursor, take a copy before closing
+ * cursors.
+ */
+ if (F_ISSET(cursor, WT_CURSTD_KEY_INT))
+ WT_ERR(__cursor_needkey(cursor));
+
+ F_CLR(curtiered, WT_CURTIERED_ITERATE_NEXT | WT_CURTIERED_ITERATE_PREV);
+
+ WT_ASSERT(session, curtiered->cursors == NULL);
+ WT_ERR(__wt_calloc_def(session, tiered->ntiers, &curtiered->cursors));
+
+ /* Open the cursors for chunks that have changed. */
+ __wt_verbose(session, WT_VERB_TIERED,
+ "tiered opening cursor session(%p):tiered cursor(%p), tiers: %u", (void *)session,
+ (void *)curtiered, tiered->ntiers);
+ for (i = 0; i != tiered->ntiers; i++) {
+ dhandle = tiered->tiers[i];
+
+ /*
+ * Read from the checkpoint if the file has been written. Once all cursors switch, the
+ * in-memory tree can be evicted.
+ */
+ WT_ASSERT(session, curtiered->cursors[i] == NULL);
+ WT_ERR(__wt_open_cursor(session, dhandle->name, cursor, NULL, &curtiered->cursors[i]));
+
+ /* Child cursors always use overwrite and raw mode. */
+ F_SET(curtiered->cursors[i], WT_CURSTD_OVERWRITE | WT_CURSTD_RAW);
+ }
+
+err:
+ return (ret);
+}
+
+/*
+ * __curtiered_close_cursors --
+ * Close any btree cursors that are not needed.
+ */
+static int
+__curtiered_close_cursors(WT_SESSION_IMPL *session, WT_CURSOR_TIERED *curtiered)
+{
+ WT_CURSOR *c;
+ u_int i;
+
+ __wt_verbose(session, WT_VERB_TIERED, "tiered close cursors session(%p):tiered cursor(%p)",
+ (void *)session, (void *)curtiered);
+
+ if (curtiered->cursors == NULL)
+ return (0);
+
+ /* Walk the cursors, closing them. */
+ for (i = 0; i < curtiered->tiered->ntiers; i++) {
+ if ((c = (curtiered)->cursors[i]) != NULL) {
+ curtiered->cursors[i] = NULL;
+ WT_RET(c->close(c));
+ }
+ }
+
+ __wt_free(session, curtiered->cursors);
+ return (0);
+}
+
+/*
+ * __curtiered_reset_cursors --
+ * Reset any positioned chunk cursors. If the skip parameter is non-NULL, that cursor is about
+ * to be used, so there is no need to reset it.
+ */
+static int
+__curtiered_reset_cursors(WT_CURSOR_TIERED *curtiered, WT_CURSOR *skip)
+{
+ WT_CURSOR *c;
+ WT_DECL_RET;
+ u_int i;
+
+ /* Fast path if the cursor is not positioned. */
+ if ((curtiered->current == NULL || curtiered->current == skip) &&
+ !F_ISSET(curtiered, WT_CLSM_ITERATE_NEXT | WT_CLSM_ITERATE_PREV))
+ return (0);
+
+ WT_FORALL_CURSORS(curtiered, c, i)
+ {
+ if (c == skip)
+ continue;
+ if (F_ISSET(c, WT_CURSTD_KEY_INT))
+ WT_TRET(c->reset(c));
+ }
+
+ curtiered->current = NULL;
+ F_CLR(curtiered, WT_CLSM_ITERATE_NEXT | WT_CLSM_ITERATE_PREV);
+
+ return (ret);
+}
+
+/*
+ * __curtiered_enter --
+ * Start an operation on a tiered cursor.
+ */
+static inline int
+__curtiered_enter(WT_CURSOR_TIERED *curtiered, bool reset)
+{
+ WT_SESSION_IMPL *session;
+
+ session = CUR2S(curtiered);
+
+ if (curtiered->cursors == NULL)
+ WT_RET(__curtiered_open_cursors(curtiered));
+
+ if (reset) {
+ WT_ASSERT(session, !F_ISSET(&curtiered->iface, WT_CURSTD_KEY_INT | WT_CURSTD_VALUE_INT));
+ WT_RET(__curtiered_reset_cursors(curtiered, NULL));
+ }
+
+ if (!F_ISSET(curtiered, WT_CURTIERED_ACTIVE)) {
+ /*
+ * Opening this tiered cursor has opened a number of other cursors, ensure we don't mistake
+ * this as the first cursor in a session.
+ */
+ ++session->ncursors;
+ WT_RET(__cursor_enter(session));
+ F_SET(curtiered, WT_CURTIERED_ACTIVE);
+ }
+
+ return (0);
+}
+/*
+ * __curtiered_leave --
+ * Finish an operation on a tiered cursor.
+ */
+static void
+__curtiered_leave(WT_CURSOR_TIERED *curtiered)
+{
+ WT_SESSION_IMPL *session;
+
+ session = CUR2S(curtiered);
+
+ if (F_ISSET(curtiered, WT_CURTIERED_ACTIVE)) {
+ --session->ncursors;
+ __cursor_leave(session);
+ F_CLR(curtiered, WT_CURTIERED_ACTIVE);
+ }
+}
+
+/*
+ * We need a tombstone to mark deleted records, and we use the special value below for that purpose.
+ * We use two 0x14 (Device Control 4) bytes to minimize the likelihood of colliding with an
+ * application-chosen encoding byte, if the application uses two leading DC4 byte for some reason,
+ * we'll do a wasted data copy each time a new value is inserted into the object.
+ */
+static const WT_ITEM __tombstone = {"\x14\x14", 2, NULL, 0, 0};
+
+/*
+ * __curtiered_deleted --
+ * Check whether the current value is a tombstone.
+ */
+static inline bool
+__curtiered_deleted(WT_CURSOR_TIERED *curtiered, const WT_ITEM *item)
+{
+ WT_UNUSED(curtiered);
+ return (item->size == __tombstone.size &&
+ memcmp(item->data, __tombstone.data, __tombstone.size) == 0);
+}
+
+/*
+ * __curtiered_deleted_encode --
+ * Encode values that are in the encoded name space.
+ */
+static inline int
+__curtiered_deleted_encode(
+ WT_SESSION_IMPL *session, const WT_ITEM *value, WT_ITEM *final_value, WT_ITEM **tmpp)
+{
+ WT_ITEM *tmp;
+
+ /*
+ * If value requires encoding, get a scratch buffer of the right size and create a copy of the
+ * data with the first byte of the tombstone appended.
+ */
+ if (value->size >= __tombstone.size &&
+ memcmp(value->data, __tombstone.data, __tombstone.size) == 0) {
+ WT_RET(__wt_scr_alloc(session, value->size + 1, tmpp));
+ tmp = *tmpp;
+
+ memcpy(tmp->mem, value->data, value->size);
+ memcpy((uint8_t *)tmp->mem + value->size, __tombstone.data, 1);
+ final_value->data = tmp->mem;
+ final_value->size = value->size + 1;
+ } else {
+ final_value->data = value->data;
+ final_value->size = value->size;
+ }
+
+ return (0);
+}
+
+/*
+ * __curtiered_deleted_decode --
+ * Decode values that start with the tombstone.
+ */
+static inline void
+__curtiered_deleted_decode(WT_CURSOR_TIERED *curtiered, WT_ITEM *value)
+{
+ WT_UNUSED(curtiered);
+ /*
+ * Take care with this check: when a tiered cursor is used for a merge, it is valid to return
+ * the tombstone value.
+ */
+ if (value->size > __tombstone.size &&
+ memcmp(value->data, __tombstone.data, __tombstone.size) == 0)
+ --value->size;
+}
+
+/*
+ * __wt_curtiered_close --
+ * WT_CURSOR->close method for the tiered cursor type.
+ */
+int
+__wt_curtiered_close(WT_CURSOR *cursor)
+{
+ WT_CURSOR_TIERED *curtiered;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+
+ /*
+ * Don't use the normal __curtiered_enter path: that is wasted work when closing, and the cursor
+ * may never have been used.
+ */
+ curtiered = (WT_CURSOR_TIERED *)cursor;
+ CURSOR_API_CALL_PREPARE_ALLOWED(cursor, session, close, NULL);
+err:
+ WT_TRET(__curtiered_close_cursors(session, curtiered));
+
+ /* In case we were somehow left positioned, clear that. */
+ __curtiered_leave(curtiered);
+
+ if (curtiered->tiered != NULL)
+ WT_WITH_DHANDLE(session, (WT_DATA_HANDLE *)curtiered->tiered,
+ WT_TRET(__wt_session_release_dhandle(session)));
+ __wt_cursor_close(cursor);
+
+ API_END_RET(session, ret);
+}
+
+/*
+ * __curtiered_get_current --
+ * Find the smallest / largest of the cursors and copy its key/value.
+ */
+static int
+__curtiered_get_current(
+ WT_SESSION_IMPL *session, WT_CURSOR_TIERED *curtiered, bool smallest, bool *deletedp)
+{
+ WT_CURSOR *c, *current;
+ u_int i;
+ int cmp;
+ bool multiple;
+
+ current = NULL;
+ multiple = false;
+
+ WT_FORALL_CURSORS(curtiered, c, i)
+ {
+ if (!F_ISSET(c, WT_CURSTD_KEY_INT))
+ continue;
+ if (current == NULL) {
+ current = c;
+ continue;
+ }
+ WT_RET(WT_TIERED_CURCMP(session, curtiered->tiered, c, current, cmp));
+ if (smallest ? cmp < 0 : cmp > 0) {
+ current = c;
+ multiple = false;
+ } else if (cmp == 0)
+ multiple = true;
+ }
+
+ c = &curtiered->iface;
+ if ((curtiered->current = current) == NULL) {
+ F_CLR(c, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET);
+ return (WT_NOTFOUND);
+ }
+
+ if (multiple)
+ F_SET(curtiered, WT_CLSM_MULTIPLE);
+ else
+ F_CLR(curtiered, WT_CLSM_MULTIPLE);
+
+ WT_RET(current->get_key(current, &c->key));
+ WT_RET(current->get_value(current, &c->value));
+
+ F_CLR(c, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET);
+ if ((*deletedp = __curtiered_deleted(curtiered, &c->value)) == false)
+ F_SET(c, WT_CURSTD_KEY_INT | WT_CURSTD_VALUE_INT);
+
+ return (0);
+}
+
+/*
+ * __curtiered_compare --
+ * WT_CURSOR->compare implementation for the LSM cursor type.
+ */
+static int
+__curtiered_compare(WT_CURSOR *a, WT_CURSOR *b, int *cmpp)
+{
+ WT_CURSOR_TIERED *alsm;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+
+ /* There's no need to sync with the LSM tree, avoid WT_LSM_ENTER. */
+ alsm = (WT_CURSOR_TIERED *)a;
+ CURSOR_API_CALL(a, session, compare, NULL);
+
+ /*
+ * Confirm both cursors refer to the same source and have keys, then compare the keys.
+ */
+ if (strcmp(a->uri, b->uri) != 0)
+ WT_ERR_MSG(session, EINVAL, "comparison method cursors must reference the same object");
+
+ WT_ERR(__cursor_needkey(a));
+ WT_ERR(__cursor_needkey(b));
+
+ WT_ERR(__wt_compare(session, alsm->tiered->collator, &a->key, &b->key, cmpp));
+
+err:
+ API_END_RET(session, ret);
+}
+
+/*
+ * __curtiered_position_chunk --
+ * Position a chunk cursor.
+ */
+static int
+__curtiered_position_chunk(WT_CURSOR_TIERED *curtiered, WT_CURSOR *c, bool forward, int *cmpp)
+{
+ WT_CURSOR *cursor;
+ WT_SESSION_IMPL *session;
+
+ cursor = &curtiered->iface;
+ session = CUR2S(cursor);
+
+ c->set_key(c, &cursor->key);
+ WT_RET(c->search_near(c, cmpp));
+
+ while (forward ? *cmpp < 0 : *cmpp > 0) {
+ WT_RET(forward ? c->next(c) : c->prev(c));
+
+ /*
+ * With higher isolation levels, where we have stable reads, we're done: the cursor is now
+ * positioned as expected.
+ *
+ * With read-uncommitted isolation, a new record could have appeared in between the search
+ * and stepping forward / back. In that case, keep going until we see a key in the expected
+ * range.
+ */
+ if (session->txn->isolation != WT_ISO_READ_UNCOMMITTED)
+ return (0);
+
+ WT_RET(WT_TIERED_CURCMP(session, curtiered->tiered, c, cursor, *cmpp));
+ }
+
+ return (0);
+}
+
+/*
+ * __curtiered_next --
+ * WT_CURSOR->next method for the LSM cursor type.
+ */
+static int
+__curtiered_next(WT_CURSOR *cursor)
+{
+ WT_CURSOR *c;
+ WT_CURSOR_TIERED *curtiered;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+ u_int i;
+ int cmp;
+ bool deleted;
+
+ curtiered = (WT_CURSOR_TIERED *)cursor;
+
+ CURSOR_API_CALL(cursor, session, next, NULL);
+ __cursor_novalue(cursor);
+ WT_ERR(__curtiered_enter(curtiered, false));
+
+ /* If we aren't positioned for a forward scan, get started. */
+ if (curtiered->current == NULL || !F_ISSET(curtiered, WT_CLSM_ITERATE_NEXT)) {
+ WT_FORALL_CURSORS(curtiered, c, i)
+ {
+ if (!F_ISSET(cursor, WT_CURSTD_KEY_SET)) {
+ WT_ERR(c->reset(c));
+ ret = c->next(c);
+ } else if (c != curtiered->current &&
+ (ret = __curtiered_position_chunk(curtiered, c, true, &cmp)) == 0 && cmp == 0 &&
+ curtiered->current == NULL)
+ curtiered->current = c;
+ WT_ERR_NOTFOUND_OK(ret, false);
+ }
+ F_SET(curtiered, WT_CLSM_ITERATE_NEXT | WT_CLSM_MULTIPLE);
+ F_CLR(curtiered, WT_CLSM_ITERATE_PREV);
+
+ /* We just positioned *at* the key, now move. */
+ if (curtiered->current != NULL)
+ goto retry;
+ } else {
+retry:
+ /*
+ * If there are multiple cursors on that key, move them forward.
+ */
+ if (F_ISSET(curtiered, WT_CLSM_MULTIPLE)) {
+ WT_FORALL_CURSORS(curtiered, c, i)
+ {
+ if (!F_ISSET(c, WT_CURSTD_KEY_INT))
+ continue;
+ if (c != curtiered->current) {
+ WT_ERR(
+ WT_TIERED_CURCMP(session, curtiered->tiered, c, curtiered->current, cmp));
+ if (cmp == 0)
+ WT_ERR_NOTFOUND_OK(c->next(c), false);
+ }
+ }
+ }
+
+ /* Move the smallest cursor forward. */
+ c = curtiered->current;
+ WT_ERR_NOTFOUND_OK(c->next(c), false);
+ }
+
+ /* Find the cursor(s) with the smallest key. */
+ if ((ret = __curtiered_get_current(session, curtiered, true, &deleted)) == 0 && deleted)
+ goto retry;
+
+err:
+ __curtiered_leave(curtiered);
+ if (ret == 0)
+ __curtiered_deleted_decode(curtiered, &cursor->value);
+ API_END_RET(session, ret);
+}
+
+/*
+ * __curtiered_prev --
+ * WT_CURSOR->prev method for the LSM cursor type.
+ */
+static int
+__curtiered_prev(WT_CURSOR *cursor)
+{
+ WT_CURSOR *c;
+ WT_CURSOR_TIERED *curtiered;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+ u_int i;
+ int cmp;
+ bool deleted;
+
+ curtiered = (WT_CURSOR_TIERED *)cursor;
+
+ CURSOR_API_CALL(cursor, session, prev, NULL);
+ __cursor_novalue(cursor);
+ WT_ERR(__curtiered_enter(curtiered, false));
+
+ /* If we aren't positioned for a reverse scan, get started. */
+ if (curtiered->current == NULL || !F_ISSET(curtiered, WT_CLSM_ITERATE_PREV)) {
+ WT_FORALL_CURSORS(curtiered, c, i)
+ {
+ if (!F_ISSET(cursor, WT_CURSTD_KEY_SET)) {
+ WT_ERR(c->reset(c));
+ ret = c->prev(c);
+ } else if (c != curtiered->current &&
+ (ret = __curtiered_position_chunk(curtiered, c, false, &cmp)) == 0 && cmp == 0 &&
+ curtiered->current == NULL)
+ curtiered->current = c;
+ WT_ERR_NOTFOUND_OK(ret, false);
+ }
+ F_SET(curtiered, WT_CLSM_ITERATE_PREV | WT_CLSM_MULTIPLE);
+ F_CLR(curtiered, WT_CLSM_ITERATE_NEXT);
+
+ /* We just positioned *at* the key, now move. */
+ if (curtiered->current != NULL)
+ goto retry;
+ } else {
+retry:
+ /*
+ * If there are multiple cursors on that key, move them backwards.
+ */
+ if (F_ISSET(curtiered, WT_CLSM_MULTIPLE)) {
+ WT_FORALL_CURSORS(curtiered, c, i)
+ {
+ if (!F_ISSET(c, WT_CURSTD_KEY_INT))
+ continue;
+ if (c != curtiered->current) {
+ WT_ERR(
+ WT_TIERED_CURCMP(session, curtiered->tiered, c, curtiered->current, cmp));
+ if (cmp == 0)
+ WT_ERR_NOTFOUND_OK(c->prev(c), false);
+ }
+ }
+ }
+
+ /* Move the largest cursor backwards. */
+ c = curtiered->current;
+ WT_ERR_NOTFOUND_OK(c->prev(c), false);
+ }
+
+ /* Find the cursor(s) with the largest key. */
+ if ((ret = __curtiered_get_current(session, curtiered, false, &deleted)) == 0 && deleted)
+ goto retry;
+
+err:
+ __curtiered_leave(curtiered);
+ if (ret == 0)
+ __curtiered_deleted_decode(curtiered, &cursor->value);
+ API_END_RET(session, ret);
+}
+
+/*
+ * __curtiered_reset --
+ * WT_CURSOR->reset method for the LSM cursor type.
+ */
+static int
+__curtiered_reset(WT_CURSOR *cursor)
+{
+ WT_CURSOR_TIERED *curtiered;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+
+ /*
+ * Don't use the normal __curtiered_enter path: that is wasted work when all we want to do is
+ * give up our position.
+ */
+ curtiered = (WT_CURSOR_TIERED *)cursor;
+ CURSOR_API_CALL_PREPARE_ALLOWED(cursor, session, reset, NULL);
+ F_CLR(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET);
+
+ WT_TRET(__curtiered_reset_cursors(curtiered, NULL));
+
+ /* In case we were left positioned, clear that. */
+ __curtiered_leave(curtiered);
+
+err:
+ API_END_RET(session, ret);
+}
+
+/*
+ * __curtiered_lookup --
+ * Position an LSM cursor.
+ */
+static int
+__curtiered_lookup(WT_CURSOR_TIERED *curtiered, WT_ITEM *value)
+{
+ WT_CURSOR *c, *cursor;
+ WT_DECL_RET;
+ u_int i;
+
+ c = NULL;
+ cursor = &curtiered->iface;
+
+ WT_FORALL_CURSORS(curtiered, c, i)
+ {
+ c->set_key(c, &cursor->key);
+ if ((ret = c->search(c)) == 0) {
+ WT_ERR(c->get_key(c, &cursor->key));
+ WT_ERR(c->get_value(c, value));
+ if (__curtiered_deleted(curtiered, value))
+ ret = WT_NOTFOUND;
+ goto done;
+ }
+ WT_ERR_NOTFOUND_OK(ret, false);
+ F_CLR(c, WT_CURSTD_KEY_SET);
+ }
+ WT_ERR(WT_NOTFOUND);
+
+done:
+err:
+ if (ret == 0) {
+ F_CLR(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET);
+ F_SET(cursor, WT_CURSTD_KEY_INT);
+ curtiered->current = c;
+ if (value == &cursor->value)
+ F_SET(cursor, WT_CURSTD_VALUE_INT);
+ } else if (c != NULL)
+ WT_TRET(c->reset(c));
+
+ return (ret);
+}
+
+/*
+ * __curtiered_search --
+ * WT_CURSOR->search method for the LSM cursor type.
+ */
+static int
+__curtiered_search(WT_CURSOR *cursor)
+{
+ WT_CURSOR_TIERED *curtiered;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+
+ curtiered = (WT_CURSOR_TIERED *)cursor;
+
+ CURSOR_API_CALL(cursor, session, search, NULL);
+ WT_ERR(__cursor_needkey(cursor));
+ __cursor_novalue(cursor);
+ WT_ERR(__curtiered_enter(curtiered, true));
+ F_CLR(curtiered, WT_CLSM_ITERATE_NEXT | WT_CLSM_ITERATE_PREV);
+
+ ret = __curtiered_lookup(curtiered, &cursor->value);
+
+err:
+ __curtiered_leave(curtiered);
+ if (ret == 0)
+ __curtiered_deleted_decode(curtiered, &cursor->value);
+ API_END_RET(session, ret);
+}
+
+/*
+ * __curtiered_search_near --
+ * WT_CURSOR->search_near method for the LSM cursor type.
+ */
+static int
+__curtiered_search_near(WT_CURSOR *cursor, int *exactp)
+{
+ WT_CURSOR *c, *closest;
+ WT_CURSOR_TIERED *curtiered;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+ u_int i;
+ int cmp, exact;
+ bool deleted;
+
+ closest = NULL;
+ curtiered = (WT_CURSOR_TIERED *)cursor;
+ exact = 0;
+
+ CURSOR_API_CALL(cursor, session, search_near, NULL);
+ WT_ERR(__cursor_needkey(cursor));
+ __cursor_novalue(cursor);
+ WT_ERR(__curtiered_enter(curtiered, true));
+ F_CLR(curtiered, WT_CLSM_ITERATE_NEXT | WT_CLSM_ITERATE_PREV);
+
+ /*
+ * search_near is somewhat fiddly: we can't just use a nearby key from the in-memory chunk
+ * because there could be a closer key on disk.
+ *
+ * As we search down the chunks, we stop as soon as we find an exact match. Otherwise, we
+ * maintain the smallest cursor larger than the search key and the largest cursor smaller than
+ * the search key. At the end, we prefer the larger cursor, but if no record is larger, position
+ * on the last record in the tree.
+ */
+ WT_FORALL_CURSORS(curtiered, c, i)
+ {
+ c->set_key(c, &cursor->key);
+ if ((ret = c->search_near(c, &cmp)) == WT_NOTFOUND) {
+ ret = 0;
+ continue;
+ }
+ if (ret != 0)
+ goto err;
+
+ /* Do we have an exact match? */
+ if (cmp == 0) {
+ closest = c;
+ exact = 1;
+ break;
+ }
+
+ /*
+ * Prefer larger cursors. There are two reasons: (1) we expect
+ * prefix searches to be a common case (as in our own indices);
+ * and (2) we need a way to unambiguously know we have the
+ * "closest" result.
+ */
+ if (cmp < 0) {
+ if ((ret = c->next(c)) == WT_NOTFOUND) {
+ ret = 0;
+ continue;
+ }
+ if (ret != 0)
+ goto err;
+ }
+
+ /*
+ * We are trying to find the smallest cursor greater than the search key.
+ */
+ if (closest == NULL)
+ closest = c;
+ else {
+ WT_ERR(WT_TIERED_CURCMP(session, curtiered->tiered, c, closest, cmp));
+ if (cmp < 0)
+ closest = c;
+ }
+ }
+
+ /*
+ * At this point, we either have an exact match, or closest is the smallest cursor larger than
+ * the search key, or it is NULL if the search key is larger than any record in the tree.
+ */
+ cmp = exact ? 0 : 1;
+
+ /*
+ * If we land on a deleted item, try going forwards or backwards to find one that isn't deleted.
+ * If the whole tree is empty, we'll end up with WT_NOTFOUND, as expected.
+ */
+ if (closest == NULL)
+ deleted = true;
+ else {
+ WT_ERR(closest->get_key(closest, &cursor->key));
+ WT_ERR(closest->get_value(closest, &cursor->value));
+ curtiered->current = closest;
+ closest = NULL;
+ deleted = __curtiered_deleted(curtiered, &cursor->value);
+ if (!deleted)
+ __curtiered_deleted_decode(curtiered, &cursor->value);
+ else {
+ /*
+ * We have a key pointing at memory that is pinned by the current chunk cursor. In the
+ * unlikely event that we have to reopen cursors to move to the next record, make sure
+ * the cursor flags are set so a copy is made before the current chunk cursor releases
+ * its position.
+ */
+ F_CLR(cursor, WT_CURSTD_KEY_SET);
+ F_SET(cursor, WT_CURSTD_KEY_INT);
+ /*
+ * We call __curtiered_next here as we want to advance forward. If we are a random LSM
+ * cursor calling next on the cursor will not advance as we intend.
+ */
+ if ((ret = __curtiered_next(cursor)) == 0) {
+ cmp = 1;
+ deleted = false;
+ }
+ }
+ WT_ERR_NOTFOUND_OK(ret, false);
+ }
+ if (deleted) {
+ curtiered->current = NULL;
+ /*
+ * We call prev directly here as cursor->prev may be "invalid" if this is a random cursor.
+ */
+ WT_ERR(__curtiered_prev(cursor));
+ cmp = -1;
+ }
+ *exactp = cmp;
+
+err:
+ __curtiered_leave(curtiered);
+ if (closest != NULL)
+ WT_TRET(closest->reset(closest));
+
+ F_CLR(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET);
+ if (ret == 0) {
+ F_SET(cursor, WT_CURSTD_KEY_INT | WT_CURSTD_VALUE_INT);
+ } else
+ curtiered->current = NULL;
+
+ API_END_RET(session, ret);
+}
+
+/*
+ * __curtiered_put --
+ * Put an entry into the primary tree.
+ */
+static inline int
+__curtiered_put(WT_CURSOR_TIERED *curtiered, const WT_ITEM *key, const WT_ITEM *value,
+ bool position, bool reserve)
+{
+ WT_CURSOR *primary;
+ WT_TIERED *tiered;
+
+ tiered = curtiered->tiered;
+
+ /*
+ * Clear the existing cursor position. Don't clear the primary cursor: we're about to use it
+ * anyway.
+ */
+ primary = curtiered->cursors[tiered->ntiers - 1];
+ WT_RET(__curtiered_reset_cursors(curtiered, primary));
+
+ /* If necessary, set the position for future scans. */
+ if (position)
+ curtiered->current = primary;
+
+ primary->set_key(primary, key);
+ if (reserve) {
+ WT_RET(primary->reserve(primary));
+ } else {
+ primary->set_value(primary, value);
+ WT_RET(primary->insert(primary));
+ }
+
+ return (0);
+}
+
+/*
+ * __curtiered_insert --
+ * WT_CURSOR->insert method for the LSM cursor type.
+ */
+static int
+__curtiered_insert(WT_CURSOR *cursor)
+{
+ WT_CURSOR_TIERED *curtiered;
+ WT_DECL_ITEM(buf);
+ WT_DECL_RET;
+ WT_ITEM value;
+ WT_SESSION_IMPL *session;
+
+ curtiered = (WT_CURSOR_TIERED *)cursor;
+
+ CURSOR_UPDATE_API_CALL(cursor, session, insert);
+ WT_ERR(__cursor_needkey(cursor));
+ WT_ERR(__cursor_needvalue(cursor));
+ WT_ERR(__curtiered_enter(curtiered, false));
+
+ /*
+ * It isn't necessary to copy the key out after the lookup in this case because any non-failed
+ * lookup results in an error, and a failed lookup leaves the original key intact.
+ */
+ if (!F_ISSET(cursor, WT_CURSTD_OVERWRITE) &&
+ (ret = __curtiered_lookup(curtiered, &value)) != WT_NOTFOUND) {
+ if (ret == 0)
+ ret = WT_DUPLICATE_KEY;
+ goto err;
+ }
+
+ WT_ERR(__curtiered_deleted_encode(session, &cursor->value, &value, &buf));
+ WT_ERR(__curtiered_put(curtiered, &cursor->key, &value, false, false));
+
+ /*
+ * WT_CURSOR.insert doesn't leave the cursor positioned, and the application may want to free
+ * the memory used to configure the insert; don't read that memory again (matching the
+ * underlying file object cursor insert semantics).
+ */
+ F_CLR(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET);
+
+err:
+ __wt_scr_free(session, &buf);
+ __curtiered_leave(curtiered);
+ CURSOR_UPDATE_API_END(session, ret);
+ return (ret);
+}
+
+/*
+ * __curtiered_update --
+ * WT_CURSOR->update method for the LSM cursor type.
+ */
+static int
+__curtiered_update(WT_CURSOR *cursor)
+{
+ WT_CURSOR_TIERED *curtiered;
+ WT_DECL_ITEM(buf);
+ WT_DECL_RET;
+ WT_ITEM value;
+ WT_SESSION_IMPL *session;
+
+ curtiered = (WT_CURSOR_TIERED *)cursor;
+
+ CURSOR_UPDATE_API_CALL(cursor, session, update);
+ WT_ERR(__cursor_needkey(cursor));
+ WT_ERR(__cursor_needvalue(cursor));
+ WT_ERR(__curtiered_enter(curtiered, false));
+
+ if (!F_ISSET(cursor, WT_CURSTD_OVERWRITE)) {
+ WT_ERR(__curtiered_lookup(curtiered, &value));
+ /*
+ * Copy the key out, since the insert resets non-primary chunk cursors which our lookup may
+ * have landed on.
+ */
+ WT_ERR(__cursor_needkey(cursor));
+ }
+ WT_ERR(__curtiered_deleted_encode(session, &cursor->value, &value, &buf));
+ WT_ERR(__curtiered_put(curtiered, &cursor->key, &value, true, false));
+
+ /*
+ * Set the cursor to reference the internal key/value of the positioned cursor.
+ */
+ F_CLR(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET);
+ WT_ITEM_SET(cursor->key, curtiered->current->key);
+ WT_ITEM_SET(cursor->value, curtiered->current->value);
+ WT_ASSERT(session, F_MASK(curtiered->current, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_INT);
+ WT_ASSERT(session, F_MASK(curtiered->current, WT_CURSTD_VALUE_SET) == WT_CURSTD_VALUE_INT);
+ F_SET(cursor, WT_CURSTD_KEY_INT | WT_CURSTD_VALUE_INT);
+
+err:
+ __wt_scr_free(session, &buf);
+ __curtiered_leave(curtiered);
+ CURSOR_UPDATE_API_END(session, ret);
+ return (ret);
+}
+
+/*
+ * __curtiered_remove --
+ * WT_CURSOR->remove method for the LSM cursor type.
+ */
+static int
+__curtiered_remove(WT_CURSOR *cursor)
+{
+ WT_CURSOR_TIERED *curtiered;
+ WT_DECL_RET;
+ WT_ITEM value;
+ WT_SESSION_IMPL *session;
+ bool positioned;
+
+ curtiered = (WT_CURSOR_TIERED *)cursor;
+
+ /* Check if the cursor is positioned. */
+ positioned = F_ISSET(cursor, WT_CURSTD_KEY_INT);
+
+ CURSOR_REMOVE_API_CALL(cursor, session, NULL);
+ WT_ERR(__cursor_needkey(cursor));
+ __cursor_novalue(cursor);
+ WT_ERR(__curtiered_enter(curtiered, false));
+
+ if (!F_ISSET(cursor, WT_CURSTD_OVERWRITE)) {
+ WT_ERR(__curtiered_lookup(curtiered, &value));
+ /*
+ * Copy the key out, since the insert resets non-primary chunk cursors which our lookup may
+ * have landed on.
+ */
+ WT_ERR(__cursor_needkey(cursor));
+ }
+ WT_ERR(__curtiered_put(curtiered, &cursor->key, &__tombstone, positioned, false));
+
+ /*
+ * If the cursor was positioned, it stays positioned with a key but no no value, otherwise,
+ * there's no position, key or value. This isn't just cosmetic, without a reset, iteration on
+ * this cursor won't start at the beginning/end of the table.
+ */
+ F_CLR(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET);
+ if (positioned)
+ F_SET(cursor, WT_CURSTD_KEY_INT);
+ else
+ WT_TRET(cursor->reset(cursor));
+
+err:
+ __curtiered_leave(curtiered);
+ CURSOR_UPDATE_API_END(session, ret);
+ return (ret);
+}
+
+/*
+ * __curtiered_reserve --
+ * WT_CURSOR->reserve method for the LSM cursor type.
+ */
+static int
+__curtiered_reserve(WT_CURSOR *cursor)
+{
+ WT_CURSOR_TIERED *curtiered;
+ WT_DECL_RET;
+ WT_ITEM value;
+ WT_SESSION_IMPL *session;
+
+ curtiered = (WT_CURSOR_TIERED *)cursor;
+
+ CURSOR_UPDATE_API_CALL(cursor, session, reserve);
+ WT_ERR(__cursor_needkey(cursor));
+ __cursor_novalue(cursor);
+ WT_ERR(__wt_txn_context_check(session, true));
+ WT_ERR(__curtiered_enter(curtiered, false));
+
+ WT_ERR(__curtiered_lookup(curtiered, &value));
+ /*
+ * Copy the key out, since the insert resets non-primary chunk cursors which our lookup may have
+ * landed on.
+ */
+ WT_ERR(__cursor_needkey(cursor));
+ ret = __curtiered_put(curtiered, &cursor->key, NULL, true, true);
+
+err:
+ __curtiered_leave(curtiered);
+ CURSOR_UPDATE_API_END(session, ret);
+
+ /*
+ * The application might do a WT_CURSOR.get_value call when we return, so we need a value and
+ * the underlying functions didn't set one up. For various reasons, those functions may not have
+ * done a search and any previous value in the cursor might race with WT_CURSOR.reserve (and in
+ * cases like LSM, the reserve never encountered the original key). For simplicity, repeat the
+ * search here.
+ */
+ return (ret == 0 ? cursor->search(cursor) : ret);
+}
+
+/*
+ * __curtiered_random_chunk --
+ * Pick a chunk at random, weighted by the size of all chunks. Weighting proportional to
+ * documents avoids biasing towards small chunks. Then return the cursor on the chunk we have
+ * picked.
+ */
+static int
+__curtiered_random_chunk(WT_SESSION_IMPL *session, WT_CURSOR_TIERED *curtiered, WT_CURSOR **cursor)
+{
+ u_int i, ntiers;
+
+ /*
+ * If the tree is empty we cannot do a random lookup, so return a WT_NOTFOUND.
+ */
+ if ((ntiers = curtiered->tiered->ntiers) == 0)
+ return (WT_NOTFOUND);
+
+ /* TODO: make randomness respect tree size. */
+ i = __wt_random(&session->rnd) % ntiers;
+ *cursor = curtiered->cursors[i];
+ return (0);
+}
+
+/*
+ * __curtiered_next_random --
+ * WT_CURSOR->next method for the LSM cursor type when configured with next_random.
+ */
+static int
+__curtiered_next_random(WT_CURSOR *cursor)
+{
+ WT_CURSOR *c;
+ WT_CURSOR_TIERED *curtiered;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+ int exact;
+
+ c = NULL;
+ curtiered = (WT_CURSOR_TIERED *)cursor;
+
+ CURSOR_API_CALL(cursor, session, next, NULL);
+ __cursor_novalue(cursor);
+ WT_ERR(__curtiered_enter(curtiered, false));
+
+ for (;;) {
+ WT_ERR(__curtiered_random_chunk(session, curtiered, &c));
+ /*
+ * This call to next_random on the chunk can potentially end in WT_NOTFOUND if the chunk we
+ * picked is empty. We want to retry in that case.
+ */
+ WT_ERR_NOTFOUND_OK(__wt_curfile_next_random(c), true);
+ if (ret == WT_NOTFOUND)
+ continue;
+
+ F_SET(cursor, WT_CURSTD_KEY_INT);
+ WT_ERR(c->get_key(c, &cursor->key));
+ /*
+ * Search near the current key to resolve any tombstones and position to a valid document.
+ * If we see a WT_NOTFOUND here that is valid, as the tree has no documents visible to us.
+ */
+ WT_ERR(__curtiered_search_near(cursor, &exact));
+ break;
+ }
+
+ /* We have found a valid doc. Set that we are now positioned */
+ if (0) {
+err:
+ F_CLR(cursor, WT_CURSTD_KEY_INT | WT_CURSTD_VALUE_INT);
+ }
+ __curtiered_leave(curtiered);
+ API_END_RET(session, ret);
+}
+
+/*
+ * __wt_curtiered_open --
+ * WT_SESSION->open_cursor method for LSM cursors.
+ */
+int
+__wt_curtiered_open(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[],
+ WT_CURSOR **cursorp)
+{
+ WT_CONFIG_ITEM cval;
+ WT_CURSOR_STATIC_INIT(iface, __wt_cursor_get_key, /* get-key */
+ __wt_cursor_get_value, /* get-value */
+ __wt_cursor_set_key, /* set-key */
+ __wt_cursor_set_value, /* set-value */
+ __curtiered_compare, /* compare */
+ __wt_cursor_equals, /* equals */
+ __curtiered_next, /* next */
+ __curtiered_prev, /* prev */
+ __curtiered_reset, /* reset */
+ __curtiered_search, /* search */
+ __curtiered_search_near, /* search-near */
+ __curtiered_insert, /* insert */
+ __wt_cursor_modify_value_format_notsup, /* modify */
+ __curtiered_update, /* update */
+ __curtiered_remove, /* remove */
+ __curtiered_reserve, /* reserve */
+ __wt_cursor_reconfigure, /* reconfigure */
+ __wt_cursor_notsup, /* cache */
+ __wt_cursor_reopen_notsup, /* reopen */
+ __wt_curtiered_close); /* close */
+ WT_CURSOR *cursor;
+ WT_CURSOR_TIERED *curtiered;
+ WT_DECL_RET;
+ WT_TIERED *tiered;
+ bool bulk;
+
+ WT_STATIC_ASSERT(offsetof(WT_CURSOR_TIERED, iface) == 0);
+
+ curtiered = NULL;
+ cursor = NULL;
+ tiered = NULL;
+
+ if (!WT_PREFIX_MATCH(uri, "tiered:"))
+ return (__wt_unexpected_object_type(session, uri, "tiered:"));
+
+ WT_RET(__wt_config_gets_def(session, cfg, "checkpoint", 0, &cval));
+ if (cval.len != 0)
+ WT_RET_MSG(session, EINVAL, "LSM does not support opening by checkpoint");
+
+ WT_RET(__wt_config_gets_def(session, cfg, "bulk", 0, &cval));
+ bulk = cval.val != 0;
+
+ /* Get the tiered data handle. */
+ ret = __wt_session_get_dhandle(session, uri, NULL, cfg, bulk ? WT_DHANDLE_EXCLUSIVE : 0);
+
+ /* Check whether the exclusive open for a bulk load succeeded. */
+ if (bulk && ret == EBUSY)
+ WT_ERR_MSG(session, EINVAL, "bulk-load is only supported on newly created trees");
+ /* Flag any errors from the tree get. */
+ WT_ERR(ret);
+
+ tiered = (WT_TIERED *)session->dhandle;
+
+ /* Make sure we have exclusive access if and only if we want it */
+ WT_ASSERT(session, !bulk || tiered->iface.excl_session != NULL);
+
+ WT_ERR(__wt_calloc_one(session, &curtiered));
+ cursor = (WT_CURSOR *)curtiered;
+ *cursor = iface;
+ cursor->session = (WT_SESSION *)session;
+ WT_ERR(__wt_strdup(session, tiered->name, &cursor->uri));
+ cursor->key_format = tiered->key_format;
+ cursor->value_format = tiered->value_format;
+
+ curtiered->tiered = tiered;
+ tiered = NULL;
+
+ /* If the next_random option is set, configure a random cursor */
+ WT_ERR(__wt_config_gets_def(session, cfg, "next_random", 0, &cval));
+ if (cval.val != 0) {
+ __wt_cursor_set_notsup(cursor);
+ cursor->next = __curtiered_next_random;
+ }
+
+ WT_ERR(__wt_cursor_init(cursor, cursor->uri, owner, cfg, cursorp));
+
+ if (bulk)
+ WT_ERR(ENOTSUP); /* TODO */
+
+ if (0) {
+err:
+ if (curtiered != NULL)
+ WT_TRET(__wt_curtiered_close(cursor));
+ else if (tiered != NULL)
+ WT_WITH_DHANDLE(
+ session, (WT_DATA_HANDLE *)tiered, WT_TRET(__wt_session_release_dhandle(session)));
+
+ *cursorp = NULL;
+ }
+
+ return (ret);
+}
diff --git a/src/third_party/wiredtiger/src/tiered/tiered_schema.c b/src/third_party/wiredtiger/src/tiered/tiered_schema.c
new file mode 100644
index 00000000000..dc153b31e43
--- /dev/null
+++ b/src/third_party/wiredtiger/src/tiered/tiered_schema.c
@@ -0,0 +1,255 @@
+/*-
+ * Copyright (c) 2014-2020 MongoDB, Inc.
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_tiered_create --
+ * Create a tiered tree structure for the given name.
+ */
+int
+__wt_tiered_create(WT_SESSION_IMPL *session, const char *uri, bool exclusive, const char *config)
+{
+ WT_DECL_RET;
+ char *meta_value;
+ const char *cfg[] = {WT_CONFIG_BASE(session, tiered_meta), config, NULL};
+ const char *metadata;
+
+ metadata = NULL;
+
+ /* If it can be opened, it already exists. */
+ if ((ret = __wt_metadata_search(session, uri, &meta_value)) != WT_NOTFOUND) {
+ if (exclusive)
+ WT_TRET(EEXIST);
+ goto err;
+ }
+ WT_RET_NOTFOUND_OK(ret);
+
+ if (!F_ISSET(S2C(session), WT_CONN_READONLY)) {
+ WT_ERR(__wt_config_merge(session, cfg, NULL, &metadata));
+ WT_ERR(__wt_metadata_insert(session, uri, metadata));
+ }
+
+err:
+ __wt_free(session, metadata);
+ return (ret);
+}
+
+/*
+ * __wt_tiered_drop --
+ * Drop a tiered store.
+ */
+int
+__wt_tiered_drop(WT_SESSION_IMPL *session, const char *uri, const char *cfg[])
+{
+ WT_DATA_HANDLE *tier;
+ WT_DECL_RET;
+ WT_TIERED *tiered;
+ u_int i;
+
+ /* Get the tiered data handle. */
+ WT_RET(__wt_session_get_dhandle(session, uri, NULL, NULL, WT_DHANDLE_EXCLUSIVE));
+ tiered = (WT_TIERED *)session->dhandle;
+
+ /* Drop the tiers. */
+ for (i = 0; i < tiered->ntiers; i++) {
+ tier = tiered->tiers[i];
+ WT_ERR(__wt_schema_drop(session, tier->name, cfg));
+ }
+
+ ret = __wt_metadata_remove(session, uri);
+
+err:
+ F_SET(session->dhandle, WT_DHANDLE_DISCARD);
+ WT_TRET(__wt_session_release_dhandle(session));
+ return (ret);
+}
+
+/*
+ * __wt_tiered_rename --
+ * Rename a tiered data source.
+ */
+int
+__wt_tiered_rename(
+ WT_SESSION_IMPL *session, const char *olduri, const char *newuri, const char *cfg[])
+{
+ WT_DECL_RET;
+ WT_TIERED *tiered;
+
+ /* Get the tiered data handle. */
+ WT_RET(__wt_session_get_dhandle(session, olduri, NULL, NULL, WT_DHANDLE_EXCLUSIVE));
+ tiered = (WT_TIERED *)session->dhandle;
+
+ /* TODO */
+ WT_UNUSED(olduri);
+ WT_UNUSED(newuri);
+ WT_UNUSED(cfg);
+ WT_UNUSED(tiered);
+
+ F_SET(session->dhandle, WT_DHANDLE_DISCARD);
+ WT_TRET(__wt_session_release_dhandle(session));
+
+ return (ret);
+}
+
+/*
+ * __wt_tiered_truncate --
+ * Truncate for a tiered data source.
+ */
+int
+__wt_tiered_truncate(WT_SESSION_IMPL *session, const char *uri, const char *cfg[])
+{
+ WT_DECL_RET;
+ WT_TIERED *tiered;
+ u_int i;
+
+ WT_RET(__wt_session_get_dhandle(session, uri, NULL, NULL, WT_DHANDLE_EXCLUSIVE));
+ tiered = (WT_TIERED *)session->dhandle;
+
+ WT_STAT_DATA_INCR(session, cursor_truncate);
+
+ /* Truncate the column groups. */
+ for (i = 0; i < tiered->ntiers; i++)
+ WT_ERR(__wt_schema_truncate(session, tiered->tiers[i]->name, cfg));
+
+err:
+ WT_TRET(__wt_session_release_dhandle(session));
+ return (ret);
+}
+
+/*
+ * __wt_tiered_worker --
+ * Run a schema worker operation on each tier of a tiered data source.
+ */
+int
+__wt_tiered_worker(WT_SESSION_IMPL *session, const char *uri,
+ int (*file_func)(WT_SESSION_IMPL *, const char *[]),
+ int (*name_func)(WT_SESSION_IMPL *, const char *, bool *), const char *cfg[], uint32_t open_flags)
+{
+ WT_DATA_HANDLE *dhandle;
+ WT_DECL_RET;
+ WT_TIERED *tiered;
+ u_int i;
+
+ /*
+ * If this was an alter operation, we need to alter the configuration for the overall tree and
+ * then reread it so it isn't out of date. TODO not yet supported.
+ */
+ if (FLD_ISSET(open_flags, WT_BTREE_ALTER))
+ WT_RET(ENOTSUP);
+
+ WT_RET(__wt_session_get_dhandle(session, uri, NULL, NULL, open_flags));
+ tiered = (WT_TIERED *)session->dhandle;
+
+ for (i = 0; i < tiered->ntiers; i++) {
+ dhandle = tiered->tiers[i];
+ WT_SAVE_DHANDLE(session,
+ ret = __wt_schema_worker(session, dhandle->name, file_func, name_func, cfg, open_flags));
+ WT_ERR(ret);
+ }
+
+err:
+ WT_TRET(__wt_session_release_dhandle(session));
+ return (ret);
+}
+
+/*
+ * __tiered_open --
+ * Open a tiered data handle (internal version).
+ */
+static int
+__tiered_open(WT_SESSION_IMPL *session, const char *cfg[])
+{
+ WT_CONFIG cparser;
+ WT_CONFIG_ITEM ckey, cval, tierconf;
+ WT_DATA_HANDLE *dhandle;
+ WT_DECL_ITEM(buf);
+ WT_DECL_RET;
+ WT_TIERED *tiered;
+ u_int i;
+ const char **tiered_cfg;
+
+ dhandle = session->dhandle;
+ tiered = (WT_TIERED *)dhandle;
+ tiered_cfg = dhandle->cfg;
+
+ WT_UNUSED(cfg);
+
+ WT_RET(__wt_config_gets(session, tiered_cfg, "key_format", &cval));
+ WT_RET(__wt_strndup(session, cval.str, cval.len, &tiered->key_format));
+ WT_RET(__wt_config_gets(session, tiered_cfg, "value_format", &cval));
+ WT_RET(__wt_strndup(session, cval.str, cval.len, &tiered->value_format));
+
+ /* Point to some items in the copy to save re-parsing. */
+ WT_RET(__wt_config_gets(session, tiered_cfg, "tiered.tiers", &tierconf));
+
+ /*
+ * Count the number of tiers.
+ */
+ __wt_config_subinit(session, &cparser, &tierconf);
+ while ((ret = __wt_config_next(&cparser, &ckey, &cval)) == 0)
+ ++tiered->ntiers;
+ WT_RET_NOTFOUND_OK(ret);
+
+ WT_RET(__wt_scr_alloc(session, 0, &buf));
+ WT_ERR(__wt_calloc_def(session, tiered->ntiers, &tiered->tiers));
+
+ __wt_config_subinit(session, &cparser, &tierconf);
+ for (i = 0; i < tiered->ntiers; i++) {
+ WT_ERR(__wt_config_next(&cparser, &ckey, &cval));
+ WT_ERR(__wt_buf_fmt(session, buf, "%.*s", (int)ckey.len, ckey.str));
+ WT_ERR(__wt_session_get_dhandle(session, (const char *)buf->data, NULL, cfg, 0));
+ __wt_atomic_addi32(&session->dhandle->session_inuse, 1);
+ /* Load in reverse order (based on LSM logic). */
+ tiered->tiers[(tiered->ntiers - 1) - i] = session->dhandle;
+ WT_ERR(__wt_session_release_dhandle(session));
+ }
+
+ if (0) {
+err:
+ __wt_free(session, tiered->tiers);
+ }
+ __wt_scr_free(session, &buf);
+ return (ret);
+}
+
+/*
+ * __wt_tiered_open --
+ * Open a tiered data handle.
+ */
+int
+__wt_tiered_open(WT_SESSION_IMPL *session, const char *cfg[])
+{
+ WT_DECL_RET;
+
+ WT_WITH_TXN_ISOLATION(session, WT_ISO_READ_UNCOMMITTED, ret = __tiered_open(session, cfg));
+
+ return (ret);
+}
+
+/*
+ * __wt_tiered_close --
+ * Close a tiered data handle.
+ */
+int
+__wt_tiered_close(WT_SESSION_IMPL *session, WT_TIERED *tiered)
+{
+ WT_DECL_RET;
+ u_int i;
+
+ ret = 0;
+ __wt_free(session, tiered->key_format);
+ __wt_free(session, tiered->value_format);
+ if (tiered->tiers != NULL) {
+ for (i = 0; i < tiered->ntiers; i++)
+ __wt_atomic_subi32(&tiered->tiers[i]->session_inuse, 1);
+ __wt_free(session, tiered->tiers);
+ }
+
+ return (ret);
+}
diff --git a/src/third_party/wiredtiger/src/txn/txn_log.c b/src/third_party/wiredtiger/src/txn/txn_log.c
index b335d4ca3cb..818f03314aa 100644
--- a/src/third_party/wiredtiger/src/txn/txn_log.c
+++ b/src/third_party/wiredtiger/src/txn/txn_log.c
@@ -730,8 +730,8 @@ __txn_printlog(WT_SESSION_IMPL *session, WT_ITEM *rawrec, WT_LSN *lsnp, WT_LSN *
* Print the log in a human-readable format.
*/
int
-__wt_txn_printlog(WT_SESSION *wt_session, const char *ofile, uint32_t flags)
- WT_GCC_FUNC_ATTRIBUTE((visibility("default")))
+__wt_txn_printlog(WT_SESSION *wt_session, const char *ofile, uint32_t flags, WT_LSN *start_lsn,
+ WT_LSN *end_lsn) WT_GCC_FUNC_ATTRIBUTE((visibility("default")))
{
WT_DECL_RET;
WT_FSTREAM *fs;
@@ -749,7 +749,7 @@ __wt_txn_printlog(WT_SESSION *wt_session, const char *ofile, uint32_t flags)
WT_ERR(__wt_fprintf(session, fs, "[\n"));
args.fs = fs;
args.flags = flags;
- WT_ERR(__wt_log_scan(session, NULL, WT_LOGSCAN_FIRST, __txn_printlog, &args));
+ WT_ERR(__wt_log_scan(session, start_lsn, end_lsn, 0x0, __txn_printlog, &args));
if (!LF_ISSET(WT_TXN_PRINTLOG_MSG))
ret = __wt_fprintf(session, fs, "\n]\n");
diff --git a/src/third_party/wiredtiger/src/txn/txn_recover.c b/src/third_party/wiredtiger/src/txn/txn_recover.c
index 26154f2d776..e81451a96b3 100644
--- a/src/third_party/wiredtiger/src/txn/txn_recover.c
+++ b/src/third_party/wiredtiger/src/txn/txn_recover.c
@@ -817,15 +817,15 @@ __wt_txn_recover(WT_SESSION_IMPL *session, const char *cfg[])
WT_ERR_MSG(session, WT_RUN_RECOVERY, "Read-only database needs recovery");
}
if (WT_IS_INIT_LSN(&metafile->ckpt_lsn))
- ret = __wt_log_scan(session, NULL, WT_LOGSCAN_FIRST, __txn_log_recover, &r);
+ ret = __wt_log_scan(session, NULL, NULL, WT_LOGSCAN_FIRST, __txn_log_recover, &r);
else {
/*
* Start at the last checkpoint LSN referenced in the metadata. If we see the end of a
* checkpoint while scanning, we will change the full scan to start from there.
*/
WT_ASSIGN_LSN(&r.ckpt_lsn, &metafile->ckpt_lsn);
- ret = __wt_log_scan(
- session, &metafile->ckpt_lsn, WT_LOGSCAN_RECOVER_METADATA, __txn_log_recover, &r);
+ ret = __wt_log_scan(session, &metafile->ckpt_lsn, NULL, WT_LOGSCAN_RECOVER_METADATA,
+ __txn_log_recover, &r);
}
if (F_ISSET(conn, WT_CONN_SALVAGE))
ret = 0;
@@ -917,9 +917,9 @@ __wt_txn_recover(WT_SESSION_IMPL *session, const char *cfg[])
FLD_SET(conn->log_flags, WT_CONN_LOG_RECOVER_DIRTY);
if (WT_IS_INIT_LSN(&r.ckpt_lsn))
ret = __wt_log_scan(
- session, NULL, WT_LOGSCAN_FIRST | WT_LOGSCAN_RECOVER, __txn_log_recover, &r);
+ session, NULL, NULL, WT_LOGSCAN_FIRST | WT_LOGSCAN_RECOVER, __txn_log_recover, &r);
else
- ret = __wt_log_scan(session, &r.ckpt_lsn, WT_LOGSCAN_RECOVER, __txn_log_recover, &r);
+ ret = __wt_log_scan(session, &r.ckpt_lsn, NULL, WT_LOGSCAN_RECOVER, __txn_log_recover, &r);
if (F_ISSET(conn, WT_CONN_SALVAGE))
ret = 0;
WT_ERR(ret);
diff --git a/src/third_party/wiredtiger/src/utilities/util_list.c b/src/third_party/wiredtiger/src/utilities/util_list.c
index ab2e6ad1299..13a3577745f 100644
--- a/src/third_party/wiredtiger/src/utilities/util_list.c
+++ b/src/third_party/wiredtiger/src/utilities/util_list.c
@@ -8,7 +8,7 @@
#include "util.h"
-static int list_get_allocsize(WT_SESSION *, const char *, size_t *);
+static int list_init_block(WT_SESSION *, const char *, WT_BLOCK *);
static int list_print(WT_SESSION *, const char *, bool, bool);
static int list_print_checkpoint(WT_SESSION *, const char *);
@@ -67,20 +67,20 @@ util_list(WT_SESSION *session, int argc, char *argv[])
}
/*
- * list_get_allocsize --
- * Get the allocation size for this file from the metadata.
+ * list_init_block --
+ * Initialize a dummy block structure for a file.
*/
static int
-list_get_allocsize(WT_SESSION *session, const char *key, size_t *allocsize)
+list_init_block(WT_SESSION *session, const char *key, WT_BLOCK *block)
{
- WT_CONFIG_ITEM szvalue;
+ WT_CONFIG_ITEM cval;
WT_CONFIG_PARSER *parser;
WT_DECL_RET;
WT_EXTENSION_API *wt_api;
int tret;
char *config;
- *allocsize = 0;
+ WT_CLEAR(*block);
parser = NULL;
config = NULL;
@@ -90,10 +90,14 @@ list_get_allocsize(WT_SESSION *session, const char *key, size_t *allocsize)
WT_ERR(util_err(session, ret, "%s: WT_EXTENSION_API.metadata_search", key));
if ((ret = wt_api->config_parser_open(wt_api, session, config, strlen(config), &parser)) != 0)
WT_ERR(util_err(session, ret, "WT_EXTENSION_API.config_parser_open"));
- if ((ret = parser->get(parser, "allocation_size", &szvalue)) == 0)
- *allocsize = (size_t)szvalue.val;
- else
- ret = ret == WT_NOTFOUND ? 0 : util_err(session, ret, "WT_CONFIG_PARSER.get");
+ if ((ret = parser->get(parser, "allocation_size", &cval)) == 0)
+ block->allocsize = (uint32_t)cval.val;
+ else if (ret != WT_NOTFOUND)
+ WT_ERR(util_err(session, ret, "WT_CONFIG_PARSER.get"));
+
+ if ((ret = parser->get(parser, "block_allocation", &cval)) == 0)
+ block->log_structured = WT_STRING_MATCH("log_structured", cval.str, cval.len);
+
err:
if (parser != NULL && (tret = parser->close(parser)) != 0) {
tret = util_err(session, tret, "WT_CONFIG_PARSER.close");
@@ -202,10 +206,11 @@ list_print_size(uint64_t v)
static int
list_print_checkpoint(WT_SESSION *session, const char *key)
{
+ WT_BLOCK _block, *block;
WT_BLOCK_CKPT ci;
WT_CKPT *ckpt, *ckptbase;
WT_DECL_RET;
- size_t allocsize, len;
+ size_t len;
time_t t;
/*
@@ -217,7 +222,9 @@ list_print_checkpoint(WT_SESSION *session, const char *key)
return (ret == WT_NOTFOUND ? 0 : ret);
/* We need the allocation size for decoding the checkpoint addr */
- if ((ret = list_get_allocsize(session, key, &allocsize)) != 0)
+ /* TODO this is a kludge: fix */
+ block = &_block;
+ if ((ret = list_init_block(session, key, block)) != 0)
return (ret);
/* Find the longest name, so we can pretty-print. */
@@ -245,7 +252,7 @@ list_print_checkpoint(WT_SESSION *session, const char *key)
/* Decode the checkpoint block. */
if (ckpt->raw.data == NULL)
continue;
- if ((ret = __wt_block_ckpt_decode(session, allocsize, ckpt->raw.data, &ci)) == 0) {
+ if ((ret = __wt_block_ckpt_decode(session, block, ckpt->raw.data, &ci)) == 0) {
printf(
"\t\t"
"file-size: ");
diff --git a/src/third_party/wiredtiger/src/utilities/util_load.c b/src/third_party/wiredtiger/src/utilities/util_load.c
index 3aeb00c2e8b..0e9bd922eeb 100644
--- a/src/third_party/wiredtiger/src/utilities/util_load.c
+++ b/src/third_party/wiredtiger/src/utilities/util_load.c
@@ -341,7 +341,8 @@ config_reorder(WT_SESSION *session, char **list)
* information.
*/
if ((list[0] == NULL || list[1] == NULL || list[2] != NULL) ||
- (WT_PREFIX_MATCH(list[0], "file:") && WT_PREFIX_MATCH(list[0], "lsm:")))
+ (!WT_PREFIX_MATCH(list[0], "file:") && !WT_PREFIX_MATCH(list[0], "lsm:") &&
+ !WT_PREFIX_MATCH(list[0], "tiered:")))
return (format(session));
entry = list;
@@ -383,7 +384,7 @@ config_update(WT_SESSION *session, char **list)
for (listp = list; *listp != NULL; listp += 2)
if (WT_PREFIX_MATCH(*listp, "colgroup:") || WT_PREFIX_MATCH(*listp, "file:") ||
WT_PREFIX_MATCH(*listp, "index:") || WT_PREFIX_MATCH(*listp, "lsm:") ||
- WT_PREFIX_MATCH(*listp, "table:"))
+ WT_PREFIX_MATCH(*listp, "table:") || WT_PREFIX_MATCH(*listp, "tiered:"))
if (config_rename(session, listp, cmdname))
return (1);
diff --git a/src/third_party/wiredtiger/src/utilities/util_printlog.c b/src/third_party/wiredtiger/src/utilities/util_printlog.c
index 9d09470bbd9..615f11768ab 100644
--- a/src/third_party/wiredtiger/src/utilities/util_printlog.c
+++ b/src/third_party/wiredtiger/src/utilities/util_printlog.c
@@ -12,9 +12,15 @@ static int
usage(void)
{
static const char *options[] = {"-f", "output to the specified file", "-x",
- "display key and value items in hexadecimal format", NULL, NULL};
+ "display key and value items in hexadecimal format", "-l",
+ "the start LSN from which the log will be printed, optionally the end LSN can also be "
+ "specified",
+ NULL, NULL};
- util_usage("printlog [-x] [-f output-file]", "options:", options);
+ util_usage(
+ "printlog [-x] [-f output-file] [-l start-file,start-offset]|[-l "
+ "start-file,start-offset,end-file,end-offset]",
+ "options:", options);
return (1);
}
@@ -22,17 +28,37 @@ int
util_printlog(WT_SESSION *session, int argc, char *argv[])
{
WT_DECL_RET;
+ WT_LSN end_lsn, start_lsn;
+ uint32_t end_lsnfile, end_lsnoffset, start_lsnfile, start_lsnoffset;
uint32_t flags;
int ch;
- char *ofile;
+ int n_args;
+ char *ofile, *start_str;
+ bool end_set, start_set;
+ end_set = start_set = false;
flags = 0;
ofile = NULL;
- while ((ch = __wt_getopt(progname, argc, argv, "f:mx")) != EOF)
+
+ while ((ch = __wt_getopt(progname, argc, argv, "f:l:mx")) != EOF)
switch (ch) {
case 'f': /* output file */
ofile = __wt_optarg;
break;
+ case 'l':
+ start_str = __wt_optarg;
+ n_args = sscanf(start_str, "%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32,
+ &start_lsnfile, &start_lsnoffset, &end_lsnfile, &end_lsnoffset);
+ if (n_args == 2) {
+ WT_SET_LSN(&start_lsn, start_lsnfile, start_lsnoffset);
+ start_set = true;
+ } else if (n_args == 4) {
+ WT_SET_LSN(&start_lsn, start_lsnfile, start_lsnoffset);
+ WT_SET_LSN(&end_lsn, end_lsnfile, end_lsnoffset);
+ end_set = start_set = true;
+ } else
+ return (usage());
+ break;
case 'm': /* messages only */
LF_SET(WT_TXN_PRINTLOG_MSG);
break;
@@ -49,7 +75,8 @@ util_printlog(WT_SESSION *session, int argc, char *argv[])
if (argc != 0)
return (usage());
- if ((ret = __wt_txn_printlog(session, ofile, flags)) != 0)
+ if ((ret = __wt_txn_printlog(session, ofile, flags, start_set == true ? &start_lsn : NULL,
+ end_set == true ? &end_lsn : NULL)) != 0)
(void)util_err(session, ret, "printlog");
return (ret);
diff --git a/src/third_party/wiredtiger/test/csuite/wt3363_checkpoint_op_races/main.c b/src/third_party/wiredtiger/test/csuite/wt3363_checkpoint_op_races/main.c
index baca92846bc..b45c573c25b 100644
--- a/src/third_party/wiredtiger/test/csuite/wt3363_checkpoint_op_races/main.c
+++ b/src/third_party/wiredtiger/test/csuite/wt3363_checkpoint_op_races/main.c
@@ -25,6 +25,13 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
+
+/*
+ * [TEST_TAGS]
+ * checkpoints:liveness:liveness
+ * [END_TAGS]
+ */
+
#include "test_util.h"
/*
diff --git a/src/third_party/wiredtiger/test/suite/suite_subprocess.py b/src/third_party/wiredtiger/test/suite/suite_subprocess.py
index d586f2a7997..a1bdeb24241 100755
--- a/src/third_party/wiredtiger/test/suite/suite_subprocess.py
+++ b/src/third_party/wiredtiger/test/suite/suite_subprocess.py
@@ -93,7 +93,9 @@ class suite_subprocess:
got = f.read(len(expect) + 100)
self.assertEqual(got, expect, filename + ': does not contain expected:\n\'' + expect + '\', but contains:\n\'' + got + '\'.')
- def check_file_contains_one_of(self, filename, expectlist):
+ # Check contents of the file against a provided checklist. Expected is used as a bool to either
+ # ensure checklist is included or ensure the checklist is not included in the file.
+ def check_file_contains_one_of(self, filename, checklist, expected):
"""
Check that the file contains the expected string in the first 100K bytes
"""
@@ -101,21 +103,27 @@ class suite_subprocess:
with open(filename, 'r') as f:
got = f.read(maxbytes)
found = False
- for expect in expectlist:
+ for expect in checklist:
pat = self.convert_to_pattern(expect)
if pat == None:
if expect in got:
found = True
- break
+ if expected:
+ break
+ else:
+ self.fail("Did not expect: " + got)
else:
if re.search(pat, got):
found = True
- break
- if not found:
- if len(expectlist) == 1:
- expect = '\'' + expectlist[0] + '\''
+ if expected:
+ break
+ else:
+ self.fail("Did not expect: " + got)
+ if not found and expected:
+ if len(checklist) == 1:
+ expect = '\'' + checklist[0] + '\''
else:
- expect = str(expectlist)
+ expect = str(checklist)
gotstr = '\'' + \
(got if len(got) < 1000 else (got[0:1000] + '...')) + '\''
if len(got) >= maxbytes:
@@ -123,8 +131,11 @@ class suite_subprocess:
else:
self.fail(filename + ': does not contain expected ' + expect + ', got ' + gotstr)
- def check_file_contains(self, filename, expect):
- self.check_file_contains_one_of(filename, [expect])
+ def check_file_contains(self, filename, content):
+ self.check_file_contains_one_of(filename, [content], True)
+
+ def check_file_not_contains(self, filename, content):
+ self.check_file_contains_one_of(filename, [content], False)
def check_empty_file(self, filename):
"""
diff --git a/src/third_party/wiredtiger/test/suite/test_backup01.py b/src/third_party/wiredtiger/test/suite/test_backup01.py
index f2745710545..65b6b3735f3 100644
--- a/src/third_party/wiredtiger/test/suite/test_backup01.py
+++ b/src/third_party/wiredtiger/test/suite/test_backup01.py
@@ -31,15 +31,15 @@ import os
import shutil
import string
import time
-from suite_subprocess import suite_subprocess
-import wiredtiger, wttest
+from wtbackup import backup_base
+import wiredtiger
from wtdataset import SimpleDataSet, ComplexDataSet, ComplexLSMDataSet
from helper import compare_files
# test_backup.py
# Utilities: wt backup
# Test backup (both backup cursors and the wt backup command).
-class test_backup(wttest.WiredTigerTestCase, suite_subprocess):
+class test_backup(backup_base):
dir='backup.dir' # Backup directory name
pfx = 'test_backup'
@@ -54,20 +54,6 @@ class test_backup(wttest.WiredTigerTestCase, suite_subprocess):
('table:' + pfx + '.8', ComplexLSMDataSet, 1),
]
- # Populate a set of objects.
- def populate(self, skiplsm):
- for i in self.objs:
- if i[2]:
- if skiplsm:
- continue
- i[1](self, i[0], 100).populate()
-
- # Compare the original and backed-up files using the wt dump command.
- def compare(self, uri):
- self.runWt(['dump', uri], outfilename='orig')
- self.runWt(['-h', self.dir, 'dump', uri], outfilename='backup')
- self.assertEqual(True, compare_files(self, 'orig', 'backup'))
-
# Test simple backup cursor open/close.
def test_cursor_simple(self):
cursor = self.session.open_cursor('backup:', None, None)
@@ -83,7 +69,7 @@ class test_backup(wttest.WiredTigerTestCase, suite_subprocess):
# Test backup of a database using the wt backup command.
def test_backup_database(self):
- self.populate(0)
+ self.populate(self.objs)
os.mkdir(self.dir)
self.runWt(['backup', self.dir])
@@ -95,20 +81,7 @@ class test_backup(wttest.WiredTigerTestCase, suite_subprocess):
# And that the contents are the same.
for i in self.objs:
- self.compare(i[0])
-
- # Check that a URI doesn't exist, both the meta-data and the file names.
- def confirmPathDoesNotExist(self, uri):
- conn = self.wiredtiger_open(self.dir)
- session = conn.open_session()
- self.assertRaises(wiredtiger.WiredTigerError,
- lambda: session.open_cursor(uri, None, None))
- conn.close()
-
- self.assertEqual(
- glob.glob(self.dir + '*' + uri.split(":")[1] + '*'), [],
- 'confirmPathDoesNotExist: URI exists, file name matching \"' +
- uri.split(":")[1] + '\" found')
+ self.compare_backups(i[0], self.dir, './')
# Backup a set of chosen tables/files using the wt backup command.
def backup_table(self, l):
@@ -127,16 +100,16 @@ class test_backup(wttest.WiredTigerTestCase, suite_subprocess):
# Confirm the objects we backed up exist, with correct contents.
for i in range(0, len(self.objs)):
if i in l:
- self.compare(self.objs[i][0])
+ self.compare_backups(self.objs[i][0], self.dir, './')
# Confirm the other objects don't exist.
for i in range(0, len(self.objs)):
if i not in l:
- self.confirmPathDoesNotExist(self.objs[i][0])
+ self.confirmPathDoesNotExist(self.objs[i][0], self.dir)
# Test backup of database subsets.
def test_backup_table(self):
- self.populate(0)
+ self.populate(self.objs)
self.backup_table([0,2,4,6])
self.backup_table([1,3,5,7])
self.backup_table([0,1,2])
@@ -145,7 +118,7 @@ class test_backup(wttest.WiredTigerTestCase, suite_subprocess):
# Test cursor reset runs through the list twice.
def test_cursor_reset(self):
- self.populate(0)
+ self.populate(self.objs)
cursor = self.session.open_cursor('backup:', None, None)
i = 0
while True:
@@ -167,7 +140,7 @@ class test_backup(wttest.WiredTigerTestCase, suite_subprocess):
# Test interaction between checkpoints and a backup cursor.
def test_checkpoint_delete(self):
# You cannot name checkpoints including LSM tables, skip those.
- self.populate(1)
+ self.populate(self.objs, False, True)
# Confirm checkpoints are being deleted.
self.session.checkpoint("name=one")
diff --git a/src/third_party/wiredtiger/test/suite/test_backup03.py b/src/third_party/wiredtiger/test/suite/test_backup03.py
index 9426e468264..6ea7a7f93c5 100644
--- a/src/third_party/wiredtiger/test/suite/test_backup03.py
+++ b/src/third_party/wiredtiger/test/suite/test_backup03.py
@@ -27,16 +27,15 @@
# OTHER DEALINGS IN THE SOFTWARE.
import glob, os, shutil, string
-import wiredtiger, wttest
-from helper import compare_files
-from suite_subprocess import suite_subprocess
+import wiredtiger
+from wtbackup import backup_base
from wtdataset import SimpleDataSet, ComplexDataSet, ComplexLSMDataSet
from wtscenario import make_scenarios
# test_backup03.py
# Utilities: wt backup
# Test cursor backup with target URIs
-class test_backup_target(wttest.WiredTigerTestCase, suite_subprocess):
+class test_backup_target(backup_base):
dir='backup.dir' # Backup directory name
# This test is written to test LSM hot backups: we test a simple LSM object
@@ -81,36 +80,6 @@ class test_backup_target(wttest.WiredTigerTestCase, suite_subprocess):
# Create a large cache, otherwise this test runs quite slowly.
conn_config = 'cache_size=1G'
- # Populate a set of objects.
- def populate(self):
- for i in self.objs:
- if self.big == i[2]:
- rows = 50000 # Big object
- else:
- rows = 1000 # Small object
- i[1](self, i[0], rows, cgconfig = i[3]).populate()
- # Backup needs a checkpoint
- self.session.checkpoint(None)
-
- # Compare the original and backed-up files using the wt dump command.
- def compare(self, uri):
- self.runWt(['dump', uri], outfilename='orig')
- self.runWt(['-h', self.dir, 'dump', uri], outfilename='backup')
- self.assertEqual(True, compare_files(self, 'orig', 'backup'))
-
- # Check that a URI doesn't exist, both the meta-data and the file names.
- def confirmPathDoesNotExist(self, uri):
- conn = self.wiredtiger_open(self.dir)
- session = conn.open_session()
- self.assertRaises(wiredtiger.WiredTigerError,
- lambda: session.open_cursor(uri, None, None))
- conn.close()
-
- self.assertEqual(
- glob.glob(self.dir + '*' + uri.split(":")[1] + '*'), [],
- 'confirmPathDoesNotExist: URI exists, file name matching \"' +
- uri.split(":")[1] + '\" found')
-
# Backup a set of target tables using a backup cursor.
def backup_table_cursor(self, l):
# Create the backup directory.
@@ -139,17 +108,18 @@ class test_backup_target(wttest.WiredTigerTestCase, suite_subprocess):
# Confirm the objects we backed up exist, with correct contents.
for i in range(0, len(self.objs)):
if not l or i in l:
- self.compare(self.objs[i][0])
+ self.compare_backups(self.objs[i][0], self.dir, './')
# Confirm the other objects don't exist.
if l:
for i in range(0, len(self.objs)):
if i not in l:
- self.confirmPathDoesNotExist(self.objs[i][0])
+ self.confirmPathDoesNotExist(self.objs[i][0], self.dir)
# Test backup with targets.
def test_backup_target(self):
- self.populate()
+ self.populate_big = self.big
+ self.populate(self.objs, True)
self.backup_table_cursor(self.list)
if __name__ == '__main__':
diff --git a/src/third_party/wiredtiger/test/suite/test_backup04.py b/src/third_party/wiredtiger/test/suite/test_backup04.py
index 5de3b1647fc..a378e5dbd63 100755
--- a/src/third_party/wiredtiger/test/suite/test_backup04.py
+++ b/src/third_party/wiredtiger/test/suite/test_backup04.py
@@ -26,10 +26,9 @@
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
-import threading, time, wiredtiger, wttest
+import threading, time, wiredtiger
import glob, os, shutil
-from helper import compare_files
-from suite_subprocess import suite_subprocess
+from wtbackup import backup_base
from wtdataset import SimpleDataSet, simple_key
from wtscenario import make_scenarios
from wtthread import op_thread
@@ -37,7 +36,7 @@ from wtthread import op_thread
# test_backup04.py
# Utilities: wt backup
# Test incremental cursor backup.
-class test_backup_target(wttest.WiredTigerTestCase, suite_subprocess):
+class test_backup_target(backup_base):
dir='backup.dir' # Backup directory name
logmax="100K"
@@ -63,7 +62,7 @@ class test_backup_target(wttest.WiredTigerTestCase, suite_subprocess):
return 'cache_size=1G,log=(archive=false,enabled,file_max=%s)' % \
self.logmax
- def populate(self, uri, dsize, rows):
+ def populate_with_string(self, uri, dsize, rows):
self.pr('populate: ' + uri + ' with ' + str(rows) + ' rows')
cursor = self.session.open_cursor(uri, None)
for i in range(1, rows + 1):
@@ -77,30 +76,6 @@ class test_backup_target(wttest.WiredTigerTestCase, suite_subprocess):
cursor[simple_key(cursor, i)] = str(i) + ':' + upd * dsize
cursor.close()
- # Compare the original and backed-up files using the wt dump command.
- def compare(self, uri, dir_full, dir_incr):
- # print "Compare: full URI: " + uri + " with incremental URI "
- if dir_full == None:
- full_name='original'
- else:
- full_name='backup_full'
- incr_name='backup_incr'
- if os.path.exists(full_name):
- os.remove(full_name)
- if os.path.exists(incr_name):
- os.remove(incr_name)
- #
- # We have been copying the logs only, so we need to force 'wt' to
- # run recovery in order to apply all the logs and check the data.
- #
- if dir_full == None:
- self.runWt(['-R', 'dump', uri], outfilename=full_name)
- else:
- self.runWt(['-R', '-h', dir_full, 'dump', uri], outfilename=full_name)
- self.runWt(['-R', '-h', dir_incr, 'dump', uri], outfilename=incr_name)
- self.assertEqual(True,
- compare_files(self, full_name, incr_name))
-
def take_full_backup(self, dir):
# Open up the backup cursor, and copy the files. Do a full backup.
cursor = self.session.open_cursor('backup:', None, None)
@@ -140,7 +115,7 @@ class test_backup_target(wttest.WiredTigerTestCase, suite_subprocess):
# Create the backup directory.
self.session.create(self.uri, "key_format=S,value_format=S")
- self.populate(self.uri, self.dsize, self.nops)
+ self.populate_with_string(self.uri, self.dsize, self.nops)
# We need to start the directory for the incremental backup with
# a full backup. The full backup function creates the directory.
@@ -157,7 +132,6 @@ class test_backup_target(wttest.WiredTigerTestCase, suite_subprocess):
# Close the backup cursor
updstr="bcdefghi"
for increment in range(0, 5):
- full_dir = self.dir + str(increment)
# Add more work to move the logs forward.
self.update(self.uri, self.dsize, updstr[increment], self.nops)
self.session.checkpoint(None)
@@ -167,9 +141,10 @@ class test_backup_target(wttest.WiredTigerTestCase, suite_subprocess):
# After running, take a full backup. Compare the incremental
# backup to the original database and the full backup database.
+ full_dir = self.dir + ".full"
self.take_full_backup(full_dir)
- self.compare(self.uri, full_dir, self.dir)
- self.compare(self.uri, None, self.dir)
+ self.compare_backups(self.uri, self.dir, full_dir)
+ self.compare_backups(self.uri, self.dir, './')
if __name__ == '__main__':
wttest.run()
diff --git a/src/third_party/wiredtiger/test/suite/test_backup06.py b/src/third_party/wiredtiger/test/suite/test_backup06.py
index 8ff3d7127a4..5821e5e9af6 100644
--- a/src/third_party/wiredtiger/test/suite/test_backup06.py
+++ b/src/third_party/wiredtiger/test/suite/test_backup06.py
@@ -26,11 +26,10 @@
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
-import glob
import os
import shutil
import string
-from suite_subprocess import suite_subprocess
+from wtbackup import backup_base
import wiredtiger, wttest
from wiredtiger import stat
from wtdataset import SimpleDataSet, ComplexDataSet, ComplexLSMDataSet
@@ -43,7 +42,7 @@ except:
# test_backup06.py
# Test that opening a backup cursor does not open file handles.
-class test_backup06(wttest.WiredTigerTestCase, suite_subprocess):
+class test_backup06(backup_base):
conn_config = 'statistics=(fast)'
# This will create several hundred tables.
num_table_sets = 10
@@ -78,12 +77,6 @@ class test_backup06(wttest.WiredTigerTestCase, suite_subprocess):
uri = i[0] + "." + str(t)
i[1](self, uri, 10).populate()
- def populate(self):
- for i in self.fobjs:
- i[1](self, i[0], 100).populate()
- for i in self.tobjs:
- i[1](self, i[0], 100).populate()
-
# Test that the open handle count does not change.
def test_cursor_open_handles(self):
if os.name == "nt":
@@ -130,7 +123,8 @@ class test_backup06(wttest.WiredTigerTestCase, suite_subprocess):
# We also want to make sure we detect and get an error when set to
# false. When set to true the open handles protect against schema
# operations.
- self.populate()
+ self.populate(self.fobjs)
+ self.populate(self.tobjs)
cursor = self.session.open_cursor('backup:', None, None)
# Check that we can create.
self.session.create(schema_uri, None)
@@ -148,7 +142,8 @@ class test_backup06(wttest.WiredTigerTestCase, suite_subprocess):
# Test cursor reset runs through the list twice.
def test_cursor_reset(self):
- self.populate()
+ self.populate(self.fobjs)
+ self.populate(self.tobjs)
cursor = self.session.open_cursor('backup:', None, None)
i = 0
while True:
diff --git a/src/third_party/wiredtiger/test/suite/test_backup07.py b/src/third_party/wiredtiger/test/suite/test_backup07.py
index 5a90ddbd8cf..360432690eb 100644
--- a/src/third_party/wiredtiger/test/suite/test_backup07.py
+++ b/src/third_party/wiredtiger/test/suite/test_backup07.py
@@ -29,21 +29,21 @@
import wiredtiger, wttest
import os, shutil
from helper import compare_files
-from suite_subprocess import suite_subprocess
+from wtbackup import backup_base
from wtdataset import simple_key
from wtscenario import make_scenarios
# test_backup07.py
# Test cursor backup with target URIs, logging and create during backup
-class test_backup07(wttest.WiredTigerTestCase, suite_subprocess):
+class test_backup07(backup_base):
dir='backup.dir' # Backup directory name
logmax="100K"
newuri="table:newtable"
pfx = 'test_backup'
scenarios = make_scenarios([
- ('table', dict(uri='table:test',dsize=100,nops=100,nthreads=1)),
+ ('table', dict(uri='table:test',dsize=100,nthreads=1))
])
# Create a large cache, otherwise this test runs quite slowly.
@@ -59,15 +59,8 @@ class test_backup07(wttest.WiredTigerTestCase, suite_subprocess):
# Insert small amounts of data at a time stopping just after we
# cross into log file 2.
- loop = 0
- c = self.session.open_cursor(self.uri)
while not os.path.exists(log2):
- for i in range(0, self.nops):
- num = i + (loop * self.nops)
- key = 'key' + str(num)
- val = 'value' + str(num)
- c[key] = val
- loop += 1
+ self.add_data(self.uri, 'key', 'value')
# Test a potential bug in full backups and creates.
# We allow creates during backup because the file doesn't exist
@@ -82,12 +75,7 @@ class test_backup07(wttest.WiredTigerTestCase, suite_subprocess):
# Now create and populate the new table. Make sure the log records
# are on disk and will be copied to the backup.
self.session.create(self.newuri, "key_format=S,value_format=S")
- c = self.session.open_cursor(self.newuri)
- for i in range(0, self.nops):
- key = 'key' + str(i)
- val = 'value' + str(i)
- c[key] = val
- c.close()
+ self.add_data(self.newuri, 'key', 'value')
self.session.log_flush('sync=on')
# Now copy the files returned by the backup cursor. This should not
diff --git a/src/third_party/wiredtiger/test/suite/test_backup10.py b/src/third_party/wiredtiger/test/suite/test_backup10.py
index 1d6304c1ba2..9a74e190b3f 100644
--- a/src/third_party/wiredtiger/test/suite/test_backup10.py
+++ b/src/third_party/wiredtiger/test/suite/test_backup10.py
@@ -29,17 +29,16 @@
import wiredtiger, wttest
import os, shutil
from helper import compare_files
-from suite_subprocess import suite_subprocess
+from wtbackup import backup_base
from wtdataset import simple_key
from wtscenario import make_scenarios
# test_backup10.py
# Test cursor backup with a duplicate backup cursor.
-class test_backup10(wttest.WiredTigerTestCase, suite_subprocess):
+class test_backup10(backup_base):
dir='backup.dir' # Backup directory name
logmax="100K"
uri="table:test"
- nops=100
pfx = 'test_backup'
@@ -62,15 +61,8 @@ class test_backup10(wttest.WiredTigerTestCase, suite_subprocess):
# Insert small amounts of data at a time stopping after we
# cross into log file 2.
- loop = 0
- c = self.session.open_cursor(self.uri)
while not os.path.exists(log2):
- for i in range(0, self.nops):
- num = i + (loop * self.nops)
- key = 'key' + str(num)
- val = 'value' + str(num)
- c[key] = val
- loop += 1
+ self.add_data(self.uri, 'key', 'value')
# Open up the backup cursor. This causes a new log file to be created.
# That log file is not part of the list returned.
@@ -78,13 +70,7 @@ class test_backup10(wttest.WiredTigerTestCase, suite_subprocess):
bkup_c = self.session.open_cursor('backup:', None, None)
# Add some data that will appear in log file 3.
- for i in range(0, self.nops):
- num = i + (loop * self.nops)
- key = 'key' + str(num)
- val = 'value' + str(num)
- c[key] = val
- loop += 1
- c.close()
+ self.add_data(self.uri, 'key', 'value')
self.session.log_flush('sync=on')
# Now copy the files returned by the backup cursor.
diff --git a/src/third_party/wiredtiger/test/suite/test_backup11.py b/src/third_party/wiredtiger/test/suite/test_backup11.py
index 3e6bd347b03..a974d505654 100644
--- a/src/third_party/wiredtiger/test/suite/test_backup11.py
+++ b/src/third_party/wiredtiger/test/suite/test_backup11.py
@@ -29,35 +29,21 @@
import wiredtiger, wttest
import os, shutil
from helper import compare_files
-from suite_subprocess import suite_subprocess
+from wtbackup import backup_base
from wtdataset import simple_key
from wtscenario import make_scenarios
# test_backup11.py
# Test cursor backup with a duplicate backup cursor.
-class test_backup11(wttest.WiredTigerTestCase, suite_subprocess):
+class test_backup11(backup_base):
conn_config= 'cache_size=1G,log=(enabled,file_max=100K)'
dir='backup.dir' # Backup directory name
- mult=0
- nops=100
pfx = 'test_backup'
uri="table:test"
- def add_data(self):
- c = self.session.open_cursor(self.uri)
- for i in range(0, self.nops):
- num = i + (self.mult * self.nops)
- key = 'key' + str(num)
- val = 'value' + str(num)
- c[key] = val
- self.mult += 1
- self.session.checkpoint()
- c.close()
-
def test_backup11(self):
self.session.create(self.uri, "key_format=S,value_format=S")
- self.add_data()
-
+ self.add_data(self.uri, 'key', 'value', True)
# Open up the backup cursor. This causes a new log file to be created.
# That log file is not part of the list returned. This is a full backup
# primary cursor with incremental configured.
@@ -66,7 +52,7 @@ class test_backup11(wttest.WiredTigerTestCase, suite_subprocess):
bkup_c = self.session.open_cursor('backup:', None, config)
# Add data while the backup cursor is open.
- self.add_data()
+ self.add_data(self.uri, 'key', 'value', True)
# Now copy the files returned by the backup cursor.
orig_logs = []
@@ -106,7 +92,7 @@ class test_backup11(wttest.WiredTigerTestCase, suite_subprocess):
bkup_c.close()
# Add more data
- self.add_data()
+ self.add_data(self.uri, 'key', 'value', True)
# Test error cases now.
diff --git a/src/third_party/wiredtiger/test/suite/test_backup12.py b/src/third_party/wiredtiger/test/suite/test_backup12.py
index 90ca31aa76e..53ad7845634 100644
--- a/src/third_party/wiredtiger/test/suite/test_backup12.py
+++ b/src/third_party/wiredtiger/test/suite/test_backup12.py
@@ -29,47 +29,34 @@
import wiredtiger, wttest
import os, shutil
from helper import compare_files
-from suite_subprocess import suite_subprocess
+from wtbackup import backup_base
from wtdataset import simple_key
from wtscenario import make_scenarios
# test_backup12.py
# Test cursor backup with a block-based incremental cursor.
-class test_backup12(wttest.WiredTigerTestCase, suite_subprocess):
+class test_backup12(backup_base):
conn_config='cache_size=1G,log=(enabled,file_max=100K)'
dir='backup.dir' # Backup directory name
logmax="100K"
uri="table:test"
uri2="table:test2"
uri_rem="table:test_rem"
- nops=1000
- mult=0
pfx = 'test_backup'
# Set the key and value big enough that we modify a few blocks.
bigkey = 'Key' * 100
bigval = 'Value' * 100
- def add_data(self, uri):
- c = self.session.open_cursor(uri)
- for i in range(0, self.nops):
- num = i + (self.mult * self.nops)
- key = self.bigkey + str(num)
- val = self.bigval + str(num)
- c[key] = val
- self.session.checkpoint()
- c.close()
- # Increase the multiplier so that later calls insert unique items.
- self.mult += 1
-
+ nops = 1000
def test_backup12(self):
self.session.create(self.uri, "key_format=S,value_format=S")
self.session.create(self.uri2, "key_format=S,value_format=S")
self.session.create(self.uri_rem, "key_format=S,value_format=S")
- self.add_data(self.uri)
- self.add_data(self.uri2)
- self.add_data(self.uri_rem)
+ self.add_data(self.uri, self.bigkey, self.bigval, True)
+ self.add_data(self.uri2, self.bigkey, self.bigval, True)
+ self.add_data(self.uri_rem, self.bigkey, self.bigval, True)
# Open up the backup cursor. This causes a new log file to be created.
# That log file is not part of the list returned. This is a full backup
@@ -82,7 +69,7 @@ class test_backup12(wttest.WiredTigerTestCase, suite_subprocess):
bkup_c = self.session.open_cursor('backup:', None, config)
# Add more data while the backup cursor is open.
- self.add_data(self.uri)
+ self.add_data(self.uri, self.bigkey, self.bigval, True)
# Now copy the files returned by the backup cursor.
all_files = []
@@ -122,8 +109,8 @@ class test_backup12(wttest.WiredTigerTestCase, suite_subprocess):
bkup_c.close()
# Add more data.
- self.add_data(self.uri)
- self.add_data(self.uri2)
+ self.add_data(self.uri, self.bigkey, self.bigval, True)
+ self.add_data(self.uri2, self.bigkey, self.bigval, True)
# Drop a table.
self.session.drop(self.uri_rem)
diff --git a/src/third_party/wiredtiger/test/suite/test_backup13.py b/src/third_party/wiredtiger/test/suite/test_backup13.py
index e77df8f5fcb..8992440c038 100644
--- a/src/third_party/wiredtiger/test/suite/test_backup13.py
+++ b/src/third_party/wiredtiger/test/suite/test_backup13.py
@@ -29,18 +29,16 @@
import wiredtiger, wttest
import os, shutil
from helper import compare_files
-from suite_subprocess import suite_subprocess
+from wtbackup import backup_base
from wtdataset import simple_key
from wtscenario import make_scenarios
# test_backup13.py
# Test cursor backup with a block-based incremental cursor and force_stop.
-class test_backup13(wttest.WiredTigerTestCase, suite_subprocess):
+class test_backup13(backup_base):
conn_config='cache_size=1G,log=(enabled,file_max=100K)'
dir='backup.dir' # Backup directory name
logmax="100K"
- mult=0
- nops=1000
uri="table:test"
scenarios = make_scenarios([
@@ -55,6 +53,8 @@ class test_backup13(wttest.WiredTigerTestCase, suite_subprocess):
bigkey = 'Key' * 100
bigval = 'Value' * 100
+ nops = 1000
+
def simulate_crash_restart(self, olddir, newdir):
''' Simulate a crash from olddir and restart in newdir. '''
# with the connection still open, copy files to new directory
@@ -73,33 +73,20 @@ class test_backup13(wttest.WiredTigerTestCase, suite_subprocess):
self.conn = self.setUpConnectionOpen(newdir)
self.session = self.setUpSessionOpen(self.conn)
- def add_data(self, uri):
- c = self.session.open_cursor(uri)
- for i in range(0, self.nops):
- num = i + (self.mult * self.nops)
- key = self.bigkey + str(num)
- val = self.bigval + str(num)
- c.set_key(key)
- c.set_value(val)
- # read committed and read uncommitted transactions are readonly, any write operations with
- # these isolation levels should throw an error.
- if self.sess_cfg == 'isolation=read-committed' or self.sess_cfg == 'isolation=read-uncommitted':
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: c.insert(), "/not supported in read-committed or read-uncommitted transactions/")
- else:
- c.insert()
- self.session.checkpoint()
- c.close()
- # Increase the multiplier so that later calls insert unique items.
- self.mult += 1
-
def session_config(self):
return self.sess_cfg
+ def add_data_and_check(self):
+ if self.sess_cfg == 'isolation=read-committed' or self.sess_cfg == 'isolation=read-uncommitted':
+ self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
+ lambda: self.add_data(self.uri, self.bigkey, self.bigval, True),
+ "/not supported in read-committed or read-uncommitted transactions/")
+ else:
+ self.add_data(self.uri, self.bigkey, self.bigval, True)
+
def test_backup13(self):
self.session.create(self.uri, "key_format=S,value_format=S")
- self.add_data(self.uri)
-
+ self.add_data_and_check()
# Open up the backup cursor. This causes a new log file to be created.
# That log file is not part of the list returned. This is a full backup
# primary cursor with incremental configured.
@@ -108,7 +95,7 @@ class test_backup13(wttest.WiredTigerTestCase, suite_subprocess):
bkup_c = self.session.open_cursor('backup:', None, config)
# Add more data while the backup cursor is open.
- self.add_data(self.uri)
+ self.add_data_and_check()
# Now copy the files returned by the backup cursor.
all_files = []
@@ -129,7 +116,7 @@ class test_backup13(wttest.WiredTigerTestCase, suite_subprocess):
bkup_c.close()
# Add more data.
- self.add_data(self.uri)
+ self.add_data_and_check()
# Now do an incremental backup.
config = 'incremental=(src_id="ID1",this_id="ID2")'
diff --git a/src/third_party/wiredtiger/test/suite/test_backup14.py b/src/third_party/wiredtiger/test/suite/test_backup14.py
index 67ebe68a8af..a4933140833 100644
--- a/src/third_party/wiredtiger/test/suite/test_backup14.py
+++ b/src/third_party/wiredtiger/test/suite/test_backup14.py
@@ -26,17 +26,16 @@
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
-import wiredtiger, wttest
+import wiredtiger
import os, shutil
-from helper import compare_files
-from suite_subprocess import suite_subprocess
+from wtbackup import backup_base
from wtdataset import simple_key
from wtscenario import make_scenarios
import glob
# test_backup14.py
# Test cursor backup with a block-based incremental cursor.
-class test_backup14(wttest.WiredTigerTestCase, suite_subprocess):
+class test_backup14(backup_base):
conn_config='cache_size=1G,log=(enabled,file_max=100K)'
dir='backup.dir' # Backup directory name
logmax="100K"
@@ -44,46 +43,20 @@ class test_backup14(wttest.WiredTigerTestCase, suite_subprocess):
uri2="table:extra"
uri_logged="table:logged_table"
uri_not_logged="table:not_logged_table"
- full_out = "./backup_block_full"
- incr_out = "./backup_block_incr"
+
bkp_home = "WT_BLOCK"
home_full = "WT_BLOCK_LOG_FULL"
home_incr = "WT_BLOCK_LOG_INCR"
logpath = "logpath"
- nops=1000
- mult=0
+ nops = 1000
max_iteration=7
- counter=0
new_table=False
- initial_backup=False
pfx = 'test_backup'
# Set the key and value big enough that we modify a few blocks.
bigkey = 'Key' * 100
bigval = 'Value' * 100
- #
- # Set up all the directories needed for the test. We have a full backup directory for each
- # iteration and an incremental backup for each iteration. That way we can compare the full and
- # incremental each time through.
- #
- def setup_directories(self):
- for i in range(0, self.max_iteration):
- remove_dir = self.home_incr + '.' + str(i)
-
- create_dir = self.home_incr + '.' + str(i) + '/' + self.logpath
- if os.path.exists(remove_dir):
- os.remove(remove_dir)
- os.makedirs(create_dir)
-
- if i == 0:
- continue
- remove_dir = self.home_full + '.' + str(i)
- create_dir = self.home_full + '.' + str(i) + '/' + self.logpath
- if os.path.exists(remove_dir):
- os.remove(remove_dir)
- os.makedirs(create_dir)
-
def take_full_backup(self):
if self.counter != 0:
hdir = self.home_full + '.' + str(self.counter)
@@ -129,7 +102,7 @@ class test_backup14(wttest.WiredTigerTestCase, suite_subprocess):
def take_incr_backup(self):
# Open the backup data source for incremental backup.
- buf = 'incremental=(src_id="ID' + str(self.counter-1) + '",this_id="ID' + str(self.counter) + '")'
+ buf = 'incremental=(src_id="ID' + str(self.counter - 1) + '",this_id="ID' + str(self.counter) + '")'
bkup_c = self.session.open_cursor('backup:', None, buf)
while True:
ret = bkup_c.next()
@@ -201,44 +174,6 @@ class test_backup14(wttest.WiredTigerTestCase, suite_subprocess):
self.assertEqual(ret, wiredtiger.WT_NOTFOUND)
bkup_c.close()
- def compare_backups(self, t_uri):
- #
- # Run wt dump on full backup directory
- #
- full_backup_out = self.full_out + '.' + str(self.counter)
- home_dir = self.home_full + '.' + str(self.counter)
- if self.counter == 0:
- home_dir = self.home
-
- self.runWt(['-R', '-h', home_dir, 'dump', t_uri], outfilename=full_backup_out)
- #
- # Run wt dump on incremental backup directory
- #
- incr_backup_out = self.incr_out + '.' + str(self.counter)
- home_dir = self.home_incr + '.' + str(self.counter)
- self.runWt(['-R', '-h', home_dir, 'dump', t_uri], outfilename=incr_backup_out)
-
- self.assertEqual(True,
- compare_files(self, full_backup_out, incr_backup_out))
-
- #
- # Add data to the given uri.
- #
- def add_data(self, uri, bulk_option):
- c = self.session.open_cursor(uri, None, bulk_option)
- for i in range(0, self.nops):
- num = i + (self.mult * self.nops)
- key = self.bigkey + str(num)
- val = self.bigval + str(num)
- c[key] = val
- c.close()
-
- # Increase the multiplier so that later calls insert unique items.
- self.mult += 1
- # Increase the counter so that later backups have unique ids.
- if self.initial_backup == False:
- self.counter += 1
-
#
# Remove data from uri (table:main)
#
@@ -265,15 +200,17 @@ class test_backup14(wttest.WiredTigerTestCase, suite_subprocess):
def add_data_validate_backups(self):
self.pr('Adding initial data')
self.initial_backup = True
- self.add_data(self.uri, None)
+ self.add_data(self.uri, self.bigkey, self.bigval)
+
self.take_full_backup()
self.initial_backup = False
self.session.checkpoint()
- self.add_data(self.uri, None)
+ self.add_data(self.uri, self.bigkey, self.bigval)
+
self.take_full_backup()
self.take_incr_backup()
- self.compare_backups(self.uri)
+ self.compare_backups(self.uri, self.home_full, self.home_incr, str(self.counter))
#
# This function will remove all the records from table (table:main), take backup and validate the
@@ -283,7 +220,7 @@ class test_backup14(wttest.WiredTigerTestCase, suite_subprocess):
self.remove_data()
self.take_full_backup()
self.take_incr_backup()
- self.compare_backups(self.uri)
+ self.compare_backups(self.uri, self.home_full, self.home_incr, str(self.counter))
#
# This function will drop the existing table uri (table:main) that is part of the backups and
@@ -298,7 +235,7 @@ class test_backup14(wttest.WiredTigerTestCase, suite_subprocess):
self.session.create(self.uri2, "key_format=S,value_format=S")
self.new_table = True
- self.add_data(self.uri2, None)
+ self.add_data(self.uri2, self.bigkey, self.bigval)
self.take_incr_backup()
table_list = 'tablelist.txt'
@@ -313,10 +250,10 @@ class test_backup14(wttest.WiredTigerTestCase, suite_subprocess):
#
def create_dropped_table_add_new_content(self):
self.session.create(self.uri, "key_format=S,value_format=S")
- self.add_data(self.uri, None)
+ self.add_data(self.uri, self.bigkey, self.bigval)
self.take_full_backup()
self.take_incr_backup()
- self.compare_backups(self.uri)
+ self.compare_backups(self.uri, self.home_full, self.home_incr, str(self.counter))
#
# This function will insert bulk data in logged and not-logged table, take backups and validate the
@@ -327,26 +264,27 @@ class test_backup14(wttest.WiredTigerTestCase, suite_subprocess):
# Insert bulk data into uri3 (table:logged_table).
#
self.session.create(self.uri_logged, "key_format=S,value_format=S")
- self.add_data(self.uri_logged, 'bulk')
+ self.add_data(self.uri_logged, self.bigkey, self.bigval)
+
self.take_full_backup()
self.take_incr_backup()
- self.compare_backups(self.uri_logged)
-
+ self.compare_backups(self.uri_logged, self.home_full, self.home_incr, str(self.counter))
#
# Insert bulk data into uri4 (table:not_logged_table).
#
self.session.create(self.uri_not_logged, "key_format=S,value_format=S,log=(enabled=false)")
- self.add_data(self.uri_not_logged, 'bulk')
+ self.add_data(self.uri_not_logged, self.bigkey, self.bigval)
+
self.take_full_backup()
self.take_incr_backup()
- self.compare_backups(self.uri_not_logged)
+ self.compare_backups(self.uri_not_logged, self.home_full, self.home_incr, str(self.counter))
def test_backup14(self):
os.mkdir(self.bkp_home)
self.home = self.bkp_home
self.session.create(self.uri, "key_format=S,value_format=S")
- self.setup_directories()
+ self.setup_directories(self.max_iteration, self.home_incr, self.home_full, self.logpath)
self.pr('*** Add data, checkpoint, take backups and validate ***')
self.add_data_validate_backups()
@@ -361,6 +299,7 @@ class test_backup14(wttest.WiredTigerTestCase, suite_subprocess):
self.create_dropped_table_add_new_content()
self.pr('*** Insert data into Logged and Not-Logged tables ***')
+ self.cursor_config = 'bulk'
self.insert_bulk_data()
if __name__ == '__main__':
diff --git a/src/third_party/wiredtiger/test/suite/test_backup15.py b/src/third_party/wiredtiger/test/suite/test_backup15.py
index 509efcacb4f..669618c151c 100644
--- a/src/third_party/wiredtiger/test/suite/test_backup15.py
+++ b/src/third_party/wiredtiger/test/suite/test_backup15.py
@@ -26,17 +26,16 @@
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
-import wiredtiger, wttest
+import wiredtiger
import os, shutil
-from helper import compare_files
-from suite_subprocess import suite_subprocess
+from wtbackup import backup_base
from wtdataset import simple_key
from wtscenario import make_scenarios
import glob
# test_backup15.py
# Test cursor backup with a block-based incremental cursor.
-class test_backup15(wttest.WiredTigerTestCase, suite_subprocess):
+class test_backup15(backup_base):
bkp_home = "WT_BLOCK"
counter=0
conn_config='cache_size=1G,log=(enabled,file_max=100K)'
@@ -52,8 +51,6 @@ class test_backup15(wttest.WiredTigerTestCase, suite_subprocess):
home_full = "WT_BLOCK_LOG_FULL"
home_incr = "WT_BLOCK_LOG_INCR"
- full_out = "./backup_block_full"
- incr_out = "./backup_block_incr"
logpath = "logpath"
new_table=False
initial_backup=False
@@ -63,21 +60,6 @@ class test_backup15(wttest.WiredTigerTestCase, suite_subprocess):
bigkey = 'Key' * 100
bigval = 'Value' * 100
- #
- # Set up all the directories needed for the test. We have a full backup directory for each
- # iteration and an incremental backup for each iteration. That way we can compare the full and
- # incremental each time through.
- #
- def setup_directories(self):
- for i in range(0, self.max_iteration):
- # The log directory is a subdirectory of the home directory,
- # creating that will make the home directory also.
- log_dir = self.home_incr + '.' + str(i) + '/' + self.logpath
- os.makedirs(log_dir)
- if i != 0:
- log_dir = self.home_full + '.' + str(i) + '/' + self.logpath
- os.makedirs(log_dir)
-
def range_copy(self, filename, offset, size):
read_from = filename
old_to = self.home_incr + '.' + str(self.counter - 1) + '/' + filename
@@ -218,27 +200,10 @@ class test_backup15(wttest.WiredTigerTestCase, suite_subprocess):
shutil.copy(copy_from, copy_to)
self.assertEqual(ret, wiredtiger.WT_NOTFOUND)
bkup_c.close()
-
- def compare_backups(self, t_uri):
- # Run wt dump on full backup directory.
- full_backup_out = self.full_out + '.' + str(self.counter)
- home_dir = self.home_full + '.' + str(self.counter)
- if self.counter == 0:
- home_dir = self.home
- self.runWt(['-R', '-h', home_dir, 'dump', t_uri], outfilename=full_backup_out)
-
- # Run wt dump on incremental backup directory.
- incr_backup_out = self.incr_out + '.' + str(self.counter)
- home_dir = self.home_incr + '.' + str(self.counter)
- self.runWt(['-R', '-h', home_dir, 'dump', t_uri], outfilename=incr_backup_out)
-
- self.assertEqual(True,
- compare_files(self, full_backup_out, incr_backup_out))
-
#
# Add data to the given uri.
#
- def add_data(self, uri):
+ def add_complex_data(self, uri):
c = self.session.open_cursor(uri, None, None)
# The first time we want to add in a lot of data. Then after that we want to
# rapidly change a single key to create a hotspot in one block.
@@ -270,12 +235,12 @@ class test_backup15(wttest.WiredTigerTestCase, suite_subprocess):
self.home = self.bkp_home
self.session.create(self.uri, "key_format=S,value_format=S")
- self.setup_directories()
+ self.setup_directories(self.max_iteration, self.home_incr, self.home_full, self.logpath)
self.pr('*** Add data, checkpoint, take backups and validate ***')
self.pr('Adding initial data')
self.initial_backup = True
- self.add_data(self.uri)
+ self.add_complex_data(self.uri)
self.take_full_backup()
self.initial_backup = False
self.session.checkpoint()
@@ -283,7 +248,7 @@ class test_backup15(wttest.WiredTigerTestCase, suite_subprocess):
# Each call now to take a full backup will make a copy into a full directory. Then
# each incremental will take an incremental backup and we can compare them.
for i in range(1, self.max_iteration):
- self.add_data(self.uri)
+ self.add_complex_data(self.uri)
self.session.checkpoint()
# Swap the order of the full and incremental backups. It should not matter. They
# should not interfere with each other.
@@ -293,7 +258,7 @@ class test_backup15(wttest.WiredTigerTestCase, suite_subprocess):
else:
self.take_incr_backup()
self.take_full_backup()
- self.compare_backups(self.uri)
+ self.compare_backups(self.uri, self.home_full, self.home_incr, str(self.counter))
if __name__ == '__main__':
wttest.run()
diff --git a/src/third_party/wiredtiger/test/suite/test_backup16.py b/src/third_party/wiredtiger/test/suite/test_backup16.py
index 82df7c39307..a589cbd9691 100644
--- a/src/third_party/wiredtiger/test/suite/test_backup16.py
+++ b/src/third_party/wiredtiger/test/suite/test_backup16.py
@@ -29,19 +29,17 @@
import wiredtiger, wttest
import os, shutil
from helper import compare_files
-from suite_subprocess import suite_subprocess
+from wtbackup import backup_base
from wtdataset import simple_key
from wtscenario import make_scenarios
# test_backup16.py
# Ensure incremental backup doesn't copy unnecessary files.
-class test_backup16(wttest.WiredTigerTestCase, suite_subprocess):
+class test_backup16(backup_base):
conn_config='cache_size=1G,log=(enabled,file_max=100K)'
counter=1
logmax='100K'
- mult=1
- nops=10
# Define the table name and its on-disk file name together.
file1='test1.wt'
@@ -62,21 +60,12 @@ class test_backup16(wttest.WiredTigerTestCase, suite_subprocess):
bigkey = 'Key' * 10
bigval = 'Value' * 10
- def add_data(self, uri):
- c = self.session.open_cursor(uri)
- for i in range(0, self.nops):
- num = i + (self.mult * self.nops)
- key = self.bigkey + str(num)
- val = self.bigval + str(num)
- c[key] = val
- self.session.checkpoint()
- c.close()
- # Increase the multiplier so that later calls insert unique items.
- self.mult += 1
+ mult = 1
+ counter = 1
+ nops = 10
def verify_incr_backup(self, expected_file_list):
-
- bkup_config = ('incremental=(src_id="ID' + str(self.counter-1) +
+ bkup_config = ('incremental=(src_id="ID' + str(self.counter - 1) +
'",this_id="ID' + str(self.counter) + '")')
bkup_cur = self.session.open_cursor('backup:', None, bkup_config)
self.counter += 1
@@ -129,8 +118,8 @@ class test_backup16(wttest.WiredTigerTestCase, suite_subprocess):
self.session.create(self.uri2, 'key_format=S,value_format=S')
self.session.create(self.uri3, 'key_format=S,value_format=S')
self.session.create(self.uri6, 'key_format=S,value_format=S')
- self.add_data(self.uri1)
- self.add_data(self.uri2)
+ self.add_data(self.uri1, self.bigkey, self.bigval, True)
+ self.add_data(self.uri2, self.bigkey, self.bigval, True)
# Checkpoint and simulate full backup.
self.session.checkpoint()
@@ -154,8 +143,8 @@ class test_backup16(wttest.WiredTigerTestCase, suite_subprocess):
#
self.session.create(self.uri4, "key_format=S,value_format=S")
self.session.create(self.uri5, "key_format=S,value_format=S")
- self.add_data(self.uri1)
- self.add_data(self.uri5)
+ self.add_data(self.uri1, self.bigkey, self.bigval, True)
+ self.add_data(self.uri5, self.bigkey, self.bigval, True)
self.session.checkpoint()
# Validate these three files are included in the incremental.
@@ -167,10 +156,10 @@ class test_backup16(wttest.WiredTigerTestCase, suite_subprocess):
# Add more data and checkpoint. Earlier old tables without new data should not
# appear in the list. The table with no data at all continues to appear in the
# list.
- self.add_data(self.uri3)
- self.add_data(self.uri5)
- self.session.checkpoint()
+ self.add_data(self.uri3, self.bigkey, self.bigval, True)
+ self.add_data(self.uri5, self.bigkey, self.bigval, True)
+ self.session.checkpoint()
# Validate these three files are included in the incremental.
files_to_backup = [self.file3, self.file4, self.file5]
self.verify_incr_backup(files_to_backup)
diff --git a/src/third_party/wiredtiger/test/suite/test_backup17.py b/src/third_party/wiredtiger/test/suite/test_backup17.py
index 5fa250fd485..04bff3ea9d8 100644
--- a/src/third_party/wiredtiger/test/suite/test_backup17.py
+++ b/src/third_party/wiredtiger/test/suite/test_backup17.py
@@ -29,21 +29,19 @@
import wiredtiger, wttest
import os, shutil
from helper import compare_files
-from suite_subprocess import suite_subprocess
+from wtbackup import backup_base
from wtdataset import simple_key
from wtscenario import make_scenarios
# test_backup17.py
# Test cursor backup with a block-based incremental cursor and consolidate.
-class test_backup17(wttest.WiredTigerTestCase, suite_subprocess):
+class test_backup17(backup_base):
dir='backup.dir' # Backup directory name
gran="100K"
granval=100*1024
logmax="100K"
uri="table:test"
uri2="table:test2"
- nops=1000
- mult=0
conn_config='cache_size=1G,log=(enabled,file_max=%s)' % logmax
@@ -52,15 +50,7 @@ class test_backup17(wttest.WiredTigerTestCase, suite_subprocess):
bigkey = 'Key' * 100
bigval = 'Value' * 100
- def add_data(self, uri):
- c = self.session.open_cursor(uri)
- for i in range(0, self.nops):
- num = i + (self.mult * self.nops)
- key = self.bigkey + str(num)
- val = self.bigval + str(num)
- c[key] = val
- self.session.checkpoint()
- c.close()
+ nops = 1000
def take_incr_backup(self, id, consolidate):
# Open the backup data source for incremental backup.
@@ -121,9 +111,9 @@ class test_backup17(wttest.WiredTigerTestCase, suite_subprocess):
self.session.create(self.uri, "key_format=S,value_format=S")
self.session.create(self.uri2, "key_format=S,value_format=S")
- self.add_data(self.uri)
- self.add_data(self.uri2)
- self.mult += 1
+ self.add_data(self.uri, self.bigkey, self.bigval, True)
+ self.mult = 0
+ self.add_data(self.uri2, self.bigkey, self.bigval, True)
# Open up the backup cursor. This causes a new log file to be created.
# That log file is not part of the list returned. This is a full backup
@@ -150,10 +140,14 @@ class test_backup17(wttest.WiredTigerTestCase, suite_subprocess):
# Then perform the incremental backup with consolidate off (the default). Then add the
# same data to the second table. Perform an incremental backup with consolidate on and
# verify we get fewer, consolidated values.
- self.add_data(self.uri)
+ self.mult = 1
+ self.add_data(self.uri, self.bigkey, self.bigval, True)
+
uri1_lens = self.take_incr_backup(2, False)
- self.add_data(self.uri2)
+ self.mult = 1
+ self.add_data(self.uri2, self.bigkey, self.bigval, True)
+
uri2_lens = self.take_incr_backup(3, True)
# Assert that we recorded fewer lengths on the consolidated backup.
diff --git a/src/third_party/wiredtiger/test/suite/test_backup18.py b/src/third_party/wiredtiger/test/suite/test_backup18.py
index 2034c8ac6d1..e7c9d65271e 100644
--- a/src/third_party/wiredtiger/test/suite/test_backup18.py
+++ b/src/third_party/wiredtiger/test/suite/test_backup18.py
@@ -29,16 +29,14 @@
import wiredtiger, wttest
import os, shutil
from helper import compare_files
-from suite_subprocess import suite_subprocess
+from wtbackup import backup_base
from wtdataset import simple_key
from wtscenario import make_scenarios
# test_backup18.py
# Test backup:query_id API.
-class test_backup18(wttest.WiredTigerTestCase, suite_subprocess):
+class test_backup18(backup_base):
conn_config= 'cache_size=1G,log=(enabled,file_max=100K)'
- mult=0
- nops=100
pfx = 'test_backup'
uri="table:test"
@@ -58,22 +56,11 @@ class test_backup18(wttest.WiredTigerTestCase, suite_subprocess):
expect.sort()
self.assertEqual(got, expect)
- def add_data(self):
- c = self.session.open_cursor(self.uri)
- for i in range(0, self.nops):
- num = i + (self.mult * self.nops)
- key = 'key' + str(num)
- val = 'value' + str(num)
- c[key] = val
- self.mult += 1
- self.session.checkpoint()
- c.close()
-
def test_backup18(self):
# We're not taking actual backups in this test, but we do want a table to
# exist for the backup cursor to generate something.
self.session.create(self.uri, "key_format=S,value_format=S")
- self.add_data()
+ self.add_data(self.uri, 'key', 'value', True)
msg = "/is not configured/"
self.pr("Query IDs before any backup")
diff --git a/src/third_party/wiredtiger/test/suite/test_backup19.py b/src/third_party/wiredtiger/test/suite/test_backup19.py
index 547445cafbe..c94bf381790 100644
--- a/src/third_party/wiredtiger/test/suite/test_backup19.py
+++ b/src/third_party/wiredtiger/test/suite/test_backup19.py
@@ -26,17 +26,16 @@
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
-import wiredtiger, wttest
+import wiredtiger
import os, shutil
-from helper import compare_files
-from suite_subprocess import suite_subprocess
+from wtbackup import backup_base
from wtdataset import simple_key
from wtscenario import make_scenarios
import glob
# test_backup19.py
# Test cursor backup with a block-based incremental cursor source id only.
-class test_backup19(wttest.WiredTigerTestCase, suite_subprocess):
+class test_backup19(backup_base):
bkp_home = "WT_BLOCK"
counter=0
conn_config='cache_size=1G,log=(enabled,file_max=100K)'
@@ -51,8 +50,6 @@ class test_backup19(wttest.WiredTigerTestCase, suite_subprocess):
home_full = "WT_BLOCK_LOG_FULL"
home_incr = "WT_BLOCK_LOG_INCR"
- full_out = "./backup_block_full"
- incr_out = "./backup_block_incr"
logpath = "logpath"
new_table=False
initial_backup=False
@@ -62,22 +59,6 @@ class test_backup19(wttest.WiredTigerTestCase, suite_subprocess):
bigkey = 'Key' * 100
bigval = 'Value' * 100
- #
- # Set up all the directories needed for the test. We have a full backup directory for each
- # iteration and an incremental backup for each iteration. That way we can compare the full and
- # incremental each time through.
- #
- def setup_directories(self):
- # We're only coming through once so just set up the 0 and 1 directories.
- for i in range(0, 2):
- # The log directory is a subdirectory of the home directory,
- # creating that will make the home directory also.
- log_dir = self.home_incr + '.' + str(i) + '/' + self.logpath
- os.makedirs(log_dir)
- if i != 0:
- log_dir = self.home_full + '.' + str(i) + '/' + self.logpath
- os.makedirs(log_dir)
-
def range_copy(self, filename, offset, size):
read_from = filename
old_to = self.home_incr + '.' + str(self.counter - 1) + '/' + filename
@@ -219,26 +200,10 @@ class test_backup19(wttest.WiredTigerTestCase, suite_subprocess):
self.assertEqual(ret, wiredtiger.WT_NOTFOUND)
bkup_c.close()
- def compare_backups(self, t_uri):
- # Run wt dump on full backup directory.
- full_backup_out = self.full_out + '.' + str(self.counter)
- home_dir = self.home_full + '.' + str(self.counter)
- if self.counter == 0:
- home_dir = self.home
- self.runWt(['-R', '-h', home_dir, 'dump', t_uri], outfilename=full_backup_out)
-
- # Run wt dump on incremental backup directory.
- incr_backup_out = self.incr_out + '.' + str(self.counter)
- home_dir = self.home_incr + '.' + str(self.counter)
- self.runWt(['-R', '-h', home_dir, 'dump', t_uri], outfilename=incr_backup_out)
-
- self.assertEqual(True,
- compare_files(self, full_backup_out, incr_backup_out))
-
#
# Add data to the given uri.
#
- def add_data(self, uri):
+ def add_complex_data(self, uri):
c = self.session.open_cursor(uri, None, None)
# The first time we want to add in a lot of data. Then after that we want to
# rapidly change a single key to create a hotspot in one block.
@@ -270,21 +235,20 @@ class test_backup19(wttest.WiredTigerTestCase, suite_subprocess):
self.home = self.bkp_home
self.session.create(self.uri, "key_format=S,value_format=S")
- self.setup_directories()
+ self.setup_directories(2, self.home_incr, self.home_full, self.logpath)
self.pr('*** Add data, checkpoint, take backups and validate ***')
self.pr('Adding initial data')
self.initial_backup = True
- self.add_data(self.uri)
+ self.add_complex_data(self.uri)
self.take_full_backup()
self.initial_backup = False
self.session.checkpoint()
- self.add_data(self.uri)
+ self.add_complex_data(self.uri)
self.session.checkpoint()
self.take_full_backup()
self.take_incr_backup()
- self.compare_backups(self.uri)
-
+ self.compare_backups(self.uri, self.home_full, self.home_incr, str(self.counter))
if __name__ == '__main__':
wttest.run()
diff --git a/src/third_party/wiredtiger/test/suite/test_base01.py b/src/third_party/wiredtiger/test/suite/test_base01.py
index cb4219a706a..4638aa7ef27 100644
--- a/src/third_party/wiredtiger/test/suite/test_base01.py
+++ b/src/third_party/wiredtiger/test/suite/test_base01.py
@@ -66,7 +66,7 @@ class test_base01(wttest.WiredTigerTestCase):
gotException = True
self.pr('got expected exception: ' + str(e))
self.assertTrue(str(e).find('nvalid argument') >= 0)
- self.assertTrue(gotException, 'expected exception')
+ self.assertTrue(gotException, msg = 'expected exception')
def test_empty(self):
"""
@@ -96,7 +96,7 @@ class test_base01(wttest.WiredTigerTestCase):
getcursor = self.cursor_s(self.table_name2, 'key1')
ret = getcursor.search()
self.assertTrue(ret == 0)
- self.assertTrue(getcursor.get_value(), 'value1')
+ self.assertEqual(getcursor.get_value(), 'value1')
self.pr('closing cursor')
getcursor.close()
diff --git a/src/third_party/wiredtiger/test/suite/test_checkpoint02.py b/src/third_party/wiredtiger/test/suite/test_checkpoint02.py
index 19fdb426eac..c64e1c32596 100755
--- a/src/third_party/wiredtiger/test/suite/test_checkpoint02.py
+++ b/src/third_party/wiredtiger/test/suite/test_checkpoint02.py
@@ -25,6 +25,11 @@
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
+#
+# [TEST_TAGS]
+# checkpoint:correctness:checkpoint_data
+# [END_TAGS]
+#
import queue, threading, time, wiredtiger, wttest
from wtthread import checkpoint_thread, op_thread
diff --git a/src/third_party/wiredtiger/test/suite/test_checkpoint03.py b/src/third_party/wiredtiger/test/suite/test_checkpoint03.py
index 9e2c299404f..2f4abdb532e 100644
--- a/src/third_party/wiredtiger/test/suite/test_checkpoint03.py
+++ b/src/third_party/wiredtiger/test/suite/test_checkpoint03.py
@@ -26,6 +26,10 @@
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
+# [TEST_TAGS]
+# checkpoint:correctness:checkpoint_data
+# [END_TAGS]
+#
# test_checkpoint03.py
# Test that checkpoint writes out updates to the history store file.
#
diff --git a/src/third_party/wiredtiger/test/suite/test_hs03.py b/src/third_party/wiredtiger/test/suite/test_hs03.py
index ea98944c3e1..a70a1bc35b6 100644
--- a/src/third_party/wiredtiger/test/suite/test_hs03.py
+++ b/src/third_party/wiredtiger/test/suite/test_hs03.py
@@ -30,6 +30,7 @@ from helper import copy_wiredtiger_home
import wiredtiger, wttest
from wiredtiger import stat
from wtdataset import SimpleDataSet
+from wtscenario import make_scenarios
def timestamp_str(t):
return '%x' % t
@@ -40,6 +41,12 @@ class test_hs03(wttest.WiredTigerTestCase):
# Force a small cache.
conn_config = 'cache_size=50MB,statistics=(fast)'
session_config = 'isolation=snapshot'
+ key_format_values = [
+ ('column', dict(key_format='r')),
+ ('integer', dict(key_format='i')),
+ ('string', dict(key_format='S'))
+ ]
+ scenarios = make_scenarios(key_format_values)
def get_stat(self, stat):
stat_cursor = self.session.open_cursor('statistics:')
@@ -61,7 +68,7 @@ class test_hs03(wttest.WiredTigerTestCase):
# Create a small table.
uri = "table:test_hs03"
nrows = 100
- ds = SimpleDataSet(self, uri, nrows, key_format="S", value_format='u')
+ ds = SimpleDataSet(self, uri, nrows, key_format=self.key_format, value_format='u')
ds.populate()
bigvalue = b"aaaaa" * 100
diff --git a/src/third_party/wiredtiger/test/suite/test_lsm01.py b/src/third_party/wiredtiger/test/suite/test_lsm01.py
index 6dae354e330..c5d84145277 100644
--- a/src/third_party/wiredtiger/test/suite/test_lsm01.py
+++ b/src/third_party/wiredtiger/test/suite/test_lsm01.py
@@ -77,7 +77,7 @@ class test_lsm01(wttest.WiredTigerTestCase):
args += ')' # Close the LSM configuration option group
self.verbose(3,
'Test LSM with config: ' + args + ' count: ' + str(self.nrecs))
- SimpleDataSet(self, self.uri, self.nrecs).populate()
+ SimpleDataSet(self, self.uri, self.nrecs, config=args).populate()
# TODO: Adding an explicit drop here can cause deadlocks, if a merge
# is still happening. See issue #349.
diff --git a/src/third_party/wiredtiger/test/suite/test_tiered01.py b/src/third_party/wiredtiger/test/suite/test_tiered01.py
new file mode 100644
index 00000000000..2a41c3ff7ef
--- /dev/null
+++ b/src/third_party/wiredtiger/test/suite/test_tiered01.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+#
+# Public Domain 2014-2020 MongoDB, Inc.
+# Public Domain 2008-2014 WiredTiger, Inc.
+#
+# This is free and unencumbered software released into the public domain.
+#
+# Anyone is free to copy, modify, publish, use, compile, sell, or
+# distribute this software, either in source code form or as a compiled
+# binary, for any purpose, commercial or non-commercial, and by any
+# means.
+#
+# In jurisdictions that recognize copyright laws, the author or authors
+# of this software dedicate any and all copyright interest in the
+# software to the public domain. We make this dedication for the benefit
+# of the public at large and to the detriment of our heirs and
+# successors. We intend this dedication to be an overt act of
+# relinquishment in perpetuity of all present and future rights to this
+# software under copyright law.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+import wiredtiger, wtscenario, wttest
+from wtdataset import SimpleDataSet
+
+# test_tiered01.py
+# Basic tiered tree test
+class test_tiered01(wttest.WiredTigerTestCase):
+ K = 1024
+ M = 1024 * K
+ G = 1024 * M
+ uri = "table:test_tiered01"
+
+ chunk_size_scenarios = wtscenario.quick_scenarios('s_chunk_size',
+ [1*M,20*M,None], [0.6,0.6,0.6])
+ # Occasionally add a lot of records, so that merges (and bloom) happen.
+ record_count_scenarios = wtscenario.quick_scenarios(
+ 'nrecs', [10, 10000], [0.9, 0.1])
+
+ config_vars = [ 'chunk_size', ]
+
+ scenarios = wtscenario.make_scenarios(
+ chunk_size_scenarios, record_count_scenarios,
+ prune=100, prunelong=500)
+
+ # Test create of an object.
+ def test_tiered(self):
+ self.session.create('file:first.wt', 'key_format=S')
+ self.session.create('file:second.wt', 'key_format=S')
+ args = 'type=tiered,key_format=S'
+ args += ',tiered=(' # Start the tiered configuration options.
+ args += 'tiers=("file:first.wt", "file:second.wt"),'
+ # add names to args, e.g. args += ',session_max=30'
+ for var in self.config_vars:
+ value = getattr(self, 's_' + var)
+ if value != None:
+ if var == 'verbose':
+ value = '[' + str(value) + ']'
+ value = {True : 'true', False : 'false'}.get(value, value)
+ args += ',' + var + '=' + str(value)
+ args += ')' # Close the tiered configuration option group
+ self.verbose(3,
+ 'Test tiered with config: ' + args + ' count: ' + str(self.nrecs))
+ SimpleDataSet(self, self.uri, self.nrecs, config=args).populate()
+
+ # self.session.drop(self.uri)
+
+if __name__ == '__main__':
+ wttest.run()
diff --git a/src/third_party/wiredtiger/test/suite/test_txn08.py b/src/third_party/wiredtiger/test/suite/test_txn08.py
index 7116aa4eb75..0f82f079867 100644
--- a/src/third_party/wiredtiger/test/suite/test_txn08.py
+++ b/src/third_party/wiredtiger/test/suite/test_txn08.py
@@ -72,6 +72,47 @@ class test_txn08(wttest.WiredTigerTestCase, suite_subprocess):
'\\u0001\\u0002abcd\\u0003\\u0004')
self.check_file_contains('printlog-hex.out',
'0102616263640304')
+ # Check the printlog start LSN and stop LSN feature.
+ self.runWt(['printlog', '-l 2,128'], outfilename='printlog-range01.out')
+ self.check_file_contains('printlog-range01.out',
+ '"lsn" : [2,128],')
+ self.check_file_contains('printlog-range01.out',
+ '"lsn" : [2,256],')
+ self.check_file_not_contains('printlog-range01.out',
+ '"lsn" : [1,128],')
+ self.runWt(['printlog', '-l 2,128,3,128'], outfilename='printlog-range02.out')
+ self.check_file_contains('printlog-range02.out',
+ '"lsn" : [2,128],')
+ self.check_file_not_contains('printlog-range02.out',
+ '"lsn" : [1,128],')
+ self.check_file_not_contains('printlog-range02.out',
+ '"lsn" : [3,256],')
+ # Test for invalid LSN, return WT_NOTFOUND
+ self.runWt(['printlog', '-l 2,300'], outfilename='printlog-range03.out', errfilename='printlog-range03.err', failure=True)
+ self.check_file_contains('printlog-range03.err','WT_NOTFOUND')
+ # Test for Start > end, print the start lsn and then stop
+ self.runWt(['printlog', '-l 3,128,2,128'], outfilename='printlog-range04.out')
+ self.check_file_contains('printlog-range04.out','"lsn" : [3,128],')
+ self.check_file_not_contains('printlog-range04.out','"lsn" : [3,256],')
+ # Test for usage error, print the usage message if arguments are invalid
+ self.runWt(['printlog', '-l'], outfilename='printlog-range05.out', errfilename='printlog-range05.err', failure=True)
+ self.check_file_contains('printlog-range05.err','wt: option requires an argument -- l')
+ # Test start and end offset of 0
+ self.runWt(['printlog', '-l 2,0,3,0'], outfilename='printlog-range06.out')
+ self.check_file_contains('printlog-range06.out',
+ '"lsn" : [2,128],')
+ self.check_file_not_contains('printlog-range06.out',
+ '"lsn" : [1,128],')
+ self.check_file_not_contains('printlog-range06.out',
+ '"lsn" : [3,256],')
+ # Test for start == end
+ self.runWt(['printlog', '-l 1,256,1,256'], outfilename='printlog-range07.out')
+ self.check_file_contains('printlog-range07.out',
+ '"lsn" : [1,256],')
+ self.check_file_not_contains('printlog-range07.out',
+ '"lsn" : [1,128],')
+ self.check_file_not_contains('printlog-range07.out',
+ '"lsn" : [1,384],')
if __name__ == '__main__':
wttest.run()
diff --git a/src/third_party/wiredtiger/test/suite/wtbackup.py b/src/third_party/wiredtiger/test/suite/wtbackup.py
new file mode 100644
index 00000000000..f418d11ddff
--- /dev/null
+++ b/src/third_party/wiredtiger/test/suite/wtbackup.py
@@ -0,0 +1,149 @@
+#!/usr/bin/env python
+#
+# Public Domain 2014-2021 MongoDB, Inc.
+# Public Domain 2008-2014 WiredTiger, Inc.
+#
+# This is free and unencumbered software released into the public domain.
+#
+# Anyone is free to copy, modify, publish, use, compile, sell, or
+# distribute this software, either in source code form or as a compiled
+# binary, for any purpose, commercial or non-commercial, and by any
+# means.
+#
+# In jurisdictions that recognize copyright laws, the author or authors
+# of this software dedicate any and all copyright interest in the
+# software to the public domain. We make this dedication for the benefit
+# of the public at large and to the detriment of our heirs and
+# successors. We intend this dedication to be an overt act of
+# relinquishment in perpetuity of all present and future rights to this
+# software under copyright law.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+import os, glob
+import wttest, wiredtiger
+from suite_subprocess import suite_subprocess
+from helper import compare_files
+
+# Shared base class used by backup tests.
+class backup_base(wttest.WiredTigerTestCase, suite_subprocess):
+ cursor_config = None # a config string for cursors
+ mult = 0 # counter to have variance in data
+ nops = 100 # number of operations added to uri
+
+ # We use counter to produce unique backup names for multiple iterations
+ # of incremental backup tests.
+ counter = 0
+ # To determine whether to increase/decrease counter, which determines
+ initial_backup = True
+ # Used for populate function
+ rows = 100
+ populate_big = None
+
+ #
+ # Add data to the given uri.
+ # Allows the option for doing a session checkpoint after adding data.
+ #
+ def add_data(self, uri, key, val, do_checkpoint=False):
+ assert(self.nops != 0)
+ c = self.session.open_cursor(uri, None, self.cursor_config)
+ for i in range(0, self.nops):
+ num = i + (self.mult * self.nops)
+ k = key + str(num)
+ v = val + str(num)
+ c[k] = v
+ c.close()
+ if do_checkpoint:
+ self.session.checkpoint()
+ # Increase the counter so that later backups have unique ids.
+ if not self.initial_backup:
+ self.counter += 1
+ # Increase the multiplier so that later calls insert unique items.
+ self.mult += 1
+
+ #
+ # Populate a set of objects.
+ #
+ def populate(self, objs, do_checkpoint=False, skiplsm=False):
+ cg_config = ''
+ for i in objs:
+ if len(i) > 2:
+ if i[2] and skiplsm:
+ continue
+ if i[2] == self.populate_big:
+ self.rows = 50000 # Big Object
+ else:
+ self.rows = 1000 # Small Object
+ if len(i) > 3:
+ cg_config = i[3]
+ i[1](self, i[0], self.rows, cgconfig = cg_config).populate()
+
+ # Backup needs a checkpoint
+ if do_checkpoint:
+ self.session.checkpoint()
+
+ #
+ # Set up all the directories needed for the test. We have a full backup directory for each
+ # iteration and an incremental backup for each iteration. That way we can compare the full and
+ # incremental each time through.
+ #
+ def setup_directories(self, max_iteration, home_incr, home_full, logpath):
+ for i in range(0, max_iteration):
+ # The log directory is a subdirectory of the home directory,
+ # creating that will make the home directory also.
+
+ home_incr_dir = home_incr + '.' + str(i)
+ if os.path.exists(home_incr_dir):
+ os.remove(home_incr_dir)
+ os.makedirs(home_incr_dir + '/' + logpath)
+
+ if i == 0:
+ continue
+ home_full_dir = home_full + '.' + str(i)
+ if os.path.exists(home_full_dir):
+ os.remove(home_full_dir)
+ os.makedirs(home_full_dir + '/' + logpath)
+
+ #
+ # Check that a URI doesn't exist, both the meta-data and the file names.
+ #
+ def confirmPathDoesNotExist(self, uri, dir):
+ conn = self.wiredtiger_open(dir)
+ session = conn.open_session()
+ self.assertRaises(wiredtiger.WiredTigerError,
+ lambda: session.open_cursor(uri, None, None))
+ conn.close()
+
+ self.assertEqual(
+ glob.glob(dir + '*' + uri.split(":")[1] + '*'), [],
+ 'confirmPathDoesNotExist: URI exists, file name matching \"' +
+ uri.split(":")[1] + '\" found')
+
+ #
+ # Compare against two directory paths using the wt dump command.
+ # The suffix allows the option to add distinctive tests adding suffix to both the output files and directories
+ #
+ def compare_backups(self, uri, base_dir_home, other_dir_home, suffix = None):
+ sfx = ""
+ if suffix != None:
+ sfx = "." + suffix
+ base_out = "./backup_base" + sfx
+ base_dir = base_dir_home + sfx
+
+ if os.path.exists(base_out):
+ os.remove(base_out)
+
+ # Run wt dump on base backup directory
+ self.runWt(['-R', '-h', base_dir, 'dump', uri], outfilename=base_out)
+ other_out = "./backup_other" + sfx
+ if os.path.exists(other_out):
+ os.remove(other_out)
+ # Run wt dump on incremental backup
+ other_dir = other_dir_home + sfx
+ self.runWt(['-R', '-h', other_dir, 'dump', uri], outfilename=other_out)
+ self.assertEqual(True, compare_files(self, base_out, other_out))