diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2012-06-18 13:53:44 +1000 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2012-06-20 15:32:47 +1000 |
commit | f3ab36014fe49487fdb791d468811e33ec8b354b (patch) | |
tree | fac4a6cb582a35e9398535d98061e9beba4573da | |
parent | a7dc715a834b3d1d2c5eb3e521ccd10b9ba0ed3a (diff) | |
download | mongo-f3ab36014fe49487fdb791d468811e33ec8b354b.tar.gz |
Fix __wt_conn_btree_apply to acquire handles correctly,
pass WT_BTREE_SNAPSHOT_OP from checkpoint code.
-rw-r--r-- | src/btree/bt_handle.c | 4 | ||||
-rw-r--r-- | src/conn/conn_btree.c | 9 | ||||
-rw-r--r-- | src/include/txn.i | 2 | ||||
-rw-r--r-- | src/txn/txn.c | 35 | ||||
-rw-r--r-- | test/format/wts_ops.c | 8 | ||||
-rw-r--r-- | test/thread/t.c | 4 |
6 files changed, 40 insertions, 22 deletions
diff --git a/src/btree/bt_handle.c b/src/btree/bt_handle.c index 3cc126b1c89..5b9a1fef052 100644 --- a/src/btree/bt_handle.c +++ b/src/btree/bt_handle.c @@ -133,8 +133,10 @@ __wt_btree_close(WT_SESSION_IMPL *session) __wt_btree_huffman_close(session); /* Snapshot lock. */ - if (btree->snaplock != NULL) + if (btree->snaplock != NULL) { (void)__wt_rwlock_destroy(session, btree->snaplock); + btree->snaplock = NULL; + } /* Free allocated memory. */ __wt_free(session, btree->key_format); diff --git a/src/conn/conn_btree.c b/src/conn/conn_btree.c index 90331c2adca..b68448be4f6 100644 --- a/src/conn/conn_btree.c +++ b/src/conn/conn_btree.c @@ -300,8 +300,15 @@ __wt_conn_btree_apply(WT_SESSION_IMPL *session, __wt_spin_lock(session, &conn->spinlock); TAILQ_FOREACH(btree, &conn->btqh, q) - if (btree->snapshot == NULL && + if (F_ISSET(btree, WT_BTREE_OPEN) && + btree->snapshot == NULL && strcmp(btree->name, WT_METADATA_URI) != 0) { + /* + * We have the connection spinlock, which prevents + * handles being opened or closed, so there is no need + * for additional handle locking here, or pulling every + * tree into this session's handle cache. + */ session->btree = btree; WT_ERR(func(session, cfg)); } diff --git a/src/include/txn.i b/src/include/txn.i index 37395341750..da9f5af9716 100644 --- a/src/include/txn.i +++ b/src/include/txn.i @@ -125,7 +125,7 @@ __wt_txn_update_check(WT_SESSION_IMPL *session, WT_UPDATE *upd) WT_TXN *txn; txn = &session->txn; - if (txn->isolation == TXN_ISO_SNAPSHOT) + if (F_ISSET(txn, TXN_RUNNING) && txn->isolation == TXN_ISO_SNAPSHOT) while (upd != NULL && !__wt_txn_visible(session, upd->txnid)) { if (upd->txnid != WT_TXN_ABORTED) return (WT_DEADLOCK); diff --git a/src/txn/txn.c b/src/txn/txn.c index 36149170239..8244a093cf0 100644 --- a/src/txn/txn.c +++ b/src/txn/txn.c @@ -193,15 +193,11 @@ int __wt_txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]) { WT_CONFIG_ITEM cval; - WT_CURSOR *cursor; WT_DECL_RET; WT_TXN_GLOBAL *txn_global; const char *snapshot; const char *txn_cfg[] = { "isolation=snapshot", NULL }; - cursor = NULL; - txn_global = &S2C(session)->txn_global; - if ((ret = __wt_config_gets( session, cfg, "snapshot", &cval)) != 0 && ret != WT_NOTFOUND) WT_RET(ret); @@ -212,12 +208,14 @@ __wt_txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]) /* Only one checkpoint can be active at a time. */ __wt_writelock(session, S2C(session)->ckpt_rwlock); - WT_ERR(__wt_txn_begin(session, txn_cfg)); /* Prevent eviction from evicting anything newer than this. */ + txn_global = &S2C(session)->txn_global; txn_global->ckpt_txnid = session->txn.snap_min; + WT_ERR(__wt_meta_track_on(session)); + /* * If we're doing an ordinary unnamed checkpoint, we only need to flush * open files. If we're creating a named snapshot, we need to walk the @@ -225,16 +223,27 @@ __wt_txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]) */ WT_TRET((snapshot == NULL) ? __wt_conn_btree_apply(session, __wt_snapshot, cfg) : - __wt_meta_btree_apply(session, __wt_snapshot, cfg, 0)); + __wt_meta_btree_apply(session, + __wt_snapshot, cfg, WT_BTREE_SNAPSHOT_OP)); - if (cursor != NULL) - WT_TRET(cursor->close(cursor)); - - txn_global->ckpt_txnid = WT_TXN_NONE; - - WT_TRET(__txn_release(session)); + /* + * XXX Rolling back the changes here is problematic. + * + * If we unroll here, we need a way to roll back changes to the avail + * list for each tree that was successfully synced before the error + * occurred. Otherwise, the next time we try this operation, we will + * try to free an old snapshot again. + * + * OTOH, if we commit the changes after a failure, we have partially + * overwritten the checkpoint, so what ends up on disk is not + * consistent. + */ + WT_TRET(__wt_meta_track_off(session, ret != 0)); -err: __wt_rwunlock(session, S2C(session)->ckpt_rwlock); +err: txn_global->ckpt_txnid = WT_TXN_NONE; + if (F_ISSET(&session->txn, TXN_RUNNING)) + WT_TRET(__txn_release(session)); + __wt_rwunlock(session, S2C(session)->ckpt_rwlock); __wt_free(session, snapshot); return (ret); } diff --git a/test/format/wts_ops.c b/test/format/wts_ops.c index 0ec003d186a..7e28f029ab7 100644 --- a/test/format/wts_ops.c +++ b/test/format/wts_ops.c @@ -171,10 +171,10 @@ ops(void *arg) WT_TABLENAME, sync_name); sync_drop = 0; } else { - if ((ret = session->sync( - session, WT_TABLENAME, sync_name)) != 0) - die(ret, "session.sync: %s: %s", - WT_TABLENAME, sync_name); + if ((ret = session->checkpoint( + session, sync_name)) != 0) + die(ret, "session.checkpoint: %s", + sync_name); sync_drop = 1; } diff --git a/test/thread/t.c b/test/thread/t.c index 554c624073b..0f40e0424e4 100644 --- a/test/thread/t.c +++ b/test/thread/t.c @@ -163,8 +163,8 @@ wt_shutdown(void) if ((ret = session->verify(session, FNAME, NULL)) != 0) die("session.verify", ret); - if ((ret = session->sync(session, FNAME, NULL)) != 0) - die("session.sync", ret); + if ((ret = session->checkpoint(session, NULL)) != 0) + die("session.checkpoint", ret); if ((ret = conn->close(conn, NULL)) != 0) die("conn.close", ret); |