Merge pull request #2282 from wiredtiger/WT-2193

WT-2193 Handle read-committed metadata checkpoints during snapshot transactions
This commit is contained in:
Alex Gorrod
2015-11-03 16:49:36 +11:00
5 changed files with 95 additions and 7 deletions

View File

@@ -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;
@@ -79,6 +80,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) {

View File

@@ -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));

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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);
}