diff options
author | Luke Chen <luke.chen@mongodb.com> | 2018-07-23 15:53:49 +1000 |
---|---|---|
committer | Luke Chen <luke.chen@mongodb.com> | 2018-07-23 15:53:49 +1000 |
commit | e065e7daa99f75f19a73fc1b2b57a8947852a006 (patch) | |
tree | d2c141fab1e7334b6a552ecda525d29c1cbf20dd /src/third_party/wiredtiger/src | |
parent | 1c1535c9ee73ac4ed0d922855ccbe44335909082 (diff) | |
download | mongo-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
Diffstat (limited to 'src/third_party/wiredtiger/src')
55 files changed, 685 insertions, 474 deletions
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{ 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{ 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{ 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; |