summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoragorrod <alexg@wiredtiger.com>2012-09-28 00:17:44 -0700
committeragorrod <alexg@wiredtiger.com>2012-09-28 00:17:44 -0700
commitc8a4341d852d323d0029b0b0a1e48a58ab2f23b6 (patch)
tree56ba57223b3b07466f22c4491684fde522d9d9b2 /src
parent1b70668459116f1100da075cf2d0532efdc5ae6e (diff)
parentabd79f526b7ef5334c2863fc84b6d9638eb8cad7 (diff)
downloadmongo-c8a4341d852d323d0029b0b0a1e48a58ab2f23b6.tar.gz
Merge pull request #343 from wiredtiger/evict-fail
If no space can be allocated in the cache, abort transactions.
Diffstat (limited to 'src')
-rw-r--r--src/btree/bt_curnext.c2
-rw-r--r--src/btree/bt_curprev.c1
-rw-r--r--src/btree/bt_cursor.c1
-rw-r--r--src/btree/bt_evict.c10
-rw-r--r--src/btree/rec_evict.c6
-rw-r--r--src/docs/cursor-ops.dox10
-rw-r--r--src/docs/transactions.dox5
-rw-r--r--src/include/api.h8
-rw-r--r--src/include/cursor.i13
9 files changed, 39 insertions, 17 deletions
diff --git a/src/btree/bt_curnext.c b/src/btree/bt_curnext.c
index 3c7b8d21a33..98ebc3c622b 100644
--- a/src/btree/bt_curnext.c
+++ b/src/btree/bt_curnext.c
@@ -403,6 +403,7 @@ __wt_btcur_next(WT_CURSOR_BTREE *cbt, int discard)
LF_SET(WT_TREE_DISCARD);
__cursor_func_init(cbt, 0);
+ __cursor_position_clear(cbt);
/*
* If we aren't already iterating in the right direction, there's
@@ -507,6 +508,7 @@ __wt_btcur_next_random(WT_CURSOR_BTREE *cbt)
WT_BSTAT_INCR(session, cursor_read_next);
__cursor_func_init(cbt, 1);
+ __cursor_position_clear(cbt);
/*
* Only supports row-store: applications can trivially select a random
diff --git a/src/btree/bt_curprev.c b/src/btree/bt_curprev.c
index 76a847ea61a..e7f9a37b742 100644
--- a/src/btree/bt_curprev.c
+++ b/src/btree/bt_curprev.c
@@ -491,6 +491,7 @@ __wt_btcur_prev(WT_CURSOR_BTREE *cbt, int discard)
LF_SET(WT_TREE_DISCARD);
__cursor_func_init(cbt, 0);
+ __cursor_position_clear(cbt);
/*
* If we aren't already iterating in the right direction, there's
diff --git a/src/btree/bt_cursor.c b/src/btree/bt_cursor.c
index b72c4a12fd0..4515063d8be 100644
--- a/src/btree/bt_cursor.c
+++ b/src/btree/bt_cursor.c
@@ -112,6 +112,7 @@ __wt_btcur_reset(WT_CURSOR_BTREE *cbt)
__cursor_leave(cbt);
__cursor_search_clear(cbt);
+ __cursor_position_clear(cbt);
return (0);
}
diff --git a/src/btree/bt_evict.c b/src/btree/bt_evict.c
index c834fd2c17f..f03a986cae3 100644
--- a/src/btree/bt_evict.c
+++ b/src/btree/bt_evict.c
@@ -940,6 +940,7 @@ int
__wt_evict_lru_page(WT_SESSION_IMPL *session, int is_app)
{
WT_BTREE *btree, *saved_btree;
+ WT_DECL_RET;
WT_PAGE *page;
__evict_get_page(session, is_app, &btree, &page);
@@ -952,19 +953,14 @@ __wt_evict_lru_page(WT_SESSION_IMPL *session, int is_app)
saved_btree = session->btree;
WT_SET_BTREE_IN_SESSION(session, btree);
- /*
- * We don't care why eviction failed (maybe the page was dirty and
- * we're out of disk space, or the page had an in-memory subtree
- * already being evicted).
- */
- (void)__evict_page(session, page);
+ ret = __evict_page(session, page);
(void)WT_ATOMIC_SUB(btree->lru_count, 1);
WT_CLEAR_BTREE_IN_SESSION(session);
session->btree = saved_btree;
- return (0);
+ return (ret);
}
/*
diff --git a/src/btree/rec_evict.c b/src/btree/rec_evict.c
index 9ff11cf5900..780ad8f1976 100644
--- a/src/btree/rec_evict.c
+++ b/src/btree/rec_evict.c
@@ -339,10 +339,10 @@ __rec_review(WT_SESSION_IMPL *session,
}
/*
- * If no pages are referenced, there are no consistency
- * issues: try to bump our snapshot.
+ * If there aren't multiple cursors active, there
+ * are no consistency issues: try to bump our snapshot.
*/
- if (session->nhazard == 0) {
+ if (session->ncursors <= 1) {
__wt_txn_read_last(session);
__wt_txn_read_first(session);
}
diff --git a/src/docs/cursor-ops.dox b/src/docs/cursor-ops.dox
index 84d089446cb..54a174a09c2 100644
--- a/src/docs/cursor-ops.dox
+++ b/src/docs/cursor-ops.dox
@@ -101,8 +101,14 @@ To remove existing data using a cursor, use the WT_CURSOR::remove method:
@section cursor_error Cursor position after error
After any cursor handle method failure, the cursor's position is
-undetermined. Applications that cannot re-position the cursor after
-failure must duplicate the cursor before calling a cursor method that will
+undetermined. For cursor operations that expect a key to be set before the
+operation begins (including WT_CURSOR::search, WT_CURSOR::insert,
+WT_CURSOR::update and WT_CURSOR::remove), the application's key and value
+will not be cleared by an error.
+
+Applications that cannot re-position the cursor after failure must
+duplicate the cursor by calling WT_SESSION::open_cursor and passing the
+cursor as the \c to_dup parameter before calling a cursor method that will
attempt to re-position the cursor.
*/
diff --git a/src/docs/transactions.dox b/src/docs/transactions.dox
index efc5934f9aa..4bc745858b8 100644
--- a/src/docs/transactions.dox
+++ b/src/docs/transactions.dox
@@ -72,6 +72,11 @@ updating the same value will fail with ::WT_DEADLOCK. Some applications
may benefit from application-level synchronization to avoid repeated
attempts to rollback and update the same value.
+Operations in transactions may also fail with the ::WT_DEADLOCK error if
+some resource cannot be allocated after repeated attempts. For example, if
+the cache is not large enough to hold the updates required to satisfy
+transactional readers, an operation may fail and return ::WT_DEADLOCK.
+
@section transaction_isolation Isolation levels
WiredTiger supports <code>read-uncommitted</code>,
diff --git a/src/include/api.h b/src/include/api.h
index 47129ee8291..11ba9656cc7 100644
--- a/src/include/api.h
+++ b/src/include/api.h
@@ -331,14 +331,18 @@ struct __wt_connection_impl {
} \
ret = __wt_txn_commit((s), NULL); \
} else { \
- WT_TRET(WT_DEADLOCK); \
(void)__wt_txn_rollback((s), NULL); \
+ if (ret == 0 || ret == WT_DEADLOCK) { \
+ ret = 0; \
+ continue; \
+ } \
} \
} else if ((ret) != 0 && \
(ret) != WT_NOTFOUND && \
(ret) != WT_DUPLICATE_KEY) \
F_SET(&(s)->txn, TXN_ERROR); \
-} while (0)
+ break; \
+} while (1)
/*
* If a session or connection method is about to return WT_NOTFOUND (some
diff --git a/src/include/cursor.i b/src/include/cursor.i
index e9a3240684c..aa0d3ef436f 100644
--- a/src/include/cursor.i
+++ b/src/include/cursor.i
@@ -17,6 +17,16 @@ __cursor_set_recno(WT_CURSOR_BTREE *cbt, uint64_t v)
}
/*
+ * __cursor_position_clear --
+ * Forget the current key and value in a cursor.
+ */
+static inline void
+__cursor_position_clear(WT_CURSOR_BTREE *cbt)
+{
+ F_CLR(&cbt->iface, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET);
+}
+
+/*
* __cursor_search_clear --
* Reset the cursor's state for a search.
*/
@@ -60,9 +70,6 @@ __cursor_leave(WT_CURSOR_BTREE *cbt)
__wt_stack_release(session, cbt->page);
cbt->page = NULL;
- /* Reset the returned key/value state. */
- F_CLR(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET);
-
if (F_ISSET(cbt, WT_CBT_ACTIVE)) {
WT_ASSERT(session, session->ncursors > 0);
if (--session->ncursors == 0)