diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2015-03-26 14:11:30 +1100 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2015-03-26 14:11:30 +1100 |
commit | fe5a1c3b0e5e51bf4980841233e6335c92d7dcf6 (patch) | |
tree | 230f9f415b081a6b6f257f848e1f90e9d6ec94a4 | |
parent | 3f7513d4616ac42cfd4c8891f4b237c7f5dfc8f1 (diff) | |
download | mongo-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.py | 1 | ||||
-rw-r--r-- | src/include/extern.h | 2 | ||||
-rw-r--r-- | src/include/flags.h | 1 | ||||
-rw-r--r-- | src/meta/meta_track.c | 25 | ||||
-rw-r--r-- | src/schema/schema_create.c | 2 | ||||
-rw-r--r-- | src/schema/schema_drop.c | 2 | ||||
-rw-r--r-- | src/schema/schema_rename.c | 2 | ||||
-rw-r--r-- | src/txn/txn_ckpt.c | 4 | ||||
-rw-r--r-- | src/txn/txn_log.c | 7 |
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); |