summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/reconcile
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@mongodb.com>2015-08-12 20:56:25 +1000
committerMichael Cahill <michael.cahill@mongodb.com>2015-08-12 20:56:25 +1000
commit7bb09c0377f5160857617c38ab07955f8f4b03f6 (patch)
tree2d7041f6e1cc121c743c368406485e39280b551c /src/third_party/wiredtiger/src/reconcile
parent6d9cbeb53eb9e6d39a24a8ac54b71e105483730b (diff)
downloadmongo-7bb09c0377f5160857617c38ab07955f8f4b03f6.tar.gz
Import wiredtiger-wiredtiger-2.6.1-500-g26d1ad2.tar.gz from wiredtiger branch mongodb-3.2
Diffstat (limited to 'src/third_party/wiredtiger/src/reconcile')
-rw-r--r--src/third_party/wiredtiger/src/reconcile/rec_write.c73
1 files changed, 32 insertions, 41 deletions
diff --git a/src/third_party/wiredtiger/src/reconcile/rec_write.c b/src/third_party/wiredtiger/src/reconcile/rec_write.c
index 53a73b44feb..37acb28a00b 100644
--- a/src/third_party/wiredtiger/src/reconcile/rec_write.c
+++ b/src/third_party/wiredtiger/src/reconcile/rec_write.c
@@ -343,11 +343,12 @@ __wt_reconcile(WT_SESSION_IMPL *session,
WT_PAGE *page;
WT_PAGE_MODIFY *mod;
WT_RECONCILE *r;
- int locked;
+ int page_lock, scan_lock, split_lock;
conn = S2C(session);
page = ref->page;
mod = page->modify;
+ page_lock = scan_lock = split_lock = 0;
/* We're shouldn't get called with a clean page, that's an error. */
if (!__wt_page_is_modified(page))
@@ -386,22 +387,38 @@ __wt_reconcile(WT_SESSION_IMPL *session,
/*
* The compaction process looks at the page's modification information;
- * if compaction is running, lock the page down.
- *
- * Otherwise, flip on the scanning flag: obsolete updates cannot be
- * freed while reconciliation is in progress.
+ * if compaction is running, acquire the page's lock.
*/
- locked = 0;
if (conn->compact_in_memory_pass) {
- locked = 1;
WT_PAGE_LOCK(session, page);
- } else
+ page_lock = 1;
+ }
+
+ /*
+ * Reconciliation reads the lists of updates, so obsolete updates cannot
+ * be discarded while reconciliation is in progress.
+ */
+ for (;;) {
+ F_CAS_ATOMIC(page, WT_PAGE_SCANNING, ret);
+ if (ret == 0)
+ break;
+ __wt_yield();
+ }
+ scan_lock = 1;
+
+ /*
+ * Mark internal pages as splitting to ensure we don't deadlock when
+ * performing an in-memory split during a checkpoint.
+ */
+ if (WT_PAGE_IS_INTERNAL(page)) {
for (;;) {
- F_CAS_ATOMIC(page, WT_PAGE_SCANNING, ret);
+ F_CAS_ATOMIC(page, WT_PAGE_SPLIT_LOCKED, ret);
if (ret == 0)
break;
__wt_yield();
}
+ split_lock = 1;
+ }
/* Reconcile the page. */
switch (page->type) {
@@ -434,11 +451,13 @@ __wt_reconcile(WT_SESSION_IMPL *session,
else
WT_TRET(__rec_write_wrapup_err(session, r, page));
- /* Release the page lock if we're holding one. */
- if (locked)
- WT_PAGE_UNLOCK(session, page);
- else
+ /* Release the locks we're holding. */
+ if (split_lock)
+ F_CLR_ATOMIC(page, WT_PAGE_SPLIT_LOCKED);
+ if (scan_lock)
F_CLR_ATOMIC(page, WT_PAGE_SCANNING);
+ if (page_lock)
+ WT_PAGE_UNLOCK(session, page);
/*
* Clean up the boundary structures: some workloads result in millions
@@ -3266,18 +3285,6 @@ __rec_col_int(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_PAGE *page)
WT_RET(__rec_split_init(
session, r, page, page->pg_intl_recno, btree->maxintlpage));
- /*
- * We need to mark this page as splitting, as this may be an in-memory
- * split during a checkpoint.
- */
- for (;;) {
- F_CAS_ATOMIC(page, WT_PAGE_SPLIT_LOCKED, ret);
- if (ret == 0) {
- break;
- }
- __wt_yield();
- }
-
/* For each entry in the in-memory page... */
WT_INTL_FOREACH_BEGIN(session, page, ref) {
/* Update the starting record number in case we split. */
@@ -3360,8 +3367,6 @@ __rec_col_int(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_PAGE *page)
__rec_copy_incr(session, r, val);
} WT_INTL_FOREACH_END;
- F_CLR_ATOMIC(page, WT_PAGE_SPLIT_LOCKED);
-
/* Write the remnant page. */
return (__rec_split_finish(session, r));
@@ -4094,18 +4099,6 @@ __rec_row_int(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_PAGE *page)
*/
r->cell_zero = 1;
- /*
- * We need to mark this page as splitting in order to ensure we don't
- * deadlock when performing an in-memory split during a checkpoint.
- */
- for (;;) {
- F_CAS_ATOMIC(page, WT_PAGE_SPLIT_LOCKED, ret);
- if (ret == 0) {
- break;
- }
- __wt_yield();
- }
-
/* For each entry in the in-memory page... */
WT_INTL_FOREACH_BEGIN(session, page, ref) {
/*
@@ -4264,8 +4257,6 @@ __rec_row_int(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_PAGE *page)
__rec_key_state_update(r, ovfl_key);
} WT_INTL_FOREACH_END;
- F_CLR_ATOMIC(page, WT_PAGE_SPLIT_LOCKED);
-
/* Write the remnant page. */
return (__rec_split_finish(session, r));