diff options
author | Michael Cahill <michael.cahill@mongodb.com> | 2015-08-12 20:56:25 +1000 |
---|---|---|
committer | Michael Cahill <michael.cahill@mongodb.com> | 2015-08-12 20:56:25 +1000 |
commit | 7bb09c0377f5160857617c38ab07955f8f4b03f6 (patch) | |
tree | 2d7041f6e1cc121c743c368406485e39280b551c /src/third_party/wiredtiger/src/reconcile | |
parent | 6d9cbeb53eb9e6d39a24a8ac54b71e105483730b (diff) | |
download | mongo-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.c | 73 |
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)); |