summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Chen <luke.chen@mongodb.com>2018-07-23 15:53:49 +1000
committerLuke Chen <luke.chen@mongodb.com>2018-07-23 15:53:49 +1000
commite065e7daa99f75f19a73fc1b2b57a8947852a006 (patch)
treed2c141fab1e7334b6a552ecda525d29c1cbf20dd
parent1c1535c9ee73ac4ed0d922855ccbe44335909082 (diff)
downloadmongo-e065e7daa99f75f19a73fc1b2b57a8947852a006.tar.gz
Import wiredtiger: 1be1b793becdfb5f4b2ae950449aa3710ca320ce from branch mongodb-4.2
ref: 3334609975..1be1b793be for: 4.1.2 WT-3276 Add recover=salvage to recover from a corrupted log file WT-3943 Include full error message when a python test asserts WT-3955 Add verbose option to log more messages on error returns WT-4160 Restore performance when timestamps are not in use WT-4168 Update upgrading documentation for 3.1.0 release WT-4169 Fix wt verify dump-pages failure WT-4171 Enabling tree walk timing stress causes excessive slowdown WT-4172 Add diagnostic hazard pointer checks in more places before freeing refs WT-4174 Do not access the lookaside file in rollback_to_stable when running with in_memory=true WT-4178 Fixes for wt_btree_immediately_durable needed for in-memory WT-4179 Expose WiredTiger crc32c functions WT-4182 Use conservative approach for log checksum errors WT-4188 Coverity: unchecked return value complaints
-rw-r--r--src/third_party/wiredtiger/NEWS8
-rw-r--r--src/third_party/wiredtiger/README6
-rw-r--r--src/third_party/wiredtiger/RELEASE_INFO2
-rw-r--r--src/third_party/wiredtiger/build_posix/aclocal/options.m413
-rw-r--r--src/third_party/wiredtiger/build_posix/aclocal/version-set.m44
-rw-r--r--src/third_party/wiredtiger/build_win/wiredtiger.def2
-rw-r--r--src/third_party/wiredtiger/build_win/wiredtiger_config.h3
-rw-r--r--src/third_party/wiredtiger/dist/api_data.py6
-rw-r--r--src/third_party/wiredtiger/dist/s_export.list2
-rw-r--r--src/third_party/wiredtiger/dist/s_funcs.list1
-rw-r--r--src/third_party/wiredtiger/dist/s_string.ok2
-rwxr-xr-xsrc/third_party/wiredtiger/dist/s_void3
-rw-r--r--src/third_party/wiredtiger/examples/c/ex_all.c5
-rw-r--r--src/third_party/wiredtiger/import.data2
-rw-r--r--src/third_party/wiredtiger/src/async/async_api.c2
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_debug.c51
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_discard.c22
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_handle.c9
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_slvg.c2
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_split.c10
-rw-r--r--src/third_party/wiredtiger/src/btree/col_srch.c2
-rw-r--r--src/third_party/wiredtiger/src/btree/row_srch.c2
-rw-r--r--src/third_party/wiredtiger/src/checksum/arm64/crc32-arm64.c30
-rw-r--r--src/third_party/wiredtiger/src/checksum/power8/crc32_wrapper.c25
-rw-r--r--src/third_party/wiredtiger/src/checksum/software/checksum.c6
-rw-r--r--src/third_party/wiredtiger/src/checksum/x86/crc32-x86.c39
-rw-r--r--src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.c29
-rw-r--r--src/third_party/wiredtiger/src/config/config_def.c87
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_api.c14
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_dhandle.c4
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_log.c7
-rw-r--r--src/third_party/wiredtiger/src/docs/config-strings.dox2
-rw-r--r--src/third_party/wiredtiger/src/docs/top/main.dox8
-rw-r--r--src/third_party/wiredtiger/src/docs/upgrading.dox66
-rw-r--r--src/third_party/wiredtiger/src/evict/evict_lru.c2
-rw-r--r--src/third_party/wiredtiger/src/evict/evict_page.c18
-rw-r--r--src/third_party/wiredtiger/src/include/btree.i13
-rw-r--r--src/third_party/wiredtiger/src/include/cache.i4
-rw-r--r--src/third_party/wiredtiger/src/include/connection.h61
-rw-r--r--src/third_party/wiredtiger/src/include/error.h13
-rw-r--r--src/third_party/wiredtiger/src/include/extern.h20
-rw-r--r--src/third_party/wiredtiger/src/include/misc.h47
-rw-r--r--src/third_party/wiredtiger/src/include/misc.i27
-rw-r--r--src/third_party/wiredtiger/src/include/os_fhandle.i4
-rw-r--r--src/third_party/wiredtiger/src/include/wiredtiger.in50
-rw-r--r--src/third_party/wiredtiger/src/log/log.c166
-rw-r--r--src/third_party/wiredtiger/src/log/log_slot.c2
-rw-r--r--src/third_party/wiredtiger/src/lsm/lsm_tree.c9
-rw-r--r--src/third_party/wiredtiger/src/os_common/os_abort.c1
-rw-r--r--src/third_party/wiredtiger/src/os_common/os_fs_inmemory.c4
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_dir.c7
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_fallocate.c12
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_fs.c2
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_map.c2
-rw-r--r--src/third_party/wiredtiger/src/os_win/os_fs.c2
-rw-r--r--src/third_party/wiredtiger/src/reconcile/rec_write.c29
-rw-r--r--src/third_party/wiredtiger/src/schema/schema_alter.c2
-rw-r--r--src/third_party/wiredtiger/src/schema/schema_list.c2
-rw-r--r--src/third_party/wiredtiger/src/schema/schema_plan.c2
-rw-r--r--src/third_party/wiredtiger/src/schema/schema_util.c2
-rw-r--r--src/third_party/wiredtiger/src/session/session_dhandle.c4
-rw-r--r--src/third_party/wiredtiger/src/support/err.c122
-rw-r--r--src/third_party/wiredtiger/src/support/global.c2
-rw-r--r--src/third_party/wiredtiger/src/support/hazard.c23
-rw-r--r--src/third_party/wiredtiger/src/support/mtx_rw.c6
-rw-r--r--src/third_party/wiredtiger/src/support/scratch.c59
-rw-r--r--src/third_party/wiredtiger/src/txn/txn_ckpt.c2
-rw-r--r--src/third_party/wiredtiger/src/txn/txn_rollback_to_stable.c3
-rw-r--r--src/third_party/wiredtiger/src/utilities/util_main.c18
-rw-r--r--src/third_party/wiredtiger/test/csuite/timestamp_abort/main.c4
-rw-r--r--src/third_party/wiredtiger/test/csuite/wt4117_checksum/main.c36
-rw-r--r--src/third_party/wiredtiger/test/format/config.h4
-rw-r--r--src/third_party/wiredtiger/test/format/format.h1
-rw-r--r--src/third_party/wiredtiger/test/format/wts.c2
-rw-r--r--src/third_party/wiredtiger/test/salvage/salvage.c2
-rw-r--r--src/third_party/wiredtiger/test/suite/run.py7
-rwxr-xr-x[-rw-r--r--]src/third_party/wiredtiger/test/suite/suite_subprocess.py51
-rwxr-xr-xsrc/third_party/wiredtiger/test/suite/test_txn19.py324
-rw-r--r--src/third_party/wiredtiger/test/suite/wtscenario.py8
-rw-r--r--src/third_party/wiredtiger/test/suite/wttest.py16
80 files changed, 1120 insertions, 553 deletions
diff --git a/src/third_party/wiredtiger/NEWS b/src/third_party/wiredtiger/NEWS
index 7bf3b0e7edb..1e821835386 100644
--- a/src/third_party/wiredtiger/NEWS
+++ b/src/third_party/wiredtiger/NEWS
@@ -1,6 +1,14 @@
Ticket reference tags refer to tickets in the MongoDB JIRA tracking system:
https://jira.mongodb.org
+WiredTiger release 3.1.0, 2018-07-12
+------------------------------------
+
+See the upgrading documentation for details of API and behavior changes.
+
+See JIRA changelog for a full listing:
+https://jira.mongodb.org/projects/WT/versions/19708
+
WiredTiger release 3.0.0, 2018-01-08
------------------------------------
diff --git a/src/third_party/wiredtiger/README b/src/third_party/wiredtiger/README
index f21ff213a7c..fd8757621bf 100644
--- a/src/third_party/wiredtiger/README
+++ b/src/third_party/wiredtiger/README
@@ -1,6 +1,6 @@
-WiredTiger 3.1.0: (April 23, 2018)
+WiredTiger 3.1.1: (July 12, 2018)
-This is version 3.1.0 of WiredTiger.
+This is version 3.1.1 of WiredTiger.
WiredTiger release packages and documentation can be found at:
@@ -8,7 +8,7 @@ WiredTiger release packages and documentation can be found at:
The documentation for this specific release can be found at:
- http://source.wiredtiger.com/3.1.0/index.html
+ http://source.wiredtiger.com/3.1.1/index.html
The WiredTiger source code can be found at:
diff --git a/src/third_party/wiredtiger/RELEASE_INFO b/src/third_party/wiredtiger/RELEASE_INFO
index ee25ecd6c56..2014ba3ee74 100644
--- a/src/third_party/wiredtiger/RELEASE_INFO
+++ b/src/third_party/wiredtiger/RELEASE_INFO
@@ -1,6 +1,6 @@
WIREDTIGER_VERSION_MAJOR=3
WIREDTIGER_VERSION_MINOR=1
-WIREDTIGER_VERSION_PATCH=0
+WIREDTIGER_VERSION_PATCH=1
WIREDTIGER_VERSION="$WIREDTIGER_VERSION_MAJOR.$WIREDTIGER_VERSION_MINOR.$WIREDTIGER_VERSION_PATCH"
WIREDTIGER_RELEASE_DATE=`date "+%B %e, %Y"`
diff --git a/src/third_party/wiredtiger/build_posix/aclocal/options.m4 b/src/third_party/wiredtiger/build_posix/aclocal/options.m4
index 7d0df5d65ac..9d07958bad9 100644
--- a/src/third_party/wiredtiger/build_posix/aclocal/options.m4
+++ b/src/third_party/wiredtiger/build_posix/aclocal/options.m4
@@ -53,19 +53,6 @@ AM_CONDITIONAL([HAVE_BUILTIN_EXTENSION_ZSTD],
[test "$wt_cv_with_builtin_extension_zstd" = "yes"])
AC_MSG_RESULT($with_builtins)
-AH_TEMPLATE(
- HAVE_CRC32_HARDWARE, [Define to 1 to configure CRC32 hardware support.])
-AC_MSG_CHECKING(if --enable-crc32-hardware option specified)
-AC_ARG_ENABLE(crc32-hardware,
- AS_HELP_STRING([--enable-crc32-hardware],
- [Enable CRC32 hardware support.]), r=$enableval, r=yes)
-case "$r" in
-no) wt_cv_enable_crc32_hardware=no;;
-*) AC_DEFINE(HAVE_CRC32_HARDWARE)
- wt_cv_enable_crc32_hardware=yes;;
-esac
-AC_MSG_RESULT($wt_cv_enable_crc32_hardware)
-
AH_TEMPLATE(HAVE_DIAGNOSTIC, [Define to 1 for diagnostic tests.])
AC_MSG_CHECKING(if --enable-diagnostic option specified)
AC_ARG_ENABLE(diagnostic,
diff --git a/src/third_party/wiredtiger/build_posix/aclocal/version-set.m4 b/src/third_party/wiredtiger/build_posix/aclocal/version-set.m4
index 3f87f7f6507..8b39a5d09d6 100644
--- a/src/third_party/wiredtiger/build_posix/aclocal/version-set.m4
+++ b/src/third_party/wiredtiger/build_posix/aclocal/version-set.m4
@@ -2,8 +2,8 @@ dnl build by dist/s_version
VERSION_MAJOR=3
VERSION_MINOR=1
-VERSION_PATCH=0
-VERSION_STRING='"WiredTiger 3.1.0: (April 23, 2018)"'
+VERSION_PATCH=1
+VERSION_STRING='"WiredTiger 3.1.1: (July 12, 2018)"'
AC_SUBST(VERSION_MAJOR)
AC_SUBST(VERSION_MINOR)
diff --git a/src/third_party/wiredtiger/build_win/wiredtiger.def b/src/third_party/wiredtiger/build_win/wiredtiger.def
index 3ee9f6b6a9d..79fa84a11e0 100644
--- a/src/third_party/wiredtiger/build_win/wiredtiger.def
+++ b/src/third_party/wiredtiger/build_win/wiredtiger.def
@@ -1,8 +1,8 @@
LIBRARY WIREDTIGER
EXPORTS
- wiredtiger_checksum_crc32c
wiredtiger_config_parser_open
wiredtiger_config_validate
+ wiredtiger_crc32c_func
wiredtiger_open
wiredtiger_pack_close
wiredtiger_pack_int
diff --git a/src/third_party/wiredtiger/build_win/wiredtiger_config.h b/src/third_party/wiredtiger/build_win/wiredtiger_config.h
index 55431f59fae..bb4cc7848f8 100644
--- a/src/third_party/wiredtiger/build_win/wiredtiger_config.h
+++ b/src/third_party/wiredtiger/build_win/wiredtiger_config.h
@@ -25,9 +25,6 @@
/* Define to 1 if you have the `clock_gettime' function. */
/* #undef HAVE_CLOCK_GETTIME */
-/* Define to 1 to enable CRC32 hardware support. */
-/* #undef HAVE_CRC32_HARDWARE */
-
/* Define to 1 for diagnostic tests. */
/* #undef HAVE_DIAGNOSTIC */
diff --git a/src/third_party/wiredtiger/dist/api_data.py b/src/third_party/wiredtiger/dist/api_data.py
index d29e9655fb3..e96a147fc70 100644
--- a/src/third_party/wiredtiger/dist/api_data.py
+++ b/src/third_party/wiredtiger/dist/api_data.py
@@ -590,8 +590,7 @@ connection_runtime_config = [
type='list', undoc=True,
choices=[
'checkpoint_slow', 'lookaside_sweep_race', 'split_1', 'split_2',
- 'split_3', 'split_4', 'split_5', 'split_6', 'split_7', 'split_8',
- 'split_9']),
+ 'split_3', 'split_4', 'split_5', 'split_6', 'split_7', 'split_8']),
Config('verbose', '', r'''
enable messages for various events. Options are given as a
list, such as <code>"verbose=[evictserver,read]"</code>''',
@@ -601,6 +600,7 @@ connection_runtime_config = [
'checkpoint',
'checkpoint_progress',
'compact',
+ 'error_returns',
'evict',
'evict_stuck',
'evictserver',
@@ -709,7 +709,7 @@ wiredtiger_open_log_configuration = [
Config('recover', 'on', r'''
run recovery or error if recovery needs to run after an
unclean shutdown''',
- choices=['error','on'])
+ choices=['error', 'on', 'salvage'])
]),
]
diff --git a/src/third_party/wiredtiger/dist/s_export.list b/src/third_party/wiredtiger/dist/s_export.list
index 72ce553ac9b..e49fa113d96 100644
--- a/src/third_party/wiredtiger/dist/s_export.list
+++ b/src/third_party/wiredtiger/dist/s_export.list
@@ -1,7 +1,7 @@
# List of OK external symbols.
-wiredtiger_checksum_crc32c
wiredtiger_config_parser_open
wiredtiger_config_validate
+wiredtiger_crc32c_func
wiredtiger_open
wiredtiger_pack_close
wiredtiger_pack_int
diff --git a/src/third_party/wiredtiger/dist/s_funcs.list b/src/third_party/wiredtiger/dist/s_funcs.list
index eed29e91fc1..95c568a19ff 100644
--- a/src/third_party/wiredtiger/dist/s_funcs.list
+++ b/src/third_party/wiredtiger/dist/s_funcs.list
@@ -33,7 +33,6 @@ __wt_stat_join_aggregate
__wt_stat_join_clear_all
__wt_stream_set_no_buffer
__wt_try_readlock
-wiredtiger_checksum_crc32c
wiredtiger_config_parser_open
wiredtiger_config_validate
wiredtiger_pack_int
diff --git a/src/third_party/wiredtiger/dist/s_string.ok b/src/third_party/wiredtiger/dist/s_string.ok
index 64b9758877e..215f1c36e8b 100644
--- a/src/third_party/wiredtiger/dist/s_string.ok
+++ b/src/third_party/wiredtiger/dist/s_string.ok
@@ -207,8 +207,8 @@ LLLLLLL
LOGREC
LOGSCAN
LOOKASIDE
+LRSVv
LRU
-LRVv
LSB
LSM
LSN
diff --git a/src/third_party/wiredtiger/dist/s_void b/src/third_party/wiredtiger/dist/s_void
index 9c5f6711da0..f97b910620f 100755
--- a/src/third_party/wiredtiger/dist/s_void
+++ b/src/third_party/wiredtiger/dist/s_void
@@ -55,6 +55,8 @@ func_ok()
-e '/int __wt_block_compact_start$/d' \
-e '/int __wt_block_manager_size$/d' \
-e '/int __wt_block_write_size$/d' \
+ -e '/int __wt_buf_catfmt$/d' \
+ -e '/int __wt_buf_fmt$/d' \
-e '/int __wt_curjoin_joined$/d' \
-e '/int __wt_cursor_close$/d' \
-e '/int __wt_cursor_noop$/d' \
@@ -65,6 +67,7 @@ func_ok()
-e '/int __wt_once$/d' \
-e '/int __wt_posix_directory_list_free$/d' \
-e '/int __wt_session_breakpoint$/d' \
+ -e '/int __wt_set_return_func$/d' \
-e '/int __wt_spin_init$/d' \
-e '/int __wt_spin_trylock$/d' \
-e '/int __wt_stat_connection_desc$/d' \
diff --git a/src/third_party/wiredtiger/examples/c/ex_all.c b/src/third_party/wiredtiger/examples/c/ex_all.c
index 139f39fe673..190c2c421d3 100644
--- a/src/third_party/wiredtiger/examples/c/ex_all.c
+++ b/src/third_party/wiredtiger/examples/c/ex_all.c
@@ -1356,8 +1356,9 @@ main(int argc, char *argv[])
const char *buffer = "some string";
size_t len = strlen(buffer);
/*! [Checksum a buffer] */
- uint32_t crc32c;
- crc32c = wiredtiger_checksum_crc32c(buffer, len);
+ uint32_t crc32c, (*func)(const void *, size_t);
+ func = wiredtiger_crc32c_func();
+ crc32c = func(buffer, len);
/*! [Checksum a buffer] */
(void)crc32c;
}
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data
index ea08c6eb2d1..3392241798d 100644
--- a/src/third_party/wiredtiger/import.data
+++ b/src/third_party/wiredtiger/import.data
@@ -1,5 +1,5 @@
{
- "commit": "333460997573558235254cb7e84dad765bb844a7",
+ "commit": "1be1b793becdfb5f4b2ae950449aa3710ca320ce",
"github": "wiredtiger/wiredtiger.git",
"vendor": "wiredtiger",
"branch": "mongodb-4.2"
diff --git a/src/third_party/wiredtiger/src/async/async_api.c b/src/third_party/wiredtiger/src/async/async_api.c
index db755db198a..cb3cd8986f3 100644
--- a/src/third_party/wiredtiger/src/async/async_api.c
+++ b/src/third_party/wiredtiger/src/async/async_api.c
@@ -145,7 +145,7 @@ retry:
*/
if (op == NULL || op->state != WT_ASYNCOP_FREE) {
WT_STAT_CONN_INCR(session, async_full);
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
}
/*
* Set the state of this op handle as READY for the user to use.
diff --git a/src/third_party/wiredtiger/src/btree/bt_debug.c b/src/third_party/wiredtiger/src/btree/bt_debug.c
index 16e25c1fe25..d18e3887ca5 100644
--- a/src/third_party/wiredtiger/src/btree/bt_debug.c
+++ b/src/third_party/wiredtiger/src/btree/bt_debug.c
@@ -53,7 +53,7 @@ static int __debug_ref(WT_DBG *, WT_REF *);
static int __debug_row_skip(WT_DBG *, WT_INSERT_HEAD *);
static int __debug_tree(WT_SESSION_IMPL *, WT_REF *, const char *, uint32_t);
static int __debug_update(WT_DBG *, WT_UPDATE *, bool);
-static int __dmsg_wrapup(WT_DBG *);
+static int __debug_wrapup(WT_DBG *);
/*
* __wt_debug_set_verbose --
@@ -270,7 +270,7 @@ __debug_config(WT_SESSION_IMPL *session, WT_DBG *ds, const char *ofile)
ds->f = __dmsg_event;
} else {
if ((ds->fp = fopen(ofile, "w")) == NULL)
- return (EIO);
+ return (__wt_set_return(session, EIO));
__wt_stream_set_line_buffer(ds->fp);
ds->f = __dmsg_file;
}
@@ -282,12 +282,13 @@ __debug_config(WT_SESSION_IMPL *session, WT_DBG *ds, const char *ofile)
}
/*
- * __dmsg_wrapup --
+ * __debug_wrapup --
* Flush any remaining output, release resources.
*/
static int
-__dmsg_wrapup(WT_DBG *ds)
+__debug_wrapup(WT_DBG *ds)
{
+ WT_DECL_RET;
WT_ITEM *msg;
WT_SESSION_IMPL *session;
@@ -303,7 +304,7 @@ __dmsg_wrapup(WT_DBG *ds)
*/
if (msg != NULL) {
if (msg->size != 0)
- WT_RET(__wt_msg(session, "%s", (char *)msg->mem));
+ ret = __wt_msg(session, "%s", (char *)msg->mem);
__wt_scr_free(session, &ds->msg);
}
@@ -311,7 +312,7 @@ __dmsg_wrapup(WT_DBG *ds)
if (ds->fp != NULL)
(void)fclose(ds->fp);
- return (0);
+ return (ret);
}
/*
@@ -435,59 +436,61 @@ __wt_debug_disk(
WT_SESSION_IMPL *session, const WT_PAGE_HEADER *dsk, const char *ofile)
{
WT_DBG *ds, _ds;
+ WT_DECL_RET;
ds = &_ds;
WT_RET(__debug_config(session, ds, ofile));
- WT_RET(ds->f(ds, "%s page", __wt_page_type_string(dsk->type)));
+ WT_ERR(ds->f(ds, "%s page", __wt_page_type_string(dsk->type)));
switch (dsk->type) {
case WT_PAGE_BLOCK_MANAGER:
break;
case WT_PAGE_COL_FIX:
case WT_PAGE_COL_INT:
case WT_PAGE_COL_VAR:
- WT_RET(ds->f(ds, ", recno %" PRIu64, dsk->recno));
+ WT_ERR(ds->f(ds, ", recno %" PRIu64, dsk->recno));
/* FALLTHROUGH */
case WT_PAGE_ROW_INT:
case WT_PAGE_ROW_LEAF:
- WT_RET(ds->f(ds, ", entries %" PRIu32, dsk->u.entries));
+ WT_ERR(ds->f(ds, ", entries %" PRIu32, dsk->u.entries));
break;
case WT_PAGE_OVFL:
- WT_RET(ds->f(ds, ", datalen %" PRIu32, dsk->u.datalen));
+ WT_ERR(ds->f(ds, ", datalen %" PRIu32, dsk->u.datalen));
break;
- WT_ILLEGAL_VALUE(session);
+ WT_ILLEGAL_VALUE_ERR(session);
}
if (F_ISSET(dsk, WT_PAGE_COMPRESSED))
- WT_RET(ds->f(ds, ", compressed"));
+ WT_ERR(ds->f(ds, ", compressed"));
if (F_ISSET(dsk, WT_PAGE_ENCRYPTED))
- WT_RET(ds->f(ds, ", encrypted"));
+ WT_ERR(ds->f(ds, ", encrypted"));
if (F_ISSET(dsk, WT_PAGE_EMPTY_V_ALL))
- WT_RET(ds->f(ds, ", empty-all"));
+ WT_ERR(ds->f(ds, ", empty-all"));
if (F_ISSET(dsk, WT_PAGE_EMPTY_V_NONE))
- WT_RET(ds->f(ds, ", empty-none"));
+ WT_ERR(ds->f(ds, ", empty-none"));
if (F_ISSET(dsk, WT_PAGE_LAS_UPDATE))
- WT_RET(ds->f(ds, ", LAS-update"));
+ WT_ERR(ds->f(ds, ", LAS-update"));
- WT_RET(ds->f(ds, ", generation %" PRIu64 "\n", dsk->write_gen));
+ WT_ERR(ds->f(ds, ", generation %" PRIu64 "\n", dsk->write_gen));
switch (dsk->type) {
case WT_PAGE_BLOCK_MANAGER:
break;
case WT_PAGE_COL_FIX:
- WT_RET(__debug_dsk_col_fix(ds, dsk));
+ WT_ERR(__debug_dsk_col_fix(ds, dsk));
break;
case WT_PAGE_COL_INT:
case WT_PAGE_COL_VAR:
case WT_PAGE_ROW_INT:
case WT_PAGE_ROW_LEAF:
- WT_RET(__debug_dsk_cell(ds, dsk));
+ WT_ERR(__debug_dsk_cell(ds, dsk));
break;
default:
break;
}
- return (__dmsg_wrapup(ds));
+err: WT_TRET(__debug_wrapup(ds));
+ return (ret);
}
/*
@@ -620,9 +623,9 @@ __wt_debug_tree_shape(
WT_WITH_PAGE_INDEX(session,
ret = __debug_tree_shape_worker(ds, page, 1));
- WT_RET(ret);
- return (__dmsg_wrapup(ds));
+ WT_TRET(__debug_wrapup(ds));
+ return (ret);
}
/* AUTOMATIC FLAG VALUE GENERATION START */
@@ -705,7 +708,7 @@ __wt_debug_page(
WT_WITH_BTREE(session, btree,
ret = __debug_page(ds, ref, WT_DEBUG_TREE_LEAF));
- WT_TRET(__dmsg_wrapup(ds));
+ WT_TRET(__debug_wrapup(ds));
return (ret);
}
@@ -744,7 +747,7 @@ __debug_tree(
ret = __debug_page(ds, ref, flags);
- WT_TRET(__dmsg_wrapup(ds));
+ WT_TRET(__debug_wrapup(ds));
return (ret);
}
diff --git a/src/third_party/wiredtiger/src/btree/bt_discard.c b/src/third_party/wiredtiger/src/btree/bt_discard.c
index d31f76f629c..0d49adc19ca 100644
--- a/src/third_party/wiredtiger/src/btree/bt_discard.c
+++ b/src/third_party/wiredtiger/src/btree/bt_discard.c
@@ -32,29 +32,14 @@ __wt_ref_out(WT_SESSION_IMPL *session, WT_REF *ref)
*/
WT_ASSERT(session, S2BT(session)->evict_ref != ref);
-#ifdef HAVE_DIAGNOSTIC
- {
- WT_HAZARD *hp;
- int i;
/*
* Make sure no other thread has a hazard pointer on the page we are
* about to discard. This is complicated by the fact that readers
* publish their hazard pointer before re-checking the page state, so
* our check can race with readers without indicating a real problem.
- * Wait for up to a second for hazard pointers to be cleared.
+ * If we find a hazard pointer, wait for it to be cleared.
*/
- for (hp = NULL, i = 0; i < 100; i++) {
- if ((hp = __wt_hazard_check(session, ref)) == NULL)
- break;
- __wt_sleep(0, 10000);
- }
- if (hp != NULL)
- __wt_errx(session,
- "discarded page has hazard pointer: (%p: %s, line %d)",
- (void *)hp->ref, hp->file, hp->line);
- WT_ASSERT(session, hp == NULL);
- }
-#endif
+ WT_ASSERT(session, __wt_hazard_check_assert(session, ref, true));
__wt_page_out(session, &ref->page);
}
@@ -263,6 +248,9 @@ __wt_free_ref(
if (ref == NULL)
return;
+ /* Assert there are no hazard pointers. */
+ WT_ASSERT(session, __wt_hazard_check_assert(session, ref, false));
+
/*
* Optionally free the referenced pages. (The path to free referenced
* page is used for error cleanup, no instantiated and then discarded
diff --git a/src/third_party/wiredtiger/src/btree/bt_handle.c b/src/third_party/wiredtiger/src/btree/bt_handle.c
index 9160ff1dd21..613a95f321b 100644
--- a/src/third_party/wiredtiger/src/btree/bt_handle.c
+++ b/src/third_party/wiredtiger/src/btree/bt_handle.c
@@ -915,10 +915,11 @@ __wt_btree_immediately_durable(WT_SESSION_IMPL *session)
/*
* This is used to determine whether timestamp updates should
- * be rolled back for this btree. It's likely that the particular
- * test required here will change when rollback to stable is
- * supported with in-memory configurations.
+ * be rolled back for this btree. With in-memory, the logging
+ * setting on tables is still important and when enabled they
+ * should be considered "durable".
*/
- return (FLD_ISSET(S2C(session)->log_flags, WT_CONN_LOG_ENABLED) &&
+ return ((FLD_ISSET(S2C(session)->log_flags, WT_CONN_LOG_ENABLED) ||
+ (F_ISSET(S2C(session), WT_CONN_IN_MEMORY))) &&
!F_ISSET(btree, WT_BTREE_NO_LOGGING));
}
diff --git a/src/third_party/wiredtiger/src/btree/bt_slvg.c b/src/third_party/wiredtiger/src/btree/bt_slvg.c
index 54f4eaa8f52..411c7ed7cfe 100644
--- a/src/third_party/wiredtiger/src/btree/bt_slvg.c
+++ b/src/third_party/wiredtiger/src/btree/bt_slvg.c
@@ -2350,7 +2350,7 @@ __slvg_ovfl_ref(WT_SESSION_IMPL *session, WT_TRACK *trk, bool multi_panic)
{
if (F_ISSET(trk, WT_TRACK_OVFL_REFD)) {
if (!multi_panic)
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
WT_PANIC_RET(session, EINVAL,
"overflow record unexpectedly referenced multiple times "
"during leaf page merge");
diff --git a/src/third_party/wiredtiger/src/btree/bt_split.c b/src/third_party/wiredtiger/src/btree/bt_split.c
index a98de6c6c9f..2a69ef84540 100644
--- a/src/third_party/wiredtiger/src/btree/bt_split.c
+++ b/src/third_party/wiredtiger/src/btree/bt_split.c
@@ -449,7 +449,7 @@ __split_root(WT_SESSION_IMPL *session, WT_PAGE *root)
children = pindex->entries / btree->split_deepen_per_child;
if (children < 10) {
if (pindex->entries < 100)
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
children = 10;
}
chunk = pindex->entries / children;
@@ -872,6 +872,8 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref, WT_REF **ref_new,
/* Free the backing block and address. */
WT_TRET(__wt_ref_block_free(session, next_ref));
+ WT_ASSERT(session,
+ __wt_hazard_check_assert(session, next_ref, false));
WT_TRET(__split_safe_free(
session, split_gen, exclusive, next_ref, sizeof(WT_REF)));
parent_decr += sizeof(WT_REF);
@@ -915,7 +917,7 @@ err: __wt_scr_free(session, &scr);
* being deleted, but don't be noisy, there's nothing wrong.
*/
if (empty_parent)
- ret = EBUSY;
+ ret = __wt_set_return(session, EBUSY);
break;
case WT_ERR_PANIC:
__wt_err(session, ret, "fatal error during parent page split");
@@ -982,7 +984,7 @@ __split_internal(WT_SESSION_IMPL *session, WT_PAGE *parent, WT_PAGE *page)
children = pindex->entries / btree->split_deepen_per_child;
if (children < 10) {
if (pindex->entries < 100)
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
children = 10;
}
chunk = pindex->entries / children;
@@ -1214,7 +1216,7 @@ __split_internal_lock(
* the parent, give up to avoid that deadlock.
*/
if (!trylock && !__wt_btree_can_evict_dirty(session))
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
/*
* Get a page-level lock on the parent to single-thread splits into the
diff --git a/src/third_party/wiredtiger/src/btree/col_srch.c b/src/third_party/wiredtiger/src/btree/col_srch.c
index 123b640cdf4..4b7b3d3d727 100644
--- a/src/third_party/wiredtiger/src/btree/col_srch.c
+++ b/src/third_party/wiredtiger/src/btree/col_srch.c
@@ -180,7 +180,7 @@ descend: /*
}
/* Encourage races. */
- __wt_timing_stress(session, WT_TIMING_STRESS_SPLIT_9);
+ WT_DIAGNOSTIC_YIELD;
/*
* Swap the current page for the child page. If the page splits
diff --git a/src/third_party/wiredtiger/src/btree/row_srch.c b/src/third_party/wiredtiger/src/btree/row_srch.c
index a3f05a2700f..38921471d74 100644
--- a/src/third_party/wiredtiger/src/btree/row_srch.c
+++ b/src/third_party/wiredtiger/src/btree/row_srch.c
@@ -432,7 +432,7 @@ append: if (__wt_split_descent_race(
}
descend: /* Encourage races. */
- __wt_timing_stress(session, WT_TIMING_STRESS_SPLIT_9);
+ WT_DIAGNOSTIC_YIELD;
/*
* Swap the current page for the child page. If the page splits
diff --git a/src/third_party/wiredtiger/src/checksum/arm64/crc32-arm64.c b/src/third_party/wiredtiger/src/checksum/arm64/crc32-arm64.c
index 01740dcd953..f09c15be450 100644
--- a/src/third_party/wiredtiger/src/checksum/arm64/crc32-arm64.c
+++ b/src/third_party/wiredtiger/src/checksum/arm64/crc32-arm64.c
@@ -26,9 +26,10 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "wt_internal.h"
+#include <inttypes.h>
+#include <stddef.h>
-#if defined(__linux__) && defined(HAVE_CRC32_HARDWARE)
+#if defined(__linux__)
#include <asm/hwcap.h>
#include <sys/auxv.h>
@@ -84,23 +85,28 @@ __wt_checksum_hw(const void *chunk, size_t len)
}
#endif
+extern uint32_t __wt_checksum_sw(const void *chunk, size_t len);
+#if defined(__GNUC__)
+extern uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t)
+ __attribute__((visibility("default")));
+#else
+extern uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t);
+#endif
+
/*
- * __wt_checksum_init --
- * WiredTiger: detect CRC hardware and set the checksum function.
+ * wiredtiger_crc32c_func --
+ * WiredTiger: detect CRC hardware and return the checksum function.
*/
-void
-__wt_checksum_init(void)
- WT_GCC_FUNC_ATTRIBUTE((cold))
+uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t)
{
-#if defined(__linux__) && defined(HAVE_CRC32_HARDWARE)
+#if defined(__linux__)
unsigned long caps = getauxval(AT_HWCAP);
if (caps & HWCAP_CRC32)
- __wt_process.checksum = __wt_checksum_hw;
- else
- __wt_process.checksum = __wt_checksum_sw;
+ return (__wt_checksum_hw);
+ return (__wt_checksum_sw);
#else
- __wt_process.checksum = __wt_checksum_sw;
+ return (__wt_checksum_sw);
#endif
}
diff --git a/src/third_party/wiredtiger/src/checksum/power8/crc32_wrapper.c b/src/third_party/wiredtiger/src/checksum/power8/crc32_wrapper.c
index 8626fa42136..cb427ea7a67 100644
--- a/src/third_party/wiredtiger/src/checksum/power8/crc32_wrapper.c
+++ b/src/third_party/wiredtiger/src/checksum/power8/crc32_wrapper.c
@@ -1,5 +1,6 @@
#if defined(__powerpc64__)
-#include "wt_internal.h"
+#include <inttypes.h>
+#include <stddef.h>
#define CRC_TABLE
#include "crc32_constants.h"
@@ -80,17 +81,23 @@ __wt_checksum_hw(const void *chunk, size_t len)
return (crc32_vpmsum(0, chunk, len));
}
+extern uint32_t __wt_checksum_sw(const void *chunk, size_t len);
+#if defined(__GNUC__)
+extern uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t)
+ __attribute__((visibility("default")));
+#else
+extern uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t);
+#endif
+
/*
- * __wt_checksum_init --
- * WiredTiger: detect CRC hardware and set the checksum function.
+ * wiredtiger_crc32c_func --
+ * WiredTiger: detect CRC hardware and return the checksum function.
*/
-void
-__wt_checksum_init(void)
- WT_GCC_FUNC_ATTRIBUTE((cold))
+uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t)
{
-#if defined(HAVE_CRC32_HARDWARE)
- __wt_process.checksum = __wt_checksum_hw;
+#if defined(__powerpc64__)
+ return (__wt_checksum_hw);
#else
- __wt_process.checksum = __wt_checksum_sw;
+ return (__wt_checksum_sw);
#endif
}
diff --git a/src/third_party/wiredtiger/src/checksum/software/checksum.c b/src/third_party/wiredtiger/src/checksum/software/checksum.c
index 1228c9a0ce1..4d93f8bf1ea 100644
--- a/src/third_party/wiredtiger/src/checksum/software/checksum.c
+++ b/src/third_party/wiredtiger/src/checksum/software/checksum.c
@@ -38,7 +38,8 @@
* little endian.
*/
-#include "wt_internal.h"
+#include <inttypes.h>
+#include <stddef.h>
/*
* The CRC slicing tables.
@@ -1095,13 +1096,14 @@ static const uint32_t g_crc_slicing[8][256] = {
#endif
};
+extern uint32_t __wt_checksum_sw(const void *chunk, size_t len);
+
/*
* __wt_checksum_sw --
* Return a checksum for a chunk of memory, computed in software.
*/
uint32_t
__wt_checksum_sw(const void *chunk, size_t len)
- WT_GCC_FUNC_ATTRIBUTE((visibility("default")))
{
uint32_t crc, next;
size_t nqwords;
diff --git a/src/third_party/wiredtiger/src/checksum/x86/crc32-x86.c b/src/third_party/wiredtiger/src/checksum/x86/crc32-x86.c
index 73199018a7d..2ff237f883e 100644
--- a/src/third_party/wiredtiger/src/checksum/x86/crc32-x86.c
+++ b/src/third_party/wiredtiger/src/checksum/x86/crc32-x86.c
@@ -26,9 +26,9 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "wt_internal.h"
+#include <inttypes.h>
+#include <stddef.h>
-#if defined(HAVE_CRC32_HARDWARE)
#if (defined(__amd64) || defined(__x86_64))
/*
* __wt_checksum_hw --
@@ -116,17 +116,21 @@ __wt_checksum_hw(const void *chunk, size_t len)
return (~crc);
}
#endif
-#endif /* HAVE_CRC32_HARDWARE */
+
+extern uint32_t __wt_checksum_sw(const void *chunk, size_t len);
+#if defined(__GNUC__)
+extern uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t)
+ __attribute__((visibility("default")));
+#else
+extern uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t);
+#endif
/*
- * __wt_checksum_init --
- * WiredTiger: detect CRC hardware and set the checksum function.
+ * wiredtiger_crc32c_func --
+ * WiredTiger: detect CRC hardware and return the checksum function.
*/
-void
-__wt_checksum_init(void)
- WT_GCC_FUNC_ATTRIBUTE((cold))
+uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t)
{
-#if defined(HAVE_CRC32_HARDWARE)
#if (defined(__amd64) || defined(__x86_64))
unsigned int eax, ebx, ecx, edx;
@@ -137,9 +141,8 @@ __wt_checksum_init(void)
#define CPUID_ECX_HAS_SSE42 (1 << 20)
if (ecx & CPUID_ECX_HAS_SSE42)
- __wt_process.checksum = __wt_checksum_hw;
- else
- __wt_process.checksum = __wt_checksum_sw;
+ return (__wt_checksum_hw);
+ return (__wt_checksum_sw);
#elif defined(_M_AMD64)
int cpuInfo[4];
@@ -148,14 +151,10 @@ __wt_checksum_init(void)
#define CPUID_ECX_HAS_SSE42 (1 << 20)
if (cpuInfo[2] & CPUID_ECX_HAS_SSE42)
- __wt_process.checksum = __wt_checksum_hw;
- else
- __wt_process.checksum = __wt_checksum_sw;
+ return (__wt_checksum_hw);
+ return (__wt_checksum_sw);
+
#else
- __wt_process.checksum = __wt_checksum_sw;
+ return (__wt_checksum_sw);
#endif
-
-#else /* !HAVE_CRC32_HARDWARE */
- __wt_process.checksum = __wt_checksum_sw;
-#endif /* HAVE_CRC32_HARDWARE */
}
diff --git a/src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.c b/src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.c
index ec7adb02cba..72117d7509d 100644
--- a/src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.c
+++ b/src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.c
@@ -6,12 +6,13 @@
* Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
*
*/
-#include "wt_internal.h"
#include <sys/types.h>
#include <endian.h>
+#include <inttypes.h>
+#include <stddef.h>
-#if defined(__linux__) && defined(HAVE_CRC32_HARDWARE)
+#if defined(__linux__)
#include <sys/auxv.h>
/* RHEL 7 has kernel support, but does not define this constant in the lib c headers. */
@@ -92,23 +93,29 @@ __wt_checksum_hw(const void *chunk, size_t len)
#endif
+extern uint32_t __wt_checksum_sw(const void *chunk, size_t len);
+#if defined(__GNUC__)
+extern uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t)
+ __attribute__((visibility("default")));
+#else
+extern uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t);
+#endif
+
/*
- * __wt_checksum_init --
- * WiredTiger: detect CRC hardware and set the checksum function.
+ * wiredtiger_crc32c_func --
+ * WiredTiger: detect CRC hardware and return the checksum function.
*/
-void
-__wt_checksum_init(void)
- WT_GCC_FUNC_ATTRIBUTE((cold))
+uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t)
{
-#if defined(__linux__) && defined(HAVE_CRC32_HARDWARE)
+#if defined(__linux__)
unsigned long caps = getauxval(AT_HWCAP);
if (caps & HWCAP_S390_VX)
- __wt_process.checksum = __wt_checksum_hw;
+ return (__wt_checksum_hw);
else
- __wt_process.checksum = __wt_checksum_sw;
+ return (__wt_checksum_sw);
#else
- __wt_process.checksum = __wt_checksum_sw;
+ return (__wt_checksum_sw);
#endif
}
diff --git a/src/third_party/wiredtiger/src/config/config_def.c b/src/third_party/wiredtiger/src/config/config_def.c
index 0945d768ce2..abbea9b1bb9 100644
--- a/src/third_party/wiredtiger/src/config/config_def.c
+++ b/src/third_party/wiredtiger/src/config/config_def.c
@@ -190,17 +190,18 @@ static const WT_CONFIG_CHECK confchk_WT_CONNECTION_reconfigure[] = {
{ "timing_stress_for_test", "list",
NULL, "choices=[\"checkpoint_slow\",\"lookaside_sweep_race\","
"\"split_1\",\"split_2\",\"split_3\",\"split_4\",\"split_5\","
- "\"split_6\",\"split_7\",\"split_8\",\"split_9\"]",
+ "\"split_6\",\"split_7\",\"split_8\"]",
NULL, 0 },
{ "verbose", "list",
NULL, "choices=[\"api\",\"block\",\"checkpoint\","
- "\"checkpoint_progress\",\"compact\",\"evict\",\"evict_stuck\","
- "\"evictserver\",\"fileops\",\"handleops\",\"log\",\"lookaside\","
- "\"lookaside_activity\",\"lsm\",\"lsm_manager\",\"metadata\","
- "\"mutex\",\"overflow\",\"read\",\"rebalance\",\"reconcile\","
- "\"recovery\",\"recovery_progress\",\"salvage\",\"shared_cache\","
- "\"split\",\"temporary\",\"thread_group\",\"timestamp\","
- "\"transaction\",\"verify\",\"version\",\"write\"]",
+ "\"checkpoint_progress\",\"compact\",\"error_returns\",\"evict\","
+ "\"evict_stuck\",\"evictserver\",\"fileops\",\"handleops\","
+ "\"log\",\"lookaside\",\"lookaside_activity\",\"lsm\","
+ "\"lsm_manager\",\"metadata\",\"mutex\",\"overflow\",\"read\","
+ "\"rebalance\",\"reconcile\",\"recovery\",\"recovery_progress\","
+ "\"salvage\",\"shared_cache\",\"split\",\"temporary\","
+ "\"thread_group\",\"timestamp\",\"transaction\",\"verify\","
+ "\"version\",\"write\"]",
NULL, 0 },
{ NULL, NULL, NULL, NULL, NULL, 0 }
};
@@ -774,7 +775,7 @@ static const WT_CONFIG_CHECK
{ "path", "string", NULL, NULL, NULL, 0 },
{ "prealloc", "boolean", NULL, NULL, NULL, 0 },
{ "recover", "string",
- NULL, "choices=[\"error\",\"on\"]",
+ NULL, "choices=[\"error\",\"on\",\"salvage\"]",
NULL, 0 },
{ "zero_fill", "boolean", NULL, NULL, NULL, 0 },
{ NULL, NULL, NULL, NULL, NULL, 0 }
@@ -881,7 +882,7 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open[] = {
{ "timing_stress_for_test", "list",
NULL, "choices=[\"checkpoint_slow\",\"lookaside_sweep_race\","
"\"split_1\",\"split_2\",\"split_3\",\"split_4\",\"split_5\","
- "\"split_6\",\"split_7\",\"split_8\",\"split_9\"]",
+ "\"split_6\",\"split_7\",\"split_8\"]",
NULL, 0 },
{ "transaction_sync", "category",
NULL, NULL,
@@ -890,13 +891,14 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open[] = {
{ "use_environment_priv", "boolean", NULL, NULL, NULL, 0 },
{ "verbose", "list",
NULL, "choices=[\"api\",\"block\",\"checkpoint\","
- "\"checkpoint_progress\",\"compact\",\"evict\",\"evict_stuck\","
- "\"evictserver\",\"fileops\",\"handleops\",\"log\",\"lookaside\","
- "\"lookaside_activity\",\"lsm\",\"lsm_manager\",\"metadata\","
- "\"mutex\",\"overflow\",\"read\",\"rebalance\",\"reconcile\","
- "\"recovery\",\"recovery_progress\",\"salvage\",\"shared_cache\","
- "\"split\",\"temporary\",\"thread_group\",\"timestamp\","
- "\"transaction\",\"verify\",\"version\",\"write\"]",
+ "\"checkpoint_progress\",\"compact\",\"error_returns\",\"evict\","
+ "\"evict_stuck\",\"evictserver\",\"fileops\",\"handleops\","
+ "\"log\",\"lookaside\",\"lookaside_activity\",\"lsm\","
+ "\"lsm_manager\",\"metadata\",\"mutex\",\"overflow\",\"read\","
+ "\"rebalance\",\"reconcile\",\"recovery\",\"recovery_progress\","
+ "\"salvage\",\"shared_cache\",\"split\",\"temporary\","
+ "\"thread_group\",\"timestamp\",\"transaction\",\"verify\","
+ "\"version\",\"write\"]",
NULL, 0 },
{ "write_through", "list",
NULL, "choices=[\"data\",\"log\"]",
@@ -985,7 +987,7 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_all[] = {
{ "timing_stress_for_test", "list",
NULL, "choices=[\"checkpoint_slow\",\"lookaside_sweep_race\","
"\"split_1\",\"split_2\",\"split_3\",\"split_4\",\"split_5\","
- "\"split_6\",\"split_7\",\"split_8\",\"split_9\"]",
+ "\"split_6\",\"split_7\",\"split_8\"]",
NULL, 0 },
{ "transaction_sync", "category",
NULL, NULL,
@@ -994,13 +996,14 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_all[] = {
{ "use_environment_priv", "boolean", NULL, NULL, NULL, 0 },
{ "verbose", "list",
NULL, "choices=[\"api\",\"block\",\"checkpoint\","
- "\"checkpoint_progress\",\"compact\",\"evict\",\"evict_stuck\","
- "\"evictserver\",\"fileops\",\"handleops\",\"log\",\"lookaside\","
- "\"lookaside_activity\",\"lsm\",\"lsm_manager\",\"metadata\","
- "\"mutex\",\"overflow\",\"read\",\"rebalance\",\"reconcile\","
- "\"recovery\",\"recovery_progress\",\"salvage\",\"shared_cache\","
- "\"split\",\"temporary\",\"thread_group\",\"timestamp\","
- "\"transaction\",\"verify\",\"version\",\"write\"]",
+ "\"checkpoint_progress\",\"compact\",\"error_returns\",\"evict\","
+ "\"evict_stuck\",\"evictserver\",\"fileops\",\"handleops\","
+ "\"log\",\"lookaside\",\"lookaside_activity\",\"lsm\","
+ "\"lsm_manager\",\"metadata\",\"mutex\",\"overflow\",\"read\","
+ "\"rebalance\",\"reconcile\",\"recovery\",\"recovery_progress\","
+ "\"salvage\",\"shared_cache\",\"split\",\"temporary\","
+ "\"thread_group\",\"timestamp\",\"transaction\",\"verify\","
+ "\"version\",\"write\"]",
NULL, 0 },
{ "version", "string", NULL, NULL, NULL, 0 },
{ "write_through", "list",
@@ -1086,20 +1089,21 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_basecfg[] = {
{ "timing_stress_for_test", "list",
NULL, "choices=[\"checkpoint_slow\",\"lookaside_sweep_race\","
"\"split_1\",\"split_2\",\"split_3\",\"split_4\",\"split_5\","
- "\"split_6\",\"split_7\",\"split_8\",\"split_9\"]",
+ "\"split_6\",\"split_7\",\"split_8\"]",
NULL, 0 },
{ "transaction_sync", "category",
NULL, NULL,
confchk_wiredtiger_open_transaction_sync_subconfigs, 2 },
{ "verbose", "list",
NULL, "choices=[\"api\",\"block\",\"checkpoint\","
- "\"checkpoint_progress\",\"compact\",\"evict\",\"evict_stuck\","
- "\"evictserver\",\"fileops\",\"handleops\",\"log\",\"lookaside\","
- "\"lookaside_activity\",\"lsm\",\"lsm_manager\",\"metadata\","
- "\"mutex\",\"overflow\",\"read\",\"rebalance\",\"reconcile\","
- "\"recovery\",\"recovery_progress\",\"salvage\",\"shared_cache\","
- "\"split\",\"temporary\",\"thread_group\",\"timestamp\","
- "\"transaction\",\"verify\",\"version\",\"write\"]",
+ "\"checkpoint_progress\",\"compact\",\"error_returns\",\"evict\","
+ "\"evict_stuck\",\"evictserver\",\"fileops\",\"handleops\","
+ "\"log\",\"lookaside\",\"lookaside_activity\",\"lsm\","
+ "\"lsm_manager\",\"metadata\",\"mutex\",\"overflow\",\"read\","
+ "\"rebalance\",\"reconcile\",\"recovery\",\"recovery_progress\","
+ "\"salvage\",\"shared_cache\",\"split\",\"temporary\","
+ "\"thread_group\",\"timestamp\",\"transaction\",\"verify\","
+ "\"version\",\"write\"]",
NULL, 0 },
{ "version", "string", NULL, NULL, NULL, 0 },
{ "write_through", "list",
@@ -1185,20 +1189,21 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_usercfg[] = {
{ "timing_stress_for_test", "list",
NULL, "choices=[\"checkpoint_slow\",\"lookaside_sweep_race\","
"\"split_1\",\"split_2\",\"split_3\",\"split_4\",\"split_5\","
- "\"split_6\",\"split_7\",\"split_8\",\"split_9\"]",
+ "\"split_6\",\"split_7\",\"split_8\"]",
NULL, 0 },
{ "transaction_sync", "category",
NULL, NULL,
confchk_wiredtiger_open_transaction_sync_subconfigs, 2 },
{ "verbose", "list",
NULL, "choices=[\"api\",\"block\",\"checkpoint\","
- "\"checkpoint_progress\",\"compact\",\"evict\",\"evict_stuck\","
- "\"evictserver\",\"fileops\",\"handleops\",\"log\",\"lookaside\","
- "\"lookaside_activity\",\"lsm\",\"lsm_manager\",\"metadata\","
- "\"mutex\",\"overflow\",\"read\",\"rebalance\",\"reconcile\","
- "\"recovery\",\"recovery_progress\",\"salvage\",\"shared_cache\","
- "\"split\",\"temporary\",\"thread_group\",\"timestamp\","
- "\"transaction\",\"verify\",\"version\",\"write\"]",
+ "\"checkpoint_progress\",\"compact\",\"error_returns\",\"evict\","
+ "\"evict_stuck\",\"evictserver\",\"fileops\",\"handleops\","
+ "\"log\",\"lookaside\",\"lookaside_activity\",\"lsm\","
+ "\"lsm_manager\",\"metadata\",\"mutex\",\"overflow\",\"read\","
+ "\"rebalance\",\"reconcile\",\"recovery\",\"recovery_progress\","
+ "\"salvage\",\"shared_cache\",\"split\",\"temporary\","
+ "\"thread_group\",\"timestamp\",\"transaction\",\"verify\","
+ "\"version\",\"write\"]",
NULL, 0 },
{ "write_through", "list",
NULL, "choices=[\"data\",\"log\"]",
diff --git a/src/third_party/wiredtiger/src/conn/conn_api.c b/src/third_party/wiredtiger/src/conn/conn_api.c
index 589560acc88..47ab622a7f4 100644
--- a/src/third_party/wiredtiger/src/conn/conn_api.c
+++ b/src/third_party/wiredtiger/src/conn/conn_api.c
@@ -1832,6 +1832,7 @@ __wt_verbose_config(WT_SESSION_IMPL *session, const char *cfg[])
{ "checkpoint", WT_VERB_CHECKPOINT },
{ "checkpoint_progress",WT_VERB_CHECKPOINT_PROGRESS },
{ "compact", WT_VERB_COMPACT },
+ { "error_returns", WT_VERB_ERROR_RETURNS },
{ "evict", WT_VERB_EVICT },
{ "evict_stuck", WT_VERB_EVICT_STUCK },
{ "evictserver", WT_VERB_EVICTSERVER },
@@ -2025,7 +2026,6 @@ __wt_timing_stress_config(WT_SESSION_IMPL *session, const char *cfg[])
{ "split_6", WT_TIMING_STRESS_SPLIT_6 },
{ "split_7", WT_TIMING_STRESS_SPLIT_7 },
{ "split_8", WT_TIMING_STRESS_SPLIT_8 },
- { "split_9", WT_TIMING_STRESS_SPLIT_9 },
{ NULL, 0 }
};
WT_CONFIG_ITEM cval, sval;
@@ -2750,15 +2750,3 @@ err: /* Discard the scratch buffers. */
return (ret);
}
-
-/*
- * wiredtiger_checksum_crc32c --
- * CRC32C checksum function entry point.
- */
-uint32_t
-wiredtiger_checksum_crc32c(const void *buffer, size_t len)
-{
- if (__wt_process.checksum == NULL)
- __wt_checksum_init();
- return (__wt_process.checksum(buffer, len));
-}
diff --git a/src/third_party/wiredtiger/src/conn/conn_dhandle.c b/src/third_party/wiredtiger/src/conn/conn_dhandle.c
index 7c24f3c126f..7013ade0f27 100644
--- a/src/third_party/wiredtiger/src/conn/conn_dhandle.c
+++ b/src/third_party/wiredtiger/src/conn/conn_dhandle.c
@@ -47,7 +47,7 @@ __conn_dhandle_config_set(WT_SESSION_IMPL *session)
if ((ret =
__wt_metadata_search(session, dhandle->name, &metaconf)) != 0) {
if (ret == WT_NOTFOUND)
- ret = ENOENT;
+ ret = __wt_set_return(session, ENOENT);
WT_RET(ret);
}
@@ -703,7 +703,7 @@ __conn_dhandle_remove(WT_SESSION_IMPL *session, bool final)
/* Check if the handle was reacquired by a session while we waited. */
if (!final &&
(dhandle->session_inuse != 0 || dhandle->session_ref != 0))
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
WT_CONN_DHANDLE_REMOVE(conn, dhandle, bucket);
return (0);
diff --git a/src/third_party/wiredtiger/src/conn/conn_log.c b/src/third_party/wiredtiger/src/conn/conn_log.c
index d8eb095d6d2..34570fdd0be 100644
--- a/src/third_party/wiredtiger/src/conn/conn_log.c
+++ b/src/third_party/wiredtiger/src/conn/conn_log.c
@@ -299,6 +299,13 @@ __logmgr_config(
session, cfg, "log.recover", 0, &cval));
if (WT_STRING_MATCH("error", cval.str, cval.len))
FLD_SET(conn->log_flags, WT_CONN_LOG_RECOVER_ERR);
+ else if (WT_STRING_MATCH("salvage", cval.str, cval.len)) {
+ if (F_ISSET(conn, WT_CONN_READONLY))
+ WT_RET_MSG(session, EINVAL,
+ "Readonly configuration incompatible with "
+ "log=(recover=salvage)");
+ FLD_SET(conn->log_flags, WT_CONN_LOG_RECOVER_SALVAGE);
+ }
}
WT_RET(__wt_config_gets(session, cfg, "log.zero_fill", &cval));
diff --git a/src/third_party/wiredtiger/src/docs/config-strings.dox b/src/third_party/wiredtiger/src/docs/config-strings.dox
index a583573214f..d6291d5b4ba 100644
--- a/src/third_party/wiredtiger/src/docs/config-strings.dox
+++ b/src/third_party/wiredtiger/src/docs/config-strings.dox
@@ -44,7 +44,7 @@ columns in a table, values are nested using parentheses. For example:
All types of parentheses are treated equivalently by the parser.
-When an integer values is expected, the value may have multiplier characters
+When an integer value is expected, the value may have multiplier characters
appended, as follows:
<table>
diff --git a/src/third_party/wiredtiger/src/docs/top/main.dox b/src/third_party/wiredtiger/src/docs/top/main.dox
index e4de22ff042..d802443a9d8 100644
--- a/src/third_party/wiredtiger/src/docs/top/main.dox
+++ b/src/third_party/wiredtiger/src/docs/top/main.dox
@@ -6,12 +6,12 @@ WiredTiger is an high performance, scalable, production quality, NoSQL,
@section releases Releases
<table>
-@row{<b>WiredTiger 3.0.0</b> (current),
+@row{<b>WiredTiger 3.1.0</b> (current),
+ <a href="releases/wiredtiger-3.1.0.tar.bz2"><b>[Release package]</b></a>,
+ <a href="3.1.0/index.html"><b>[Documentation]</b></a>}
+@row{<b>WiredTiger 3.0.0</b> (previous),
<a href="releases/wiredtiger-3.0.0.tar.bz2"><b>[Release package]</b></a>,
<a href="3.0.0/index.html"><b>[Documentation]</b></a>}
-@row{<b>WiredTiger 2.9.3</b> (previous),
- <a href="releases/wiredtiger-2.9.3.tar.bz2"><b>[Release package]</b></a>,
- <a href="2.9.3/index.html"><b>[Documentation]</b></a>}
@row{<b>Development branch</b>,
<a href="https://github.com/wiredtiger/wiredtiger"><b>[Source code]</b></a>,
<a href="develop/index.html"><b>[Documentation]</b></a>}
diff --git a/src/third_party/wiredtiger/src/docs/upgrading.dox b/src/third_party/wiredtiger/src/docs/upgrading.dox
index 2e4990e8a33..7e89d23230f 100644
--- a/src/third_party/wiredtiger/src/docs/upgrading.dox
+++ b/src/third_party/wiredtiger/src/docs/upgrading.dox
@@ -1,5 +1,61 @@
/*! @page upgrading Upgrading WiredTiger applications
+@section version_310 Upgrading to Version 3.1.0
+<dl>
+
+<dt>WiredTiger on-disk log file format change</dt>
+<dd>
+The WiredTiger on-disk file format for write-ahead log files has changed
+as the log file version number was incremented. See
+<a href=https://jira.mongodb.org/browse/WT-4029>WT-4029</a> for details.
+</dd>
+
+<dt>::wiredtiger_open compatibility configuration changes</dt>
+<dd>
+The compatibility setting now takes additional options that can define
+the minimum or maximum required version of existing data files. See
+<a href=https://jira.mongodb.org/browse/WT-4056>WT-4056</a> and
+<a href=https://jira.mongodb.org/browse/WT-4098>WT-4098</a> for details.
+</dd>
+<dt>::wiredtiger_open cache configuration changes</dt>
+<dd>
+The cache configuration options \c eviction_checkpoint_target, \c
+eviction_dirty_target, \c eviction_dirty_trigger, \c eviction_target and \c
+eviction_trigger have changed. The options can now take an absolute size. It would
+be a percentage of the cache size if the value is within the range of 0 to 100
+or an absolute size when greater than 100. This API change is compatible with
+existing usage. See <a href=https://jira.mongodb.org/browse/WT-3632>WT-3632</a>
+for details.
+</dd>
+
+<dt>Changed transaction semantics around schema operations</dt>
+<dd>
+WiredTiger does not offer fully transactional create and drop operations.
+We have made some changes to how create and drop are implemented
+if done within the scope of an explicit transaction. If an application
+is relying on particular visibility/atomicity guarantees around table
+create or drop, care should be taken when upgrading. See
+<a href=https://jira.mongodb.org/browse/WT-3964>WT-3964</a> for details.
+</dd>
+
+<dt>On-disk format change for metadata</dt>
+<dd>
+There was a change to the content stored in the WiredTiger owned metadata
+files, which means metadata created or updated by this version of WiredTiger
+is not compatible with earlier versions. See
+<a href=https://jira.mongodb.org/browse/WT-3905>WT-3905</a> for details.
+</dd>
+
+<dt>Implement a per-session cursor cache</dt>
+<dd>
+WiredTiger now holds a cache of recently closed cursors in each
+session. This improves performance for applications that open and
+close cursors frequently, but increases memory overhead. The cache
+is enabled by default, but can be disabled. See
+<a href=https://jira.mongodb.org/browse/WT-1228>WT-1228</a> for details.
+</dd>
+
+</dl><hr>
@section version_300 Upgrading to Version 3.0.0
<dl>
@@ -28,16 +84,6 @@ The performance visualization tool \c wtstats has been removed and is
no longer supported.
</dd>
-<dt>::wiredtiger_open cache configuration changes</dt>
-<dd>
-The cache configuration options \c eviction_checkpoint_target, \c
-eviction_dirty_target, \c eviction_dirty_trigger, \c eviction_target and \c
-eviction_trigger have changed. The options can now take absolute size. It would
-be a percentage of the cache size if the value is within the range of 0 to 100
-or an absolute size when greater than 100. This API change is compatible with
-existing usage.
-</dd>
-
</dl><hr>
@section version_292 Upgrading to Version 2.9.2
<dl>
diff --git a/src/third_party/wiredtiger/src/evict/evict_lru.c b/src/third_party/wiredtiger/src/evict/evict_lru.c
index 05397843fc7..13b5dfc4c8d 100644
--- a/src/third_party/wiredtiger/src/evict/evict_lru.c
+++ b/src/third_party/wiredtiger/src/evict/evict_lru.c
@@ -451,7 +451,7 @@ __evict_server(WT_SESSION_IMPL *session, bool *did_work)
"Cache stuck for too long, giving up");
WT_RET(__wt_verbose_dump_txn(session));
WT_RET(__wt_verbose_dump_cache(session));
- return (ETIMEDOUT);
+ return (__wt_set_return(session, ETIMEDOUT));
#else
if (WT_VERBOSE_ISSET(session, WT_VERB_EVICT_STUCK)) {
WT_RET(__wt_verbose_dump_txn(session));
diff --git a/src/third_party/wiredtiger/src/evict/evict_page.c b/src/third_party/wiredtiger/src/evict/evict_page.c
index 0daccdf5b1c..71e084773d0 100644
--- a/src/third_party/wiredtiger/src/evict/evict_page.c
+++ b/src/third_party/wiredtiger/src/evict/evict_page.c
@@ -42,7 +42,7 @@ __evict_exclusive(WT_SESSION_IMPL *session, WT_REF *ref)
WT_STAT_DATA_INCR(session, cache_eviction_hazard);
WT_STAT_CONN_INCR(session, cache_eviction_hazard);
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
}
/*
@@ -453,7 +453,7 @@ __evict_child_check(WT_SESSION_IMPL *session, WT_REF *parent)
* page.
*/
if (__wt_page_del_active(session, child, true))
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
break;
case WT_REF_LOOKASIDE:
/*
@@ -461,10 +461,10 @@ __evict_child_check(WT_SESSION_IMPL *session, WT_REF *parent)
* can be ignored.
*/
if (__wt_page_las_active(session, child))
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
break;
default:
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
}
} WT_INTL_FOREACH_END;
@@ -528,7 +528,7 @@ __evict_review(
* should be uncommon - we don't add clean pages to the queue.
*/
if (F_ISSET(conn, WT_CONN_IN_MEMORY) && !modified && !closing)
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
/* Check if the page can be evicted. */
if (!closing) {
@@ -541,7 +541,7 @@ __evict_review(
session, WT_TXN_OLDEST_STRICT));
if (!__wt_page_can_evict(session, ref, inmem_splitp))
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
/*
* Check for an append-only workload needing an in-memory
@@ -563,7 +563,7 @@ __evict_review(
* eviction that writes to lookaside), give up.
*/
if (F_ISSET(session, WT_SESSION_NO_RECONCILE))
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
/*
* If the page is dirty, reconcile it to decide if we can evict it.
@@ -636,7 +636,7 @@ __evict_review(
if (WT_SESSION_IS_CHECKPOINT(session) && !__wt_page_is_modified(page) &&
!__wt_txn_visible_all(session, page->modify->rec_max_txn,
WT_TIMESTAMP_NULL(&page->modify->rec_max_timestamp)))
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
/*
* If reconciliation fails but reports it might succeed if we use the
@@ -663,7 +663,7 @@ __evict_review(
*/
if (WT_SESSION_IS_CHECKPOINT(session) &&
page->modify->rec_result == WT_PM_REC_MULTIBLOCK)
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
/*
* Success: assert the page is clean or reconciliation was configured
diff --git a/src/third_party/wiredtiger/src/include/btree.i b/src/third_party/wiredtiger/src/include/btree.i
index 7813f1299fd..ed3480a40d0 100644
--- a/src/third_party/wiredtiger/src/include/btree.i
+++ b/src/third_party/wiredtiger/src/include/btree.i
@@ -1357,13 +1357,12 @@ __wt_page_evict_retry(WT_SESSION_IMPL *session, WT_PAGE *page)
return (true);
#ifdef HAVE_TIMESTAMPS
- if (!__wt_timestamp_iszero(&mod->last_eviction_timestamp)) {
- __wt_txn_pinned_timestamp(session, &pinned_ts);
- if (__wt_timestamp_cmp(
- &mod->last_eviction_timestamp,
- &txn_global->pinned_timestamp) != 0)
- return (true);
- }
+ if (__wt_timestamp_iszero(&mod->last_eviction_timestamp))
+ return (true);
+
+ __wt_txn_pinned_timestamp(session, &pinned_ts);
+ if (__wt_timestamp_cmp(&pinned_ts, &mod->last_eviction_timestamp) > 0)
+ return (true);
#endif
return (false);
diff --git a/src/third_party/wiredtiger/src/include/cache.i b/src/third_party/wiredtiger/src/include/cache.i
index 7f12949e162..2e3700f6287 100644
--- a/src/third_party/wiredtiger/src/include/cache.i
+++ b/src/third_party/wiredtiger/src/include/cache.i
@@ -220,9 +220,9 @@ __wt_cache_update_lookaside_score(
global_score = cache->evict_lookaside_score;
if (score > global_score && global_score < 100)
- __wt_atomic_addi32(&cache->evict_lookaside_score, 1);
+ (void)__wt_atomic_addi32(&cache->evict_lookaside_score, 1);
else if (score < global_score && global_score > 0)
- __wt_atomic_subi32(&cache->evict_lookaside_score, 1);
+ (void)__wt_atomic_subi32(&cache->evict_lookaside_score, 1);
}
/*
diff --git a/src/third_party/wiredtiger/src/include/connection.h b/src/third_party/wiredtiger/src/include/connection.h
index 22459b0072c..19bb21ce2f1 100644
--- a/src/third_party/wiredtiger/src/include/connection.h
+++ b/src/third_party/wiredtiger/src/include/connection.h
@@ -322,7 +322,8 @@ struct __wt_connection_impl {
#define WT_CONN_LOG_RECOVER_DIRTY 0x020u /* Recovering unclean */
#define WT_CONN_LOG_RECOVER_DONE 0x040u /* Recovery completed */
#define WT_CONN_LOG_RECOVER_ERR 0x080u /* Error if recovery required */
-#define WT_CONN_LOG_ZERO_FILL 0x100u /* Manually zero files */
+#define WT_CONN_LOG_RECOVER_SALVAGE 0x100u /* Salvage log files */
+#define WT_CONN_LOG_ZERO_FILL 0x200u /* Manually zero files */
/* AUTOMATIC FLAG VALUE GENERATION STOP */
uint32_t log_flags; /* Global logging configuration */
WT_CONDVAR *log_cond; /* Log server wait mutex */
@@ -413,34 +414,35 @@ struct __wt_connection_impl {
#define WT_VERB_CHECKPOINT 0x000000004u
#define WT_VERB_CHECKPOINT_PROGRESS 0x000000008u
#define WT_VERB_COMPACT 0x000000010u
-#define WT_VERB_EVICT 0x000000020u
-#define WT_VERB_EVICTSERVER 0x000000040u
-#define WT_VERB_EVICT_STUCK 0x000000080u
-#define WT_VERB_FILEOPS 0x000000100u
-#define WT_VERB_HANDLEOPS 0x000000200u
-#define WT_VERB_LOG 0x000000400u
-#define WT_VERB_LOOKASIDE 0x000000800u
-#define WT_VERB_LOOKASIDE_ACTIVITY 0x000001000u
-#define WT_VERB_LSM 0x000002000u
-#define WT_VERB_LSM_MANAGER 0x000004000u
-#define WT_VERB_METADATA 0x000008000u
-#define WT_VERB_MUTEX 0x000010000u
-#define WT_VERB_OVERFLOW 0x000020000u
-#define WT_VERB_READ 0x000040000u
-#define WT_VERB_REBALANCE 0x000080000u
-#define WT_VERB_RECONCILE 0x000100000u
-#define WT_VERB_RECOVERY 0x000200000u
-#define WT_VERB_RECOVERY_PROGRESS 0x000400000u
-#define WT_VERB_SALVAGE 0x000800000u
-#define WT_VERB_SHARED_CACHE 0x001000000u
-#define WT_VERB_SPLIT 0x002000000u
-#define WT_VERB_TEMPORARY 0x004000000u
-#define WT_VERB_THREAD_GROUP 0x008000000u
-#define WT_VERB_TIMESTAMP 0x010000000u
-#define WT_VERB_TRANSACTION 0x020000000u
-#define WT_VERB_VERIFY 0x040000000u
-#define WT_VERB_VERSION 0x080000000u
-#define WT_VERB_WRITE 0x100000000u
+#define WT_VERB_ERROR_RETURNS 0x000000020u
+#define WT_VERB_EVICT 0x000000040u
+#define WT_VERB_EVICTSERVER 0x000000080u
+#define WT_VERB_EVICT_STUCK 0x000000100u
+#define WT_VERB_FILEOPS 0x000000200u
+#define WT_VERB_HANDLEOPS 0x000000400u
+#define WT_VERB_LOG 0x000000800u
+#define WT_VERB_LOOKASIDE 0x000001000u
+#define WT_VERB_LOOKASIDE_ACTIVITY 0x000002000u
+#define WT_VERB_LSM 0x000004000u
+#define WT_VERB_LSM_MANAGER 0x000008000u
+#define WT_VERB_METADATA 0x000010000u
+#define WT_VERB_MUTEX 0x000020000u
+#define WT_VERB_OVERFLOW 0x000040000u
+#define WT_VERB_READ 0x000080000u
+#define WT_VERB_REBALANCE 0x000100000u
+#define WT_VERB_RECONCILE 0x000200000u
+#define WT_VERB_RECOVERY 0x000400000u
+#define WT_VERB_RECOVERY_PROGRESS 0x000800000u
+#define WT_VERB_SALVAGE 0x001000000u
+#define WT_VERB_SHARED_CACHE 0x002000000u
+#define WT_VERB_SPLIT 0x004000000u
+#define WT_VERB_TEMPORARY 0x008000000u
+#define WT_VERB_THREAD_GROUP 0x010000000u
+#define WT_VERB_TIMESTAMP 0x020000000u
+#define WT_VERB_TRANSACTION 0x040000000u
+#define WT_VERB_VERIFY 0x080000000u
+#define WT_VERB_VERSION 0x100000000u
+#define WT_VERB_WRITE 0x200000000u
/* AUTOMATIC FLAG VALUE GENERATION STOP */
uint64_t verbose;
@@ -459,7 +461,6 @@ struct __wt_connection_impl {
#define WT_TIMING_STRESS_SPLIT_6 0x080u
#define WT_TIMING_STRESS_SPLIT_7 0x100u
#define WT_TIMING_STRESS_SPLIT_8 0x200u
-#define WT_TIMING_STRESS_SPLIT_9 0x400u
/* AUTOMATIC FLAG VALUE GENERATION STOP */
uint64_t timing_stress_flags;
diff --git a/src/third_party/wiredtiger/src/include/error.h b/src/third_party/wiredtiger/src/include/error.h
index f94c3d7b880..c85f67e6f0b 100644
--- a/src/third_party/wiredtiger/src/include/error.h
+++ b/src/third_party/wiredtiger/src/include/error.h
@@ -19,6 +19,13 @@
#define WT_DIAGNOSTIC_YIELD
#endif
+#define __wt_err(session, error, ...) \
+ __wt_err_func(session, error, __func__, __LINE__, __VA_ARGS__)
+#define __wt_errx(session, ...) \
+ __wt_errx_func(session, __func__, __LINE__, __VA_ARGS__)
+#define __wt_set_return(session, error) \
+ __wt_set_return_func(session, __func__, __LINE__, error)
+
/* Set "ret" and branch-to-err-label tests. */
#define WT_ERR(a) do { \
if ((ret = (a)) != 0) \
@@ -125,8 +132,10 @@
*/
#ifdef HAVE_DIAGNOSTIC
#define WT_ASSERT(session, exp) do { \
- if (!(exp)) \
- __wt_assert(session, 0, __func__, __LINE__, "%s", #exp);\
+ if (!(exp)) { \
+ __wt_errx(session, "%s", #exp); \
+ __wt_abort(session); \
+ } \
} while (0)
#else
#define WT_ASSERT(session, exp) \
diff --git a/src/third_party/wiredtiger/src/include/extern.h b/src/third_party/wiredtiger/src/include/extern.h
index 24e16adefd1..6df9da759c3 100644
--- a/src/third_party/wiredtiger/src/include/extern.h
+++ b/src/third_party/wiredtiger/src/include/extern.h
@@ -215,8 +215,7 @@ extern int __wt_las_cursor_position(WT_CURSOR *cursor, uint64_t pageid) WT_GCC_F
extern int __wt_las_remove_block(WT_SESSION_IMPL *session, uint64_t pageid, bool lock_wait) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_las_save_dropped(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_las_sweep(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
-extern uint32_t __wt_checksum_sw(const void *chunk, size_t len) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")));
-extern void __wt_checksum_init(void) WT_GCC_FUNC_DECL_ATTRIBUTE((cold));
+extern uint32_t __wt_checksum_sw(const void *chunk, size_t len);
extern void __wt_config_initn(WT_SESSION_IMPL *session, WT_CONFIG *conf, const char *str, size_t len);
extern void __wt_config_init(WT_SESSION_IMPL *session, WT_CONFIG *conf, const char *str);
extern void __wt_config_subinit(WT_SESSION_IMPL *session, WT_CONFIG *conf, WT_CONFIG_ITEM *item);
@@ -549,7 +548,7 @@ extern int __wt_nfilename(WT_SESSION_IMPL *session, const char *name, size_t nam
extern int __wt_filename_construct(WT_SESSION_IMPL *session, const char *path, const char *file_prefix, uintmax_t id_1, uint32_t id_2, WT_ITEM *buf) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_remove_if_exists(WT_SESSION_IMPL *session, const char *name, bool durable) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_copy_and_sync(WT_SESSION *wt_session, const char *from, const char *to) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default"))) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
-extern void __wt_abort(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn));
+extern void __wt_abort(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")));
extern int __wt_calloc(WT_SESSION_IMPL *session, size_t number, size_t size, void *retp) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default"))) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_malloc(WT_SESSION_IMPL *session, size_t bytes_to_allocate, void *retp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_realloc(WT_SESSION_IMPL *session, size_t *bytes_allocated_ret, size_t bytes_to_allocate, void *retp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
@@ -676,23 +675,15 @@ extern int __wt_decrypt(WT_SESSION_IMPL *session, WT_ENCRYPTOR *encryptor, size_
extern int __wt_encrypt(WT_SESSION_IMPL *session, WT_KEYED_ENCRYPTOR *kencryptor, size_t skip, WT_ITEM *in, WT_ITEM *out) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern void __wt_encrypt_size(WT_SESSION_IMPL *session, WT_KEYED_ENCRYPTOR *kencryptor, size_t incoming_size, size_t *sizep);
extern void __wt_event_handler_set(WT_SESSION_IMPL *session, WT_EVENT_HANDLER *handler);
-extern void __wt_err(WT_SESSION_IMPL *session, int error, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4))) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")));
-extern void __wt_errx(WT_SESSION_IMPL *session, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 2, 3)));
+extern void __wt_err_func(WT_SESSION_IMPL *session, int error, const char *func_name, int line_number, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 5, 6))) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")));
+extern void __wt_errx_func(WT_SESSION_IMPL *session, const char *func_name, int line_number, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 4, 5))) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")));
+extern int __wt_set_return_func(WT_SESSION_IMPL *session, const char*func, int line, int err) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_ext_err_printf(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4))) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern void __wt_verbose_worker(WT_SESSION_IMPL *session, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 2, 3))) WT_GCC_FUNC_DECL_ATTRIBUTE((cold));
extern int __wt_msg(WT_SESSION_IMPL *session, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 2, 3))) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_ext_msg_printf(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4))) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern const char *__wt_ext_strerror(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, int error);
extern int __wt_progress(WT_SESSION_IMPL *session, const char *s, uint64_t v) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
-extern void
-__wt_assert(WT_SESSION_IMPL *session,
- int error, const char *file_name, int line_number, const char *fmt, ...)
- WT_GCC_FUNC_DECL_ATTRIBUTE((cold))
- WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 5, 6)))
-#ifdef HAVE_DIAGNOSTIC
- WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn))
-#endif
- WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")));
extern int __wt_panic(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default"))) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_illegal_value_func(WT_SESSION_IMPL *session, const char *tag, const char *file, int line) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default"))) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_inmem_unsupported_op(WT_SESSION_IMPL *session, const char *tag) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
@@ -724,6 +715,7 @@ extern int __wt_hazard_clear(WT_SESSION_IMPL *session, WT_REF *ref) WT_GCC_FUNC_
extern void __wt_hazard_close(WT_SESSION_IMPL *session);
extern WT_HAZARD *__wt_hazard_check(WT_SESSION_IMPL *session, WT_REF *ref);
extern u_int __wt_hazard_count(WT_SESSION_IMPL *session, WT_REF *ref);
+extern bool __wt_hazard_check_assert(WT_SESSION_IMPL *session, void *ref, bool waitfor) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern void __wt_fill_hex(const uint8_t *src, size_t src_max, uint8_t *dest, size_t dest_max, size_t *lenp);
extern int __wt_raw_to_hex(WT_SESSION_IMPL *session, const uint8_t *from, size_t size, WT_ITEM *to) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_raw_to_esc_hex(WT_SESSION_IMPL *session, const uint8_t *from, size_t size, WT_ITEM *to) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
diff --git a/src/third_party/wiredtiger/src/include/misc.h b/src/third_party/wiredtiger/src/include/misc.h
index 7060e6cea23..c56dea0a074 100644
--- a/src/third_party/wiredtiger/src/include/misc.h
+++ b/src/third_party/wiredtiger/src/include/misc.h
@@ -338,3 +338,50 @@ union __wt_rand_state {
continue; \
}
#define WT_TAILQ_SAFE_REMOVE_END }
+
+/*
+ * WT_VA_ARGS_BUF_FORMAT --
+ * Format into a scratch buffer, extending it as necessary. This is a
+ * macro because we need to repeatedly call va_start/va_end and there's no
+ * way to do that inside a function call.
+ */
+#define WT_VA_ARGS_BUF_FORMAT(session, buf, fmt, concatenate) do { \
+ size_t __len, __space; \
+ va_list __ap; \
+ int __ret_xx; /* __ret already used by WT_RET */ \
+ char *__p; \
+ \
+ /* \
+ * This macro is used to both initialize and concatenate into a \
+ * buffer. If not concatenating, clear the size so we don't use \
+ * any existing contents. \
+ */ \
+ if (!concatenate) \
+ (buf)->size = 0; \
+ for (;;) { \
+ WT_ASSERT(session, (buf)->memsize >= (buf)->size); \
+ __p = (char *)((uint8_t *)(buf)->mem + (buf)->size); \
+ __space = (buf)->memsize - (buf)->size; \
+ \
+ /* Format into the buffer. */ \
+ va_start(__ap, fmt); \
+ __ret_xx = __wt_vsnprintf_len_set( \
+ __p, __space, &__len, fmt, __ap); \
+ va_end(__ap); \
+ WT_RET(__ret_xx); \
+ \
+ /* Check if there was enough space. */ \
+ if (__len < __space) { \
+ (buf)->data = (buf)->mem; \
+ (buf)->size += __len; \
+ break; \
+ } \
+ \
+ /* \
+ * If not, double the size of the buffer: we're dealing \
+ * with strings, we don't expect the size to get huge. \
+ */ \
+ WT_RET(__wt_buf_extend( \
+ session, buf, (buf)->size + __len + 1)); \
+ } \
+} while (0)
diff --git a/src/third_party/wiredtiger/src/include/misc.i b/src/third_party/wiredtiger/src/include/misc.i
index 2c380e95ade..5c9f95bc08a 100644
--- a/src/third_party/wiredtiger/src/include/misc.i
+++ b/src/third_party/wiredtiger/src/include/misc.i
@@ -259,15 +259,26 @@ __wt_spin_backoff(uint64_t *yield_count, uint64_t *sleep_usecs)
static inline void
__wt_timing_stress(WT_SESSION_IMPL *session, u_int flag)
{
- WT_CONNECTION_IMPL *conn;
- uint64_t sleep_usecs;
+ uint64_t i;
- conn = S2C(session);
-
- /* Only sleep when the specified configuration flag is set. */
- if (!FLD_ISSET(conn->timing_stress_flags, flag))
+ /* Optionally only sleep when a specified configuration flag is set. */
+ if (flag != 0 && !FLD_ISSET(S2C(session)->timing_stress_flags, flag))
return;
- sleep_usecs = __wt_random(&session->rnd) % WT_TIMING_STRESS_MAX_DELAY;
- __wt_sleep(0, sleep_usecs);
+ /*
+ * We need a fast way to choose a sleep time. We want to sleep a short
+ * period most of the time, but occasionally wait longer. Divide the
+ * maximum period of time into 10 buckets (where bucket 0 doesn't sleep
+ * at all), and roll dice, advancing to the next bucket 50% of the time.
+ * That means we'll hit the maximum roughly every 1K calls.
+ */
+ for (i = 0;;)
+ if (__wt_random(&session->rnd) & 0x1 || ++i > 9)
+ break;
+
+ if (i == 0)
+ __wt_yield();
+ else
+ /* The default maximum delay is 1/10th of a second. */
+ __wt_sleep(0, i * (WT_TIMING_STRESS_MAX_DELAY / 10));
}
diff --git a/src/third_party/wiredtiger/src/include/os_fhandle.i b/src/third_party/wiredtiger/src/include/os_fhandle.i
index 7c09a83132c..78d01abca4b 100644
--- a/src/third_party/wiredtiger/src/include/os_fhandle.i
+++ b/src/third_party/wiredtiger/src/include/os_fhandle.i
@@ -72,7 +72,7 @@ __wt_fextend(WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t offset)
if (handle->fh_extend != NULL)
return (handle->fh_extend(
handle, (WT_SESSION *)session, offset));
- return (ENOTSUP);
+ return (__wt_set_return(session, ENOTSUP));
}
/*
@@ -157,7 +157,7 @@ __wt_ftruncate(WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t offset)
if (handle->fh_truncate != NULL)
return (handle->fh_truncate(
handle, (WT_SESSION *)session, offset));
- return (ENOTSUP);
+ return (__wt_set_return(session, ENOTSUP));
}
/*
diff --git a/src/third_party/wiredtiger/src/include/wiredtiger.in b/src/third_party/wiredtiger/src/include/wiredtiger.in
index a4ba834d5ef..2dcf65319b8 100644
--- a/src/third_party/wiredtiger/src/include/wiredtiger.in
+++ b/src/third_party/wiredtiger/src/include/wiredtiger.in
@@ -2334,15 +2334,15 @@ struct __wt_connection {
* given as a list\, such as
* <code>"verbose=[evictserver\,read]"</code>., a list\, with values
* chosen from the following options: \c "api"\, \c "block"\, \c
- * "checkpoint"\, \c "checkpoint_progress"\, \c "compact"\, \c "evict"\,
- * \c "evict_stuck"\, \c "evictserver"\, \c "fileops"\, \c "handleops"\,
- * \c "log"\, \c "lookaside"\, \c "lookaside_activity"\, \c "lsm"\, \c
- * "lsm_manager"\, \c "metadata"\, \c "mutex"\, \c "overflow"\, \c
- * "read"\, \c "rebalance"\, \c "reconcile"\, \c "recovery"\, \c
- * "recovery_progress"\, \c "salvage"\, \c "shared_cache"\, \c "split"\,
- * \c "temporary"\, \c "thread_group"\, \c "timestamp"\, \c
- * "transaction"\, \c "verify"\, \c "version"\, \c "write"; default
- * empty.}
+ * "checkpoint"\, \c "checkpoint_progress"\, \c "compact"\, \c
+ * "error_returns"\, \c "evict"\, \c "evict_stuck"\, \c "evictserver"\,
+ * \c "fileops"\, \c "handleops"\, \c "log"\, \c "lookaside"\, \c
+ * "lookaside_activity"\, \c "lsm"\, \c "lsm_manager"\, \c "metadata"\,
+ * \c "mutex"\, \c "overflow"\, \c "read"\, \c "rebalance"\, \c
+ * "reconcile"\, \c "recovery"\, \c "recovery_progress"\, \c "salvage"\,
+ * \c "shared_cache"\, \c "split"\, \c "temporary"\, \c "thread_group"\,
+ * \c "timestamp"\, \c "transaction"\, \c "verify"\, \c "version"\, \c
+ * "write"; default empty.}
* @configend
* @errors
*/
@@ -2902,9 +2902,10 @@ struct __wt_connection {
* flag; default \c true.}
* @config{&nbsp;&nbsp;&nbsp;&nbsp;recover, run recovery
* or error if recovery needs to run after an unclean shutdown., a string\,
- * chosen from the following options: \c "error"\, \c "on"; default \c on.}
- * @config{&nbsp;&nbsp;&nbsp;&nbsp;zero_fill, manually write zeroes into log
- * files., a boolean flag; default \c false.}
+ * chosen from the following options: \c "error"\, \c "on"\, \c "salvage";
+ * default \c on.}
+ * @config{&nbsp;&nbsp;&nbsp;&nbsp;zero_fill, manually write
+ * zeroes into log files., a boolean flag; default \c false.}
* @config{ ),,}
* @config{lsm_manager = (, configure database wide options for LSM tree
* management. The LSM manager is started automatically the first time an LSM
@@ -3017,14 +3018,14 @@ struct __wt_connection {
* @config{verbose, enable messages for various events. Options are given as a
* list\, such as <code>"verbose=[evictserver\,read]"</code>., a list\, with
* values chosen from the following options: \c "api"\, \c "block"\, \c
- * "checkpoint"\, \c "checkpoint_progress"\, \c "compact"\, \c "evict"\, \c
- * "evict_stuck"\, \c "evictserver"\, \c "fileops"\, \c "handleops"\, \c "log"\,
- * \c "lookaside"\, \c "lookaside_activity"\, \c "lsm"\, \c "lsm_manager"\, \c
- * "metadata"\, \c "mutex"\, \c "overflow"\, \c "read"\, \c "rebalance"\, \c
- * "reconcile"\, \c "recovery"\, \c "recovery_progress"\, \c "salvage"\, \c
- * "shared_cache"\, \c "split"\, \c "temporary"\, \c "thread_group"\, \c
- * "timestamp"\, \c "transaction"\, \c "verify"\, \c "version"\, \c "write";
- * default empty.}
+ * "checkpoint"\, \c "checkpoint_progress"\, \c "compact"\, \c "error_returns"\,
+ * \c "evict"\, \c "evict_stuck"\, \c "evictserver"\, \c "fileops"\, \c
+ * "handleops"\, \c "log"\, \c "lookaside"\, \c "lookaside_activity"\, \c
+ * "lsm"\, \c "lsm_manager"\, \c "metadata"\, \c "mutex"\, \c "overflow"\, \c
+ * "read"\, \c "rebalance"\, \c "reconcile"\, \c "recovery"\, \c
+ * "recovery_progress"\, \c "salvage"\, \c "shared_cache"\, \c "split"\, \c
+ * "temporary"\, \c "thread_group"\, \c "timestamp"\, \c "transaction"\, \c
+ * "verify"\, \c "version"\, \c "write"; default empty.}
* @config{write_through, Use \c FILE_FLAG_WRITE_THROUGH on Windows to write to
* files. Ignored on non-Windows systems. Options are given as a list\, such
* as <code>"write_through=[data]"</code>. Configuring \c write_through requires
@@ -3549,18 +3550,17 @@ struct __wt_config_parser {
*/
/*!
- * Return a buffer's CRC32C checksum.
+ * Return a pointer to a function that calculates a CRC32C checksum.
*
* The WiredTiger library CRC32C checksum function uses hardware support where
* available, else it falls back to a software implementation.
*
* @snippet ex_all.c Checksum a buffer
*
- * @param buffer a pointer to a buffer
- * @param len the number of valid bytes in the buffer
- * @returns the buffer's CRC32C checksum
+ * @returns a pointer to a function that takes a buffer and length and returns
+ * the CRC32C checksum
*/
-uint32_t wiredtiger_checksum_crc32c(const void *buffer, size_t len)
+uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t)
WT_ATTRIBUTE_LIBRARY_VISIBLE;
/*! @} */
diff --git a/src/third_party/wiredtiger/src/log/log.c b/src/third_party/wiredtiger/src/log/log.c
index 6ce26e03c5d..243af64cb18 100644
--- a/src/third_party/wiredtiger/src/log/log.c
+++ b/src/third_party/wiredtiger/src/log/log.c
@@ -10,6 +10,7 @@
static int __log_newfile(WT_SESSION_IMPL *, bool, bool *);
static int __log_openfile(WT_SESSION_IMPL *, uint32_t, uint32_t, WT_FH **);
+static int __log_truncate(WT_SESSION_IMPL *, WT_LSN *, bool, bool);
static int __log_write_internal(
WT_SESSION_IMPL *, WT_ITEM *, WT_LSN *, uint32_t);
@@ -926,7 +927,7 @@ err: __wt_scr_free(session, &buf);
*/
static int
__log_open_verify(WT_SESSION_IMPL *session, uint32_t id, WT_FH **fhp,
- WT_LSN *lsnp, uint16_t *versionp)
+ WT_LSN *lsnp, uint16_t *versionp, bool *need_salvagep)
{
WT_CONNECTION_IMPL *conn;
WT_DECL_ITEM(buf);
@@ -937,11 +938,15 @@ __log_open_verify(WT_SESSION_IMPL *session, uint32_t id, WT_FH **fhp,
WT_LOG_RECORD *logrec;
uint32_t allocsize, rectype;
const uint8_t *end, *p;
+ bool need_salvage, salvage_mode;
conn = S2C(session);
+ fh = NULL;
log = conn->log;
+ need_salvage = false;
WT_RET(__wt_scr_alloc(session, 0, &buf));
- WT_ERR(__log_openfile(session, id, 0, &fh));
+ salvage_mode = (need_salvagep != NULL &&
+ FLD_ISSET(conn->log_flags, WT_CONN_LOG_RECOVER_SALVAGE));
if (log == NULL)
allocsize = WT_LOG_ALIGN;
@@ -953,17 +958,30 @@ __log_open_verify(WT_SESSION_IMPL *session, uint32_t id, WT_FH **fhp,
memset(buf->mem, 0, allocsize);
/*
+ * Any operation that fails from here on out indicates corruption
+ * that could be salvaged.
+ */
+ need_salvage = true;
+
+ /*
* Read in the log file header and verify it.
*/
+ WT_ERR(__log_openfile(session, id, 0, &fh));
WT_ERR(__wt_read(session, fh, 0, allocsize, buf->mem));
logrec = (WT_LOG_RECORD *)buf->mem;
__wt_log_record_byteswap(logrec);
desc = (WT_LOG_DESC *)logrec->record;
__wt_log_desc_byteswap(desc);
- if (desc->log_magic != WT_LOG_MAGIC)
- WT_PANIC_RET(session, WT_ERROR,
- "log file %s corrupted: Bad magic number %" PRIu32,
- fh->name, desc->log_magic);
+ if (desc->log_magic != WT_LOG_MAGIC) {
+ if (salvage_mode)
+ WT_ERR_MSG(session, WT_ERROR,
+ "log file %s corrupted: Bad magic number %" PRIu32,
+ fh->name, desc->log_magic);
+ else
+ WT_PANIC_RET(session, WT_ERROR,
+ "log file %s corrupted: Bad magic number %" PRIu32,
+ fh->name, desc->log_magic);
+ }
/*
* We cannot read future log file formats.
*/
@@ -1043,7 +1061,14 @@ err: __wt_scr_free(session, &buf);
*/
if (fhp != NULL && ret == 0)
*fhp = fh;
- else
+ else if (ret != 0 && need_salvage && salvage_mode) {
+ /* Let the caller know this file must be salvaged. */
+ ret = 0;
+ WT_TRET(__wt_close(session, &fh));
+ if (fhp != NULL)
+ *fhp = NULL;
+ *need_salvagep = true;
+ } else
WT_TRET(__wt_close(session, &fh));
return (ret);
@@ -1131,7 +1156,7 @@ __log_newfile(WT_SESSION_IMPL *session, bool conn_open, bool *created)
WT_STAT_CONN_INCR(session, log_close_yields);
__wt_log_wrlsn(session, NULL);
if (++yield_cnt > 10000)
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
__wt_yield();
}
/*
@@ -1200,7 +1225,8 @@ __log_newfile(WT_SESSION_IMPL *session, bool conn_open, bool *created)
* we must pass in a local file handle. Otherwise there is a wide
* window where another thread could see a NULL log file handle.
*/
- WT_RET(__log_open_verify(session, log->fileid, &log_fh, NULL, NULL));
+ WT_RET(__log_open_verify(session, log->fileid, &log_fh, NULL, NULL,
+ NULL));
/*
* Write the LSN at the end of the last record in the previous log file
* as the first record in this log file.
@@ -1412,25 +1438,31 @@ __log_truncate_file(WT_SESSION_IMPL *session, WT_FH *log_fh, wt_off_t offset)
* it will truncate between the given LSN and the trunc_lsn. That is,
* since we pre-allocate log files, it will free that space and allow the
* log to be traversed. We use the trunc_lsn because logging has already
- * opened the new/next log file before recovery ran. This function assumes
- * we are in recovery or other dedicated time and not during live running.
+ * opened the new/next log file before recovery ran. If salvage_mode is
+ * set, we verify headers of log files visited and recreate them if they
+ * are damaged. This function assumes we are in recovery or other
+ * dedicated time and not during live running.
*/
static int
-__log_truncate(WT_SESSION_IMPL *session, WT_LSN *lsn, bool this_log)
+__log_truncate(WT_SESSION_IMPL *session, WT_LSN *lsn, bool this_log,
+ bool salvage_mode)
{
WT_CONNECTION_IMPL *conn;
WT_DECL_RET;
WT_FH *log_fh;
WT_LOG *log;
- uint32_t lognum;
+ uint32_t lognum, salvage_first, salvage_last;
u_int i, logcount;
char **logfiles;
+ bool need_salvage, opened;
conn = S2C(session);
log = conn->log;
log_fh = NULL;
logcount = 0;
logfiles = NULL;
+ salvage_first = salvage_last = 0;
+ need_salvage = false;
/*
* Truncate the log file to the given LSN.
@@ -1446,6 +1478,10 @@ __log_truncate(WT_SESSION_IMPL *session, WT_LSN *lsn, bool this_log)
WT_ERR(__wt_fsync(session, log_fh, true));
WT_ERR(__wt_close(session, &log_fh));
+ if (salvage_mode)
+ WT_ERR(__wt_msg(session,
+ "salvage: log file %" PRIu32 " truncated", lsn->l.file));
+
/*
* If we just want to truncate the current log, return and skip
* looking for intervening logs.
@@ -1456,7 +1492,32 @@ __log_truncate(WT_SESSION_IMPL *session, WT_LSN *lsn, bool this_log)
for (i = 0; i < logcount; i++) {
WT_ERR(__wt_log_extract_lognum(session, logfiles[i], &lognum));
if (lognum > lsn->l.file && lognum < log->trunc_lsn.l.file) {
- WT_ERR(__log_openfile(session, lognum, 0, &log_fh));
+ opened = false;
+ if (salvage_mode) {
+ /*
+ * When salvaging, we verify that the
+ * header of the log file is valid.
+ * If not, create a new, empty one.
+ */
+ need_salvage = false;
+ WT_ERR(__log_open_verify(session, lognum,
+ &log_fh, NULL, NULL, &need_salvage));
+ if (need_salvage) {
+ WT_ASSERT(session, log_fh == NULL);
+ WT_ERR(__wt_log_remove(session,
+ WT_LOG_FILENAME, lognum));
+ WT_ERR(__wt_log_allocfile(session,
+ lognum, WT_LOG_FILENAME));
+ } else
+ opened = true;
+
+ if (salvage_first == 0)
+ salvage_first = lognum;
+ salvage_last = lognum;
+ }
+ if (!opened)
+ WT_ERR(__log_openfile(session, lognum, 0,
+ &log_fh));
/*
* If there are intervening files pre-allocated,
* truncate them to the end of the log file header.
@@ -1469,6 +1530,17 @@ __log_truncate(WT_SESSION_IMPL *session, WT_LSN *lsn, bool this_log)
}
err: WT_TRET(__wt_close(session, &log_fh));
WT_TRET(__wt_fs_directory_list_free(session, &logfiles, logcount));
+ if (salvage_first != 0) {
+ if (salvage_last > salvage_first)
+ WT_TRET(__wt_msg(session,
+ "salvage: log files %" PRIu32 "-%" PRIu32
+ " truncated at beginning", salvage_first,
+ salvage_last));
+ else
+ WT_TRET(__wt_msg(session,
+ "salvage: log file %" PRIu32
+ " truncated at beginning", salvage_first));
+ }
return (ret);
}
@@ -1566,13 +1638,12 @@ __wt_log_open(WT_SESSION_IMPL *session)
uint16_t version;
u_int i, logcount;
char **logfiles;
+ bool need_salvage;
conn = S2C(session);
log = conn->log;
logfiles = NULL;
logcount = 0;
- lastlog = 0;
- firstlog = UINT32_MAX;
/*
* Open up a file handle to the log directory if we haven't.
@@ -1587,9 +1658,14 @@ __wt_log_open(WT_SESSION_IMPL *session)
if (!F_ISSET(conn, WT_CONN_READONLY))
WT_ERR(__log_prealloc_remove(session));
+again:
/*
* Now look at the log files and set our LSNs.
*/
+ lastlog = 0;
+ firstlog = UINT32_MAX;
+ need_salvage = false;
+
WT_ERR(__log_get_files(session, WT_LOG_FILENAME, &logfiles, &logcount));
for (i = 0; i < logcount; i++) {
WT_ERR(__wt_log_extract_lognum(session, logfiles[i], &lognum));
@@ -1610,8 +1686,23 @@ __wt_log_open(WT_SESSION_IMPL *session)
* we create a new log file so that we can detect an unsupported
* version before modifying the file space.
*/
- WT_ERR(__log_open_verify(session,
- lastlog, NULL, NULL, &version));
+ WT_ERR(__log_open_verify(session, lastlog, NULL, NULL,
+ &version, &need_salvage));
+
+ /*
+ * If we were asked to salvage and the last log file was
+ * indeed corrupt, remove it and try all over again.
+ */
+ if (need_salvage) {
+ WT_ERR(__wt_log_remove(
+ session, WT_LOG_FILENAME, lastlog));
+ WT_ERR(__wt_msg(session,
+ "salvage: log file %" PRIu32 " removed", lastlog));
+ WT_ERR(__wt_fs_directory_list_free(session, &logfiles,
+ logcount));
+ logfiles = NULL;
+ goto again;
+ }
}
/*
@@ -1641,7 +1732,7 @@ __wt_log_open(WT_SESSION_IMPL *session)
* have to close the file.
*/
WT_ERR(__log_open_verify(session,
- lognum, NULL, NULL, &version));
+ lognum, NULL, NULL, &version, NULL));
/*
* If we find any log file at the wrong version
* set the flag and we're done.
@@ -1957,7 +2048,7 @@ __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags,
u_int i, logcount;
int firstrecord;
char **logfiles;
- bool eol, partial_record;
+ bool eol, need_salvage, partial_record;
conn = S2C(session);
log = conn->log;
@@ -1966,6 +2057,7 @@ __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags,
logfiles = NULL;
eol = false;
firstrecord = 1;
+ need_salvage = false;
/*
* If the caller did not give us a callback function there is nothing
@@ -2064,8 +2156,9 @@ __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags,
if (!WT_IS_INIT_LSN(lsnp))
start_lsn = *lsnp;
}
- WT_ERR(__log_open_verify(session,
- start_lsn.l.file, &log_fh, &prev_lsn, NULL));
+ WT_ERR(__log_open_verify(session, start_lsn.l.file, &log_fh, &prev_lsn,
+ NULL, &need_salvage));
+ WT_ERR_TEST(need_salvage, WT_ERROR);
WT_ERR(__wt_filesize(session, log_fh, &log_size));
rd_lsn = start_lsn;
if (LF_ISSET(WT_LOGSCAN_RECOVER))
@@ -2103,7 +2196,8 @@ advance:
__wt_verbose(session, WT_VERB_LOG,
"Truncate end of log %" PRIu32 "/%" PRIu32,
rd_lsn.l.file, rd_lsn.l.offset);
- WT_ERR(__log_truncate(session, &rd_lsn, true));
+ WT_ERR(__log_truncate(session, &rd_lsn, true,
+ false));
}
/*
* If we had a partial record, we'll want to break
@@ -2128,7 +2222,9 @@ advance:
" through %" PRIu32,
rd_lsn.l.file, end_lsn.l.file);
WT_ERR(__log_open_verify(session,
- rd_lsn.l.file, &log_fh, &prev_lsn, &version));
+ rd_lsn.l.file, &log_fh, &prev_lsn, &version,
+ &need_salvage));
+ WT_ERR_TEST(need_salvage, WT_ERROR);
/*
* Opening the log file reads with verify sets up the
* previous LSN from the first record. This detects
@@ -2161,10 +2257,15 @@ advance:
}
/*
* Read the minimum allocation size a record could be.
+ * Conditionally set the need_salvage flag so that if the
+ * read fails, we know this is an situation we can salvage.
*/
WT_ASSERT(session, buf->memsize >= allocsize);
+ need_salvage = FLD_ISSET(conn->log_flags,
+ WT_CONN_LOG_RECOVER_SALVAGE);
WT_ERR(__wt_read(session,
log_fh, rd_lsn.l.offset, (size_t)allocsize, buf->mem));
+ need_salvage = false;
/*
* See if we need to read more than the allocation size. We
* expect that we rarely will have to read more. Most log
@@ -2215,7 +2316,9 @@ advance:
WT_STAT_CONN_INCR(session, log_scan_rereads);
}
/*
- * We read in the record, verify checksum.
+ * We read in the record, verify checksum. A failed checksum
+ * does not imply corruption, it may be the result of a
+ * partial write.
*
* Handle little- and big-endian objects. Objects are written
* in little-endian format: save the header checksum, and
@@ -2291,11 +2394,22 @@ advance:
__wt_verbose(session, WT_VERB_LOG,
"End of recovery truncate end of log %" PRIu32 "/%" PRIu32,
rd_lsn.l.file, rd_lsn.l.offset);
- WT_ERR(__log_truncate(session, &rd_lsn, false));
+ WT_ERR(__log_truncate(session, &rd_lsn, false, false));
}
err: WT_STAT_CONN_INCR(session, log_scans);
/*
+ * If we are salvaging and failed a salvageable operation, then
+ * truncate the log at the fail point.
+ */
+ if (ret != 0 && need_salvage) {
+ WT_TRET(__wt_close(session, &log_fh));
+ log_fh = NULL;
+ WT_TRET(__log_truncate(session, &rd_lsn, false, true));
+ ret = 0;
+ }
+
+ /*
* If the first attempt to read a log record results in
* an error recovery is likely going to fail. Try to provide
* a helpful failure message.
diff --git a/src/third_party/wiredtiger/src/log/log_slot.c b/src/third_party/wiredtiger/src/log/log_slot.c
index 8deda5e242f..c75181d0687 100644
--- a/src/third_party/wiredtiger/src/log/log_slot.c
+++ b/src/third_party/wiredtiger/src/log/log_slot.c
@@ -119,7 +119,7 @@ retry:
* decide if retrying is necessary or not.
*/
if (forced && WT_LOG_SLOT_INPROGRESS(old_state))
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
/*
* If someone else is switching out this slot we lost. Nothing to
* do but return. Return WT_NOTFOUND anytime the given slot was
diff --git a/src/third_party/wiredtiger/src/lsm/lsm_tree.c b/src/third_party/wiredtiger/src/lsm/lsm_tree.c
index 16b28a1aecc..03feafe3c8c 100644
--- a/src/third_party/wiredtiger/src/lsm/lsm_tree.c
+++ b/src/third_party/wiredtiger/src/lsm/lsm_tree.c
@@ -419,7 +419,8 @@ __lsm_tree_find(WT_SESSION_IMPL *session,
*/
if (!__wt_atomic_cas_ptr(
&lsm_tree->excl_session, NULL, session))
- return (EBUSY);
+ return (__wt_set_return(
+ session, EBUSY));
/*
* Drain the work queue before checking for
@@ -431,7 +432,8 @@ __lsm_tree_find(WT_SESSION_IMPL *session,
if (lsm_tree->refcnt != 1) {
__wt_lsm_tree_release(
session, lsm_tree);
- return (EBUSY);
+ return (__wt_set_return(
+ session, EBUSY));
}
} else {
(void)__wt_atomic_add32(&lsm_tree->refcnt, 1);
@@ -445,7 +447,8 @@ __lsm_tree_find(WT_SESSION_IMPL *session,
lsm_tree->refcnt > 0);
__wt_lsm_tree_release(
session, lsm_tree);
- return (EBUSY);
+ return (__wt_set_return(
+ session, EBUSY));
}
}
diff --git a/src/third_party/wiredtiger/src/os_common/os_abort.c b/src/third_party/wiredtiger/src/os_common/os_abort.c
index 85dcc741855..54cae3e61aa 100644
--- a/src/third_party/wiredtiger/src/os_common/os_abort.c
+++ b/src/third_party/wiredtiger/src/os_common/os_abort.c
@@ -15,6 +15,7 @@
void
__wt_abort(WT_SESSION_IMPL *session)
WT_GCC_FUNC_ATTRIBUTE((noreturn))
+ WT_GCC_FUNC_ATTRIBUTE((visibility("default")))
{
#ifdef HAVE_ATTACH
u_int i;
diff --git a/src/third_party/wiredtiger/src/os_common/os_fs_inmemory.c b/src/third_party/wiredtiger/src/os_common/os_fs_inmemory.c
index cb7a05e05d9..182f89cc5e1 100644
--- a/src/third_party/wiredtiger/src/os_common/os_fs_inmemory.c
+++ b/src/third_party/wiredtiger/src/os_common/os_fs_inmemory.c
@@ -63,7 +63,7 @@ __im_handle_remove(WT_SESSION_IMPL *session,
if (im_fh->ref != 0) {
__wt_err(session, EBUSY, "%s: file-remove", im_fh->iface.name);
if (!force)
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
}
bucket = im_fh->name_hash % WT_HASH_ARRAY_SIZE;
@@ -272,7 +272,7 @@ __im_fs_size(WT_FILE_SYSTEM *file_system,
/* Search for the handle, then get its size. */
if ((im_fh = __im_handle_search(file_system, name)) == NULL)
- ret = ENOENT;
+ ret = __wt_set_return(session, ENOENT);
else
*sizep = (wt_off_t)im_fh->buf.size;
diff --git a/src/third_party/wiredtiger/src/os_posix/os_dir.c b/src/third_party/wiredtiger/src/os_posix/os_dir.c
index 2c2cb084a91..54614d67649 100644
--- a/src/third_party/wiredtiger/src/os_posix/os_dir.c
+++ b/src/third_party/wiredtiger/src/os_posix/os_dir.c
@@ -41,11 +41,12 @@ __directory_list_worker(WT_FILE_SYSTEM *file_system,
* but various static analysis programs remain unconvinced, check both.
*/
WT_SYSCALL_RETRY(((dirp = opendir(directory)) == NULL ? -1 : 0), ret);
- if (dirp == NULL && ret == 0)
- ret = EINVAL;
- if (ret != 0)
+ if (dirp == NULL || ret != 0) {
+ if (ret == 0)
+ ret = EINVAL;
WT_RET_MSG(session, ret,
"%s: directory-list: opendir", directory);
+ }
for (count = 0; (dp = readdir(dirp)) != NULL;) {
/*
diff --git a/src/third_party/wiredtiger/src/os_posix/os_fallocate.c b/src/third_party/wiredtiger/src/os_posix/os_fallocate.c
index 6f6e6a6bdc2..cde6adfe780 100644
--- a/src/third_party/wiredtiger/src/os_posix/os_fallocate.c
+++ b/src/third_party/wiredtiger/src/os_posix/os_fallocate.c
@@ -33,9 +33,9 @@ __posix_std_fallocate(
return (ret);
#else
WT_UNUSED(file_handle);
- WT_UNUSED(wt_session);
WT_UNUSED(offset);
- return (ENOTSUP);
+
+ return (__wt_set_return((WT_SESSION_IMPL *)wt_session, ENOTSUP));
#endif
}
@@ -66,9 +66,9 @@ __posix_sys_fallocate(
return (ret);
#else
WT_UNUSED(file_handle);
- WT_UNUSED(wt_session);
WT_UNUSED(offset);
- return (ENOTSUP);
+
+ return (__wt_set_return((WT_SESSION_IMPL *)wt_session, ENOTSUP));
#endif
}
@@ -92,9 +92,9 @@ __posix_posix_fallocate(
return (ret);
#else
WT_UNUSED(file_handle);
- WT_UNUSED(wt_session);
WT_UNUSED(offset);
- return (ENOTSUP);
+
+ return (__wt_set_return((WT_SESSION_IMPL *)wt_session, ENOTSUP));
#endif
}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_fs.c b/src/third_party/wiredtiger/src/os_posix/os_fs.c
index 0af67ad38c5..42e6e411440 100644
--- a/src/third_party/wiredtiger/src/os_posix/os_fs.c
+++ b/src/third_party/wiredtiger/src/os_posix/os_fs.c
@@ -338,7 +338,7 @@ __posix_file_advise(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session,
*/
if (ret == EINVAL) {
file_handle->fh_advise = NULL;
- return (ENOTSUP);
+ return (__wt_set_return(session, ENOTSUP));
}
WT_RET_MSG(session, ret,
diff --git a/src/third_party/wiredtiger/src/os_posix/os_map.c b/src/third_party/wiredtiger/src/os_posix/os_map.c
index b9ec284e124..f04a966c468 100644
--- a/src/third_party/wiredtiger/src/os_posix/os_map.c
+++ b/src/third_party/wiredtiger/src/os_posix/os_map.c
@@ -33,7 +33,7 @@ __wt_posix_map(WT_FILE_HANDLE *fh, WT_SESSION *wt_session,
* mmap(2) of files with direct I/O to the same files.
*/
if (pfh->direct_io)
- return (ENOTSUP);
+ return (__wt_set_return(session, ENOTSUP));
/*
* There's no locking here to prevent the underlying file from changing
diff --git a/src/third_party/wiredtiger/src/os_win/os_fs.c b/src/third_party/wiredtiger/src/os_win/os_fs.c
index 66f4de87299..c75e8365116 100644
--- a/src/third_party/wiredtiger/src/os_win/os_fs.c
+++ b/src/third_party/wiredtiger/src/os_win/os_fs.c
@@ -393,7 +393,7 @@ __win_file_set_end(
if (SetEndOfFile(win_fh->filehandle_secondary) == FALSE) {
if (GetLastError() == ERROR_USER_MAPPED_FILE)
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
windows_error = __wt_getlasterror();
ret = __wt_map_windows_error(windows_error);
__wt_err(session, ret,
diff --git a/src/third_party/wiredtiger/src/reconcile/rec_write.c b/src/third_party/wiredtiger/src/reconcile/rec_write.c
index 2ec28e31201..7faf19734a5 100644
--- a/src/third_party/wiredtiger/src/reconcile/rec_write.c
+++ b/src/third_party/wiredtiger/src/reconcile/rec_write.c
@@ -420,7 +420,7 @@ __wt_reconcile(WT_SESSION_IMPL *session, WT_REF *ref,
if (LF_ISSET(WT_REC_EVICT) &&
!__wt_page_can_evict(session, ref, NULL)) {
WT_PAGE_UNLOCK(session, page);
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
}
/* Initialize the reconciliation structure for each new run. */
@@ -442,8 +442,9 @@ __wt_reconcile(WT_SESSION_IMPL *session, WT_REF *ref,
if (LF_ISSET(WT_REC_EVICT)) {
mod->last_eviction_id = oldest_id;
#ifdef HAVE_TIMESTAMPS
- __wt_txn_pinned_timestamp(
- session, &mod->last_eviction_timestamp);
+ if (S2C(session)->txn_global.has_pinned_timestamp)
+ __wt_txn_pinned_timestamp(
+ session, &mod->last_eviction_timestamp);
#endif
mod->last_evict_pass_gen = S2C(session)->cache->evict_pass_gen;
}
@@ -651,7 +652,7 @@ __rec_write_check_complete(
return (0);
*lookaside_retryp = true;
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
}
/*
@@ -1397,7 +1398,7 @@ __rec_txn_read(WT_SESSION_IMPL *session, WT_RECONCILE *r,
if (F_ISSET(r, WT_REC_UPDATE_RESTORE) &&
*updp != NULL && uncommitted) {
r->leave_dirty = true;
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
}
if (upd->type == WT_UPDATE_BIRTHMARK)
@@ -1517,9 +1518,9 @@ __rec_txn_read(WT_SESSION_IMPL *session, WT_RECONCILE *r,
* the WT_REC_LOOKASIDE flag.
*/
if (!F_ISSET(r, WT_REC_LOOKASIDE | WT_REC_UPDATE_RESTORE))
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
if (uncommitted && !F_ISSET(r, WT_REC_UPDATE_RESTORE))
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
WT_ASSERT(session, r->max_txn != WT_TXN_NONE);
@@ -1704,7 +1705,7 @@ __rec_child_deleted(WT_SESSION_IMPL *session,
* the original page and which should see the deleted page).
*/
if (F_ISSET(r, WT_REC_EVICT))
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
/*
* If there are deleted child pages we can't discard immediately, keep
@@ -1789,7 +1790,7 @@ __rec_child_modify(WT_SESSION_IMPL *session,
*/
WT_ASSERT(session, !F_ISSET(r, WT_REC_EVICT));
if (F_ISSET(r, WT_REC_EVICT))
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
/*
* If called during checkpoint, the child is being
@@ -1817,7 +1818,7 @@ __rec_child_modify(WT_SESSION_IMPL *session,
if (F_ISSET(r, WT_REC_EVICT) &&
__wt_page_las_active(session, ref)) {
WT_ASSERT(session, false);
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
}
/*
@@ -1842,7 +1843,7 @@ __rec_child_modify(WT_SESSION_IMPL *session,
*/
WT_ASSERT(session, !F_ISSET(r, WT_REC_EVICT));
if (F_ISSET(r, WT_REC_EVICT))
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
/*
* If called during checkpoint, acquire a hazard pointer
@@ -1877,7 +1878,7 @@ __rec_child_modify(WT_SESSION_IMPL *session,
*/
WT_ASSERT(session, !F_ISSET(r, WT_REC_EVICT));
if (F_ISSET(r, WT_REC_EVICT))
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
goto done;
case WT_REF_SPLIT:
@@ -1894,7 +1895,7 @@ __rec_child_modify(WT_SESSION_IMPL *session,
* for checkpoint.
*/
WT_ASSERT(session, WT_REF_SPLIT != WT_REF_SPLIT);
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
WT_ILLEGAL_VALUE(session);
}
@@ -3704,7 +3705,7 @@ __rec_split_write(WT_SESSION_IMPL *session, WT_RECONCILE *r,
* allocate a zero-length array.
*/
if (r->page->type != WT_PAGE_ROW_LEAF && chunk->entries == 0)
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
if (F_ISSET(r, WT_REC_LOOKASIDE)) {
r->cache_write_lookaside = true;
diff --git a/src/third_party/wiredtiger/src/schema/schema_alter.c b/src/third_party/wiredtiger/src/schema/schema_alter.c
index e880cb415c8..aba708f0e0b 100644
--- a/src/third_party/wiredtiger/src/schema/schema_alter.c
+++ b/src/third_party/wiredtiger/src/schema/schema_alter.c
@@ -53,7 +53,7 @@ err: __wt_free(session, config);
* there was no metadata entry.
*/
if (ret == WT_NOTFOUND)
- ret = ENOENT;
+ ret = __wt_set_return(session, ENOENT);
return (ret);
}
diff --git a/src/third_party/wiredtiger/src/schema/schema_list.c b/src/third_party/wiredtiger/src/schema/schema_list.c
index 0f8806dd462..990f2636bf9 100644
--- a/src/third_party/wiredtiger/src/schema/schema_list.c
+++ b/src/third_party/wiredtiger/src/schema/schema_list.c
@@ -28,7 +28,7 @@ __wt_schema_get_table_uri(WT_SESSION_IMPL *session,
WT_ERR(__wt_session_get_dhandle(session, uri, NULL, NULL, flags));
table = (WT_TABLE *)session->dhandle;
if (!ok_incomplete && !table->cg_complete) {
- ret = EINVAL;
+ ret = __wt_set_return(session, EINVAL);
WT_TRET(__wt_session_release_dhandle(session));
WT_ERR_MSG(session, ret, "'%s' cannot be used "
"until all column groups are created",
diff --git a/src/third_party/wiredtiger/src/schema/schema_plan.c b/src/third_party/wiredtiger/src/schema/schema_plan.c
index abe76013e12..7fb2a391784 100644
--- a/src/third_party/wiredtiger/src/schema/schema_plan.c
+++ b/src/third_party/wiredtiger/src/schema/schema_plan.c
@@ -298,7 +298,7 @@ __find_column_format(WT_SESSION_IMPL *session, WT_TABLE *table,
if (k.len == colname->len &&
strncmp(colname->str, k.str, k.len) == 0) {
if (value_only && inkey)
- return (EINVAL);
+ return (__wt_set_return(session, EINVAL));
return (0);
}
}
diff --git a/src/third_party/wiredtiger/src/schema/schema_util.c b/src/third_party/wiredtiger/src/schema/schema_util.c
index ceec6db6cb5..a281ec3fe12 100644
--- a/src/third_party/wiredtiger/src/schema/schema_util.c
+++ b/src/third_party/wiredtiger/src/schema/schema_util.c
@@ -39,7 +39,7 @@ __wt_schema_backup_check(WT_SESSION_IMPL *session, const char *name)
}
for (i = 0; backup_list[i] != NULL; ++i) {
if (strcmp(backup_list[i], name) == 0) {
- ret = EBUSY;
+ ret = __wt_set_return(session, EBUSY);
break;
}
}
diff --git a/src/third_party/wiredtiger/src/session/session_dhandle.c b/src/third_party/wiredtiger/src/session/session_dhandle.c
index caa775686cf..30399cafd22 100644
--- a/src/third_party/wiredtiger/src/session/session_dhandle.c
+++ b/src/third_party/wiredtiger/src/session/session_dhandle.c
@@ -140,7 +140,7 @@ __wt_session_lock_dhandle(
if (!LF_ISSET(WT_DHANDLE_LOCK_ONLY) &&
(!F_ISSET(dhandle, WT_DHANDLE_OPEN) ||
(btree != NULL && F_ISSET(btree, WT_BTREE_SPECIAL_FLAGS))))
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
++dhandle->excl_ref;
return (0);
}
@@ -167,7 +167,7 @@ __wt_session_lock_dhandle(
* give up.
*/
if (btree != NULL && F_ISSET(btree, WT_BTREE_SPECIAL_FLAGS))
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
/*
* If the handle is open, get a read lock and recheck.
diff --git a/src/third_party/wiredtiger/src/support/err.c b/src/third_party/wiredtiger/src/support/err.c
index 0569d0545e6..6010b310ba1 100644
--- a/src/third_party/wiredtiger/src/support/err.c
+++ b/src/third_party/wiredtiger/src/support/err.c
@@ -174,7 +174,7 @@ __wt_event_handler_set(WT_SESSION_IMPL *session, WT_EVENT_HANDLER *handler)
*/
static int
__eventv(WT_SESSION_IMPL *session, bool msg_event, int error,
- const char *file_name, int line_number, const char *fmt, va_list ap)
+ const char *func_name, int line_number, const char *fmt, va_list ap)
WT_GCC_FUNC_ATTRIBUTE((cold))
{
struct timespec ts;
@@ -231,8 +231,8 @@ __eventv(WT_SESSION_IMPL *session, bool msg_event, int error,
WT_ERROR_APPEND(p, remain, ", %s", prefix);
WT_ERROR_APPEND(p, remain, ": ");
- if (file_name != NULL)
- WT_ERROR_APPEND(p, remain, "%s, %d: ", file_name, line_number);
+ if (func_name != NULL)
+ WT_ERROR_APPEND(p, remain, "%s, %d: ", func_name, line_number);
WT_ERROR_APPEND_AP(p, remain, fmt, ap);
@@ -309,13 +309,14 @@ err: if (fprintf(stderr,
}
/*
- * __wt_err --
+ * __wt_err_func --
* Report an error.
*/
void
-__wt_err(WT_SESSION_IMPL *session, int error, const char *fmt, ...)
+__wt_err_func(WT_SESSION_IMPL *session,
+ int error, const char *func_name, int line_number, const char *fmt, ...)
WT_GCC_FUNC_ATTRIBUTE((cold))
- WT_GCC_FUNC_ATTRIBUTE((format (printf, 3, 4)))
+ WT_GCC_FUNC_ATTRIBUTE((format (printf, 5, 6)))
WT_GCC_FUNC_ATTRIBUTE((visibility("default")))
{
va_list ap;
@@ -325,18 +326,21 @@ __wt_err(WT_SESSION_IMPL *session, int error, const char *fmt, ...)
* an error value to return.
*/
va_start(ap, fmt);
- WT_IGNORE_RET(__eventv(session, false, error, NULL, 0, fmt, ap));
+ WT_IGNORE_RET(__eventv(session,
+ false, error, func_name, line_number, fmt, ap));
va_end(ap);
}
/*
- * __wt_errx --
+ * __wt_errx_func --
* Report an error with no error code.
*/
void
-__wt_errx(WT_SESSION_IMPL *session, const char *fmt, ...)
+__wt_errx_func(WT_SESSION_IMPL *session,
+ const char *func_name, int line_number, const char *fmt, ...)
WT_GCC_FUNC_ATTRIBUTE((cold))
- WT_GCC_FUNC_ATTRIBUTE((format (printf, 2, 3)))
+ WT_GCC_FUNC_ATTRIBUTE((format (printf, 4, 5)))
+ WT_GCC_FUNC_ATTRIBUTE((visibility("default")))
{
va_list ap;
@@ -345,11 +349,25 @@ __wt_errx(WT_SESSION_IMPL *session, const char *fmt, ...)
* an error value to return.
*/
va_start(ap, fmt);
- WT_IGNORE_RET(__eventv(session, false, 0, NULL, 0, fmt, ap));
+ WT_IGNORE_RET(__eventv(session,
+ false, 0, func_name, line_number, fmt, ap));
va_end(ap);
}
/*
+ * __wt_set_return_func --
+ * Conditionally log the source of an error code and return the error.
+ */
+int
+__wt_set_return_func(
+ WT_SESSION_IMPL *session, const char* func, int line, int err)
+{
+ __wt_verbose(session,
+ WT_VERB_ERROR_RETURNS, "%s: %d Error: %d", func, line, err);
+ return (err);
+}
+
+/*
* __wt_ext_err_printf --
* Extension API call to print to the error stream.
*/
@@ -388,44 +406,28 @@ __wt_verbose_worker(WT_SESSION_IMPL *session, const char *fmt, ...)
}
/*
- * info_msg --
+ * __wt_msg --
* Informational message.
*/
-static int
-info_msg(WT_SESSION_IMPL *session, const char *fmt, va_list ap)
+int
+__wt_msg(WT_SESSION_IMPL *session, const char *fmt, ...)
+ WT_GCC_FUNC_ATTRIBUTE((cold))
+ WT_GCC_FUNC_ATTRIBUTE((format (printf, 2, 3)))
{
+ WT_DECL_ITEM(buf);
+ WT_DECL_RET;
WT_EVENT_HANDLER *handler;
WT_SESSION *wt_session;
- /*
- * !!!
- * SECURITY:
- * Buffer placed at the end of the stack in case snprintf overflows.
- */
- char s[2048];
+ WT_RET(__wt_scr_alloc(session, 0, &buf));
- WT_RET(__wt_vsnprintf(s, sizeof(s), fmt, ap));
+ WT_VA_ARGS_BUF_FORMAT(session, buf, fmt, false);
wt_session = (WT_SESSION *)session;
handler = session->event_handler;
- return (handler->handle_message(handler, wt_session, s));
-}
+ ret = handler->handle_message(handler, wt_session, buf->data);
-/*
- * __wt_msg --
- * Informational message.
- */
-int
-__wt_msg(WT_SESSION_IMPL *session, const char *fmt, ...)
- WT_GCC_FUNC_ATTRIBUTE((cold))
- WT_GCC_FUNC_ATTRIBUTE((format (printf, 2, 3)))
-{
- WT_DECL_RET;
- va_list ap;
-
- va_start(ap, fmt);
- ret = info_msg(session, fmt, ap);
- va_end(ap);
+ __wt_scr_free(session, &buf);
return (ret);
}
@@ -439,16 +441,24 @@ __wt_ext_msg_printf(
WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *fmt, ...)
WT_GCC_FUNC_ATTRIBUTE((format (printf, 3, 4)))
{
+ WT_DECL_ITEM(buf);
WT_DECL_RET;
+ WT_EVENT_HANDLER *handler;
WT_SESSION_IMPL *session;
- va_list ap;
if ((session = (WT_SESSION_IMPL *)wt_session) == NULL)
session = ((WT_CONNECTION_IMPL *)wt_api->conn)->default_session;
- va_start(ap, fmt);
- ret = info_msg(session, fmt, ap);
- va_end(ap);
+ WT_RET(__wt_scr_alloc(session, 0, &buf));
+
+ WT_VA_ARGS_BUF_FORMAT(session, buf, fmt, false);
+
+ wt_session = (WT_SESSION *)session;
+ handler = session->event_handler;
+ ret = handler->handle_message(handler, wt_session, buf->data);
+
+ __wt_scr_free(session, &buf);
+
return (ret);
}
@@ -487,34 +497,6 @@ __wt_progress(WT_SESSION_IMPL *session, const char *s, uint64_t v)
}
/*
- * __wt_assert --
- * Assert and other unexpected failures, includes file/line information
- * for debugging.
- */
-void
-__wt_assert(WT_SESSION_IMPL *session,
- int error, const char *file_name, int line_number, const char *fmt, ...)
- WT_GCC_FUNC_ATTRIBUTE((cold))
- WT_GCC_FUNC_ATTRIBUTE((format (printf, 5, 6)))
-#ifdef HAVE_DIAGNOSTIC
- WT_GCC_FUNC_ATTRIBUTE((noreturn))
-#endif
- WT_GCC_FUNC_ATTRIBUTE((visibility("default")))
-{
- va_list ap;
-
- va_start(ap, fmt);
- WT_IGNORE_RET(__eventv(
- session, false, error, file_name, line_number, fmt, ap));
- va_end(ap);
-
-#ifdef HAVE_DIAGNOSTIC
- __wt_abort(session); /* Drop core if testing. */
- /* NOTREACHED */
-#endif
-}
-
-/*
* __wt_panic --
* A standard error message when we panic.
*/
diff --git a/src/third_party/wiredtiger/src/support/global.c b/src/third_party/wiredtiger/src/support/global.c
index d1271e0d427..f71f91a4daa 100644
--- a/src/third_party/wiredtiger/src/support/global.c
+++ b/src/third_party/wiredtiger/src/support/global.c
@@ -117,7 +117,7 @@ __wt_global_once(void)
return;
}
- __wt_checksum_init();
+ __wt_process.checksum = wiredtiger_crc32c_func();
__global_calibrate_ticks();
TAILQ_INIT(&__wt_process.connqh);
diff --git a/src/third_party/wiredtiger/src/support/hazard.c b/src/third_party/wiredtiger/src/support/hazard.c
index 815c876f444..4116638e31c 100644
--- a/src/third_party/wiredtiger/src/support/hazard.c
+++ b/src/third_party/wiredtiger/src/support/hazard.c
@@ -401,6 +401,29 @@ __wt_hazard_count(WT_SESSION_IMPL *session, WT_REF *ref)
#ifdef HAVE_DIAGNOSTIC
/*
+ * __wt_hazard_check_assert --
+ * Assert there's no hazard pointer to the page.
+ */
+bool
+__wt_hazard_check_assert(WT_SESSION_IMPL *session, void *ref, bool waitfor)
+{
+ WT_HAZARD *hp;
+ int i;
+
+ for (i = 0;;) {
+ if ((hp = __wt_hazard_check(session, ref)) == NULL)
+ return (true);
+ if (!waitfor || ++i > 100)
+ break;
+ __wt_sleep(0, 10000);
+ }
+ __wt_errx(session,
+ "hazard pointer reference to discarded object: (%p: %s, line %d)",
+ (void *)hp->ref, hp->file, hp->line);
+ return (false);
+}
+
+/*
* __hazard_dump --
* Display the list of hazard pointers.
*/
diff --git a/src/third_party/wiredtiger/src/support/mtx_rw.c b/src/third_party/wiredtiger/src/support/mtx_rw.c
index fd66a1a40bb..959405dee50 100644
--- a/src/third_party/wiredtiger/src/support/mtx_rw.c
+++ b/src/third_party/wiredtiger/src/support/mtx_rw.c
@@ -137,7 +137,7 @@ __wt_try_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *l)
/* This read lock can only be granted if there are no active writers. */
if (old.u.s.current != old.u.s.next)
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
/*
* The replacement lock value is a result of adding an active reader.
@@ -146,7 +146,7 @@ __wt_try_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *l)
*/
new.u.v = old.u.v;
if (++new.u.s.readers_active == 0)
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
/* We rely on this atomic operation to provide a barrier. */
return (__wt_atomic_casv64(&l->u.v, old.u.v, new.u.v) ? 0 : EBUSY);
@@ -331,7 +331,7 @@ __wt_try_writelock(WT_SESSION_IMPL *session, WT_RWLOCK *l)
*/
old.u.v = l->u.v;
if (old.u.s.current != old.u.s.next || old.u.s.readers_active != 0)
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
/*
* We've checked above that there is no writer active (since
diff --git a/src/third_party/wiredtiger/src/support/scratch.c b/src/third_party/wiredtiger/src/support/scratch.c
index 2ead79a1c1c..72e312da325 100644
--- a/src/third_party/wiredtiger/src/support/scratch.c
+++ b/src/third_party/wiredtiger/src/support/scratch.c
@@ -71,30 +71,9 @@ __wt_buf_fmt(WT_SESSION_IMPL *session, WT_ITEM *buf, const char *fmt, ...)
WT_GCC_FUNC_ATTRIBUTE((format (printf, 3, 4)))
WT_GCC_FUNC_ATTRIBUTE((visibility("default")))
{
- WT_DECL_RET;
- size_t len;
- va_list ap;
-
- for (;;) {
- va_start(ap, fmt);
- ret = __wt_vsnprintf_len_set(
- buf->mem, buf->memsize, &len, fmt, ap);
- va_end(ap);
- WT_RET(ret);
-
- /* Check if there was enough space. */
- if (len < buf->memsize) {
- buf->data = buf->mem;
- buf->size = len;
- return (0);
- }
+ WT_VA_ARGS_BUF_FORMAT(session, buf, fmt, false);
- /*
- * If not, double the size of the buffer: we're dealing with
- * strings, and we don't expect these numbers to get huge.
- */
- WT_RET(__wt_buf_extend(session, buf, len + 1));
- }
+ return (0);
}
/*
@@ -106,11 +85,6 @@ __wt_buf_catfmt(WT_SESSION_IMPL *session, WT_ITEM *buf, const char *fmt, ...)
WT_GCC_FUNC_ATTRIBUTE((format (printf, 3, 4)))
WT_GCC_FUNC_ATTRIBUTE((visibility("default")))
{
- WT_DECL_RET;
- size_t len, space;
- char *p;
- va_list ap;
-
/*
* If we're appending data to an existing buffer, any data field should
* point into the allocated memory. (It wouldn't be insane to copy any
@@ -119,27 +93,9 @@ __wt_buf_catfmt(WT_SESSION_IMPL *session, WT_ITEM *buf, const char *fmt, ...)
*/
WT_ASSERT(session, buf->data == NULL || WT_DATA_IN_ITEM(buf));
- for (;;) {
- va_start(ap, fmt);
- p = (char *)((uint8_t *)buf->mem + buf->size);
- WT_ASSERT(session, buf->memsize >= buf->size);
- space = buf->memsize - buf->size;
- ret = __wt_vsnprintf_len_set(p, space, &len, fmt, ap);
- va_end(ap);
- WT_RET(ret);
-
- /* Check if there was enough space. */
- if (len < space) {
- buf->size += len;
- return (0);
- }
+ WT_VA_ARGS_BUF_FORMAT(session, buf, fmt, true);
- /*
- * If not, double the size of the buffer: we're dealing with
- * strings, and we don't expect these numbers to get huge.
- */
- WT_RET(__wt_buf_extend(session, buf, buf->size + len + 1));
- }
+ return (0);
}
/*
@@ -400,16 +356,19 @@ __wt_scr_discard(WT_SESSION_IMPL *session)
if (*bufp == NULL)
continue;
if (F_ISSET(*bufp, WT_ITEM_INUSE))
+#ifdef HAVE_DIAGNOSTIC
__wt_errx(session,
"scratch buffer allocated and never discarded"
-#ifdef HAVE_DIAGNOSTIC
": %s: %d",
session->
scratch_track[bufp - session->scratch].file,
session->
scratch_track[bufp - session->scratch].line
-#endif
);
+#else
+ __wt_errx(session,
+ "scratch buffer allocated and never discarded");
+#endif
__wt_buf_free(session, *bufp);
__wt_free(session, *bufp);
diff --git a/src/third_party/wiredtiger/src/txn/txn_ckpt.c b/src/third_party/wiredtiger/src/txn/txn_ckpt.c
index ad8351923a0..59d9fa2e7c1 100644
--- a/src/third_party/wiredtiger/src/txn/txn_ckpt.c
+++ b/src/third_party/wiredtiger/src/txn/txn_ckpt.c
@@ -1896,7 +1896,7 @@ __wt_checkpoint_close(WT_SESSION_IMPL *session, bool final)
if (btree->modified && !bulk &&
S2C(session)->txn_global.has_stable_timestamp &&
!__wt_btree_immediately_durable(session))
- return (EBUSY);
+ return (__wt_set_return(session, EBUSY));
/*
* Turn on metadata tracking if:
diff --git a/src/third_party/wiredtiger/src/txn/txn_rollback_to_stable.c b/src/third_party/wiredtiger/src/txn/txn_rollback_to_stable.c
index e01db53fda9..ba00198adbe 100644
--- a/src/third_party/wiredtiger/src/txn/txn_rollback_to_stable.c
+++ b/src/third_party/wiredtiger/src/txn/txn_rollback_to_stable.c
@@ -466,7 +466,8 @@ __wt_txn_rollback_to_stable(WT_SESSION_IMPL *session, const char *cfg[])
* trees in cache populates a list that is used to check which
* lookaside records should be removed.
*/
- WT_ERR(__txn_rollback_to_stable_lookaside_fixup(session));
+ if (!F_ISSET(conn, WT_CONN_IN_MEMORY))
+ WT_ERR(__txn_rollback_to_stable_lookaside_fixup(session));
err: F_CLR(conn, WT_CONN_EVICTION_NO_LOOKASIDE);
__wt_free(session, conn->stable_rollback_bitstring);
diff --git a/src/third_party/wiredtiger/src/utilities/util_main.c b/src/third_party/wiredtiger/src/utilities/util_main.c
index 2d08c4c5274..7042736e2a2 100644
--- a/src/third_party/wiredtiger/src/utilities/util_main.c
+++ b/src/third_party/wiredtiger/src/utilities/util_main.c
@@ -11,7 +11,7 @@
const char *home = "."; /* Home directory */
const char *progname; /* Program name */
/* Global arguments */
-const char *usage_prefix = "[-LRVv] [-C config] [-E secretkey] [-h home]";
+const char *usage_prefix = "[-LRSVv] [-C config] [-E secretkey] [-h home]";
bool verbose = false; /* Verbose flag */
static const char *command; /* Command name */
@@ -19,6 +19,7 @@ static const char *command; /* Command name */
#define REC_ERROR "log=(recover=error)"
#define REC_LOGOFF "log=(enabled=false)"
#define REC_RECOVER "log=(recover=on)"
+#define REC_SALVAGE "log=(recover=salvage)"
static void
usage(void)
@@ -70,7 +71,7 @@ main(int argc, char *argv[])
int ch, major_v, minor_v, tret, (*func)(WT_SESSION *, int, char *[]);
const char *cmd_config, *config, *p1, *p2, *p3, *rec_config;
char *p, *secretkey;
- bool logoff, needconn, recover;
+ bool logoff, needconn, recover, salvage;
conn = NULL;
p = NULL;
@@ -105,9 +106,9 @@ main(int argc, char *argv[])
* needed, the user can specify -R to run recovery.
*/
rec_config = REC_ERROR;
- logoff = recover = false;
+ logoff = recover = salvage = false;
/* Check for standard options. */
- while ((ch = __wt_getopt(progname, argc, argv, "C:E:h:LRVv")) != EOF)
+ while ((ch = __wt_getopt(progname, argc, argv, "C:E:h:LRSVv")) != EOF)
switch (ch) {
case 'C': /* wiredtiger_open config */
cmd_config = __wt_optarg;
@@ -131,6 +132,10 @@ main(int argc, char *argv[])
rec_config = REC_RECOVER;
recover = true;
break;
+ case 'S': /* salvage */
+ rec_config = REC_SALVAGE;
+ salvage = true;
+ break;
case 'V': /* version */
printf("%s\n", wiredtiger_version(NULL, NULL, NULL));
goto done;
@@ -142,8 +147,9 @@ main(int argc, char *argv[])
usage();
goto err;
}
- if (logoff && recover) {
- fprintf(stderr, "Only one of -L and -R is allowed.\n");
+ if ((logoff && recover) || (logoff && salvage) ||
+ (recover && salvage)) {
+ fprintf(stderr, "Only one of -L, -R, and -S is allowed.\n");
goto err;
}
argc -= __wt_optind;
diff --git a/src/third_party/wiredtiger/test/csuite/timestamp_abort/main.c b/src/third_party/wiredtiger/test/csuite/timestamp_abort/main.c
index 8a1781eae45..11cabf4e9db 100644
--- a/src/third_party/wiredtiger/test/csuite/timestamp_abort/main.c
+++ b/src/third_party/wiredtiger/test/csuite/timestamp_abort/main.c
@@ -210,7 +210,7 @@ thread_ckpt_run(void *arg)
session, "use_timestamp=true"));
testutil_check(td->conn->query_timestamp(
td->conn, buf, "get=last_checkpoint"));
- sscanf(buf, "%" SCNx64, &stable);
+ testutil_assert(sscanf(buf, "%" SCNx64, &stable) == 1);
printf("Checkpoint %d complete at stable %"
PRIu64 ".\n", i, stable);
fflush(stdout);
@@ -728,7 +728,7 @@ main(int argc, char *argv[])
if (use_ts) {
testutil_check(
conn->query_timestamp(conn, buf, "get=recovery"));
- sscanf(buf, "%" SCNx64, &stable_val);
+ testutil_assert(sscanf(buf, "%" SCNx64, &stable_val) == 1);
printf("Got stable_val %" PRIu64 "\n", stable_val);
}
diff --git a/src/third_party/wiredtiger/test/csuite/wt4117_checksum/main.c b/src/third_party/wiredtiger/test/csuite/wt4117_checksum/main.c
index 9a786e5d222..fff7b55bbf9 100644
--- a/src/third_party/wiredtiger/test/csuite/wt4117_checksum/main.c
+++ b/src/third_party/wiredtiger/test/csuite/wt4117_checksum/main.c
@@ -44,65 +44,51 @@ static void
run(void)
{
size_t len;
- uint32_t crc32c;
+ uint32_t crc32c, (*func)(const void *, size_t);
uint8_t *data;
/* Allocate aligned memory for the data. */
data = dcalloc(100, sizeof(uint8_t));
+ /* Get a pointer to the CRC32C function. */
+ func = wiredtiger_crc32c_func();
+
/*
* Some simple known checksums.
*/
len = 1;
- crc32c = wiredtiger_checksum_crc32c(data, len);
+ crc32c = func(data, len);
check(crc32c, (uint32_t)0x527d5351, len, "nul x1");
len = 2;
- crc32c = wiredtiger_checksum_crc32c(data, len);
+ crc32c = func(data, len);
check(crc32c, (uint32_t)0xf16177d2, len, "nul x2");
len = 3;
- crc32c = wiredtiger_checksum_crc32c(data, len);
+ crc32c = func(data, len);
check(crc32c, (uint32_t)0x6064a37a, len, "nul x3");
len = 4;
- crc32c = wiredtiger_checksum_crc32c(data, len);
+ crc32c = func(data, len);
check(crc32c, (uint32_t)0x48674bc7, len, "nul x4");
len = strlen("123456789");
memcpy(data, "123456789", len);
- crc32c = wiredtiger_checksum_crc32c(data, len);
+ crc32c = func(data, len);
check(crc32c, (uint32_t)0xe3069283, len, "known string #1");
len = strlen("The quick brown fox jumps over the lazy dog");
memcpy(data, "The quick brown fox jumps over the lazy dog", len);
- crc32c = wiredtiger_checksum_crc32c(data, len);
+ crc32c = func(data, len);
check(crc32c, (uint32_t)0x22620404, len, "known string #2");
free(data);
}
int
-main(int argc, char *argv[])
+main(void)
{
- TEST_OPTS *opts, _opts;
-
- opts = &_opts;
- memset(opts, 0, sizeof(*opts));
- testutil_check(testutil_parse_opts(argc, argv, opts));
- testutil_make_work_dir(opts->home);
-
- /*
- * The external API should work before the library configures itself,
- * run before and after calling wiredtiger_open().
- */
- run();
-
- testutil_check(
- wiredtiger_open(opts->home, NULL, "create", &opts->conn));
-
run();
- testutil_cleanup(opts);
return (EXIT_SUCCESS);
}
diff --git a/src/third_party/wiredtiger/test/format/config.h b/src/third_party/wiredtiger/test/format/config.h
index c398c1a96b2..70e8165e97d 100644
--- a/src/third_party/wiredtiger/test/format/config.h
+++ b/src/third_party/wiredtiger/test/format/config.h
@@ -370,10 +370,6 @@ static CONFIG c[] = {
"stress splits (#8)", /* 2% */
C_BOOL, 2, 0, 0, &g.c_timing_stress_split_8, NULL },
- { "timing_stress_split_9",
- "stress splits (#9)", /* 2% */
- C_BOOL, 2, 0, 0, &g.c_timing_stress_split_9, NULL },
-
{ "transaction_timestamps", /* 10% */
"enable transaction timestamp support",
C_BOOL, 10, 0, 0, &g.c_txn_timestamps, NULL },
diff --git a/src/third_party/wiredtiger/test/format/format.h b/src/third_party/wiredtiger/test/format/format.h
index 1406d2b3fb5..83b75f70f26 100644
--- a/src/third_party/wiredtiger/test/format/format.h
+++ b/src/third_party/wiredtiger/test/format/format.h
@@ -222,7 +222,6 @@ typedef struct {
uint32_t c_timing_stress_split_6;
uint32_t c_timing_stress_split_7;
uint32_t c_timing_stress_split_8;
- uint32_t c_timing_stress_split_9;
uint32_t c_truncate;
uint32_t c_txn_freq;
uint32_t c_txn_timestamps;
diff --git a/src/third_party/wiredtiger/test/format/wts.c b/src/third_party/wiredtiger/test/format/wts.c
index 8040142aa19..6452f74384d 100644
--- a/src/third_party/wiredtiger/test/format/wts.c
+++ b/src/third_party/wiredtiger/test/format/wts.c
@@ -264,8 +264,6 @@ wts_open(const char *home, bool set_api, WT_CONNECTION **connp)
CONFIG_APPEND(p, ",split_7");
if (g.c_timing_stress_split_8)
CONFIG_APPEND(p, ",split_8");
- if (g.c_timing_stress_split_9)
- CONFIG_APPEND(p, ",split_9");
CONFIG_APPEND(p, "]");
/* Extensions. */
diff --git a/src/third_party/wiredtiger/test/salvage/salvage.c b/src/third_party/wiredtiger/test/salvage/salvage.c
index 9c8a90d37b9..895a31620d9 100644
--- a/src/third_party/wiredtiger/test/salvage/salvage.c
+++ b/src/third_party/wiredtiger/test/salvage/salvage.c
@@ -670,7 +670,7 @@ empty(int cnt)
if (page_type == WT_PAGE_COL_FIX)
for (i = 0; i < cnt; ++i)
- fputs("\\00\n", res_fp);
+ CHECK(fputs("\\00\n", res_fp));
}
/*
diff --git a/src/third_party/wiredtiger/test/suite/run.py b/src/third_party/wiredtiger/test/suite/run.py
index 6b668ad3e07..74fa259c3c4 100644
--- a/src/third_party/wiredtiger/test/suite/run.py
+++ b/src/third_party/wiredtiger/test/suite/run.py
@@ -238,7 +238,7 @@ if __name__ == '__main__':
tests = unittest.TestSuite()
# Turn numbers and ranges into test module names
- preserve = timestamp = debug = dryRun = gdbSub = longtest = False
+ preserve = timestamp = debug = dryRun = gdbSub = lldbSub = longtest = False
parallel = 0
configfile = None
configwrite = False
@@ -269,6 +269,9 @@ if __name__ == '__main__':
if option == '-gdb' or option == 'g':
gdbSub = True
continue
+ if option == '-lldb':
+ lldbSub = True
+ continue
if option == '-help' or option == 'h':
usage()
sys.exit(0)
@@ -323,7 +326,7 @@ if __name__ == '__main__':
# All global variables should be set before any test classes are loaded.
# That way, verbose printing can be done at the class definition level.
- wttest.WiredTigerTestCase.globalSetup(preserve, timestamp, gdbSub,
+ wttest.WiredTigerTestCase.globalSetup(preserve, timestamp, gdbSub, lldbSub,
verbose, wt_builddir, dirarg,
longtest)
diff --git a/src/third_party/wiredtiger/test/suite/suite_subprocess.py b/src/third_party/wiredtiger/test/suite/suite_subprocess.py
index c2e9d99f691..4b0f6823e06 100644..100755
--- a/src/third_party/wiredtiger/test/suite/suite_subprocess.py
+++ b/src/third_party/wiredtiger/test/suite/suite_subprocess.py
@@ -26,7 +26,7 @@
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
-import os, subprocess, sys
+import os, re, subprocess, sys
from run import wt_builddir
from wttest import WiredTigerTestCase
@@ -79,23 +79,51 @@ class suite_subprocess:
print '********************************'
self.fail('ERROR found in output file: ' + filename)
+ # If the string is of the form '/.../', then return just the embedded
+ # pattern, otherwise, return None
+ def convert_to_pattern(self, s):
+ if len(s) >= 2 and s[0] == '/' and s[-1] == '/':
+ return s[1:-1]
+ else:
+ return None
+
def check_file_content(self, filename, expect):
with open(filename, 'r') as f:
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(self, filename, expect):
+ def check_file_contains_one_of(self, filename, expectlist):
"""
Check that the file contains the expected string in the first 100K bytes
"""
maxbytes = 1024*100
with open(filename, 'r') as f:
got = f.read(maxbytes)
- if not (expect in got):
+ found = False
+ for expect in expectlist:
+ pat = self.convert_to_pattern(expect)
+ if pat == None:
+ if expect in got:
+ found = True
+ break
+ else:
+ if re.search(pat, got):
+ found = True
+ break
+ if not found:
+ if len(expectlist) == 1:
+ expect = '\'' + expectlist[0] + '\''
+ else:
+ expect = str(expectlist)
+ gotstr = '\'' + \
+ (got if len(got) < 1000 else (got[0:1000] + '...')) + '\''
if len(got) >= maxbytes:
- self.fail(filename + ': does not contain expected \'' + expect + '\', or output is too large')
+ self.fail(filename + ': does not contain expected ' + expect + ', or output is too large, got ' + gotstr)
else:
- self.fail(filename + ': does not contain expected \'' + expect + '\'')
+ 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_empty_file(self, filename):
"""
@@ -165,6 +193,8 @@ class suite_subprocess:
procargs = [ wtexe ]
if self._gdbSubprocess:
procargs = [ "gdb", "--args" ] + procargs
+ elif self._lldbSubprocess:
+ procargs = [ "lldb", "--" ] + procargs
procargs.extend(args)
if self._gdbSubprocess:
infilepart = ""
@@ -177,6 +207,17 @@ class suite_subprocess:
">" + wtoutname + " 2>" + wterrname
print "*********************************************"
returncode = subprocess.call(procargs)
+ elif self._lldbSubprocess:
+ infilepart = ""
+ if infilename != None:
+ infilepart = "<" + infilename + " "
+ print str(procargs)
+ print "*********************************************"
+ print "**** Run 'wt' via: run " + \
+ " ".join(procargs[3:]) + infilepart + \
+ ">" + wtoutname + " 2>" + wterrname
+ print "*********************************************"
+ returncode = subprocess.call(procargs)
elif infilename:
with open(infilename, "r") as wtin:
returncode = subprocess.call(
diff --git a/src/third_party/wiredtiger/test/suite/test_txn19.py b/src/third_party/wiredtiger/test/suite/test_txn19.py
new file mode 100755
index 00000000000..79b040a4cec
--- /dev/null
+++ b/src/third_party/wiredtiger/test/suite/test_txn19.py
@@ -0,0 +1,324 @@
+#!/usr/bin/env python
+#
+# Public Domain 2014-2018 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.
+#
+# test_txn19.py
+# Transactions: test recovery with corrupted log files
+#
+
+import fnmatch, os, shutil, time
+from wtscenario import make_scenarios
+from suite_subprocess import suite_subprocess
+import wiredtiger, wttest
+
+# This test uses an artificially small log file limit, and creates
+# large records so two fit into a log file. This allows us to test
+# both the case when corruption happens at the beginning of a log file
+# (an even number of records have been created), and when corruption
+# happens in the middle of a log file (with an odd number of records).
+
+def corrupt(fname, truncate, offset, writeit):
+ with open(fname, 'r+') as log:
+ if truncate:
+ log.truncate()
+ if offset:
+ if offset < 0: # Negative offset means seek to the end
+ log.seek(0, 2)
+ else:
+ log.seek(offset)
+ if writeit:
+ log.write(writeit)
+
+class test_txn19(wttest.WiredTigerTestCase, suite_subprocess):
+ base_config = 'log=(archive=false,enabled,file_max=100K),' + \
+ 'transaction_sync=(enabled,method=none)'
+ conn_config = base_config
+ corruption_type = [
+ ('removal', dict(kind='removal', f=lambda fname:
+ os.remove(fname))),
+ ('truncate', dict(kind='truncate', f=lambda fname:
+ corrupt(fname, True, 0, None))),
+ ('zero-begin', dict(kind='zero', f=lambda fname:
+ corrupt(fname, False, 0, '\0' * 4096))),
+ ('zero-trunc', dict(kind='zero', f=lambda fname:
+ corrupt(fname, True, 0, '\0' * 4096))),
+ ('zero-end', dict(kind='zero-end', f=lambda fname:
+ corrupt(fname, False, -1, '\0' * 4096))),
+ ('garbage-begin', dict(kind='garbage-begin', f=lambda fname:
+ corrupt(fname, False, 0, 'Bad!' * 1024))),
+ ('garbage-middle', dict(kind='garbage-middle', f=lambda fname:
+ corrupt(fname, False, 1024 * 25, 'Bad!' * 1024))),
+ ('garbage-end', dict(kind='garbage-end', f=lambda fname:
+ corrupt(fname, False, -1, 'Bad!' * 1024))),
+ ]
+ # The list comprehension below expands each entry in the integer tuple
+ # list to a scenario. For example, (3, 4, 2) expands to:
+ # ('corrupt=[3,4],checkpoint=2', dict(corruptpos=3, corruptpos2=4, chkpt=2))
+ #
+ # Each number corresponds to a log file, so for this example, we have
+ # corruption in log file 3 (using the style of corruption from
+ # corruption_type), there is a second corruption in log file 4,
+ # and there is a checkpoint in log file 2. A value of 0 means no
+ # corruption or checkpoint.
+ corruption_pos = [
+ ('corrupt=[' + str(x) + ',' + str(y) + '],checkpoint=' + str(z),
+ dict(corruptpos=x,corruptpos2=y,chkpt=z)) for (x,y,z) in (
+ (0, 0, 0), (0, 0, 2), (6, 0, 0), (6, 0, 3), (3, 0, 0),
+ (3, 0, 2), (3, 4, 2), (3, 5, 2), (3, 0, 4))]
+ nrecords = [('nrecords=10', dict(nrecords=10)),
+ ('nrecords=11', dict(nrecords=11))]
+
+ # This function prunes out unnecessary or problematic test cases
+ # from the list of scenarios.
+ def includeFunc(name, dictarg):
+ kind = dictarg['kind']
+ corruptpos = dictarg['corruptpos']
+ chkpt = dictarg['chkpt']
+
+ # corruptpos == 0 indicates there is no corruption.
+ # (i.e. corrupt log file 0, which doesn't exist)
+ # We do want to test the case of no corruption, but we don't
+ # need to try it against every type of corruption, only one.
+ if corruptpos == 0:
+ return kind == 'removal'
+
+ # NOTE:
+ # The removal or truncation of a middle log file (not first or last)
+ # that would be used in recovery is not currently handled gracefully.
+ if (kind == 'removal' or kind == 'truncate') and \
+ corruptpos != 6 and corruptpos > chkpt:
+ return False
+
+ # All the other cases are valid
+ return True
+
+ scenarios = make_scenarios(
+ corruption_type, corruption_pos, nrecords,
+ include=includeFunc, prune=20, prunelong=1000)
+
+ uri = 'table:test_txn19'
+ create_params = 'key_format=i,value_format=S'
+
+ # Return the log file number that contains the given record
+ # number. In this test, two records fit into each log file, and
+ # after each even record is written, a new log file is created
+ # (having no records initially). The last log file is this
+ # (nrecords/2 + 1), given that we start with log 1.
+ def record_to_logfile(self, recordnum):
+ return recordnum / 2 + 1
+
+ # Returns the first record number in a log file.
+ def logfile_to_record(self, logfile):
+ return (logfile - 1) * 2
+
+ # Return true if the log file is corrupted.
+ # If not corrupted, the log file will produce no errors,
+ # and all the records originally written should be recovered.
+ def corrupted(self):
+ # Corruptpos == 0 means to do no corruption in any log file
+ if self.corruptpos == 0:
+ return False
+
+ # Adding zeroes to the end of a log file is indistinguishable
+ # from having a log file that is preallocated that has not been
+ # totally filled. One might argue that if this does not occur
+ # in the final log file, it could/should have been truncated.
+ # At any rate, we consider this particular corruption to be benign.
+ if self.kind == 'zero-end':
+ return False
+
+ # NOTE:
+ # If garbage is added to an otherwise valid log file, the invalid
+ # portion is effectively 'skipped over'.
+ if self.kind == 'garbage-end':
+ return False
+ return True
+
+ def show_logs(self, homedir, msg):
+ loglist = []
+ for i in range(0, 10):
+ basename = 'WiredTigerLog.000000000' + str(i)
+ fullname = homedir + os.sep + basename
+ if os.path.isfile(fullname):
+ loglist.append(i)
+ if os.stat(fullname).st_size == 0:
+ self.tty('LOGS ' + msg + ': ' + str(i) + ' is empty')
+ self.tty('LOGS ' + msg + ': ' + str(loglist))
+
+ def copy_for_crash_restart(self, olddir, newdir):
+ ''' Simulate a crash from olddir and restart in newdir. '''
+ # with the connection still open, copy files to new directory
+ shutil.rmtree(newdir, ignore_errors=True)
+ os.mkdir(newdir)
+ for fname in os.listdir(olddir):
+ fullname = os.path.join(olddir, fname)
+ # Skip lock file on Windows since it is locked
+ if os.path.isfile(fullname) and \
+ "WiredTiger.lock" not in fullname and \
+ "Tmplog" not in fullname and \
+ "Preplog" not in fullname:
+ shutil.copy(fullname, newdir)
+
+ # Generate a value that is a bit over half the size of the log file.
+ def valuegen(self, i):
+ return str(i) + 'A' * (1024 * 60) # ~60K
+
+ # Insert a list of keys
+ def inserts(self, keylist):
+ c = self.session.open_cursor(self.uri)
+ for i in keylist:
+ if self.chkpt > 0 and self.logfile_to_record(self.chkpt) == i:
+ self.session.checkpoint()
+ c[i] = self.valuegen(i)
+ c.close()
+
+ def checks(self, expectlist):
+ c = self.session.open_cursor(self.uri, None, None)
+ gotlist = []
+ for key, value in c:
+ gotlist.append(key)
+ self.assertEqual(self.valuegen(key), value)
+ self.assertEqual(expectlist, gotlist)
+ c.close()
+
+ def log_number_to_file_name(self, homedir, n):
+ self.assertLess(n, 10) # assuming 1 digit
+ return homedir + os.sep + 'WiredTigerLog.000000000' + str(n)
+
+ def corrupt_log(self, homedir):
+ if not self.corrupted():
+ return
+ self.f(self.log_number_to_file_name(homedir, self.corruptpos))
+
+ # Corrupt a second log file if needed
+ if self.corruptpos2 != 0:
+ self.f(self.log_number_to_file_name(homedir, self.corruptpos2))
+
+ # Return true iff the log has been damaged in a way that
+ # is not detected as a corruption.
+ # This includes:
+ # - removal of the last log
+ # - corruption in the middle of a log file.
+ def log_corrupt_but_valid(self):
+ # NOTE:
+ # Currently, corruption in the middle of a log file is not yet
+ # detected.
+ if self.kind == 'garbage-middle':
+ return True
+ if self.corruptpos == self.record_to_logfile(self.nrecords):
+ if self.kind == 'removal':
+ return True
+ return False
+
+ # For this test, at least, salvage identifies and fixes all
+ # recovery failures.
+ def expect_salvage_messages(self):
+ return self.expect_recovery_failure()
+
+ def expect_recovery_failure(self):
+ return self.corrupted() and \
+ self.corruptpos >= self.chkpt and \
+ not self.log_corrupt_but_valid()
+
+ def recovered_records(self):
+ if not self.corrupted() or self.chkpt > self.corruptpos:
+ return self.nrecords
+ return self.logfile_to_record(self.corruptpos)
+
+ def test_corrupt_log(self):
+ ''' Corrupt the log and restart with different kinds of recovery '''
+
+ # This test creates some data, then simulates a crash with corruption.
+ # Then does a restart with recovery, then starts again with salvage,
+ # and finally starts again with recovery (adding new records).
+
+ self.session.create(self.uri, self.create_params)
+ self.inserts([x for x in range(0, self.nrecords)])
+ newdir = "RESTART"
+ self.copy_for_crash_restart(self.home, newdir)
+ self.close_conn()
+ #self.show_logs(newdir, 'before corruption')
+ self.corrupt_log(newdir)
+ #self.show_logs(newdir, 'after corruption')
+ salvage_config = self.base_config + ',log=(recover=salvage)'
+ errfile = 'list.err'
+ outfile = 'list.out'
+ expect_fail = self.expect_recovery_failure()
+
+ # In cases of corruption, we cannot always call wiredtiger_open
+ # directly, because there may be a panic, and abort() is called
+ # in diagnostic mode which terminates the Python interpreter.
+ #
+ # Running any wt command externally to Python allows
+ # us to observe the failure or success safely.
+ # Use -R to force recover=on, which is the default for
+ # wiredtiger_open, (wt utilities normally have recover=error)
+ self.runWt(['-h', newdir, '-C', self.base_config, '-R', 'list'],
+ errfilename=errfile, outfilename=outfile, failure=expect_fail,
+ closeconn=False)
+
+ if expect_fail:
+ self.check_file_contains_one_of(errfile,
+ ['/log file.*corrupted/', 'WT_ERROR: non-specific WiredTiger error'])
+ else:
+ self.check_empty_file(errfile)
+ self.check_file_contains(outfile, self.uri)
+
+ found_records = self.recovered_records()
+ expect = [x for x in range(0, found_records)]
+
+ # If we are salvaging, expect an informational message
+ if self.expect_salvage_messages():
+ errpat = '.*'
+ # Possible messages:
+ # salvage: log files x-y truncated at beginning
+ # salvage: log file x truncated at beginning
+ # salvage: log file x truncated
+ # salvage: log file x removed
+ outpat = 'salvage: log file'
+ else:
+ errpat = '^$'
+ outpat = '^$'
+ with self.expectedStdoutPattern(outpat):
+ with self.expectedStderrPattern(errpat):
+ self.conn = self.wiredtiger_open(newdir, salvage_config)
+ self.session = self.setUpSessionOpen(self.conn)
+ self.checks(expect)
+
+ # Insert a couple more and simulate another crash.
+ newdir2 = "RESTART2"
+ self.inserts([self.nrecords, self.nrecords + 1])
+ expect.extend([self.nrecords, self.nrecords + 1])
+ self.copy_for_crash_restart(newdir, newdir2)
+ self.checks(expect)
+ self.reopen_conn(newdir)
+ self.checks(expect)
+ self.reopen_conn(newdir2, self.conn_config)
+ self.checks(expect)
+
+if __name__ == '__main__':
+ wttest.run()
diff --git a/src/third_party/wiredtiger/test/suite/wtscenario.py b/src/third_party/wiredtiger/test/suite/wtscenario.py
index 76824e428df..d953b7f627f 100644
--- a/src/third_party/wiredtiger/test/suite/wtscenario.py
+++ b/src/third_party/wiredtiger/test/suite/wtscenario.py
@@ -68,6 +68,9 @@ def make_scenarios(*args, **kwargs):
"""
The standard way to create scenarios for WT tests.
Scenarios can be combined by listing them all as arguments.
+ If some scenario combinations should not be included,
+ a include= argument function may be listed, which given a name and
+ dictionary argument, returns True if the scenario should be included.
A final prune= and/or prunelong= argument may be given that
forces the list of entries in the scenario to be pruned.
The result is a (combined) scenario that has been checked
@@ -76,14 +79,19 @@ def make_scenarios(*args, **kwargs):
scenes = multiply_scenarios('.', *args)
pruneval = None
prunelong = None
+ includefunc = None
for key in kwargs:
if key == 'prune':
pruneval = kwargs[key]
elif key == 'prunelong':
prunelong = kwargs[key]
+ elif key == 'include':
+ includefunc = kwargs[key]
else:
raise AssertionError(
'make_scenarios: unexpected named arg: ' + key)
+ if includefunc:
+ scenes = [(name, d) for (name, d) in scenes if includefunc(name, d)]
if pruneval != None or prunelong != None:
pruneval = pruneval if pruneval != None else -1
prunelong = prunelong if prunelong != None else -1
diff --git a/src/third_party/wiredtiger/test/suite/wttest.py b/src/third_party/wiredtiger/test/suite/wttest.py
index 8c0915bc9c7..1a2fddce031 100644
--- a/src/third_party/wiredtiger/test/suite/wttest.py
+++ b/src/third_party/wiredtiger/test/suite/wttest.py
@@ -101,7 +101,7 @@ class CapturedFd(object):
' unexpected ' + self.desc +
', contains:\n"' + contents + '"')
testcase.fail('unexpected ' + self.desc + ', contains: "' +
- shortenWithEllipsis(contents,100) + '"')
+ contents + '"')
self.expectpos = filesize
def checkAdditional(self, testcase, expect):
@@ -180,7 +180,7 @@ class WiredTigerTestCase(unittest.TestCase):
@staticmethod
def globalSetup(preserveFiles = False, useTimestamp = False,
- gdbSub = False, verbose = 1, builddir = None, dirarg = None,
+ gdbSub = False, lldbSub = False, verbose = 1, builddir = None, dirarg = None,
longtest = False):
WiredTigerTestCase._preserveFiles = preserveFiles
d = 'WT_TEST' if dirarg == None else dirarg
@@ -194,6 +194,7 @@ class WiredTigerTestCase(unittest.TestCase):
WiredTigerTestCase._origcwd = os.getcwd()
WiredTigerTestCase._resultfile = open(os.path.join(d, 'results.txt'), "w", 0) # unbuffered
WiredTigerTestCase._gdbSubprocess = gdbSub
+ WiredTigerTestCase._lldbSubprocess = lldbSub
WiredTigerTestCase._longtest = longtest
WiredTigerTestCase._verbose = verbose
WiredTigerTestCase._dupout = os.dup(sys.stdout.fileno())
@@ -339,20 +340,25 @@ class WiredTigerTestCase(unittest.TestCase):
self.conn.close(config)
self.conn = None
- def open_conn(self, directory="."):
+ def open_conn(self, directory=".", config=None):
"""
Open the connection if already closed.
"""
if self.conn == None:
+ if config != None:
+ self._old_config = self.conn_config
+ self.conn_config = config
self.conn = self.setUpConnectionOpen(directory)
+ if config != None:
+ self.conn_config = self._old_config
self.session = self.setUpSessionOpen(self.conn)
- def reopen_conn(self, directory="."):
+ def reopen_conn(self, directory=".", config=None):
"""
Reopen the connection.
"""
self.close_conn()
- self.open_conn(directory)
+ self.open_conn(directory, config)
def setUp(self):
if not hasattr(self.__class__, 'wt_ntests'):