summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/reconcile
diff options
context:
space:
mode:
authorAlexander Gorrod <alexander.gorrod@mongodb.com>2015-05-08 05:34:43 +0000
committerAlexander Gorrod <alexander.gorrod@mongodb.com>2015-05-08 05:34:43 +0000
commitcddb4b8f5a193e32d1400963cd177fe47c8570df (patch)
treedade044e688956af69505fc796244f229d40241c /src/third_party/wiredtiger/src/reconcile
parent3a8bcdfb23ab85b57e5da308fb4d3c607ce77a49 (diff)
downloadmongo-cddb4b8f5a193e32d1400963cd177fe47c8570df.tar.gz
Import wiredtiger-wiredtiger-2.5.3-486-g4f9aa1c.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.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/src/third_party/wiredtiger/src/reconcile/rec_write.c b/src/third_party/wiredtiger/src/reconcile/rec_write.c
index 5bef5cd2d2d..76d61642bfd 100644
--- a/src/third_party/wiredtiger/src/reconcile/rec_write.c
+++ b/src/third_party/wiredtiger/src/reconcile/rec_write.c
@@ -483,6 +483,7 @@ __rec_root_write(WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t flags)
switch (F_ISSET(mod, WT_PM_REC_MASK)) {
case WT_PM_REC_EMPTY: /* Page is empty */
case WT_PM_REC_REPLACE: /* 1-for-1 page swap */
+ case WT_PM_REC_REWRITE: /* Rewrite */
return (0);
case WT_PM_REC_MULTIBLOCK: /* Multiple blocks */
break;
@@ -3229,6 +3230,18 @@ __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. */
@@ -3271,6 +3284,8 @@ __rec_col_int(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_PAGE *page)
case WT_PM_REC_REPLACE:
addr = &child->modify->mod_replace;
break;
+ case WT_PM_REC_REWRITE:
+ break;
WT_ILLEGAL_VALUE_ERR(session);
}
} else
@@ -3309,6 +3324,8 @@ __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));
@@ -4041,6 +4058,18 @@ __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) {
/*
@@ -4199,6 +4228,8 @@ __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));
@@ -4836,6 +4867,7 @@ __rec_write_wrapup(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_PAGE *page)
case WT_PM_REC_EMPTY: /* Page deleted */
break;
case WT_PM_REC_MULTIBLOCK: /* Multiple blocks */
+ case WT_PM_REC_REWRITE: /* Rewrite */
/*
* Discard the multiple replacement blocks.
*/
@@ -4914,7 +4946,7 @@ __rec_write_wrapup(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_PAGE *page)
bnd->dsk = NULL;
mod->mod_multi_entries = 1;
- F_SET(mod, WT_PM_REC_MULTIBLOCK);
+ F_SET(mod, WT_PM_REC_REWRITE);
break;
}
@@ -5064,10 +5096,14 @@ __rec_write_wrapup_err(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_PAGE *page)
* information (otherwise we might think the backing block is being
* reused on a subsequent reconciliation where we want to free it).
*/
- if (F_ISSET(mod, WT_PM_REC_MASK) == WT_PM_REC_MULTIBLOCK)
+ switch (F_ISSET(mod, WT_PM_REC_MASK)) {
+ case WT_PM_REC_MULTIBLOCK:
+ case WT_PM_REC_REWRITE:
for (multi = mod->mod_multi,
i = 0; i < mod->mod_multi_entries; ++multi, ++i)
multi->addr.reuse = 0;
+ break;
+ }
/*
* On error, discard blocks we've written, they're unreferenced by the