summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2015-03-26 14:11:30 +1100
committerMichael Cahill <michael.cahill@wiredtiger.com>2015-03-26 14:11:30 +1100
commitfe5a1c3b0e5e51bf4980841233e6335c92d7dcf6 (patch)
tree230f9f415b081a6b6f257f848e1f90e9d6ec94a4
parent3f7513d4616ac42cfd4c8891f4b237c7f5dfc8f1 (diff)
downloadmongo-fe5a1c3b0e5e51bf4980841233e6335c92d7dcf6.tar.gz
When we complete a schema-changing operation, make sure the metadata is stable. Here "schema-changing" implies that we are using the metadata tracking code, and "stable" means that either the log has been flushed or we checkpoint the metadata.
-rw-r--r--dist/flags.py1
-rw-r--r--src/include/extern.h2
-rw-r--r--src/include/flags.h1
-rw-r--r--src/meta/meta_track.c25
-rw-r--r--src/schema/schema_create.c2
-rw-r--r--src/schema/schema_drop.c2
-rw-r--r--src/schema/schema_rename.c2
-rw-r--r--src/txn/txn_ckpt.c4
-rw-r--r--src/txn/txn_log.c7
9 files changed, 33 insertions, 13 deletions
diff --git a/dist/flags.py b/dist/flags.py
index f1eb6b24968..34f3ab3e02f 100644
--- a/dist/flags.py
+++ b/dist/flags.py
@@ -54,6 +54,7 @@ flags = {
'TXN_LOG_CKPT_PREPARE',
'TXN_LOG_CKPT_START',
'TXN_LOG_CKPT_STOP',
+ 'TXN_LOG_CKPT_SYNC',
],
'verbose' : [
'VERB_API',
diff --git a/src/include/extern.h b/src/include/extern.h
index 6ac926b494c..da6660dd3a6 100644
--- a/src/include/extern.h
+++ b/src/include/extern.h
@@ -425,7 +425,7 @@ extern int __wt_metadata_remove(WT_SESSION_IMPL *session, const char *key);
extern int __wt_metadata_search( WT_SESSION_IMPL *session, const char *key, char **valuep);
extern void __wt_meta_track_discard(WT_SESSION_IMPL *session);
extern int __wt_meta_track_on(WT_SESSION_IMPL *session);
-extern int __wt_meta_track_off(WT_SESSION_IMPL *session, int unroll);
+extern int __wt_meta_track_off(WT_SESSION_IMPL *session, int sync, int unroll);
extern int __wt_meta_track_sub_on(WT_SESSION_IMPL *session);
extern int __wt_meta_track_sub_off(WT_SESSION_IMPL *session);
extern int __wt_meta_track_checkpoint(WT_SESSION_IMPL *session);
diff --git a/src/include/flags.h b/src/include/flags.h
index 30b2ab1c0e3..99c77c94f49 100644
--- a/src/include/flags.h
+++ b/src/include/flags.h
@@ -65,6 +65,7 @@
#define WT_TXN_LOG_CKPT_PREPARE 0x00000002
#define WT_TXN_LOG_CKPT_START 0x00000004
#define WT_TXN_LOG_CKPT_STOP 0x00000008
+#define WT_TXN_LOG_CKPT_SYNC 0x00000010
#define WT_VERB_API 0x00000001
#define WT_VERB_BLOCK 0x00000002
#define WT_VERB_CHECKPOINT 0x00000004
diff --git a/src/meta/meta_track.c b/src/meta/meta_track.c
index 85ca1732586..42955e734e1 100644
--- a/src/meta/meta_track.c
+++ b/src/meta/meta_track.c
@@ -188,7 +188,7 @@ free: trk->op = WT_ST_EMPTY;
* Turn off metadata operation tracking, unrolling on error.
*/
int
-__wt_meta_track_off(WT_SESSION_IMPL *session, int unroll)
+__wt_meta_track_off(WT_SESSION_IMPL *session, int sync, int unroll)
{
WT_DECL_RET;
WT_META_TRACK *trk, *trk_orig;
@@ -218,13 +218,28 @@ __wt_meta_track_off(WT_SESSION_IMPL *session, int unroll)
WT_TRET(__meta_track_apply(session, trk, unroll));
/*
- * If the operation succeeded and we aren't relying on the log for
- * durability, checkpoint the metadata.
+ * Unroll operations don't need to flush the metadata.
+ *
+ * Also, if we don't have the metadata handle (e.g, we're in the
+ * process of creating the metadata), we can't sync it.
*/
- if (!unroll && ret == 0 && session->meta_dhandle != NULL &&
- !FLD_ISSET(S2C(session)->log_flags, WT_CONN_LOG_ENABLED))
+ if (unroll || ret != 0 || !sync || session->meta_dhandle == NULL)
+ return (ret);
+
+ /* If we're logging, make sure the metadata update was flushed. */
+ if (FLD_ISSET(S2C(session)->log_flags, WT_CONN_LOG_ENABLED)) {
+ if (!FLD_ISSET(S2C(session)->txn_logsync,
+ WT_LOG_DSYNC | WT_LOG_FSYNC))
+ WT_WITH_DHANDLE(session, session->meta_dhandle,
+ ret = __wt_txn_checkpoint_log(session,
+ 0, WT_TXN_LOG_CKPT_SYNC, NULL));
+ } else {
WT_WITH_DHANDLE(session, session->meta_dhandle,
ret = __wt_checkpoint(session, NULL));
+ WT_RET(ret);
+ WT_WITH_DHANDLE(session, session->meta_dhandle,
+ ret = __wt_checkpoint_sync(session, NULL));
+ }
return (ret);
}
diff --git a/src/schema/schema_create.c b/src/schema/schema_create.c
index 720b6fc6412..80e443d8a21 100644
--- a/src/schema/schema_create.c
+++ b/src/schema/schema_create.c
@@ -637,7 +637,7 @@ __wt_schema_create(
ret = __wt_bad_object_type(session, uri);
session->dhandle = NULL;
- WT_TRET(__wt_meta_track_off(session, ret != 0));
+ WT_TRET(__wt_meta_track_off(session, 1, ret != 0));
return (ret);
}
diff --git a/src/schema/schema_drop.c b/src/schema/schema_drop.c
index 03dece47722..03097128ec2 100644
--- a/src/schema/schema_drop.c
+++ b/src/schema/schema_drop.c
@@ -192,7 +192,7 @@ __wt_schema_drop(WT_SESSION_IMPL *session, const char *uri, const char *cfg[])
/* Bump the schema generation so that stale data is ignored. */
++S2C(session)->schema_gen;
- WT_TRET(__wt_meta_track_off(session, ret != 0));
+ WT_TRET(__wt_meta_track_off(session, 1, ret != 0));
return (ret);
}
diff --git a/src/schema/schema_rename.c b/src/schema/schema_rename.c
index 38124754cd5..51281eccec5 100644
--- a/src/schema/schema_rename.c
+++ b/src/schema/schema_rename.c
@@ -274,7 +274,7 @@ __wt_schema_rename(WT_SESSION_IMPL *session,
/* Bump the schema generation so that stale data is ignored. */
++S2C(session)->schema_gen;
- WT_TRET(__wt_meta_track_off(session, ret != 0));
+ WT_TRET(__wt_meta_track_off(session, 1, ret != 0));
/* If we didn't find a metadata entry, map that error to ENOENT. */
return (ret == WT_NOTFOUND ? ENOENT : ret);
diff --git a/src/txn/txn_ckpt.c b/src/txn/txn_ckpt.c
index 8e3d0aa8fbe..7c1532390f9 100644
--- a/src/txn/txn_ckpt.c
+++ b/src/txn/txn_ckpt.c
@@ -534,7 +534,7 @@ err: /*
*/
session->isolation = txn->isolation = TXN_ISO_READ_UNCOMMITTED;
if (tracking)
- WT_TRET(__wt_meta_track_off(session, ret != 0));
+ WT_TRET(__wt_meta_track_off(session, 0, ret != 0));
if (F_ISSET(txn, TXN_RUNNING)) {
/*
@@ -1133,7 +1133,7 @@ __wt_checkpoint_close(WT_SESSION_IMPL *session, int final, int force)
WT_TRET(__checkpoint_worker(session, NULL, 0));
if (need_tracking)
- WT_RET(__wt_meta_track_off(session, ret != 0));
+ WT_RET(__wt_meta_track_off(session, 1, ret != 0));
return (ret);
}
diff --git a/src/txn/txn_log.c b/src/txn/txn_log.c
index afe98d95c6f..bf0b1990557 100644
--- a/src/txn/txn_log.c
+++ b/src/txn/txn_log.c
@@ -221,11 +221,12 @@ __txn_log_file_sync(WT_SESSION_IMPL *session, uint32_t flags, WT_LSN *lsnp)
WT_DECL_RET;
size_t header_size;
uint32_t rectype = WT_LOGREC_FILE_SYNC;
- int start;
+ int start, sync;
const char *fmt = WT_UNCHECKED_STRING(III);
btree = S2BT(session);
start = LF_ISSET(WT_TXN_LOG_CKPT_START);
+ sync = LF_ISSET(WT_TXN_LOG_CKPT_SYNC);
WT_RET(__wt_struct_size(
session, &header_size, fmt, rectype, btree->id, start));
@@ -236,7 +237,7 @@ __txn_log_file_sync(WT_SESSION_IMPL *session, uint32_t flags, WT_LSN *lsnp)
fmt, rectype, btree->id, start));
logrec->size += (uint32_t)header_size;
- WT_ERR(__wt_log_write(session, logrec, lsnp, 0));
+ WT_ERR(__wt_log_write(session, logrec, lsnp, sync ? WT_LOG_FSYNC : 0));
err: __wt_logrec_free(session, &logrec);
return (ret);
}
@@ -360,6 +361,8 @@ __wt_txn_checkpoint_log(
__wt_scr_free(session, &txn->ckpt_snapshot);
txn->full_ckpt = 0;
break;
+
+ WT_ILLEGAL_VALUE_ERR(session);
}
err: __wt_logrec_free(session, &logrec);