summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Chen <luke.chen@mongodb.com>2018-04-27 21:55:41 +1000
committerLuke Chen <luke.chen@mongodb.com>2018-04-27 21:55:41 +1000
commit5891912b5622eed300b11b05cd3269be580e086c (patch)
tree0ef6c39d542d68771617109e20a29963c3e4a582
parent7cd83e5486cfb3383c2e4e5671ae9602be297547 (diff)
downloadmongo-5891912b5622eed300b11b05cd3269be580e086c.tar.gz
Import wiredtiger: abf0651a814a01169c21a3cbe689ad2534134701 from branch mongodb-3.8
ref: 43c20b5583..abf0651a81 for: 4.0.0-rc0 WT-3914 Add general documentation for prepared transactions WT-3937 Tune lookaside sweep to react to workload WT-4039 Move row-store missing-value support into the cell unpack code. WT-4044 Add an internal API to return if a generation is active WT-4052 Free transaction resources should on session reset WT-4055 Format transaction prepare and logging configuration is incorrect WT-4057 round_to_oldest should establish txn snapshot after establishing rounded read timestamp WT-4059 Start lookaside sweep at full records WT-4063 Update docs to make clear when log archiving is disabled.
-rw-r--r--src/third_party/wiredtiger/import.data2
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_debug.c11
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_read.c2
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_ret.c12
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_slvg.c27
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_split.c5
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_stat.c9
-rw-r--r--src/third_party/wiredtiger/src/cache/cache_las.c41
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_sweep.c23
-rw-r--r--src/third_party/wiredtiger/src/docs/backup.dox4
-rw-r--r--src/third_party/wiredtiger/src/docs/cursor-log.dox4
-rw-r--r--src/third_party/wiredtiger/src/docs/transactions.dox75
-rw-r--r--src/third_party/wiredtiger/src/evict/evict_lru.c2
-rw-r--r--src/third_party/wiredtiger/src/include/btree.i16
-rw-r--r--src/third_party/wiredtiger/src/include/cache.h7
-rw-r--r--src/third_party/wiredtiger/src/include/cell.i33
-rw-r--r--src/third_party/wiredtiger/src/include/cursor.i37
-rw-r--r--src/third_party/wiredtiger/src/include/extern.h3
-rw-r--r--src/third_party/wiredtiger/src/include/misc.h2
-rw-r--r--src/third_party/wiredtiger/src/reconcile/rec_write.c19
-rw-r--r--src/third_party/wiredtiger/src/session/session_api.c3
-rw-r--r--src/third_party/wiredtiger/src/support/generation.c45
-rw-r--r--src/third_party/wiredtiger/src/txn/txn.c22
-rw-r--r--src/third_party/wiredtiger/src/txn/txn_timestamp.c20
-rw-r--r--src/third_party/wiredtiger/test/format/config.c43
25 files changed, 286 insertions, 181 deletions
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data
index 520728572e7..08ac7c3b053 100644
--- a/src/third_party/wiredtiger/import.data
+++ b/src/third_party/wiredtiger/import.data
@@ -1,5 +1,5 @@
{
- "commit": "43c20b5583d8e38ae127beb8b3930d7577902ad0",
+ "commit": "abf0651a814a01169c21a3cbe689ad2534134701",
"github": "wiredtiger/wiredtiger.git",
"vendor": "wiredtiger",
"branch": "mongodb-3.8"
diff --git a/src/third_party/wiredtiger/src/btree/bt_debug.c b/src/third_party/wiredtiger/src/btree/bt_debug.c
index 2d6f8623059..2e027f73550 100644
--- a/src/third_party/wiredtiger/src/btree/bt_debug.c
+++ b/src/third_party/wiredtiger/src/btree/bt_debug.c
@@ -1051,7 +1051,6 @@ __debug_page_row_int(WT_DBG *ds, WT_PAGE *page, uint32_t flags)
static int
__debug_page_row_leaf(WT_DBG *ds, WT_PAGE *page)
{
- WT_CELL *cell;
WT_CELL_UNPACK *unpack, _unpack;
WT_DECL_ITEM(key);
WT_DECL_RET;
@@ -1077,13 +1076,9 @@ __debug_page_row_leaf(WT_DBG *ds, WT_PAGE *page)
WT_ERR(__wt_row_leaf_key(session, page, rip, key, false));
WT_ERR(__debug_item_key(ds, "K", key->data, key->size));
- if ((cell = __wt_row_leaf_value_cell(page, rip, NULL)) == NULL)
- WT_ERR(ds->f(ds, "\tV {}\n"));
- else {
- __wt_cell_unpack(cell, unpack);
- WT_ERR(__debug_cell_data(
- ds, page, WT_PAGE_ROW_LEAF, "V", unpack));
- }
+ __wt_row_leaf_value_cell(page, rip, NULL, unpack);
+ WT_ERR(__debug_cell_data(
+ ds, page, WT_PAGE_ROW_LEAF, "V", unpack));
if ((upd = WT_ROW_UPDATE(page, rip)) != NULL)
WT_ERR(__debug_update(ds, upd, false));
diff --git a/src/third_party/wiredtiger/src/btree/bt_read.c b/src/third_party/wiredtiger/src/btree/bt_read.c
index b98e994640d..32de6d60566 100644
--- a/src/third_party/wiredtiger/src/btree/bt_read.c
+++ b/src/third_party/wiredtiger/src/btree/bt_read.c
@@ -160,7 +160,9 @@ __las_page_instantiate(WT_SESSION_IMPL *session, WT_REF *ref)
* for a key and then insert those updates into the page, then all the
* updates for the next key, and so on.
*/
+ WT_PUBLISH(cache->las_reader, true);
__wt_readlock(session, &cache->las_sweepwalk_lock);
+ WT_PUBLISH(cache->las_reader, false);
locked = true;
for (ret = __wt_las_cursor_position(cursor, las_pageid);
ret == 0;
diff --git a/src/third_party/wiredtiger/src/btree/bt_ret.c b/src/third_party/wiredtiger/src/btree/bt_ret.c
index 7d0da631e2b..95ba4114345 100644
--- a/src/third_party/wiredtiger/src/btree/bt_ret.c
+++ b/src/third_party/wiredtiger/src/btree/bt_ret.c
@@ -100,16 +100,8 @@ __value_return(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt)
if (__wt_row_leaf_value(page, rip, &cursor->value))
return (0);
- /*
- * Take the value from the original page cell (which may be
- * empty).
- */
- if ((cell =
- __wt_row_leaf_value_cell(page, rip, NULL)) == NULL) {
- cursor->value.size = 0;
- return (0);
- }
- __wt_cell_unpack(cell, &unpack);
+ /* Take the value from the original page cell. */
+ __wt_row_leaf_value_cell(page, rip, NULL, &unpack);
return (__wt_page_cell_data_ref(
session, page, &unpack, &cursor->value));
diff --git a/src/third_party/wiredtiger/src/btree/bt_slvg.c b/src/third_party/wiredtiger/src/btree/bt_slvg.c
index ebb01bf818a..54f4eaa8f52 100644
--- a/src/third_party/wiredtiger/src/btree/bt_slvg.c
+++ b/src/third_party/wiredtiger/src/btree/bt_slvg.c
@@ -2034,16 +2034,15 @@ err: WT_TRET(__wt_page_release(session, ref, 0));
* referenced.
*/
static int
-__slvg_row_ovfl_single(WT_SESSION_IMPL *session, WT_TRACK *trk, WT_CELL *cell)
+__slvg_row_ovfl_single(
+ WT_SESSION_IMPL *session, WT_TRACK *trk, WT_CELL_UNPACK *unpack)
{
- WT_CELL_UNPACK unpack;
WT_TRACK *ovfl;
uint32_t i;
- /* Unpack the cell, and check if it's an overflow record. */
- __wt_cell_unpack(cell, &unpack);
- if (unpack.type != WT_CELL_KEY_OVFL &&
- unpack.type != WT_CELL_VALUE_OVFL)
+ /* Check if it's an overflow record. */
+ if (unpack->type != WT_CELL_KEY_OVFL &&
+ unpack->type != WT_CELL_VALUE_OVFL)
return (0);
/*
@@ -2052,8 +2051,8 @@ __slvg_row_ovfl_single(WT_SESSION_IMPL *session, WT_TRACK *trk, WT_CELL *cell)
*/
for (i = 0; i < trk->trk_ovfl_cnt; ++i) {
ovfl = trk->ss->ovfl[trk->trk_ovfl_slot[i]];
- if (unpack.size == ovfl->trk_addr_size &&
- memcmp(unpack.data, ovfl->trk_addr, unpack.size) == 0)
+ if (unpack->size == ovfl->trk_addr_size &&
+ memcmp(unpack->data, ovfl->trk_addr, unpack->size) == 0)
return (__slvg_ovfl_ref(session, ovfl, true));
}
@@ -2070,6 +2069,7 @@ __slvg_row_ovfl(WT_SESSION_IMPL *session,
WT_TRACK *trk, WT_PAGE *page, uint32_t start, uint32_t stop)
{
WT_CELL *cell;
+ WT_CELL_UNPACK unpack;
WT_ROW *rip;
void *copy;
@@ -2081,11 +2081,12 @@ __slvg_row_ovfl(WT_SESSION_IMPL *session,
copy = WT_ROW_KEY_COPY(rip);
(void)__wt_row_leaf_key_info(
page, copy, NULL, &cell, NULL, NULL);
- if (cell != NULL)
- WT_RET(__slvg_row_ovfl_single(session, trk, cell));
- cell = __wt_row_leaf_value_cell(page, rip, NULL);
- if (cell != NULL)
- WT_RET(__slvg_row_ovfl_single(session, trk, cell));
+ if (cell != NULL) {
+ __wt_cell_unpack(cell, &unpack);
+ WT_RET(__slvg_row_ovfl_single(session, trk, &unpack));
+ }
+ __wt_row_leaf_value_cell(page, rip, NULL, &unpack);
+ WT_RET(__slvg_row_ovfl_single(session, trk, &unpack));
}
return (0);
}
diff --git a/src/third_party/wiredtiger/src/btree/bt_split.c b/src/third_party/wiredtiger/src/btree/bt_split.c
index 381c0ee8a9b..0f8f01dd356 100644
--- a/src/third_party/wiredtiger/src/btree/bt_split.c
+++ b/src/third_party/wiredtiger/src/btree/bt_split.c
@@ -65,10 +65,7 @@ __split_safe_free(WT_SESSION_IMPL *session,
* We have swapped something in a page: if we don't have exclusive
* access, check whether there are other threads in the same tree.
*/
- if (!exclusive && __wt_gen_oldest(session, WT_GEN_SPLIT) > split_gen)
- exclusive = true;
-
- if (exclusive) {
+ if (exclusive || !__wt_gen_active(session, WT_GEN_SPLIT, split_gen)) {
__wt_overwrite_and_free_len(session, p, s);
return (0);
}
diff --git a/src/third_party/wiredtiger/src/btree/bt_stat.c b/src/third_party/wiredtiger/src/btree/bt_stat.c
index c00b2bfda39..0fbd5ce869f 100644
--- a/src/third_party/wiredtiger/src/btree/bt_stat.c
+++ b/src/third_party/wiredtiger/src/btree/bt_stat.c
@@ -291,10 +291,11 @@ __stat_page_row_leaf(
(upd->type != WT_UPDATE_RESERVE &&
upd->type != WT_UPDATE_TOMBSTONE))
++entry_cnt;
- if (upd == NULL && (cell =
- __wt_row_leaf_value_cell(page, rip, NULL)) != NULL &&
- __wt_cell_type(cell) == WT_CELL_VALUE_OVFL)
- ++ovfl_cnt;
+ if (upd == NULL) {
+ __wt_row_leaf_value_cell(page, rip, NULL, &unpack);
+ if (unpack.type == WT_CELL_VALUE_OVFL)
+ ++ovfl_cnt;
+ }
/* Walk K/V pairs inserted after the on-page K/V pair. */
WT_SKIP_FOREACH(ins, WT_ROW_INSERT(page, rip))
diff --git a/src/third_party/wiredtiger/src/cache/cache_las.c b/src/third_party/wiredtiger/src/cache/cache_las.c
index 620800a8fb9..1d9078d6aee 100644
--- a/src/third_party/wiredtiger/src/cache/cache_las.c
+++ b/src/third_party/wiredtiger/src/cache/cache_las.c
@@ -893,9 +893,8 @@ static inline uint64_t
__las_sweep_count(WT_CACHE *cache)
{
/*
- * The sweep server wakes up every 10 seconds (by default), it's a slow
- * moving thread. Try to review the entire lookaside table once every 5
- * minutes, or every 30 calls.
+ * The sweep server is a slow moving thread. Try to review the entire
+ * lookaside table once every 5 minutes.
*
* The reason is because the lookaside table exists because we're seeing
* cache/eviction pressure (it allows us to trade performance and disk
@@ -909,8 +908,8 @@ __las_sweep_count(WT_CACHE *cache)
* with lookaside entries are blocked during sweep, make sure we do
* some work but don't block reads for too long.
*/
- return ((uint64_t)WT_MAX(100, WT_MIN(10 * WT_THOUSAND,
- cache->las_entry_count / 30)));
+ return ((uint64_t)WT_MAX(100,
+ cache->las_entry_count / (WT_MINUTE * 5 / WT_LAS_SWEEP_SEC)));
}
/*
@@ -925,7 +924,6 @@ __las_sweep_init(WT_SESSION_IMPL *session)
u_int i;
cache = S2C(session)->cache;
- cache->las_sweep_cnt = __las_sweep_count(cache);
__wt_spin_lock(session, &cache->las_sweep_lock);
@@ -984,8 +982,8 @@ __wt_las_sweep(WT_SESSION_IMPL *session)
#else
wt_timestamp_t *val_ts;
#endif
- uint64_t cnt, remove_cnt, las_counter, las_pageid, saved_pageid;
- uint64_t las_txnid;
+ uint64_t cnt, remove_cnt, las_pageid, saved_pageid, visit_cnt;
+ uint64_t las_counter, las_txnid;
uint32_t las_id, session_flags;
uint8_t upd_type;
int notused;
@@ -1050,8 +1048,9 @@ __wt_las_sweep(WT_SESSION_IMPL *session)
* rather than driving the lookaside table to empty.
*/
cnt = __las_sweep_count(cache);
- if (cnt < cache->las_sweep_cnt)
- cnt = cache->las_sweep_cnt;
+ if (cnt < WT_LAS_SWEEP_ENTRIES)
+ cnt = WT_LAS_SWEEP_ENTRIES;
+ visit_cnt = 0;
/* Walk the file. */
while ((ret = cursor->next(cursor)) == 0) {
@@ -1078,13 +1077,17 @@ __wt_las_sweep(WT_SESSION_IMPL *session)
cnt = 0;
/*
- * If we have processed enough entries and we are between
- * blocks, give up.
+ * We only want to break between key blocks. Stop if we've
+ * processed enough entries either all we wanted or enough
+ * and there is a reader waiting and we're on a key boundary.
*/
+ ++visit_cnt;
+ if ((cnt == 0 ||
+ (visit_cnt > WT_LAS_SWEEP_ENTRIES && cache->las_reader)) &&
+ saved_key->size == 0)
+ break;
if (cnt > 0)
--cnt;
- else if (saved_key->size == 0)
- break;
/*
* If the entry belongs to a dropped tree, discard it.
@@ -1138,9 +1141,19 @@ __wt_las_sweep(WT_SESSION_IMPL *session)
if (cnt == 0)
break;
+ /* We can only start removing from a full value. */
+ if (upd_type == WT_UPDATE_MODIFY) {
+ saved_key->size = 0;
+ continue;
+ }
+
WT_ERR(__wt_buf_set(session, saved_key,
las_key.data, las_key.size));
+ /*
+ * If the first stable record contains data, we have to
+ * keep it.
+ */
if (upd_type != WT_UPDATE_BIRTHMARK)
continue;
}
diff --git a/src/third_party/wiredtiger/src/conn/conn_sweep.c b/src/third_party/wiredtiger/src/conn/conn_sweep.c
index 4d2267d176b..52a4a5424b4 100644
--- a/src/third_party/wiredtiger/src/conn/conn_sweep.c
+++ b/src/third_party/wiredtiger/src/conn/conn_sweep.c
@@ -259,7 +259,7 @@ __sweep_remove_handles(WT_SESSION_IMPL *session)
/*
* __sweep_server_run_chk --
- * Check to decide if the checkpoint server should continue running.
+ * Check to decide if the sweep server should continue running.
*/
static bool
__sweep_server_run_chk(WT_SESSION_IMPL *session)
@@ -277,21 +277,23 @@ __sweep_server(void *arg)
WT_CONNECTION_IMPL *conn;
WT_DECL_RET;
WT_SESSION_IMPL *session;
- time_t now;
- uint64_t last_las_sweep_id, oldest_id;
+ time_t last, now;
+ uint64_t last_las_sweep_id, min_sleep, oldest_id;
u_int dead_handles;
session = arg;
conn = S2C(session);
last_las_sweep_id = WT_TXN_NONE;
+ min_sleep = WT_MIN(WT_LAS_SWEEP_SEC, conn->sweep_interval);
/*
* Sweep for dead and excess handles.
*/
+ __wt_seconds(session, &last);
for (;;) {
/* Wait until the next event. */
__wt_cond_wait(session, conn->sweep_cond,
- conn->sweep_interval * WT_MILLION, __sweep_server_run_chk);
+ min_sleep * WT_MILLION, __sweep_server_run_chk);
/* Check if we're quitting or being reconfigured. */
if (!__sweep_server_run_chk(session))
@@ -299,8 +301,6 @@ __sweep_server(void *arg)
__wt_seconds(session, &now);
- WT_STAT_CONN_INCR(session, dh_sweeps);
-
/*
* Sweep the lookaside table. If the lookaside table hasn't yet
* been written, there's no work to do.
@@ -312,7 +312,8 @@ __sweep_server(void *arg)
* bringing in and evicting pages from the lookaside table,
* which will stop the cache from moving into the stuck state.
*/
- if (__wt_las_nonempty(session) &&
+ if (now - last >= WT_LAS_SWEEP_SEC &&
+ __wt_las_nonempty(session) &&
!__wt_cache_stuck(session)) {
oldest_id = __wt_txn_oldest_id(session);
if (WT_TXNID_LT(last_las_sweep_id, oldest_id)) {
@@ -322,6 +323,14 @@ __sweep_server(void *arg)
}
/*
+ * See if it is time to sweep the data handles. Those are swept
+ * less frequently than the lookaside table by default and the
+ * frequency is controlled by a user setting.
+ */
+ if ((uint64_t)(now - last) < conn->sweep_interval)
+ continue;
+ WT_STAT_CONN_INCR(session, dh_sweeps);
+ /*
* Mark handles with a time of death, and report whether any
* handles are marked dead. If sweep_idle_time is 0, handles
* never become idle.
diff --git a/src/third_party/wiredtiger/src/docs/backup.dox b/src/third_party/wiredtiger/src/docs/backup.dox
index b952a975788..b59d099175f 100644
--- a/src/third_party/wiredtiger/src/docs/backup.dox
+++ b/src/third_party/wiredtiger/src/docs/backup.dox
@@ -57,7 +57,9 @@ arguments to a file archiver such as the system tar utility.
During the period the backup cursor is open, database checkpoints can
be created, but no checkpoints can be deleted. This may result in
-significant file growth.
+significant file growth. Additionally while the backup cursor is open
+automatic log file archiving, even if enabled, will not reclaim any
+log files.
Additionally, if a crash occurs during the period the backup cursor is
open and logging is disabled (in other words, when depending on
diff --git a/src/third_party/wiredtiger/src/docs/cursor-log.dox b/src/third_party/wiredtiger/src/docs/cursor-log.dox
index fd247dd7105..edaa9e8a31f 100644
--- a/src/third_party/wiredtiger/src/docs/cursor-log.dox
+++ b/src/third_party/wiredtiger/src/docs/cursor-log.dox
@@ -7,6 +7,8 @@ that have been configured for logging using the \c log configuration for
::wiredtiger_open. In databases with log files, a log cursor provides
access to the log records. Although log cursors are read-only,
applications may store records in the log using WT_SESSION::log_printf.
+While the log cursor is open automatic log file archiving, even if
+enabled, will not reclaim any log files.
Each physical WiredTiger log record represents one or more operations
in the database. When a log record represents more than a single
@@ -88,7 +90,7 @@ common transaction ID, and operation counters starting at 1 and ending
at 5. The final return from the log cursor will again have a unique log
ID, a unique transaction ID, and an operation counter of 0.
-Here's a more complete example of walking the file file and displaying
+Here's a more complete example of walking the log and displaying
the results:
@snippet ex_log.c log cursor walk
diff --git a/src/third_party/wiredtiger/src/docs/transactions.dox b/src/third_party/wiredtiger/src/docs/transactions.dox
index d27e796b8e9..917986f7df3 100644
--- a/src/third_party/wiredtiger/src/docs/transactions.dox
+++ b/src/third_party/wiredtiger/src/docs/transactions.dox
@@ -36,7 +36,9 @@ operations on any cursors open in that WT_SESSION handle (whether opened
before or after the WT_SESSION::begin_transaction call), are part of the
transaction and their effects committed by calling
WT_SESSION::commit_transaction, or discarded by calling
-WT_SESSION::rollback_transaction.
+WT_SESSION::rollback_transaction. Applications that use
+@ref transaction_timestamps can utilize the WT_SESSION::prepare_transaction API
+as a basis for implementing a two phase commit protocol.
If WT_SESSION::commit_transaction returns an error for any reason, the
transaction was rolled back, not committed.
@@ -151,6 +153,8 @@ Named snapshots are not durable: they do not survive WT_CONNECTION::close.
@section transaction_timestamps Application-specified Transaction Timestamps
+@subsection timestamp_overview Timestamp overview
+
Some applications have their own notion of time, including an expected commit
order for transactions that may be inconsistent with the order assigned by
WiredTiger. We assume that applications can represent their notion of a
@@ -161,23 +165,57 @@ generate transaction timestamps, if that is sufficient for the application.
The application's timestamp size is specified as a number of bytes at build
time, with <code>configure --with-timestamp-size=X</code>. The default
timestamp size is 8 bytes (i.e., 64 bits). Setting a size of zero disables
-transaction timestamp functionality.
-
-Applications can assign explicit commit timestamps to transactions, then read
-"as of" a timestamp. Timestamps are communicated to WiredTiger using a
-hexadecimal encoding, so the encoded value can be twice as long as the raw
-timestamp value.
-
-WiredTiger also provides the ability to set a different commit timestamp for
-different set of updates in a single transaction. This can be done by calling
-WT_SESSION::timestamp_transaction repeatedly to set a new commit timestamp
-between a set of updates for the current transaction. This gives the ability to
-commit several updates with different read "as of" timestamp in a single
-transaction.
+transaction timestamp functionality. Timestamps are communicated to WiredTiger
+using a hexadecimal encoding, so the encoded value can be twice as long as the
+raw timestamp value.
+
+Applications assign explicit commit timestamps to transactions, then read
+"as of" a timestamp. The timestamp mechanism operates in parallel with
+WiredTiger's internal transaction ID management. It is recommended that once
+timestamps are in use for a particular table, all subsequent updates also use
+timestamps.
+
+@subsection timestamp_transactions Using transactions with timestamps
+
+Applications that use timestamps will generally provide a timestamp at
+WT_SESSION::transaction_commit that will be assigned to all updates that are
+part of the transaction. WiredTiger also provides the ability to set a different
+commit timestamp for different sets of updates in a single transaction. This can
+be done by calling WT_SESSION::timestamp_transaction repeatedly to set a new
+commit timestamp between a set of updates for the current transaction. This
+gives the ability to commit updates with different read "as of" timestamps in a
+single transaction.
Setting a read timestamp in WT_SESSION::begin_transaction forces a transaction
to run at snapshot isolation and ignore any commits with a newer timestamp.
+Commit timestamps cannot be set in the past of any read timestamp that has
+been used. This is enforced by assertions in diagnostic builds, if
+applications violate this rule, data consistency can be violated.
+
+The commits to a particular data item must be performed in timestamp order.
+If applications violate this rule, data consistency can be violated.
+
+The WT_SESSION::prepare_transaction API is designed to be used in conjunction
+with timestamps and assigns a prepare timestamp to the transaction, which will
+be used for visibility checks until the transaction is committed or aborted.
+Once a transaction has been prepared the only other operations that can be
+completed are WT_SESSION::commit_transaction or
+WT_SESSION::rollback_transaction. The WT_SESSION::prepare_transaction API only
+guarantees that transactional conflicts will not cause the transaction to
+rollback - it does not guarantee that the transactions updates are durable. If
+a read operation encounters an update from a prepared transaction a
+WT_PREPARE_CONFLICT error will be returned indicating that it is not possible
+to choose a version of data to return until a prepared transaction is resolved,
+it is reasonable to retry such operations.
+
+@subsection timestamp_connection Managing global timestamp state
+
+Applications that use timestamps need to manage some global state in order
+to allow WiredTiger to clean up old updates, and not make new updates durable
+until it is safe to do so. That state is managed using the
+WT_CONNECTION::set_timestamp API.
+
Setting an oldest timestamp in WT_CONNECTION::set_timestamp indicates that
future read timestamps will be at least as recent as the oldest timestamp, so
WiredTiger can discard history before the specified point. It is critical
@@ -196,14 +234,7 @@ does not automatically reset the maximum commit timestamp it is tracking. The
application should explicitly do so by setting a commit timestamp in
WT_CONNECTION::set_timestamp.
-Commit timestamps cannot be set in the past of any read timestamp that has
-been used. This is enforced by assertions in diagnostic builds, if
-applications violate this rule, data consistency can be violated.
-
-The commits to a particular data item must be performed in timestamp order.
-If applications violate this rule, data consistency can be violated.
-
-@subsection Timestamp support in the extension API
+@subsection timestamp_extensions Timestamp support in the extension API
The extension API, used by modules that extend WiredTiger via
WT_CONNECTION::get_extension_api, is not timestamp-aware. In particular,
diff --git a/src/third_party/wiredtiger/src/evict/evict_lru.c b/src/third_party/wiredtiger/src/evict/evict_lru.c
index 7e769c03cf0..3c1bdee2ef3 100644
--- a/src/third_party/wiredtiger/src/evict/evict_lru.c
+++ b/src/third_party/wiredtiger/src/evict/evict_lru.c
@@ -445,7 +445,7 @@ __evict_server(WT_SESSION_IMPL *session, bool *did_work)
return (0);
__wt_epoch(session, &now);
- if (WT_TIMEDIFF_SEC(now, cache->stuck_time) > 300) {
+ if (WT_TIMEDIFF_SEC(now, cache->stuck_time) > WT_MINUTE * 5) {
#if defined(HAVE_DIAGNOSTIC)
__wt_err(session, ETIMEDOUT,
"Cache stuck for too long, giving up");
diff --git a/src/third_party/wiredtiger/src/include/btree.i b/src/third_party/wiredtiger/src/include/btree.i
index 79d6634913e..a706ff8aa5c 100644
--- a/src/third_party/wiredtiger/src/include/btree.i
+++ b/src/third_party/wiredtiger/src/include/btree.i
@@ -1013,11 +1013,11 @@ __wt_row_leaf_key(WT_SESSION_IMPL *session,
/*
* __wt_row_leaf_value_cell --
- * Return a pointer to the value cell for a row-store leaf page key, or
- * NULL if there isn't one.
+ * Return the unpacked value for a row-store leaf page key.
*/
-static inline WT_CELL *
-__wt_row_leaf_value_cell(WT_PAGE *page, WT_ROW *rip, WT_CELL_UNPACK *kpack)
+static inline void
+__wt_row_leaf_value_cell(
+ WT_PAGE *page, WT_ROW *rip, WT_CELL_UNPACK *kpack, WT_CELL_UNPACK *vpack)
{
WT_CELL *kcell, *vcell;
WT_CELL_UNPACK unpack;
@@ -1052,7 +1052,7 @@ __wt_row_leaf_value_cell(WT_PAGE *page, WT_ROW *rip, WT_CELL_UNPACK *kpack)
}
}
- return (__wt_cell_leaf_value_parse(page, vcell));
+ __wt_cell_unpack(__wt_cell_leaf_value_parse(page, vcell), vpack);
}
/*
@@ -1425,9 +1425,9 @@ __wt_page_can_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool *inmem_splitp)
* locked exclusive (e.g., when the whole tree is being evicted). In
* that case, no readers can be looking at an old index.
*/
- if (!F_ISSET(session->dhandle, WT_DHANDLE_EXCLUSIVE) &&
- WT_PAGE_IS_INTERNAL(page) &&
- page->pg_intl_split_gen >= __wt_gen_oldest(session, WT_GEN_SPLIT))
+ if (WT_PAGE_IS_INTERNAL(page) &&
+ !F_ISSET(session->dhandle, WT_DHANDLE_EXCLUSIVE) &&
+ __wt_gen_active(session, WT_GEN_SPLIT, page->pg_intl_split_gen))
return (false);
/*
diff --git a/src/third_party/wiredtiger/src/include/cache.h b/src/third_party/wiredtiger/src/include/cache.h
index 9203e692291..5d2d4bbf6cb 100644
--- a/src/third_party/wiredtiger/src/include/cache.h
+++ b/src/third_party/wiredtiger/src/include/cache.h
@@ -54,6 +54,10 @@ typedef enum __wt_cache_op {
WT_SYNC_WRITE_LEAVES
} WT_CACHE_OP;
+#define WT_LAS_NUM_SESSIONS 5
+#define WT_LAS_SWEEP_ENTRIES (20 * WT_THOUSAND)
+#define WT_LAS_SWEEP_SEC 2
+
/*
* WiredTiger cache structure.
*/
@@ -191,7 +195,6 @@ struct __wt_cache {
* the lookaside table (other than eviction server and worker threads
* and the sweep thread, all of which have their own lookaside cursors).
*/
-#define WT_LAS_NUM_SESSIONS 5
WT_SPINLOCK las_lock;
WT_SESSION_IMPL *las_session[WT_LAS_NUM_SESSIONS];
bool las_session_inuse[WT_LAS_NUM_SESSIONS];
@@ -200,7 +203,7 @@ struct __wt_cache {
uint64_t las_entry_count; /* Count of entries in lookaside */
uint64_t las_pageid; /* Lookaside table page ID counter */
- uint64_t las_sweep_cnt; /* Entries to walk per sweep. */
+ bool las_reader; /* Indicate an LAS reader to sweep */
WT_RWLOCK las_sweepwalk_lock;
WT_SPINLOCK las_sweep_lock;
WT_ITEM las_sweep_key; /* Track sweep position. */
diff --git a/src/third_party/wiredtiger/src/include/cell.i b/src/third_party/wiredtiger/src/include/cell.i
index ff3486c1750..c160f84b870 100644
--- a/src/third_party/wiredtiger/src/include/cell.i
+++ b/src/third_party/wiredtiger/src/include/cell.i
@@ -717,28 +717,23 @@ done: WT_CELL_LEN_CHK(cell, unpack->__len);
static inline void
__wt_cell_unpack(WT_CELL *cell, WT_CELL_UNPACK *unpack)
{
- (void)__wt_cell_unpack_safe(cell, unpack, NULL, NULL);
-}
-
-/*
- * __wt_cell_unpack_empty_value --
- * Create an unpacked cell that looks like zero-length row-store value.
- */
-static inline void
-__wt_cell_unpack_empty_value(WT_CELL_UNPACK *unpack)
-{
/*
* Row-store doesn't store zero-length values on pages, but this allows
* us to pretend.
*/
- unpack->cell = NULL;
- unpack->v = 0;
- unpack->data = "";
- unpack->size = 0;
- unpack->__len = 0;
- unpack->prefix = 0;
- unpack->raw = unpack->type = WT_CELL_VALUE;
- unpack->ovfl = 0;
+ if (cell == NULL) {
+ unpack->cell = NULL;
+ unpack->v = 0;
+ unpack->data = "";
+ unpack->size = 0;
+ unpack->__len = 0;
+ unpack->prefix = 0;
+ unpack->raw = unpack->type = WT_CELL_VALUE;
+ unpack->ovfl = 0;
+ return;
+ }
+
+ (void)__wt_cell_unpack_safe(cell, unpack, NULL, NULL);
}
/*
@@ -786,7 +781,7 @@ __cell_data_ref(WT_SESSION_IMPL *session,
WT_ILLEGAL_VALUE(session);
}
- return (huffman == NULL ? 0 :
+ return (huffman == NULL || store->size == 0 ? 0 :
__wt_huffman_decode(
session, huffman, store->data, store->size, store));
}
diff --git a/src/third_party/wiredtiger/src/include/cursor.i b/src/third_party/wiredtiger/src/include/cursor.i
index d338c47dfae..cb665e17f5b 100644
--- a/src/third_party/wiredtiger/src/include/cursor.i
+++ b/src/third_party/wiredtiger/src/include/cursor.i
@@ -376,7 +376,7 @@ __cursor_row_slot_return(WT_CURSOR_BTREE *cbt, WT_ROW *rip, WT_UPDATE *upd)
{
WT_BTREE *btree;
WT_CELL *cell;
- WT_CELL_UNPACK *unpack, _unpack;
+ WT_CELL_UNPACK *kpack, _kpack, *vpack, _vpack;
WT_ITEM *kb, *vb;
WT_PAGE *page;
WT_SESSION_IMPL *session;
@@ -386,7 +386,8 @@ __cursor_row_slot_return(WT_CURSOR_BTREE *cbt, WT_ROW *rip, WT_UPDATE *upd)
btree = S2BT(session);
page = cbt->ref->page;
- unpack = NULL;
+ kpack = NULL;
+ vpack = &_vpack;
kb = &cbt->iface.key;
vb = &cbt->iface.value;
@@ -417,11 +418,11 @@ __cursor_row_slot_return(WT_CURSOR_BTREE *cbt, WT_ROW *rip, WT_UPDATE *upd)
* Inline building simple prefix-compressed keys from a previous key,
* otherwise build from scratch.
*/
- unpack = &_unpack;
- __wt_cell_unpack(cell, unpack);
- if (unpack->type == WT_CELL_KEY &&
+ kpack = &_kpack;
+ __wt_cell_unpack(cell, kpack);
+ if (kpack->type == WT_CELL_KEY &&
cbt->rip_saved != NULL && cbt->rip_saved == rip - 1) {
- WT_ASSERT(session, cbt->row_key->size >= unpack->prefix);
+ WT_ASSERT(session, cbt->row_key->size >= kpack->prefix);
/*
* Grow the buffer as necessary as well as ensure data has been
@@ -431,12 +432,12 @@ __cursor_row_slot_return(WT_CURSOR_BTREE *cbt, WT_ROW *rip, WT_UPDATE *upd)
* Don't grow the buffer unnecessarily or copy data we don't
* need, truncate the item's data length to the prefix bytes.
*/
- cbt->row_key->size = unpack->prefix;
+ cbt->row_key->size = kpack->prefix;
WT_RET(__wt_buf_grow(
- session, cbt->row_key, cbt->row_key->size + unpack->size));
+ session, cbt->row_key, cbt->row_key->size + kpack->size));
memcpy((uint8_t *)cbt->row_key->data + cbt->row_key->size,
- unpack->data, unpack->size);
- cbt->row_key->size += unpack->size;
+ kpack->data, kpack->size);
+ cbt->row_key->size += kpack->size;
} else {
/*
* Call __wt_row_leaf_key_work instead of __wt_row_leaf_key: we
@@ -462,17 +463,7 @@ value:
if (__wt_row_leaf_value(page, rip, vb))
return (0);
- /*
- * Else, take the value from the original page cell (which may be
- * empty).
- */
- if ((cell = __wt_row_leaf_value_cell(page, rip, unpack)) == NULL) {
- vb->data = "";
- vb->size = 0;
- return (0);
- }
-
- unpack = &_unpack;
- __wt_cell_unpack(cell, unpack);
- return (__wt_page_cell_data_ref(session, cbt->ref->page, unpack, vb));
+ /* Else, take the value from the original page cell. */
+ __wt_row_leaf_value_cell(page, rip, kpack, vpack);
+ return (__wt_page_cell_data_ref(session, cbt->ref->page, vpack, vb));
}
diff --git a/src/third_party/wiredtiger/src/include/extern.h b/src/third_party/wiredtiger/src/include/extern.h
index 579a2e5ed36..cce787e46bc 100644
--- a/src/third_party/wiredtiger/src/include/extern.h
+++ b/src/third_party/wiredtiger/src/include/extern.h
@@ -702,7 +702,7 @@ extern uint64_t __wt_gen(WT_SESSION_IMPL *session, int which);
extern uint64_t __wt_gen_next(WT_SESSION_IMPL *session, int which);
extern uint64_t __wt_gen_next_drain(WT_SESSION_IMPL *session, int which);
extern void __wt_gen_drain(WT_SESSION_IMPL *session, int which, uint64_t generation);
-extern uint64_t __wt_gen_oldest(WT_SESSION_IMPL *session, int which);
+extern bool __wt_gen_active(WT_SESSION_IMPL *session, int which, uint64_t generation) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern uint64_t __wt_session_gen(WT_SESSION_IMPL *session, int which);
extern void __wt_session_gen_enter(WT_SESSION_IMPL *session, int which);
extern void __wt_session_gen_leave(WT_SESSION_IMPL *session, int which);
@@ -810,6 +810,7 @@ extern int __wt_txn_rollback(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC
extern int __wt_txn_rollback_required(WT_SESSION_IMPL *session, const char *reason) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_txn_init(WT_SESSION_IMPL *session, WT_SESSION_IMPL *session_ret) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern void __wt_txn_stats_update(WT_SESSION_IMPL *session);
+extern void __wt_txn_release_resources(WT_SESSION_IMPL *session);
extern void __wt_txn_destroy(WT_SESSION_IMPL *session);
extern int __wt_txn_global_init(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern void __wt_txn_global_destroy(WT_SESSION_IMPL *session);
diff --git a/src/third_party/wiredtiger/src/include/misc.h b/src/third_party/wiredtiger/src/include/misc.h
index 6b30e63d2a3..1507e2d07cc 100644
--- a/src/third_party/wiredtiger/src/include/misc.h
+++ b/src/third_party/wiredtiger/src/include/misc.h
@@ -28,6 +28,8 @@
#define WT_MILLION (1000000)
#define WT_BILLION (1000000000)
+#define WT_MINUTE (60)
+
#define WT_KILOBYTE (1024)
#define WT_MEGABYTE (1048576)
#define WT_GIGABYTE (1073741824)
diff --git a/src/third_party/wiredtiger/src/reconcile/rec_write.c b/src/third_party/wiredtiger/src/reconcile/rec_write.c
index 7a97d5ae959..f9e49b79f20 100644
--- a/src/third_party/wiredtiger/src/reconcile/rec_write.c
+++ b/src/third_party/wiredtiger/src/reconcile/rec_write.c
@@ -5304,7 +5304,7 @@ __rec_row_leaf(WT_SESSION_IMPL *session,
WT_RECONCILE *r, WT_PAGE *page, WT_SALVAGE_COOKIE *salvage)
{
WT_BTREE *btree;
- WT_CELL *cell, *val_cell;
+ WT_CELL *cell;
WT_CELL_UNPACK *kpack, _kpack, *vpack, _vpack;
WT_CURSOR_BTREE *cbt;
WT_DECL_ITEM(tmpkey);
@@ -5377,19 +5377,8 @@ __rec_row_leaf(WT_SESSION_IMPL *session,
__wt_cell_unpack(cell, kpack);
}
- /*
- * Unpack the on-page value cell, and look for an update. Under
- * some conditions, the underlying code returning updates will
- * restructure the update list to include the original on-page
- * value, represented by the unpacked-cell argument. Row-store
- * doesn't store zero-length values on the page, so we build an
- * unpacked cell that allows us to pretend.
- */
- if ((val_cell =
- __wt_row_leaf_value_cell(page, rip, NULL)) == NULL)
- __wt_cell_unpack_empty_value(vpack);
- else
- __wt_cell_unpack(val_cell, vpack);
+ /* Unpack the on-page value cell, and look for an update. */
+ __wt_row_leaf_value_cell(page, rip, NULL, vpack);
WT_ERR(__rec_txn_read(
session, r, NULL, rip, vpack, NULL, &upd));
@@ -5467,7 +5456,7 @@ __rec_row_leaf(WT_SESSION_IMPL *session,
"ovfl-unused", strlen("ovfl-unused"),
(uint64_t)0));
} else {
- val->buf.data = val_cell;
+ val->buf.data = vpack->cell;
val->buf.size = __wt_cell_total_len(vpack);
val->cell_len = 0;
val->len = val->buf.size;
diff --git a/src/third_party/wiredtiger/src/session/session_api.c b/src/third_party/wiredtiger/src/session/session_api.c
index 5249108382b..ee68c9d67a2 100644
--- a/src/third_party/wiredtiger/src/session/session_api.c
+++ b/src/third_party/wiredtiger/src/session/session_api.c
@@ -157,6 +157,9 @@ __wt_session_release_resources(WT_SESSION_IMPL *session)
{
WT_DECL_RET;
+ /* Transaction cleanup */
+ __wt_txn_release_resources(session);
+
/* Block manager cleanup */
if (session->block_manager_cleanup != NULL)
WT_TRET(session->block_manager_cleanup(session));
diff --git a/src/third_party/wiredtiger/src/support/generation.c b/src/third_party/wiredtiger/src/support/generation.c
index b962bca739a..f71ce2237e1 100644
--- a/src/third_party/wiredtiger/src/support/generation.c
+++ b/src/third_party/wiredtiger/src/support/generation.c
@@ -136,11 +136,11 @@ __wt_gen_drain(WT_SESSION_IMPL *session, int which, uint64_t generation)
}
/*
- * __wt_gen_oldest --
+ * __gen_oldest --
* Return the oldest generation in use for the resource.
*/
-uint64_t
-__wt_gen_oldest(WT_SESSION_IMPL *session, int which)
+static uint64_t
+__gen_oldest(WT_SESSION_IMPL *session, int which)
{
WT_CONNECTION_IMPL *conn;
WT_SESSION_IMPL *s;
@@ -174,6 +174,43 @@ __wt_gen_oldest(WT_SESSION_IMPL *session, int which)
}
/*
+ * __wt_gen_active --
+ * Return if a specified generation is in use for the resource.
+ */
+bool
+__wt_gen_active(WT_SESSION_IMPL *session, int which, uint64_t generation)
+{
+ WT_CONNECTION_IMPL *conn;
+ WT_SESSION_IMPL *s;
+ uint64_t v;
+ uint32_t i, session_cnt;
+
+ conn = S2C(session);
+
+ /*
+ * No lock is required because the session array is fixed size, but it
+ * may contain inactive entries. We must review any active session, so
+ * insert a read barrier after reading the active session count. That
+ * way, no matter what sessions come or go, we'll check the slots for
+ * all of the sessions that could have been active when we started our
+ * check.
+ */
+ WT_ORDERED_READ(session_cnt, conn->session_cnt);
+ for (s = conn->sessions, i = 0; i < session_cnt; ++s, ++i) {
+ if (!s->active)
+ continue;
+
+ /* Ensure we only read the value once. */
+ WT_ORDERED_READ(v, s->generations[which]);
+
+ if (v != 0 && generation >= v)
+ return (true);
+ }
+
+ return (false);
+}
+
+/*
* __wt_session_gen --
* Return the thread's resource generation.
*/
@@ -240,7 +277,7 @@ __stash_discard(WT_SESSION_IMPL *session, int which)
session_stash = &session->stash[which];
/* Get the resource's oldest generation. */
- oldest = __wt_gen_oldest(session, which);
+ oldest = __gen_oldest(session, which);
for (i = 0,
stash = session_stash->list; i < session_stash->cnt; ++i, ++stash) {
diff --git a/src/third_party/wiredtiger/src/txn/txn.c b/src/third_party/wiredtiger/src/txn/txn.c
index 400edb59e61..b43380e97dc 100644
--- a/src/third_party/wiredtiger/src/txn/txn.c
+++ b/src/third_party/wiredtiger/src/txn/txn.c
@@ -1296,17 +1296,31 @@ __wt_txn_stats_update(WT_SESSION_IMPL *session)
}
/*
- * __wt_txn_destroy --
- * Destroy a session's transaction data.
+ * __wt_txn_release_resources --
+ * Release resources for a session's transaction data.
*/
void
-__wt_txn_destroy(WT_SESSION_IMPL *session)
+__wt_txn_release_resources(WT_SESSION_IMPL *session)
{
WT_TXN *txn;
txn = &session->txn;
+
+ WT_ASSERT(session, txn->mod_count == 0);
__wt_free(session, txn->mod);
- __wt_free(session, txn->snapshot);
+ txn->mod_alloc = 0;
+ txn->mod_count = 0;
+}
+
+/*
+ * __wt_txn_destroy --
+ * Destroy a session's transaction data.
+ */
+void
+__wt_txn_destroy(WT_SESSION_IMPL *session)
+{
+ __wt_txn_release_resources(session);
+ __wt_free(session, session->txn.snapshot);
}
/*
diff --git a/src/third_party/wiredtiger/src/txn/txn_timestamp.c b/src/third_party/wiredtiger/src/txn/txn_timestamp.c
index 6fd82db5917..3baffa0ad04 100644
--- a/src/third_party/wiredtiger/src/txn/txn_timestamp.c
+++ b/src/third_party/wiredtiger/src/txn/txn_timestamp.c
@@ -780,17 +780,10 @@ __wt_txn_parse_read_timestamp(WT_SESSION_IMPL *session, const char *cfg[])
txn_global = &S2C(session)->txn_global;
WT_RET(__wt_txn_parse_timestamp(session, "read", &ts, &cval));
- /*
- * Read timestamps imply / require snapshot isolation.
- *
- * If we already have a snapshot, it may be too early
- * to match the timestamp. Get a new one.
- */
+ /* Read timestamps imply / require snapshot isolation. */
if (!F_ISSET(txn, WT_TXN_RUNNING))
txn->isolation = WT_ISO_SNAPSHOT;
- else if (txn->isolation == WT_ISO_SNAPSHOT)
- __wt_txn_get_snapshot(session);
- else
+ else if (txn->isolation != WT_ISO_SNAPSHOT)
WT_RET_MSG(session, EINVAL, "setting a read_timestamp"
" requires a transaction running at snapshot"
" isolation");
@@ -853,6 +846,15 @@ __wt_txn_parse_read_timestamp(WT_SESSION_IMPL *session, const char *cfg[])
"timestamp %s : Rounded to oldest timestamp %s",
hex_timestamp[0], hex_timestamp[1]);
}
+
+ /*
+ * If we already have a snapshot, it may be too early to match
+ * the timestamp (including the one we just read, if rounding
+ * to oldest). Get a new one.
+ */
+ if (F_ISSET(txn, WT_TXN_RUNNING))
+ __wt_txn_get_snapshot(session);
+
#else
WT_UNUSED(txn);
WT_RET_MSG(session, EINVAL, "read_timestamp requires a "
diff --git a/src/third_party/wiredtiger/test/format/config.c b/src/third_party/wiredtiger/test/format/config.c
index 7e54c7ad171..c77d51f5df0 100644
--- a/src/third_party/wiredtiger/test/format/config.c
+++ b/src/third_party/wiredtiger/test/format/config.c
@@ -34,6 +34,7 @@ static void config_checksum(void);
static void config_compression(const char *);
static void config_encryption(void);
static const char *config_file_type(u_int);
+static bool config_fix(void);
static void config_helium_reset(void);
static void config_in_memory(void);
static void config_in_memory_reset(void);
@@ -74,15 +75,15 @@ config_setup(void)
config_single("file_type=row", 0);
else
switch (mmrand(NULL, 1, 10)) {
- case 1: /* 10% */
- if (!config_is_perm("modify_pct")) {
+ case 1: case 2: case 3: /* 30% */
+ config_single("file_type=var", 0);
+ break;
+ case 4: /* 10% */
+ if (config_fix()) {
config_single("file_type=fix", 0);
break;
}
- /* FALLTHROUGH */
- case 2: case 3: case 4: /* 30% */
- config_single("file_type=var", 0);
- break; /* 60% */
+ /* FALLTHROUGH */ /* 60% */
case 5: case 6: case 7: case 8: case 9: case 10:
config_single("file_type=row", 0);
break;
@@ -393,6 +394,24 @@ config_encryption(void)
}
/*
+ * config_fix --
+ * Fixed-length column-store configuration.
+ */
+static bool
+config_fix(void)
+{
+ /*
+ * Fixed-length column stores don't support the lookaside table (so, no
+ * long running transactions), or modify operations.
+ */
+ if (config_is_perm("long_running_txn"))
+ return (false);
+ if (config_is_perm("modify_pct"))
+ return (false);
+ return (true);
+}
+
+/*
* config_helium_reset --
* Helium configuration review.
*/
@@ -552,8 +571,8 @@ config_lrt(void)
* WiredTiger doesn't support a lookaside file for fixed-length column
* stores.
*/
- if (g.type == FIX) {
- if (config_is_perm("long_running_txn") && g.c_long_running_txn)
+ if (g.type == FIX && g.c_long_running_txn) {
+ if (config_is_perm("long_running_txn"))
testutil_die(EINVAL,
"long_running_txn not supported with fixed-length "
"column store");
@@ -693,10 +712,14 @@ config_prepare(void)
testutil_die(EINVAL,
"prepare requires transaction timestamps");
}
- if (g.c_logging && config_is_perm("logging"))
+ if (g.c_logging && config_is_perm("logging")) {
+ config_single("prepare=off", 0);
return;
- if (!g.c_txn_timestamps && config_is_perm("transaction_timestamps"))
+ }
+ if (!g.c_txn_timestamps && config_is_perm("transaction_timestamps")) {
+ config_single("prepare=off", 0);
return;
+ }
config_single("logging=off", 0);
config_single("transaction_timestamps=on", 0);