summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/third_party/wiredtiger/src/block/block_open.c6
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_split.c15
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_sync.c27
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_open.c6
-rw-r--r--src/third_party/wiredtiger/src/evict/evict_lru.c2
-rw-r--r--src/third_party/wiredtiger/src/evict/evict_page.c4
-rw-r--r--src/third_party/wiredtiger/src/include/connection.h2
-rw-r--r--src/third_party/wiredtiger/src/include/extern.h2
-rw-r--r--src/third_party/wiredtiger/src/lsm/lsm_tree.c5
-rw-r--r--src/third_party/wiredtiger/src/meta/meta_track.c65
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_filesize.c7
-rw-r--r--src/third_party/wiredtiger/src/os_win/os_filesize.c7
-rw-r--r--src/third_party/wiredtiger/src/schema/schema_stat.c23
13 files changed, 138 insertions, 33 deletions
diff --git a/src/third_party/wiredtiger/src/block/block_open.c b/src/third_party/wiredtiger/src/block/block_open.c
index e1f3e6de0fe..e97e86d9aaa 100644
--- a/src/third_party/wiredtiger/src/block/block_open.c
+++ b/src/third_party/wiredtiger/src/block/block_open.c
@@ -422,9 +422,13 @@ int
__wt_block_manager_size(
WT_SESSION_IMPL *session, const char *filename, WT_DSRC_STATS *stats)
{
+ WT_DECL_RET;
wt_off_t filesize;
- WT_RET(__wt_filesize_name(session, filename, &filesize));
+ ret = __wt_filesize_name(session, filename, &filesize);
+ if (ret != 0)
+ WT_RET_MSG(session, ret, "%s: file size", filename);
+
stats->block_size = filesize;
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 2145d6ac014..c0c739d68ad 100644
--- a/src/third_party/wiredtiger/src/btree/bt_split.c
+++ b/src/third_party/wiredtiger/src/btree/bt_split.c
@@ -1031,10 +1031,13 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref,
/*
* If the entire (sub)tree is empty, give up: we can't leave an empty
- * internal page.
+ * internal page. Mark it to be evicted soon and clean up any
+ * references that have changed state.
*/
- if (result_entries == 0)
- return (0);
+ if (result_entries == 0) {
+ __wt_page_evict_soon(parent);
+ goto err;
+ }
/*
* Allocate and initialize a new page index array for the parent, then
@@ -1226,6 +1229,12 @@ err: /*
next_ref->state = WT_REF_DELETED;
}
+ /* If we gave up on a reverse split, unlock the child. */
+ if (ref_new == NULL) {
+ WT_ASSERT(session, ref->state == WT_REF_LOCKED);
+ ref->state = WT_REF_DELETED;
+ }
+
__wt_free_ref_index(session, NULL, alloc_index, false);
}
diff --git a/src/third_party/wiredtiger/src/btree/bt_sync.c b/src/third_party/wiredtiger/src/btree/bt_sync.c
index 237d900c3d1..110f9f8fb0c 100644
--- a/src/third_party/wiredtiger/src/btree/bt_sync.c
+++ b/src/third_party/wiredtiger/src/btree/bt_sync.c
@@ -22,16 +22,17 @@ __sync_file(WT_SESSION_IMPL *session, int syncop)
WT_PAGE_MODIFY *mod;
WT_REF *walk;
WT_TXN *txn;
- uint64_t internal_bytes, leaf_bytes;
- uint64_t internal_pages, leaf_pages;
+ uint64_t internal_bytes, internal_pages, leaf_bytes, leaf_pages;
+ uint64_t saved_snap_min;
uint32_t flags;
bool evict_reset;
btree = S2BT(session);
- flags = WT_READ_CACHE | WT_READ_NO_GEN;
walk = NULL;
txn = &session->txn;
+ saved_snap_min = WT_SESSION_TXN_STATE(session)->snap_min;
+ flags = WT_READ_CACHE | WT_READ_NO_GEN;
internal_bytes = leaf_bytes = 0;
internal_pages = leaf_pages = 0;
@@ -80,6 +81,19 @@ __sync_file(WT_SESSION_IMPL *session, int syncop)
break;
case WT_SYNC_CHECKPOINT:
/*
+ * If we are flushing a file at read-committed isolation, which
+ * is of particular interest for flushing the metadata to make
+ * schema-changing operation durable, get a transactional
+ * snapshot now.
+ *
+ * All changes committed up to this point should be included.
+ * We don't update the snapshot in between pages because (a)
+ * the metadata shouldn't be that big, and (b) if we do ever
+ */
+ if (txn->isolation == WT_ISO_READ_COMMITTED)
+ __wt_txn_get_snapshot(session);
+
+ /*
* We cannot check the tree modified flag in the case of a
* checkpoint, the checkpoint code has already cleared it.
*
@@ -174,7 +188,12 @@ err: /* On error, clear any left-over tree walk. */
if (walk != NULL)
WT_TRET(__wt_page_release(session, walk, flags));
- if (txn->isolation == WT_ISO_READ_COMMITTED && session->ncursors == 0)
+ /*
+ * If we got a snapshot in order to write pages, and there was no
+ * snapshot active when we started, release it.
+ */
+ if (txn->isolation == WT_ISO_READ_COMMITTED &&
+ saved_snap_min == WT_TXN_NONE)
__wt_txn_release_snapshot(session);
if (btree->checkpointing != WT_CKPT_OFF) {
diff --git a/src/third_party/wiredtiger/src/conn/conn_open.c b/src/third_party/wiredtiger/src/conn/conn_open.c
index 04815c8e152..4fe1db1c524 100644
--- a/src/third_party/wiredtiger/src/conn/conn_open.c
+++ b/src/third_party/wiredtiger/src/conn/conn_open.c
@@ -126,6 +126,9 @@ __wt_connection_close(WT_CONNECTION_IMPL *conn)
/* Close open data handles. */
WT_TRET(__wt_conn_dhandle_discard(session));
+ /* Shut down metadata tracking, required before creating tables. */
+ WT_TRET(__wt_meta_track_destroy(session));
+
/*
* Now that all data handles are closed, tell logging that a checkpoint
* has completed then shut down the log manager (only after closing
@@ -252,6 +255,9 @@ __wt_connection_workers(WT_SESSION_IMPL *session, const char *cfg[])
*/
WT_RET(__wt_logmgr_open(session));
+ /* Initialize metadata tracking, required before creating tables. */
+ WT_RET(__wt_meta_track_init(session));
+
/* Create the lookaside table. */
WT_RET(__wt_las_create(session));
diff --git a/src/third_party/wiredtiger/src/evict/evict_lru.c b/src/third_party/wiredtiger/src/evict/evict_lru.c
index c28b89b81ce..18335d6fb5e 100644
--- a/src/third_party/wiredtiger/src/evict/evict_lru.c
+++ b/src/third_party/wiredtiger/src/evict/evict_lru.c
@@ -159,7 +159,7 @@ __evict_server(void *arg)
WT_DECL_RET;
WT_SESSION_IMPL *session;
#ifdef HAVE_DIAGNOSTIC
- struct timespec now, stuck_ts;
+ struct timespec now, stuck_ts = { 0, 0 };
#endif
u_int spins;
diff --git a/src/third_party/wiredtiger/src/evict/evict_page.c b/src/third_party/wiredtiger/src/evict/evict_page.c
index 2c0312a6f60..e49098e90db 100644
--- a/src/third_party/wiredtiger/src/evict/evict_page.c
+++ b/src/third_party/wiredtiger/src/evict/evict_page.c
@@ -394,7 +394,9 @@ __evict_review(
/*
* Retrieve the modified state of the page. This must happen after the
* check for evictable internal pages otherwise there is a race where a
- * page could be marked modified whilst performing the check.
+ * page could be marked modified due to a child being transitioned to
+ * WT_REF_DISK after the modified check and before we visited the ref
+ * while walking the parent index.
*/
modified = __wt_page_is_modified(page);
diff --git a/src/third_party/wiredtiger/src/include/connection.h b/src/third_party/wiredtiger/src/include/connection.h
index 03b8174b7e1..a585e08ef1a 100644
--- a/src/third_party/wiredtiger/src/include/connection.h
+++ b/src/third_party/wiredtiger/src/include/connection.h
@@ -363,6 +363,8 @@ struct __wt_connection_impl {
uint32_t log_prealloc; /* Log file pre-allocation */
uint32_t txn_logsync; /* Log sync configuration */
+ WT_SESSION_IMPL *meta_ckpt_session;/* Metadata checkpoint session */
+
WT_SESSION_IMPL *sweep_session; /* Handle sweep session */
wt_thread_t sweep_tid; /* Handle sweep thread */
int sweep_tid_set; /* Handle sweep thread set */
diff --git a/src/third_party/wiredtiger/src/include/extern.h b/src/third_party/wiredtiger/src/include/extern.h
index 3dd479acc0a..4c934f95c2b 100644
--- a/src/third_party/wiredtiger/src/include/extern.h
+++ b/src/third_party/wiredtiger/src/include/extern.h
@@ -456,6 +456,8 @@ extern int __wt_meta_track_update(WT_SESSION_IMPL *session, const char *key);
extern int __wt_meta_track_fileop( WT_SESSION_IMPL *session, const char *olduri, const char *newuri);
extern int __wt_meta_track_drop( WT_SESSION_IMPL *session, const char *filename);
extern int __wt_meta_track_handle_lock(WT_SESSION_IMPL *session, bool created);
+extern int __wt_meta_track_init(WT_SESSION_IMPL *session);
+extern int __wt_meta_track_destroy(WT_SESSION_IMPL *session);
extern int __wt_turtle_init(WT_SESSION_IMPL *session);
extern int __wt_turtle_read(WT_SESSION_IMPL *session, const char *key, char **valuep);
extern int __wt_turtle_update( WT_SESSION_IMPL *session, const char *key, const char *value);
diff --git a/src/third_party/wiredtiger/src/lsm/lsm_tree.c b/src/third_party/wiredtiger/src/lsm/lsm_tree.c
index bd54202de5e..7371f3a407c 100644
--- a/src/third_party/wiredtiger/src/lsm/lsm_tree.c
+++ b/src/third_party/wiredtiger/src/lsm/lsm_tree.c
@@ -213,6 +213,7 @@ int
__wt_lsm_tree_set_chunk_size(
WT_SESSION_IMPL *session, WT_LSM_CHUNK *chunk)
{
+ WT_DECL_RET;
wt_off_t size;
const char *filename;
@@ -220,7 +221,9 @@ __wt_lsm_tree_set_chunk_size(
if (!WT_PREFIX_SKIP(filename, "file:"))
WT_RET_MSG(session, EINVAL,
"Expected a 'file:' URI: %s", chunk->uri);
- WT_RET(__wt_filesize_name(session, filename, &size));
+ ret = __wt_filesize_name(session, filename, &size);
+ if (ret != 0)
+ WT_RET_MSG(session, ret, "%s: file size", filename);
chunk->size = (uint64_t)size;
diff --git a/src/third_party/wiredtiger/src/meta/meta_track.c b/src/third_party/wiredtiger/src/meta/meta_track.c
index bc96a35efc7..1a773ef67c4 100644
--- a/src/third_party/wiredtiger/src/meta/meta_track.c
+++ b/src/third_party/wiredtiger/src/meta/meta_track.c
@@ -231,6 +231,7 @@ __wt_meta_track_off(WT_SESSION_IMPL *session, bool need_sync, bool unroll)
{
WT_DECL_RET;
WT_META_TRACK *trk, *trk_orig;
+ WT_SESSION_IMPL *ckpt_session;
WT_ASSERT(session,
WT_META_TRACKING(session) && session->meta_track_nest > 0);
@@ -275,9 +276,18 @@ __wt_meta_track_off(WT_SESSION_IMPL *session, bool need_sync, bool unroll)
session, false, WT_TXN_LOG_CKPT_SYNC, NULL));
WT_RET(ret);
} else {
- WT_WITH_DHANDLE(session, session->meta_dhandle,
- WT_WITH_TXN_ISOLATION(session, WT_ISO_READ_COMMITTED,
- ret = __wt_checkpoint(session, NULL)));
+ WT_ASSERT(session, F_ISSET(session, WT_SESSION_LOCKED_SCHEMA));
+ ckpt_session = S2C(session)->meta_ckpt_session;
+ /*
+ * If this operation is part of a running transaction, that
+ * should be included in the checkpoint.
+ */
+ ckpt_session->txn.id = session->txn.id;
+ F_SET(ckpt_session, WT_SESSION_LOCKED_SCHEMA);
+ WT_WITH_DHANDLE(ckpt_session, session->meta_dhandle, ret =
+ __wt_checkpoint(ckpt_session, NULL));
+ F_CLR(ckpt_session, WT_SESSION_LOCKED_SCHEMA);
+ ckpt_session->txn.id = WT_TXN_NONE;
WT_RET(ret);
WT_WITH_DHANDLE(session, session->meta_dhandle,
ret = __wt_checkpoint_sync(session, NULL));
@@ -458,3 +468,52 @@ __wt_meta_track_handle_lock(WT_SESSION_IMPL *session, bool created)
trk->created = created;
return (0);
}
+
+/*
+ * __wt_meta_track_init --
+ * Intialize metadata tracking.
+ */
+int
+__wt_meta_track_init(WT_SESSION_IMPL *session)
+{
+ WT_CONNECTION_IMPL *conn;
+
+ conn = S2C(session);
+ if (!FLD_ISSET(conn->log_flags, WT_CONN_LOG_ENABLED)) {
+ WT_RET(__wt_open_internal_session(conn,
+ "metadata-ckpt", false, WT_SESSION_NO_DATA_HANDLES,
+ &conn->meta_ckpt_session));
+
+ /*
+ * Sessions default to read-committed isolation, we rely on
+ * that for the correctness of metadata checkpoints.
+ */
+ WT_ASSERT(session, conn->meta_ckpt_session->txn.isolation ==
+ WT_ISO_READ_COMMITTED);
+ }
+
+ return (0);
+}
+
+/*
+ * __wt_meta_track_destroy --
+ * Release resources allocated for metadata tracking.
+ */
+int
+__wt_meta_track_destroy(WT_SESSION_IMPL *session)
+{
+ WT_CONNECTION_IMPL *conn;
+ WT_DECL_RET;
+ WT_SESSION *wt_session;
+
+ conn = S2C(session);
+
+ /* Close the session used for metadata checkpoints. */
+ if (conn->meta_ckpt_session != NULL) {
+ wt_session = &conn->meta_ckpt_session->iface;
+ WT_TRET(wt_session->close(wt_session, NULL));
+ conn->meta_ckpt_session = NULL;
+ }
+
+ return (ret);
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_filesize.c b/src/third_party/wiredtiger/src/os_posix/os_filesize.c
index b01fc91514b..09174ffcd90 100644
--- a/src/third_party/wiredtiger/src/os_posix/os_filesize.c
+++ b/src/third_party/wiredtiger/src/os_posix/os_filesize.c
@@ -47,10 +47,9 @@ __wt_filesize_name(
__wt_free(session, path);
- if (ret == 0) {
+ if (ret == 0)
*sizep = sb.st_size;
- return (0);
- }
- WT_RET_MSG(session, ret, "%s: fstat", filename);
+ /* Some callers expect failure, so don't log an error message. */
+ return (ret);
}
diff --git a/src/third_party/wiredtiger/src/os_win/os_filesize.c b/src/third_party/wiredtiger/src/os_win/os_filesize.c
index dfeadc31fc4..c51303d7215 100644
--- a/src/third_party/wiredtiger/src/os_win/os_filesize.c
+++ b/src/third_party/wiredtiger/src/os_win/os_filesize.c
@@ -47,11 +47,10 @@ __wt_filesize_name(
__wt_free(session, path);
- if (ret != 0) {
+ if (ret != 0)
*sizep =
((int64_t)data.nFileSizeHigh << 32) | data.nFileSizeLow;
- return (0);
- }
- WT_RET_MSG(session, __wt_errno(), "%s: GetFileAttributesEx", filename);
+ /* Some callers expect failure, so don't log an error message. */
+ return (ret);
}
diff --git a/src/third_party/wiredtiger/src/schema/schema_stat.c b/src/third_party/wiredtiger/src/schema/schema_stat.c
index d14b81d389f..355abf8f343 100644
--- a/src/third_party/wiredtiger/src/schema/schema_stat.c
+++ b/src/third_party/wiredtiger/src/schema/schema_stat.c
@@ -90,18 +90,19 @@ __curstat_size_only(WT_SESSION_IMPL *session,
WT_ERR(__wt_buf_fmt(
session, &namebuf, "%s.wt", uri + strlen("table:")));
/*
- * Get the size of the underlying file. There is nothing stopping a
- * race with schema level table operations (for example drop) if there
- * is a race there will be an error message generated.
+ * Get the size of the underlying file. This will fail for anything
+ * other than simple tables (LSM for example) and will fail if there
+ * are concurrent schema level operations (for example drop). That is
+ * fine - failing here results in falling back to the slow path of
+ * opening the handle.
*/
- WT_ERR(__wt_filesize_name(session, namebuf.data, &filesize));
-
- /* Setup and populate the statistics structure */
- __wt_stat_dsrc_init_single(&cst->u.dsrc_stats);
- cst->u.dsrc_stats.block_size = filesize;
- __wt_curstat_dsrc_final(cst);
-
- *was_fast = true;
+ if (__wt_filesize_name(session, namebuf.data, &filesize) == 0) {
+ /* Setup and populate the statistics structure */
+ __wt_stat_dsrc_init_single(&cst->u.dsrc_stats);
+ cst->u.dsrc_stats.block_size = filesize;
+ __wt_curstat_dsrc_final(cst);
+ *was_fast = true;
+ }
err: __wt_free(session, tableconf);
__wt_buf_free(session, &namebuf);