diff options
-rw-r--r-- | src/third_party/wiredtiger/src/block/block_open.c | 6 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/btree/bt_split.c | 15 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/btree/bt_sync.c | 27 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/conn/conn_open.c | 6 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/evict/evict_lru.c | 2 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/evict/evict_page.c | 4 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/include/connection.h | 2 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/include/extern.h | 2 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/lsm/lsm_tree.c | 5 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/meta/meta_track.c | 65 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/os_posix/os_filesize.c | 7 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/os_win/os_filesize.c | 7 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/schema/schema_stat.c | 23 |
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); |