summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Chen <luke.chen@mongodb.com>2018-06-14 14:30:37 +1000
committerLuke Chen <luke.chen@mongodb.com>2018-06-14 14:30:37 +1000
commit637de7eb8646122684bc9a56a16a977debcfb454 (patch)
tree117c7335a5dbb12652d221ca47cd77e274ca30a1
parent9aa2a05618d984b1cb23783ab9ebc49b8cfc654a (diff)
downloadmongo-637de7eb8646122684bc9a56a16a977debcfb454.tar.gz
Import wiredtiger: 7d3e691fd4d5ba7810647c317692129fea694602 from branch mongodb-4.0
ref: d16557c82c..7d3e691fd4 for: 4.1.1 WT-4071 Run unit tests with timestamps disabled WT-4115 Valgrind error in est_wt4105_large_doc_small_upd WT-4116 Coverity #1393311 Copy-paste error WT-4117 Expose WiredTiger crc32c function WT-4120 Enhance test/format to dump the cache when timing out WT-4122 Ensure compatibility downgrade cleans up old log files WT-4127 Add common prefix for compatibility version errors WT-4128 Skip checkpoints while stable timestamp doesn't change
-rw-r--r--src/third_party/wiredtiger/build_win/wiredtiger.def1
-rw-r--r--src/third_party/wiredtiger/dist/s_export.list1
-rw-r--r--src/third_party/wiredtiger/dist/s_funcs.list1
-rw-r--r--src/third_party/wiredtiger/dist/stat_data.py2
-rw-r--r--src/third_party/wiredtiger/examples/c/ex_all.c10
-rw-r--r--src/third_party/wiredtiger/import.data2
-rw-r--r--src/third_party/wiredtiger/src/checksum/arm64/crc32-arm64.c1
-rw-r--r--src/third_party/wiredtiger/src/checksum/power8/crc32_wrapper.c1
-rw-r--r--src/third_party/wiredtiger/src/checksum/x86/crc32-x86.c1
-rw-r--r--src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.c1
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_api.c12
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_ckpt.c49
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_log.c36
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_reconfig.c8
-rw-r--r--src/third_party/wiredtiger/src/include/error.h1
-rw-r--r--src/third_party/wiredtiger/src/include/extern.h2
-rw-r--r--src/third_party/wiredtiger/src/include/stat.h2
-rw-r--r--src/third_party/wiredtiger/src/include/wiredtiger.in29
-rw-r--r--src/third_party/wiredtiger/src/log/log.c8
-rw-r--r--src/third_party/wiredtiger/src/support/stat.c7
-rw-r--r--src/third_party/wiredtiger/src/txn/txn_ckpt.c125
-rw-r--r--src/third_party/wiredtiger/src/txn/txn_recover.c7
-rw-r--r--src/third_party/wiredtiger/test/csuite/Makefile.am12
-rw-r--r--src/third_party/wiredtiger/test/csuite/wt4105_large_doc_small_upd/main.c11
-rw-r--r--src/third_party/wiredtiger/test/csuite/wt4117_checksum/main.c108
-rw-r--r--src/third_party/wiredtiger/test/format/ops.c6
-rw-r--r--src/third_party/wiredtiger/test/suite/test_compat01.py72
-rw-r--r--src/third_party/wiredtiger/test/suite/test_compat02.py13
-rw-r--r--src/third_party/wiredtiger/test/suite/test_compat03.py13
-rw-r--r--src/third_party/wiredtiger/test/suite/test_compat04.py116
-rw-r--r--src/third_party/wiredtiger/test/suite/test_las01.py3
-rw-r--r--src/third_party/wiredtiger/test/suite/test_las02.py3
-rw-r--r--src/third_party/wiredtiger/test/suite/test_prepare01.py6
-rw-r--r--src/third_party/wiredtiger/test/suite/test_prepare03.py3
34 files changed, 542 insertions, 131 deletions
diff --git a/src/third_party/wiredtiger/build_win/wiredtiger.def b/src/third_party/wiredtiger/build_win/wiredtiger.def
index 25e7a01e0d9..3ee9f6b6a9d 100644
--- a/src/third_party/wiredtiger/build_win/wiredtiger.def
+++ b/src/third_party/wiredtiger/build_win/wiredtiger.def
@@ -1,5 +1,6 @@
LIBRARY WIREDTIGER
EXPORTS
+ wiredtiger_checksum_crc32c
wiredtiger_config_parser_open
wiredtiger_config_validate
wiredtiger_open
diff --git a/src/third_party/wiredtiger/dist/s_export.list b/src/third_party/wiredtiger/dist/s_export.list
index c7f088bc2d5..72ce553ac9b 100644
--- a/src/third_party/wiredtiger/dist/s_export.list
+++ b/src/third_party/wiredtiger/dist/s_export.list
@@ -1,4 +1,5 @@
# List of OK external symbols.
+wiredtiger_checksum_crc32c
wiredtiger_config_parser_open
wiredtiger_config_validate
wiredtiger_open
diff --git a/src/third_party/wiredtiger/dist/s_funcs.list b/src/third_party/wiredtiger/dist/s_funcs.list
index 95c568a19ff..eed29e91fc1 100644
--- a/src/third_party/wiredtiger/dist/s_funcs.list
+++ b/src/third_party/wiredtiger/dist/s_funcs.list
@@ -33,6 +33,7 @@ __wt_stat_join_aggregate
__wt_stat_join_clear_all
__wt_stream_set_no_buffer
__wt_try_readlock
+wiredtiger_checksum_crc32c
wiredtiger_config_parser_open
wiredtiger_config_validate
wiredtiger_pack_int
diff --git a/src/third_party/wiredtiger/dist/stat_data.py b/src/third_party/wiredtiger/dist/stat_data.py
index 32927b56625..c1b43ac6b2d 100644
--- a/src/third_party/wiredtiger/dist/stat_data.py
+++ b/src/third_party/wiredtiger/dist/stat_data.py
@@ -370,7 +370,7 @@ connection_stats = [
LogStat('log_compress_write_fails', 'log records not compressed'),
LogStat('log_compress_writes', 'log records compressed'),
LogStat('log_flush', 'log flush operations'),
- LogStat('log_force_ckpt_sleep', 'force checkpoint calls slept'),
+ LogStat('log_force_archive_sleep', 'force archive time sleeping (usecs)'),
LogStat('log_force_write', 'log force write operations'),
LogStat('log_force_write_skip', 'log force write operations skipped'),
LogStat('log_max_filesize', 'maximum log file size', 'no_clear,no_scale,size'),
diff --git a/src/third_party/wiredtiger/examples/c/ex_all.c b/src/third_party/wiredtiger/examples/c/ex_all.c
index 1aa648f01c0..139f39fe673 100644
--- a/src/third_party/wiredtiger/examples/c/ex_all.c
+++ b/src/third_party/wiredtiger/examples/c/ex_all.c
@@ -1352,5 +1352,15 @@ main(int argc, char *argv[])
/*! [Get the WiredTiger library version #2] */
}
+ {
+ const char *buffer = "some string";
+ size_t len = strlen(buffer);
+ /*! [Checksum a buffer] */
+ uint32_t crc32c;
+ crc32c = wiredtiger_checksum_crc32c(buffer, len);
+ /*! [Checksum a buffer] */
+ (void)crc32c;
+ }
+
return (EXIT_SUCCESS);
}
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data
index 7a2886a3fe1..702b2430339 100644
--- a/src/third_party/wiredtiger/import.data
+++ b/src/third_party/wiredtiger/import.data
@@ -1,5 +1,5 @@
{
- "commit": "d16557c82ca66ff220238299d0f7c9a182d1720e",
+ "commit": "7d3e691fd4d5ba7810647c317692129fea694602",
"github": "wiredtiger/wiredtiger.git",
"vendor": "wiredtiger",
"branch": "mongodb-4.0"
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 d0c989fd757..01740dcd953 100644
--- a/src/third_party/wiredtiger/src/checksum/arm64/crc32-arm64.c
+++ b/src/third_party/wiredtiger/src/checksum/arm64/crc32-arm64.c
@@ -90,6 +90,7 @@ __wt_checksum_hw(const void *chunk, size_t len)
*/
void
__wt_checksum_init(void)
+ WT_GCC_FUNC_ATTRIBUTE((cold))
{
#if defined(__linux__) && defined(HAVE_CRC32_HARDWARE)
unsigned long caps = getauxval(AT_HWCAP);
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 a9be9ced1c6..8626fa42136 100644
--- a/src/third_party/wiredtiger/src/checksum/power8/crc32_wrapper.c
+++ b/src/third_party/wiredtiger/src/checksum/power8/crc32_wrapper.c
@@ -86,6 +86,7 @@ __wt_checksum_hw(const void *chunk, size_t len)
*/
void
__wt_checksum_init(void)
+ WT_GCC_FUNC_ATTRIBUTE((cold))
{
#if defined(HAVE_CRC32_HARDWARE)
__wt_process.checksum = __wt_checksum_hw;
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 8de987d4fc9..73199018a7d 100644
--- a/src/third_party/wiredtiger/src/checksum/x86/crc32-x86.c
+++ b/src/third_party/wiredtiger/src/checksum/x86/crc32-x86.c
@@ -124,6 +124,7 @@ __wt_checksum_hw(const void *chunk, size_t len)
*/
void
__wt_checksum_init(void)
+ WT_GCC_FUNC_ATTRIBUTE((cold))
{
#if defined(HAVE_CRC32_HARDWARE)
#if (defined(__amd64) || defined(__x86_64))
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 ae024391ff7..ec7adb02cba 100644
--- a/src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.c
+++ b/src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.c
@@ -98,6 +98,7 @@ __wt_checksum_hw(const void *chunk, size_t len)
*/
void
__wt_checksum_init(void)
+ WT_GCC_FUNC_ATTRIBUTE((cold))
{
#if defined(__linux__) && defined(HAVE_CRC32_HARDWARE)
unsigned long caps = getauxval(AT_HWCAP);
diff --git a/src/third_party/wiredtiger/src/conn/conn_api.c b/src/third_party/wiredtiger/src/conn/conn_api.c
index a413e31d1c9..d322caac04a 100644
--- a/src/third_party/wiredtiger/src/conn/conn_api.c
+++ b/src/third_party/wiredtiger/src/conn/conn_api.c
@@ -2748,3 +2748,15 @@ 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_ckpt.c b/src/third_party/wiredtiger/src/conn/conn_ckpt.c
index d302a59c928..8691a72cc47 100644
--- a/src/third_party/wiredtiger/src/conn/conn_ckpt.c
+++ b/src/third_party/wiredtiger/src/conn/conn_ckpt.c
@@ -83,6 +83,7 @@ __ckpt_server(void *arg)
WT_DECL_RET;
WT_SESSION *wt_session;
WT_SESSION_IMPL *session;
+ uint64_t checkpoint_gen;
session = arg;
conn = S2C(session);
@@ -101,37 +102,27 @@ __ckpt_server(void *arg)
if (!__ckpt_server_run_chk(session))
break;
+ checkpoint_gen = __wt_gen(session, WT_GEN_CHECKPOINT);
+ WT_ERR(wt_session->checkpoint(wt_session, NULL));
+
/*
- * Checkpoint the database if the connection is marked dirty.
- * A connection is marked dirty whenever a btree gets marked
- * dirty, which reflects upon a change in the database that
- * needs to be checkpointed. Said that, there can be short
- * instances when a btree gets marked dirty and the connection
- * is yet to be. We might skip a checkpoint in that short
- * instance, which is okay because by the next time we get to
- * checkpoint, the connection would have been marked dirty and
- * hence the checkpoint will not be skipped this time.
+ * Reset the log file size counters if the checkpoint wasn't
+ * skipped.
*/
- if (conn->modified) {
- WT_ERR(wt_session->checkpoint(wt_session, NULL));
-
- /* Reset. */
- if (conn->ckpt_logsize) {
- __wt_log_written_reset(session);
- conn->ckpt_signalled = false;
-
- /*
- * In case we crossed the log limit during the
- * checkpoint and the condition variable was
- * already signalled, do a tiny wait to clear
- * it so we don't do another checkpoint
- * immediately.
- */
- __wt_cond_wait(
- session, conn->ckpt_cond, 1, NULL);
- }
- } else
- WT_STAT_CONN_INCR(session, txn_checkpoint_skipped);
+ if (checkpoint_gen != __wt_gen(session, WT_GEN_CHECKPOINT) &&
+ conn->ckpt_logsize) {
+ __wt_log_written_reset(session);
+ conn->ckpt_signalled = false;
+
+ /*
+ * In case we crossed the log limit during the
+ * checkpoint and the condition variable was
+ * already signalled, do a tiny wait to clear
+ * it so we don't do another checkpoint
+ * immediately.
+ */
+ __wt_cond_wait(session, conn->ckpt_cond, 1, NULL);
+ }
}
if (0) {
diff --git a/src/third_party/wiredtiger/src/conn/conn_log.c b/src/third_party/wiredtiger/src/conn/conn_log.c
index 0599d491ccb..d8eb095d6d2 100644
--- a/src/third_party/wiredtiger/src/conn/conn_log.c
+++ b/src/third_party/wiredtiger/src/conn/conn_log.c
@@ -40,24 +40,25 @@ __logmgr_sync_cfg(WT_SESSION_IMPL *session, const char **cfg)
}
/*
- * __logmgr_force_ckpt --
- * Force a checkpoint out, waiting for the checkpoint LSN in the log
- * is up to the given log number.
+ * __logmgr_force_archive --
+ * Force a checkpoint out and then force an archive, waiting for the
+ * first log to be archived up to the given log number.
*/
static int
-__logmgr_force_ckpt(WT_SESSION_IMPL *session, uint32_t lognum)
+__logmgr_force_archive(WT_SESSION_IMPL *session, uint32_t lognum)
{
WT_CONNECTION_IMPL *conn;
WT_LOG *log;
WT_SESSION_IMPL *tmp_session;
- int yield;
+ uint64_t sleep_usecs, yield_cnt;
conn = S2C(session);
log = conn->log;
- yield = 0;
+ sleep_usecs = yield_cnt = 0;
+
WT_RET(__wt_open_internal_session(conn,
"compatibility-reconfig", true, 0, &tmp_session));
- while (log->ckpt_lsn.l.file < lognum) {
+ while (log->first_lsn.l.file < lognum) {
/*
* Force a checkpoint to be written in the new log file and
* force the archiving of all previous log files. We do the
@@ -69,15 +70,16 @@ __logmgr_force_ckpt(WT_SESSION_IMPL *session, uint32_t lognum)
*/
WT_RET(tmp_session->iface.checkpoint(
&tmp_session->iface, "force=1"));
- WT_RET(WT_SESSION_CHECK_PANIC(tmp_session));
/*
- * Only sleep in the rare case that we had to come through
- * this loop more than once.
+ * It's reasonable to start the back off prior to trying at all
+ * because the backoff is very gradual.
*/
- if (yield++) {
- WT_STAT_CONN_INCR(session, log_force_ckpt_sleep);
- __wt_sleep(0, WT_THOUSAND);
- }
+ __wt_spin_backoff(&yield_cnt, &sleep_usecs);
+ WT_STAT_CONN_INCRV(session,
+ log_force_archive_sleep, sleep_usecs);
+
+ WT_RET(WT_SESSION_CHECK_PANIC(tmp_session));
+ WT_RET(__wt_log_truncate_files(tmp_session, NULL, true));
}
WT_RET(tmp_session->iface.close(&tmp_session->iface, NULL));
return (0);
@@ -105,6 +107,10 @@ __logmgr_version(WT_SESSION_IMPL *session, bool reconfig)
* Set the log file format versions based on compatibility versions
* set in the connection. We must set this before we call log_open
* to open or create a log file.
+ *
+ * Note: downgrade in this context means the new version is not the
+ * latest possible version. It does not mean the direction of change
+ * from the release we may be running currently.
*/
if (conn->compat_major < WT_LOG_V2_MAJOR) {
new_version = 1;
@@ -167,7 +173,7 @@ __logmgr_version(WT_SESSION_IMPL *session, bool reconfig)
WT_RET(__wt_log_set_version(session, new_version,
first_record, downgrade, reconfig, &lognum));
if (reconfig && FLD_ISSET(conn->log_flags, WT_CONN_LOG_DOWNGRADED))
- WT_RET(__logmgr_force_ckpt(session, lognum));
+ WT_RET(__logmgr_force_archive(session, lognum));
return (0);
}
diff --git a/src/third_party/wiredtiger/src/conn/conn_reconfig.c b/src/third_party/wiredtiger/src/conn/conn_reconfig.c
index ae774ae58c0..8672e824579 100644
--- a/src/third_party/wiredtiger/src/conn/conn_reconfig.c
+++ b/src/third_party/wiredtiger/src/conn/conn_reconfig.c
@@ -31,10 +31,12 @@ __conn_compat_parse(WT_SESSION_IMPL *session,
"illegal compatibility release");
if (*majorp > WIREDTIGER_VERSION_MAJOR)
WT_RET_MSG(session, ENOTSUP,
+ WT_COMPAT_MSG_PREFIX
"unsupported major version");
if (*majorp == WIREDTIGER_VERSION_MAJOR &&
*minorp > WIREDTIGER_VERSION_MINOR)
WT_RET_MSG(session, ENOTSUP,
+ WT_COMPAT_MSG_PREFIX
"unsupported minor version");
return (0);
}
@@ -115,6 +117,7 @@ __wt_conn_compat_config(
(max_major < rel_major ||
(max_major == rel_major && max_minor < rel_minor)))
WT_RET_MSG(session, ENOTSUP,
+ WT_COMPAT_MSG_PREFIX
"required max of %" PRIu16 ".%" PRIu16
"cannot be smaller than compatibility release %"
PRIu16 ".%" PRIu16,
@@ -130,6 +133,7 @@ __wt_conn_compat_config(
(min_major > rel_major ||
(min_major == rel_major && min_minor > rel_minor)))
WT_RET_MSG(session, ENOTSUP,
+ WT_COMPAT_MSG_PREFIX
"required min of %" PRIu16 ".%" PRIu16
"cannot be larger than compatibility release %"
PRIu16 ".%" PRIu16,
@@ -144,6 +148,7 @@ __wt_conn_compat_config(
(conn->req_max_major == rel_major &&
conn->req_max_minor < rel_minor)))
WT_RET_MSG(session, ENOTSUP,
+ WT_COMPAT_MSG_PREFIX
"required max of %" PRIu16 ".%" PRIu16
"cannot be smaller than requested compatibility release %"
PRIu16 ".%" PRIu16,
@@ -159,6 +164,7 @@ __wt_conn_compat_config(
(conn->req_min_major == rel_major &&
conn->req_min_minor > rel_minor)))
WT_RET_MSG(session, ENOTSUP,
+ WT_COMPAT_MSG_PREFIX
"required min of %" PRIu16 ".%" PRIu16
"cannot be larger than requested compatibility release %"
PRIu16 ".%" PRIu16,
@@ -202,6 +208,7 @@ __wt_conn_compat_config(
(max_major < rel_major ||
(max_major == rel_major && max_minor < rel_minor)))
WT_ERR_MSG(session, ENOTSUP,
+ WT_COMPAT_MSG_PREFIX
"required max of %" PRIu16 ".%" PRIu16
"cannot be larger than saved release %"
PRIu16 ".%" PRIu16,
@@ -210,6 +217,7 @@ __wt_conn_compat_config(
(min_major > rel_major ||
(min_major == rel_major && min_minor > rel_minor)))
WT_ERR_MSG(session, ENOTSUP,
+ WT_COMPAT_MSG_PREFIX
"required min of %" PRIu16 ".%" PRIu16
"cannot be larger than saved release %"
PRIu16 ".%" PRIu16,
diff --git a/src/third_party/wiredtiger/src/include/error.h b/src/third_party/wiredtiger/src/include/error.h
index 601d99ac251..f94c3d7b880 100644
--- a/src/third_party/wiredtiger/src/include/error.h
+++ b/src/third_party/wiredtiger/src/include/error.h
@@ -5,6 +5,7 @@
*
* See the file LICENSE for redistribution information.
*/
+#define WT_COMPAT_MSG_PREFIX "Version incompatibility detected: "
#define WT_DEBUG_POINT ((void *)(uintptr_t)0xdeadbeef)
#define WT_DEBUG_BYTE (0xab)
diff --git a/src/third_party/wiredtiger/src/include/extern.h b/src/third_party/wiredtiger/src/include/extern.h
index 004c3fcd2e3..7e2d4a4786d 100644
--- a/src/third_party/wiredtiger/src/include/extern.h
+++ b/src/third_party/wiredtiger/src/include/extern.h
@@ -216,7 +216,7 @@ extern int __wt_las_remove_block(WT_SESSION_IMPL *session, uint64_t pageid, bool
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);
+extern void __wt_checksum_init(void) WT_GCC_FUNC_DECL_ATTRIBUTE((cold));
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);
diff --git a/src/third_party/wiredtiger/src/include/stat.h b/src/third_party/wiredtiger/src/include/stat.h
index a4e28e59826..77e0fa85b0f 100644
--- a/src/third_party/wiredtiger/src/include/stat.h
+++ b/src/third_party/wiredtiger/src/include/stat.h
@@ -508,7 +508,7 @@ struct __wt_connection_stats {
int64_t lock_txn_global_read_count;
int64_t lock_txn_global_write_count;
int64_t log_slot_switch_busy;
- int64_t log_force_ckpt_sleep;
+ int64_t log_force_archive_sleep;
int64_t log_bytes_payload;
int64_t log_bytes_written;
int64_t log_zero_fills;
diff --git a/src/third_party/wiredtiger/src/include/wiredtiger.in b/src/third_party/wiredtiger/src/include/wiredtiger.in
index 9e0b5d4f02c..2991d6f74e3 100644
--- a/src/third_party/wiredtiger/src/include/wiredtiger.in
+++ b/src/third_party/wiredtiger/src/include/wiredtiger.in
@@ -3518,10 +3518,33 @@ struct __wt_config_parser {
const char *key, WT_CONFIG_ITEM *value);
};
-#endif /* !defined(SWIG) */
/*! @} */
/*!
+ * @name Support functions
+ * @anchor support_functions
+ * @{
+ */
+
+/*!
+ * Return a buffer's 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
+ */
+uint32_t wiredtiger_checksum_crc32c(const void *buffer, size_t len)
+ WT_ATTRIBUTE_LIBRARY_VISIBLE;
+
+/*! @} */
+#endif /* !defined(SWIG) */
+
+/*!
* Get version information.
*
* @snippet ex_all.c Get the WiredTiger library version #1
@@ -5326,8 +5349,8 @@ extern int wiredtiger_extension_terminate(WT_CONNECTION *connection);
#define WT_STAT_CONN_LOCK_TXN_GLOBAL_WRITE_COUNT 1193
/*! log: busy returns attempting to switch slots */
#define WT_STAT_CONN_LOG_SLOT_SWITCH_BUSY 1194
-/*! log: force checkpoint calls slept */
-#define WT_STAT_CONN_LOG_FORCE_CKPT_SLEEP 1195
+/*! log: force archive time sleeping (usecs) */
+#define WT_STAT_CONN_LOG_FORCE_ARCHIVE_SLEEP 1195
/*! log: log bytes of payload data */
#define WT_STAT_CONN_LOG_BYTES_PAYLOAD 1196
/*! log: log bytes written */
diff --git a/src/third_party/wiredtiger/src/log/log.c b/src/third_party/wiredtiger/src/log/log.c
index 8dfd0c0d153..6ce26e03c5d 100644
--- a/src/third_party/wiredtiger/src/log/log.c
+++ b/src/third_party/wiredtiger/src/log/log.c
@@ -975,12 +975,13 @@ __log_open_verify(WT_SESSION_IMPL *session, uint32_t id, WT_FH **fhp,
WT_LOG_VERSION, desc->version);
/*
- * We error if the log version is less than the required minimum
- * or larger than the required maximum.
+ * We error if the log version is less than the required minimum or
+ * larger than the required maximum.
*/
if (conn->req_max_major != WT_CONN_COMPAT_NONE &&
desc->version > conn->log_req_max)
WT_ERR_MSG(session, WT_ERROR,
+ WT_COMPAT_MSG_PREFIX
"unsupported WiredTiger file version: this build"
" requires a maximum version of %" PRIu16 ","
" and the file is version %" PRIu16,
@@ -989,13 +990,14 @@ __log_open_verify(WT_SESSION_IMPL *session, uint32_t id, WT_FH **fhp,
if (conn->req_min_major != WT_CONN_COMPAT_NONE &&
desc->version < conn->log_req_min)
WT_ERR_MSG(session, WT_ERROR,
+ WT_COMPAT_MSG_PREFIX
"unsupported WiredTiger file version: this build"
" requires a minimum version of %" PRIu16 ","
" and the file is version %" PRIu16,
conn->log_req_min, desc->version);
/*
- * Set up the return values if the magic number is valid.
+ * Set up the return values since the header is valid.
*/
if (versionp != NULL)
*versionp = desc->version;
diff --git a/src/third_party/wiredtiger/src/support/stat.c b/src/third_party/wiredtiger/src/support/stat.c
index 4edafcbb8ce..749564c2464 100644
--- a/src/third_party/wiredtiger/src/support/stat.c
+++ b/src/third_party/wiredtiger/src/support/stat.c
@@ -942,7 +942,7 @@ static const char * const __stats_connection_desc[] = {
"lock: txn global read lock acquisitions",
"lock: txn global write lock acquisitions",
"log: busy returns attempting to switch slots",
- "log: force checkpoint calls slept",
+ "log: force archive time sleeping (usecs)",
"log: log bytes of payload data",
"log: log bytes written",
"log: log files manually zero-filled",
@@ -1339,7 +1339,7 @@ __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats)
stats->lock_txn_global_read_count = 0;
stats->lock_txn_global_write_count = 0;
stats->log_slot_switch_busy = 0;
- stats->log_force_ckpt_sleep = 0;
+ stats->log_force_archive_sleep = 0;
stats->log_bytes_payload = 0;
stats->log_bytes_written = 0;
stats->log_zero_fills = 0;
@@ -1807,7 +1807,8 @@ __wt_stat_connection_aggregate(
to->lock_txn_global_write_count +=
WT_STAT_READ(from, lock_txn_global_write_count);
to->log_slot_switch_busy += WT_STAT_READ(from, log_slot_switch_busy);
- to->log_force_ckpt_sleep += WT_STAT_READ(from, log_force_ckpt_sleep);
+ to->log_force_archive_sleep +=
+ WT_STAT_READ(from, log_force_archive_sleep);
to->log_bytes_payload += WT_STAT_READ(from, log_bytes_payload);
to->log_bytes_written += WT_STAT_READ(from, log_bytes_written);
to->log_zero_fills += WT_STAT_READ(from, log_zero_fills);
diff --git a/src/third_party/wiredtiger/src/txn/txn_ckpt.c b/src/third_party/wiredtiger/src/txn/txn_ckpt.c
index dd5eb99750b..10af61caeaf 100644
--- a/src/third_party/wiredtiger/src/txn/txn_ckpt.c
+++ b/src/third_party/wiredtiger/src/txn/txn_ckpt.c
@@ -126,7 +126,7 @@ __checkpoint_update_generation(WT_SESSION_IMPL *session)
*/
static int
__checkpoint_apply_all(WT_SESSION_IMPL *session, const char *cfg[],
- int (*op)(WT_SESSION_IMPL *, const char *[]), bool *fullp)
+ int (*op)(WT_SESSION_IMPL *, const char *[]))
{
WT_CONFIG targetconf;
WT_CONFIG_ITEM cval, k, v;
@@ -196,9 +196,6 @@ __checkpoint_apply_all(WT_SESSION_IMPL *session, const char *cfg[],
__wt_conn_btree_apply(session, NULL, op, NULL, cfg));
}
- if (fullp != NULL)
- *fullp = !target_list;
-
err: __wt_scr_free(session, &tmp);
return (ret);
}
@@ -767,11 +764,101 @@ __checkpoint_prepare(
*/
WT_ASSERT(session, session->ckpt_handle_next == 0);
WT_WITH_TABLE_READ_LOCK(session, ret = __checkpoint_apply_all(
- session, cfg, __wt_checkpoint_get_handles, NULL));
+ session, cfg, __wt_checkpoint_get_handles));
return (ret);
}
/*
+ * __txn_checkpoint_can_skip --
+ * Determine whether it's safe to skip taking a checkpoint.
+ */
+static int
+__txn_checkpoint_can_skip(WT_SESSION_IMPL *session,
+ const char *cfg[], bool *fullp, bool *use_timestampp, bool *can_skipp)
+{
+ WT_CONFIG targetconf;
+ WT_CONFIG_ITEM cval, k, v;
+ WT_CONNECTION_IMPL *conn;
+ WT_TXN_GLOBAL *txn_global;
+ bool full, use_timestamp;
+
+ /*
+ * Default to not skipping - also initialize the other output
+ * parameters - even though they will always be initialized unless
+ * there is an error and callers need to ignore the results on error.
+ */
+ *can_skipp = *fullp = *use_timestampp = false;
+
+ conn = S2C(session);
+ txn_global = &conn->txn_global;
+
+ /*
+ * This function also parses out some configuration options and hands
+ * them back to the caller - make sure it does that parsing regardless
+ * of the result.
+ *
+ * Determine if this is going to be a full checkpoint, that is a
+ * checkpoint that applies to all data tables in a database.
+ */
+ WT_RET(__wt_config_gets(session, cfg, "target", &cval));
+ __wt_config_subinit(session, &targetconf, &cval);
+ full = __wt_config_next(&targetconf, &k, &v) != 0;
+ if (fullp != NULL)
+ *fullp = full;
+
+ WT_RET(__wt_config_gets(session, cfg, "use_timestamp", &cval));
+ use_timestamp = cval.val != 0;
+ if (use_timestampp != NULL)
+ *use_timestampp = use_timestamp;
+
+ /* Never skip non-full checkpoints */
+ if (!full)
+ return (0);
+
+ /* Never skip if force is configured. */
+ WT_RET(__wt_config_gets_def(session, cfg, "force", 0, &cval));
+ if (cval.val != 0)
+ return (0);
+
+ /* Never skip named checkpoints. */
+ WT_RET(__wt_config_gets(session, cfg, "name", &cval));
+ if (cval.val != 0)
+ return (0);
+
+ /*
+ * Skip checkpointing the database if nothing has been dirtied since
+ * the last checkpoint. That said there can be short instances when a
+ * btree gets marked dirty and the connection is yet to be. We might
+ * skip a checkpoint in that short instance, which is okay because by
+ * the next time we get to checkpoint, the connection would have been
+ * marked dirty and hence the checkpoint will not be skipped again.
+ */
+ if (!conn->modified) {
+ *can_skipp = true;
+ return (0);
+ }
+
+#ifdef HAVE_TIMESTAMPS
+ /*
+ * If the checkpoint is using timestamps, and the stable timestamp
+ * hasn't been updated since the last checkpoint there is nothing
+ * more that could be written.
+ */
+ if (use_timestamp && txn_global->has_stable_timestamp &&
+ !__wt_timestamp_iszero(&txn_global->last_ckpt_timestamp) &&
+ __wt_timestamp_cmp(&txn_global->last_ckpt_timestamp,
+ &txn_global->stable_timestamp) == 0) {
+ *can_skipp = true;
+ return (0);
+ }
+#else
+ WT_UNUSED(txn_global);
+#endif
+
+ return (0);
+}
+
+/*
* __txn_checkpoint --
* Checkpoint a database or a list of objects in the database.
*/
@@ -787,7 +874,7 @@ __txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[])
WT_TXN_ISOLATION saved_isolation;
uint64_t fsync_duration_usecs, generation, time_start, time_stop;
u_int i;
- bool failed, full, idle, logging, tracking;
+ bool can_skip, failed, full, idle, logging, tracking, use_timestamp;
void *saved_meta_next;
conn = S2C(session);
@@ -795,15 +882,22 @@ __txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[])
txn = &session->txn;
txn_global = &conn->txn_global;
saved_isolation = session->isolation;
- full = idle = logging = tracking = false;
+ full = idle = logging = tracking = use_timestamp = false;
+
+ /* Avoid doing work if possible. */
+ WT_RET(__txn_checkpoint_can_skip(session,
+ cfg, &full, &use_timestamp, &can_skip));
+ if (can_skip) {
+ WT_STAT_CONN_INCR(session, txn_checkpoint_skipped);
+ return (0);
+ }
/*
* Do a pass over the configuration arguments and figure out what kind
* of checkpoint this is.
*/
- WT_RET(__checkpoint_apply_all(session, cfg, NULL, &full));
+ WT_RET(__checkpoint_apply_all(session, cfg, NULL));
- /* Configure logging only if doing a full checkpoint. */
logging = FLD_ISSET(conn->log_flags, WT_CONN_LOG_ENABLED);
/* Reset the maximum page size seen by eviction. */
@@ -994,8 +1088,17 @@ __txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[])
if (full) {
__checkpoint_stats(session);
#ifdef HAVE_TIMESTAMPS
- __wt_timestamp_set(
- &conn->txn_global.last_ckpt_timestamp, &ckpt_tmp_ts);
+ /*
+ * If timestamps were used to define the content of the
+ * checkpoint update the saved last checkpoint timestamp,
+ * otherwise leave it alone. If a checkpoint is taken without
+ * timestamps, it's likely a bug, but we don't want to clear
+ * the saved last checkpoint timestamp regardless.
+ */
+ if (use_timestamp)
+ __wt_timestamp_set(
+ &conn->txn_global.last_ckpt_timestamp,
+ &ckpt_tmp_ts);
#endif
}
diff --git a/src/third_party/wiredtiger/src/txn/txn_recover.c b/src/third_party/wiredtiger/src/txn/txn_recover.c
index c2a1c7d3b27..ac656047e62 100644
--- a/src/third_party/wiredtiger/src/txn/txn_recover.c
+++ b/src/third_party/wiredtiger/src/txn/txn_recover.c
@@ -704,6 +704,13 @@ done: WT_ERR(__recovery_set_checkpoint_timestamp(&r));
* archiving.
*/
WT_ERR(session->iface.checkpoint(&session->iface, "force=1"));
+
+ /*
+ * If we're downgrading and have newer log files, force an archive,
+ * no matter what the archive setting is.
+ */
+ if (FLD_ISSET(conn->log_flags, WT_CONN_LOG_FORCE_DOWNGRADE))
+ WT_ERR(__wt_log_truncate_files(session, NULL, true));
FLD_SET(conn->log_flags, WT_CONN_LOG_RECOVER_DONE);
err: WT_TRET(__recovery_free(&r));
diff --git a/src/third_party/wiredtiger/test/csuite/Makefile.am b/src/third_party/wiredtiger/test/csuite/Makefile.am
index 1981b3e6831..b3dde5ec628 100644
--- a/src/third_party/wiredtiger/test/csuite/Makefile.am
+++ b/src/third_party/wiredtiger/test/csuite/Makefile.am
@@ -11,6 +11,10 @@ test_random_abort_SOURCES = random_abort/main.c
noinst_PROGRAMS += test_random_abort
all_TESTS += random_abort/smoke.sh
+test_rwlock_SOURCES = rwlock/main.c
+noinst_PROGRAMS += test_rwlock
+all_TESTS += test_rwlock
+
test_scope_SOURCES = scope/main.c
noinst_PROGRAMS += test_scope
all_TESTS += test_scope
@@ -99,14 +103,14 @@ test_wt3874_pad_byte_collator_SOURCES = wt3874_pad_byte_collator/main.c
noinst_PROGRAMS += test_wt3874_pad_byte_collator
all_TESTS += test_wt3874_pad_byte_collator
-test_rwlock_SOURCES = rwlock/main.c
-noinst_PROGRAMS += test_rwlock
-all_TESTS += test_rwlock
-
test_wt4105_large_doc_small_upd_SOURCES = wt4105_large_doc_small_upd/main.c
noinst_PROGRAMS += test_wt4105_large_doc_small_upd
all_TESTS += test_wt4105_large_doc_small_upd
+test_wt4117_checksum_SOURCES = wt4117_checksum/main.c
+noinst_PROGRAMS += test_wt4117_checksum
+all_TESTS += test_wt4117_checksum
+
# Run this during a "make check" smoke test.
TESTS = $(all_TESTS)
LOG_COMPILER = $(TEST_WRAPPER)
diff --git a/src/third_party/wiredtiger/test/csuite/wt4105_large_doc_small_upd/main.c b/src/third_party/wiredtiger/test/csuite/wt4105_large_doc_small_upd/main.c
index 75ee0ade1cb..1efe22c1816 100644
--- a/src/third_party/wiredtiger/test/csuite/wt4105_large_doc_small_upd/main.c
+++ b/src/third_party/wiredtiger/test/csuite/wt4105_large_doc_small_upd/main.c
@@ -46,7 +46,7 @@ on_alarm(int signo)
/* NOTREACHED */
}
-static int ignore_errors;
+static int ignore_errors = 0;
static int
handle_error(WT_EVENT_HANDLER *handler,
@@ -82,9 +82,8 @@ main(int argc, char *argv[])
WT_ITEM value;
WT_MODIFY modify_entry;
WT_SESSION *session, *session2;
-
- char *large_doc;
uint64_t i, j, offset;
+ char *large_doc;
opts = &_opts;
memset(opts, 0, sizeof(*opts));
@@ -106,7 +105,7 @@ main(int argc, char *argv[])
session->open_cursor(session, uri, NULL, NULL, &c));
/* Value is initialized with 'v' and has not significance to it. */
- large_doc = (char *)malloc(DATASIZE);
+ large_doc = dmalloc(DATASIZE);
memset(large_doc, 'v', DATASIZE);
value.data = large_doc;
value.size = DATASIZE;
@@ -132,8 +131,7 @@ main(int argc, char *argv[])
/* Start another session to perform small updates. */
testutil_check(
opts->conn->open_session(opts->conn, NULL, NULL, &session2));
- testutil_check(
- session->open_cursor(session2, uri, NULL, NULL, &c));
+ testutil_check(session2->open_cursor(session2, uri, NULL, NULL, &c));
j = offset = 0;
while (++j < MODIFY_COUNT) {
@@ -159,6 +157,7 @@ main(int argc, char *argv[])
printf("modify count %" PRIu64"\n", j * NUM_DOCS);
}
+ free(large_doc);
testutil_cleanup(opts);
return (EXIT_SUCCESS);
diff --git a/src/third_party/wiredtiger/test/csuite/wt4117_checksum/main.c b/src/third_party/wiredtiger/test/csuite/wt4117_checksum/main.c
new file mode 100644
index 00000000000..9a786e5d222
--- /dev/null
+++ b/src/third_party/wiredtiger/test/csuite/wt4117_checksum/main.c
@@ -0,0 +1,108 @@
+/*-
+ * Public Domain 2014-2018 MongoDB, Inc.
+ * Public Domain 2008-2014 WiredTiger, Inc.
+ *
+ * This is free and unencumbered software released into the public domain.
+ *
+ * Anyone is free to copy, modify, publish, use, compile, sell, or
+ * distribute this software, either in source code form or as a compiled
+ * binary, for any purpose, commercial or non-commercial, and by any
+ * means.
+ *
+ * In jurisdictions that recognize copyright laws, the author or authors
+ * of this software dedicate any and all copyright interest in the
+ * software to the public domain. We make this dedication for the benefit
+ * of the public at large and to the detriment of our heirs and
+ * successors. We intend this dedication to be an overt act of
+ * relinquishment in perpetuity of all present and future rights to this
+ * software under copyright law.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "test_util.h"
+
+/*
+ * JIRA ticket reference: WT-4117
+ * Test case description: Smoke-test the CRC32C external API.
+ */
+
+static inline void
+check(uint32_t crc32c, uint32_t expected, size_t len, const char *msg)
+{
+ testutil_checkfmt(crc32c == expected ? 0 : 1,
+ "%s checksum mismatch of %" WT_SIZET_FMT " bytes: %#08x != %#08x\n",
+ msg, len, crc32c, expected);
+}
+
+static void
+run(void)
+{
+ size_t len;
+ uint32_t crc32c;
+ uint8_t *data;
+
+ /* Allocate aligned memory for the data. */
+ data = dcalloc(100, sizeof(uint8_t));
+
+ /*
+ * Some simple known checksums.
+ */
+ len = 1;
+ crc32c = wiredtiger_checksum_crc32c(data, len);
+ check(crc32c, (uint32_t)0x527d5351, len, "nul x1");
+
+ len = 2;
+ crc32c = wiredtiger_checksum_crc32c(data, len);
+ check(crc32c, (uint32_t)0xf16177d2, len, "nul x2");
+
+ len = 3;
+ crc32c = wiredtiger_checksum_crc32c(data, len);
+ check(crc32c, (uint32_t)0x6064a37a, len, "nul x3");
+
+ len = 4;
+ crc32c = wiredtiger_checksum_crc32c(data, len);
+ check(crc32c, (uint32_t)0x48674bc7, len, "nul x4");
+
+ len = strlen("123456789");
+ memcpy(data, "123456789", len);
+ crc32c = wiredtiger_checksum_crc32c(data, len);
+ check(crc32c, (uint32_t)0xe3069283, len, "known string #1");
+
+ len = strlen("The quick brown fox jumps over the lazy dog");
+ memcpy(data, "The quick brown fox jumps over the lazy dog", len);
+ crc32c = wiredtiger_checksum_crc32c(data, len);
+ check(crc32c, (uint32_t)0x22620404, len, "known string #2");
+
+ free(data);
+}
+
+int
+main(int argc, char *argv[])
+{
+ TEST_OPTS *opts, _opts;
+
+ opts = &_opts;
+ memset(opts, 0, sizeof(*opts));
+ testutil_check(testutil_parse_opts(argc, argv, opts));
+ testutil_make_work_dir(opts->home);
+
+ /*
+ * The external API should work before the library configures itself,
+ * run before and after calling wiredtiger_open().
+ */
+ run();
+
+ testutil_check(
+ wiredtiger_open(opts->home, NULL, "create", &opts->conn));
+
+ run();
+
+ testutil_cleanup(opts);
+ return (EXIT_SUCCESS);
+}
diff --git a/src/third_party/wiredtiger/test/format/ops.c b/src/third_party/wiredtiger/test/format/ops.c
index 0d3e9892962..7d08dbd8bd8 100644
--- a/src/third_party/wiredtiger/test/format/ops.c
+++ b/src/third_party/wiredtiger/test/format/ops.c
@@ -127,7 +127,7 @@ wts_ops(int lastrun)
if (!SINGLETHREADED)
g.rand_log_stop = true;
- /* Open a session. */
+ /* Logging requires a session. */
if (g.logging != 0) {
testutil_check(conn->open_session(conn, NULL, NULL, &session));
(void)g.wt_api->msg_printf(g.wt_api, session,
@@ -241,6 +241,10 @@ wts_ops(int lastrun)
fprintf(stderr, "%s\n",
"format run exceeded 15 minutes past the maximum "
"time, aborting the process.");
+
+ (void)conn->debug_info(conn, "txn");
+ (void)conn->debug_info(conn, "cache");
+
abort();
}
}
diff --git a/src/third_party/wiredtiger/test/suite/test_compat01.py b/src/third_party/wiredtiger/test/suite/test_compat01.py
index 696e24f4569..f9131331640 100644
--- a/src/third_party/wiredtiger/test/suite/test_compat01.py
+++ b/src/third_party/wiredtiger/test/suite/test_compat01.py
@@ -47,28 +47,25 @@ class test_compat01(wttest.WiredTigerTestCase, suite_subprocess):
# Log version 2 introduced that record.
# Log version 3 continues to have that record.
min_logv = 2
+ latest_logv = 3
# The API uses only the major and minor numbers but accepts with
# and without the patch number. Test both.
start_compat = [
('def', dict(compat1='none', logv1=3)),
('31', dict(compat1="3.1", logv1=3)),
- ('31_patch', dict(compat1="3.1.0", logv1=3)),
('30', dict(compat1="3.0", logv1=2)),
('30_patch', dict(compat1="3.0.0", logv1=2)),
('26', dict(compat1="2.6", logv1=1)),
- ('26_patch', dict(compat1="2.6.1", logv1=1)),
('old', dict(compat1="1.8", logv1=1)),
('old_patch', dict(compat1="1.8.1", logv1=1)),
]
restart_compat = [
('def2', dict(compat2='none', logv2=3)),
- ('31.2', dict(compat2="3.1", logv2=3)),
- ('31_patch2', dict(compat2="3.1.0", logv2=3)),
- ('30.2', dict(compat2="3.0", logv2=2)),
+ ('31_2', dict(compat2="3.1", logv2=3)),
+ ('30_2', dict(compat2="3.0", logv2=2)),
('30_patch2', dict(compat2="3.0.0", logv2=2)),
- ('26.2', dict(compat2="2.6", logv2=1)),
- ('26_patch2', dict(compat2="2.6.1", logv2=1)),
+ ('26_2', dict(compat2="2.6", logv2=1)),
('old2', dict(compat2="1.8", logv2=1)),
('old_patch2', dict(compat2="1.8.1", logv2=1)),
]
@@ -91,7 +88,7 @@ class test_compat01(wttest.WiredTigerTestCase, suite_subprocess):
self.pr("Conn config:" + log_str + compat_str)
return log_str + compat_str
- def check_prev_lsn(self, conn_close, prev_lsn_count):
+ def check_prev_lsn(self, exists, conn_close):
#
# Run printlog and look for the prev_lsn log record. Verify its
# existence with the passed in expected result. We don't use
@@ -100,30 +97,30 @@ class test_compat01(wttest.WiredTigerTestCase, suite_subprocess):
# the entire file if needed and set a boolean for comparison.
#
self.runWt(['printlog'], outfilename='printlog.out', closeconn=conn_close)
- pstr = str(prev_lsn_count)
- self.pr("CHECK PREV: Looking for " + pstr + " prev LSN entries")
- contains = 0
+ contains = False
with open('printlog.out') as logfile:
for line in logfile:
if 'optype' in line and 'prev_lsn' in line:
- contains += 1
- self.assertEqual(prev_lsn_count, contains)
+ contains = True
+ break
+ self.assertEqual(exists, contains)
def check_log(self, reconfig):
orig_logs = fnmatch.filter(os.listdir('.'), "*gerLog*")
compat_str = self.make_compat_str(False)
- if self.logv1 >= self.min_logv:
- prev_lsn_logs = len(orig_logs)
- else:
- prev_lsn_logs = 0
- pstr = str(prev_lsn_logs)
- self.pr("CHECK LOG: Orig " + pstr + " prev LSN log files")
if not reconfig:
#
- # Close and open the connection to force recovery and reset the
- # compatibility string on startup.
+ # Close and open the connection to force recovery and log archiving
+ # even if archive is turned off (in some circumstances). If we are
+ # downgrading we must archive newer logs. Verify the log files
+ # have or have not been archived.
#
+ exist = True
+ if self.logv1 < self.min_logv:
+ exist = False
+ self.check_prev_lsn(exist, True)
+
self.conn.close()
log_str = 'log=(enabled,file_max=%s,archive=false),' % self.logmax
restart_config = log_str + compat_str
@@ -134,31 +131,30 @@ class test_compat01(wttest.WiredTigerTestCase, suite_subprocess):
conn = self.wiredtiger_open('.', restart_config)
conn.close()
check_close = False
- #
- # If the version was upgraded we'll see a new log file containing
- # the new log record no matter what the original setting was.
- #
- if self.logv2 > 1:
- prev_lsn_logs += 1
else:
self.pr("Reconfigure: " + compat_str)
self.conn.reconfigure(compat_str)
check_close = True
+
#
- # If we're reconfiguring, we'll see another new log file
- # when transitioning between log version numbers. Staying
- # at the same version has no effect. We'll only see another
- # new log file with the prevlsn if the new version supports it.
+ # Archiving is turned off explicitly.
#
- if self.logv1 != self.logv2 and self.logv2 >= self.min_logv:
- prev_lsn_logs += 1
+ # Check logs. The original logs should have been archived only if
+ # we downgraded. In all other cases the original logs should be there.
+ # Downgrade means not running the latest possible log version, not
+ # the difference between original and current.
+ cur_logs = fnmatch.filter(os.listdir('.'), "*Log*")
+ log_present = True
+ if self.logv1 != self.logv2 and self.logv2 != self.latest_logv:
+ log_present = False
+ for o in orig_logs:
+ self.assertEqual(log_present, o in cur_logs)
# Run printlog and verify the new record does or does not exist.
- # Need to check count of log files that should and should not have
- # the prev_lsn record based on the count of log files that exist
- # before and after. Pass that into this function and check the
- # number of prev_lsn records we see.
- self.check_prev_lsn(check_close, prev_lsn_logs)
+ exist = True
+ if self.logv2 < self.min_logv:
+ exist = False
+ self.check_prev_lsn(exist, check_close)
def run_test(self, reconfig):
# If reconfiguring with the empty string there is nothing to do.
diff --git a/src/third_party/wiredtiger/test/suite/test_compat02.py b/src/third_party/wiredtiger/test/suite/test_compat02.py
index 15d6a58e84f..1b6c2dd2889 100644
--- a/src/third_party/wiredtiger/test/suite/test_compat02.py
+++ b/src/third_party/wiredtiger/test/suite/test_compat02.py
@@ -49,9 +49,9 @@ class test_compat02(wttest.WiredTigerTestCase, suite_subprocess):
min_logv = 2
# Test detecting a not-yet-existing log version. This should
- # hold us for a couple years.
- future_logv = 5
- future_rel = "5.0"
+ # hold us for many years.
+ future_logv = 20
+ future_rel = "20.0"
# The API uses only the major and minor numbers but accepts with
# and without the patch number. Test one on release and the
@@ -150,10 +150,9 @@ class test_compat02(wttest.WiredTigerTestCase, suite_subprocess):
expect_err = False
if (expect_err == True):
- self.pr("EXPECT ERROR")
- with self.expectedStderrPattern(''):
- self.assertRaisesException(wiredtiger.WiredTigerError,
- lambda: self.wiredtiger_open('.', restart_config))
+ msg = '/Version incompatibility detected:/'
+ self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
+ lambda: self.wiredtiger_open('.', restart_config), msg)
else:
self.pr("EXPECT SUCCESS")
conn = self.wiredtiger_open('.', restart_config)
diff --git a/src/third_party/wiredtiger/test/suite/test_compat03.py b/src/third_party/wiredtiger/test/suite/test_compat03.py
index e6b8ead50a6..caf8a4bc4e8 100644
--- a/src/third_party/wiredtiger/test/suite/test_compat03.py
+++ b/src/third_party/wiredtiger/test/suite/test_compat03.py
@@ -49,9 +49,9 @@ class test_compat03(wttest.WiredTigerTestCase, suite_subprocess):
min_logv = 2
# Test detecting a not-yet-existing log version. This should
- # hold us for a couple years.
- future_logv = 5
- future_rel = "5.0"
+ # hold us for many years.
+ future_logv = 20
+ future_rel = "20.0"
# The API uses only the major and minor numbers but accepts with
# and without the patch number. Test one on release and the
@@ -122,10 +122,9 @@ class test_compat03(wttest.WiredTigerTestCase, suite_subprocess):
expect_err = False
if (expect_err == True):
- self.pr("EXPECT ERROR")
- with self.expectedStderrPattern(''):
- self.assertRaisesException(wiredtiger.WiredTigerError,
- lambda: self.wiredtiger_open(testdir, config_str))
+ msg = '/Version incompatibility detected:/'
+ self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
+ lambda: self.wiredtiger_open(testdir, config_str), msg)
else:
self.pr("EXPECT SUCCESS")
conn = self.wiredtiger_open(testdir, config_str)
diff --git a/src/third_party/wiredtiger/test/suite/test_compat04.py b/src/third_party/wiredtiger/test/suite/test_compat04.py
new file mode 100644
index 00000000000..409a0bd1b76
--- /dev/null
+++ b/src/third_party/wiredtiger/test/suite/test_compat04.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python
+#
+# Public Domain 2014-2018 MongoDB, Inc.
+# Public Domain 2008-2014 WiredTiger, Inc.
+#
+# This is free and unencumbered software released into the public domain.
+#
+# Anyone is free to copy, modify, publish, use, compile, sell, or
+# distribute this software, either in source code form or as a compiled
+# binary, for any purpose, commercial or non-commercial, and by any
+# means.
+#
+# In jurisdictions that recognize copyright laws, the author or authors
+# of this software dedicate any and all copyright interest in the
+# software to the public domain. We make this dedication for the benefit
+# of the public at large and to the detriment of our heirs and
+# successors. We intend this dedication to be an overt act of
+# relinquishment in perpetuity of all present and future rights to this
+# software under copyright law.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# test_compat04.py
+# Check compatibility API
+
+import fnmatch, os
+import wiredtiger, wttest
+from suite_subprocess import suite_subprocess
+from wtdataset import SimpleDataSet, simple_key
+from wtscenario import make_scenarios
+
+class test_compat04(wttest.WiredTigerTestCase, suite_subprocess):
+ # Add enough entries and use a small log size to generate more than
+ # one log file.
+ entries = 2000
+ logmax = "100K"
+ tablename = 'test_compat04'
+ uri = 'table:' + tablename
+ # Declare the log versions that do and do not have prevlsn.
+ # Log version 1 does not have the prevlsn record.
+ # Log version 2 introduced that record.
+ # Log version 3 continues to have that record.
+ min_logv = 2
+
+ # The outline of this test is that we create the database at the
+ # create release value. Then we reconfigure the release to the
+ # reconfig release value. Then we close and reopen the database with
+ # a release and compatibility maximum of that release value. This
+ # should be successful for all directions.
+ #
+ create_release = [
+ ('def_rel', dict(create_rel='none', log_crrel=3)),
+ ('31_rel', dict(create_rel="3.1", log_crrel=3)),
+ ('30_rel', dict(create_rel="3.0", log_crrel=2)),
+ ('26_rel', dict(create_rel="2.6", log_crrel=1)),
+ ]
+ reconfig_release = [
+ ('31_rel', dict(rel="3.1", log_rel=3)),
+ ('30_rel', dict(rel="3.0", log_rel=2)),
+ ('300_rel', dict(rel="3.0.0", log_rel=2)),
+ ('26_rel', dict(rel="2.6", log_rel=1)),
+ ]
+ base_config = [
+ ('basecfg_true', dict(basecfg='true')),
+ ('basecfg_false', dict(basecfg='false')),
+ ]
+ scenarios = make_scenarios(create_release, reconfig_release, base_config)
+
+ # This test creates scenarios that lead to errors. This is different
+ # than compat02 because it is testing errors (or success) using the
+ # compatibility settings on the initial database creation.
+ def conn_config(self):
+ config_str = 'create,config_base=%s,' % self.basecfg
+ log_str = 'log=(archive=false,enabled,file_max=%s),' % self.logmax
+ compat_str = ''
+ if (self.create_rel != 'none'):
+ compat_str += 'compatibility=(release="%s"),' % self.create_rel
+ config_str += log_str + compat_str
+ self.pr("Conn config:" + config_str)
+ return config_str
+
+ def test_compat04(self):
+ #
+ # Create initial database at the compatibility level requested
+ # and a table with some data.
+ #
+ self.session.create(self.uri, 'key_format=i,value_format=i')
+ c = self.session.open_cursor(self.uri, None)
+ #
+ # Add some entries to generate log files.
+ #
+ for i in range(self.entries):
+ c[i] = i + 1
+ c.close()
+
+ # Reconfigure and close the connection. Then reopen with that release.
+ # We expect success.
+ config_str = 'compatibility=(release=%s)' % self.rel
+ self.conn.reconfigure(config_str)
+ self.conn.close()
+
+ config_str = 'compatibility=(release=%s,require_max=%s)' % (self.rel, self.rel)
+ conn = self.wiredtiger_open('.', config_str)
+ conn.close()
+
+if __name__ == '__main__':
+ wttest.run()
+
+if __name__ == '__main__':
+ wttest.run()
diff --git a/src/third_party/wiredtiger/test/suite/test_las01.py b/src/third_party/wiredtiger/test/suite/test_las01.py
index fd4dea87c35..8b6132f8418 100644
--- a/src/third_party/wiredtiger/test/suite/test_las01.py
+++ b/src/third_party/wiredtiger/test/suite/test_las01.py
@@ -92,6 +92,9 @@ class test_las01(wttest.WiredTigerTestCase):
conn.close()
def test_las(self):
+ if not wiredtiger.timestamp_build():
+ self.skipTest('requires a timestamp build')
+
# Create a small table.
uri = "table:test_las01"
nrows = 100
diff --git a/src/third_party/wiredtiger/test/suite/test_las02.py b/src/third_party/wiredtiger/test/suite/test_las02.py
index af089d6c19e..7291214fe7e 100644
--- a/src/third_party/wiredtiger/test/suite/test_las02.py
+++ b/src/third_party/wiredtiger/test/suite/test_las02.py
@@ -62,6 +62,9 @@ class test_las02(wttest.WiredTigerTestCase):
self.assertEqual(count, nrows)
def test_las(self):
+ if not wiredtiger.timestamp_build():
+ self.skipTest('requires a timestamp build')
+
nrows = 10000
# Create a table without logging to ensure we get "skew_newest" lookaside eviction behavior.
diff --git a/src/third_party/wiredtiger/test/suite/test_prepare01.py b/src/third_party/wiredtiger/test/suite/test_prepare01.py
index 20615ab836c..d88fdff9fd6 100644
--- a/src/third_party/wiredtiger/test/suite/test_prepare01.py
+++ b/src/third_party/wiredtiger/test/suite/test_prepare01.py
@@ -103,6 +103,9 @@ class test_prepare01(wttest.WiredTigerTestCase):
# Loop through a set of inserts, periodically committing; before each
# commit, verify the number of visible records matches the expected value.
def test_visibility(self):
+ if not wiredtiger.timestamp_build():
+ self.skipTest('requires a timestamp build')
+
self.session.create(self.uri,
'key_format=' + self.key_format +
',value_format=' + self.value_format)
@@ -148,6 +151,9 @@ class test_read_committed_default(wttest.WiredTigerTestCase):
return count
def test_read_committed_default(self):
+ if not wiredtiger.timestamp_build():
+ self.skipTest('requires a timestamp build')
+
self.session.create(self.uri, 'key_format=S,value_format=S')
cursor = self.session.open_cursor(self.uri, None)
self.session.begin_transaction()
diff --git a/src/third_party/wiredtiger/test/suite/test_prepare03.py b/src/third_party/wiredtiger/test/suite/test_prepare03.py
index 974a9d09b1c..870d62bb790 100644
--- a/src/third_party/wiredtiger/test/suite/test_prepare03.py
+++ b/src/third_party/wiredtiger/test/suite/test_prepare03.py
@@ -74,6 +74,9 @@ class test_prepare03(wttest.WiredTigerTestCase):
# Create the table and test cursor operations.
def test_prepare_cursor(self):
+ if not wiredtiger.timestamp_build():
+ self.skipTest('requires a timestamp build')
+
tablearg = self.uri + ':' + self.table_name
create_args = self.format
preparemsg = "/ not permitted in a prepared transaction/"