diff options
author | Susan LoVerso <sue@wiredtiger.com> | 2016-01-25 12:07:27 -0500 |
---|---|---|
committer | Susan LoVerso <sue@wiredtiger.com> | 2016-01-25 12:07:27 -0500 |
commit | 7880038b807a530b347e213e9d773960c45c6df0 (patch) | |
tree | 0d3345a768935250a7cd0d99613f8220f64697b6 /src | |
parent | d3f0af2aaa9ae0b624193ee314287f1b2490bb71 (diff) | |
download | mongo-7880038b807a530b347e213e9d773960c45c6df0.tar.gz |
WT-2215 Use 32-bit LSN file and offsets. Set LSNs as a 64-bit value.
Diffstat (limited to 'src')
-rw-r--r-- | src/conn/conn_log.c | 44 | ||||
-rw-r--r-- | src/cursor/cur_log.c | 15 | ||||
-rw-r--r-- | src/include/log.h | 52 | ||||
-rw-r--r-- | src/include/log.i | 19 | ||||
-rw-r--r-- | src/include/wiredtiger.in | 17 | ||||
-rw-r--r-- | src/include/wt_internal.h | 2 | ||||
-rw-r--r-- | src/log/log.c | 94 | ||||
-rw-r--r-- | src/log/log_slot.c | 10 | ||||
-rw-r--r-- | src/meta/meta_ckpt.c | 2 | ||||
-rw-r--r-- | src/txn/txn_log.c | 25 | ||||
-rw-r--r-- | src/txn/txn_recover.c | 19 |
11 files changed, 156 insertions, 143 deletions
diff --git a/src/conn/conn_log.c b/src/conn/conn_log.c index ed226393fb0..f088ba47a19 100644 --- a/src/conn/conn_log.c +++ b/src/conn/conn_log.c @@ -180,9 +180,10 @@ __log_archive_once(WT_SESSION_IMPL *session, uint32_t backup_file) * disk and the checkpoint LSN. */ if (backup_file != 0) - min_lognum = WT_MIN(log->ckpt_lsn.file, backup_file); + min_lognum = WT_MIN(log->ckpt_lsn.lsn_file, backup_file); else - min_lognum = WT_MIN(log->ckpt_lsn.file, log->sync_lsn.file); + min_lognum = WT_MIN( + log->ckpt_lsn.lsn_file, log->sync_lsn.lsn_file); WT_RET(__wt_verbose(session, WT_VERB_LOG, "log_archive: archive to log number %" PRIu32, min_lognum)); @@ -218,8 +219,7 @@ __log_archive_once(WT_SESSION_IMPL *session, uint32_t backup_file) * Indicate what is our new earliest LSN. It is the start * of the log file containing the last checkpoint. */ - log->first_lsn.file = min_lognum; - log->first_lsn.offset = 0; + WT_SET_LSN(&log->first_lsn, min_lognum, 0); if (0) err: __wt_err(session, ret, "log archive server error"); @@ -317,7 +317,7 @@ __wt_log_truncate_files( backup_file = 0; if (cursor != NULL) backup_file = WT_CURSOR_BACKUP_ID(cursor); - WT_ASSERT(session, backup_file <= log->alloc_lsn.file); + WT_ASSERT(session, backup_file <= log->alloc_lsn.lsn_file); WT_RET(__wt_verbose(session, WT_VERB_LOG, "log_truncate_files: Archive once up to %" PRIu32, backup_file)); @@ -367,7 +367,7 @@ __log_file_server(void *arg) * could see mismatched settings. If we do, yield * until it is set. This should rarely happen. */ - while (log->log_close_lsn.file < filenum) + while (log->log_close_lsn.lsn_file < filenum) __wt_yield(); if (__wt_log_cmp( @@ -398,10 +398,10 @@ __log_file_server(void *arg) * actual data and has minimal pre-allocated * zeroed space. */ - WT_ERR(__wt_ftruncate( - session, close_fh, close_end_lsn.offset)); - close_end_lsn.file++; - close_end_lsn.offset = 0; + WT_ERR(__wt_ftruncate(session, + close_fh, close_end_lsn.lsn_offset)); + WT_SET_LSN(&close_end_lsn, + close_end_lsn.lsn_file + 1, 0); __wt_spin_lock(session, &log->log_sync_lock); locked = true; WT_ERR(__wt_close(session, &close_fh)); @@ -440,9 +440,9 @@ __log_file_server(void *arg) * this worker thread process that older file * immediately. */ - if ((log->sync_lsn.file < - log->bg_sync_lsn.file) || - (log->sync_lsn.file < min_lsn.file)) + if ((log->sync_lsn.lsn_file < + log->bg_sync_lsn.lsn_file) || + (log->sync_lsn.lsn_file < min_lsn.lsn_file)) continue; WT_ERR(__wt_fsync(session, log->log_fh)); __wt_spin_lock(session, &log->log_sync_lock); @@ -454,7 +454,8 @@ __log_file_server(void *arg) if (__wt_log_cmp( &log->sync_lsn, &min_lsn) <= 0) { WT_ASSERT(session, - min_lsn.file == log->sync_lsn.file); + min_lsn.lsn_file == + log->sync_lsn.lsn_file); log->sync_lsn = min_lsn; WT_ERR(__wt_cond_signal( session, log->log_sync_cond)); @@ -500,9 +501,9 @@ typedef struct { * Return comparison of a written slot pair by LSN. */ #define WT_WRLSN_ENTRY_CMP_LT(entry1, entry2) \ - ((entry1).lsn.file < (entry2).lsn.file || \ - ((entry1).lsn.file == (entry2).lsn.file && \ - (entry1).lsn.offset < (entry2).lsn.offset)) + ((entry1).lsn.lsn_file < (entry2).lsn.lsn_file || \ + ((entry1).lsn.lsn_file == (entry2).lsn.lsn_file && \ + (entry1).lsn.lsn_offset < (entry2).lsn.lsn_offset)) /* * __wt_log_wrlsn -- @@ -539,7 +540,7 @@ restart: save_i = i; slot = &log->slot_pool[i++]; WT_ASSERT(session, slot->slot_state != 0 || - slot->slot_release_lsn.file >= log->write_lsn.file); + slot->slot_release_lsn.lsn_file >= log->write_lsn.lsn_file); if (slot->slot_state != WT_LOG_SLOT_WRITTEN) continue; written[written_i].slot_index = save_i; @@ -629,10 +630,11 @@ restart: * the checkpoint LSN is close to the end of * the record. */ - if (slot->slot_start_lsn.offset != + if (slot->slot_start_lsn.lsn_offset != slot->slot_last_offset) - slot->slot_start_lsn.offset = - slot->slot_last_offset; + WT_SET_LSN_OFFSET( + &slot->slot_start_lsn, + slot->slot_last_offset); log->write_start_lsn = slot->slot_start_lsn; log->write_lsn = slot->slot_end_lsn; WT_ERR(__wt_cond_signal( diff --git a/src/cursor/cur_log.c b/src/cursor/cur_log.c index 35a2d00e6ec..c5518ea5e67 100644 --- a/src/cursor/cur_log.c +++ b/src/cursor/cur_log.c @@ -187,13 +187,13 @@ __curlog_kv(WT_SESSION_IMPL *session, WT_CURSOR *cursor) if (FLD_ISSET(cursor->flags, WT_CURSTD_RAW)) { memset(&item, 0, sizeof(item)); WT_RET(wiredtiger_struct_size((WT_SESSION *)session, - &item.size, WT_LOGC_KEY_FORMAT, cl->cur_lsn->file, - cl->cur_lsn->offset, key_count)); + &item.size, WT_LOGC_KEY_FORMAT, cl->cur_lsn->lsn_file, + cl->cur_lsn->lsn_offset, key_count)); WT_RET(__wt_realloc(session, NULL, item.size, &cl->packed_key)); item.data = cl->packed_key; WT_RET(wiredtiger_struct_pack((WT_SESSION *)session, cl->packed_key, item.size, WT_LOGC_KEY_FORMAT, - cl->cur_lsn->file, cl->cur_lsn->offset, key_count)); + cl->cur_lsn->lsn_file, cl->cur_lsn->lsn_offset, key_count)); __wt_cursor_set_key(cursor, &item); WT_RET(wiredtiger_struct_size((WT_SESSION *)session, @@ -208,8 +208,8 @@ __curlog_kv(WT_SESSION_IMPL *session, WT_CURSOR *cursor) cl->opvalue)); __wt_cursor_set_value(cursor, &item); } else { - __wt_cursor_set_key(cursor, cl->cur_lsn->file, - cl->cur_lsn->offset, key_count); + __wt_cursor_set_key(cursor, cl->cur_lsn->lsn_file, + cl->cur_lsn->lsn_offset, key_count); __wt_cursor_set_value(cursor, cl->txnid, cl->rectype, optype, fileid, cl->opkey, cl->opvalue); } @@ -264,7 +264,7 @@ __curlog_search(WT_CURSOR *cursor) WT_DECL_RET; WT_LSN key; WT_SESSION_IMPL *session; - uint32_t counter; + uint32_t counter, key_file, key_offset; cl = (WT_CURSOR_LOG *)cursor; @@ -274,7 +274,8 @@ __curlog_search(WT_CURSOR *cursor) * !!! We are ignoring the counter and only searching based on the LSN. */ WT_ERR(__wt_cursor_get_key((WT_CURSOR *)cl, - &key.file, &key.offset, &counter)); + &key_file, &key_offset, &counter)); + WT_SET_LSN(&key, key_file, key_offset); ret = __wt_log_scan(session, &key, WT_LOGSCAN_ONE, __curlog_logrec, cl); if (ret == ENOENT) diff --git a/src/include/log.h b/src/include/log.h index 577f6a888a3..246c8d901ae 100644 --- a/src/include/log.h +++ b/src/include/log.h @@ -6,6 +6,27 @@ * See the file LICENSE for redistribution information. */ +/* + * WT_LSN -- + * A log sequence number, representing a position in the transaction log. + */ +struct __wt_lsn { + union { + struct { +#ifdef WORDS_BIGENDIAN + uint32_t file; + uint32_t offset; +#else + uint32_t offset; + uint32_t file; +#endif + } l; + uint64_t file_offset; + } u; +}; +#define lsn_file u.l.file +#define lsn_offset u.l.offset + #define WT_LOG_FILENAME "WiredTigerLog" /* Log file name */ #define WT_LOG_PREPNAME "WiredTigerPreplog" /* Log pre-allocated name */ #define WT_LOG_TMPNAME "WiredTigerTmplog" /* Log temporary name */ @@ -13,32 +34,43 @@ /* Logging subsystem declarations. */ #define WT_LOG_ALIGN 128 +/* + * Atomically set the two components of the LSN. + */ +#define lsn_file u.l.file +#define lsn_offset u.l.offset +#define WT_SET_LSN(l, f, o) (l)->u.file_offset = (((uint64_t)(f) << 32) + (o)) +#define WT_SET_LSN_FILE(l, f) WT_SET_LSN((l), (f), (l)->lsn_offset) +#define WT_SET_LSN_OFFSET(l, o) WT_SET_LSN((l), (l)->lsn_file, (o)) + #define WT_INIT_LSN(l) do { \ - (l)->file = 1; \ - (l)->offset = 0; \ + WT_SET_LSN((l), 1, 0); \ } while (0) #define WT_MAX_LSN(l) do { \ - (l)->file = UINT32_MAX; \ - (l)->offset = INT64_MAX; \ + WT_SET_LSN((l), UINT32_MAX, INT32_MAX); \ } while (0) #define WT_ZERO_LSN(l) do { \ - (l)->file = 0; \ - (l)->offset = 0; \ + WT_SET_LSN((l), 0, 0); \ } while (0) -#define WT_IS_INIT_LSN(l) \ - ((l)->file == 1 && (l)->offset == 0) +/* + * Initialize LSN is (1,0). We only need to shift the 1 for comparison. + */ +#define WT_IS_INIT_LSN(l) ((l)->u.file_offset == ((uint64_t)1 << 32)) +/* + * XXX Original tested INT32_MAX. + */ #define WT_IS_MAX_LSN(l) \ - ((l)->file == UINT32_MAX && (l)->offset == INT64_MAX) + ((l)->lsn_file == UINT32_MAX && (l)->lsn_offset == INT32_MAX) /* * Both of the macros below need to change if the content of __wt_lsn * ever changes. The value is the following: * txnid, record type, operation type, file id, operation key, operation value */ -#define WT_LOGC_KEY_FORMAT WT_UNCHECKED_STRING(IqI) +#define WT_LOGC_KEY_FORMAT WT_UNCHECKED_STRING(III) #define WT_LOGC_VALUE_FORMAT WT_UNCHECKED_STRING(qIIIuu) #define WT_LOG_SKIP_HEADER(data) \ diff --git a/src/include/log.i b/src/include/log.i index fcdbc72c388..993c405818e 100644 --- a/src/include/log.i +++ b/src/include/log.i @@ -16,25 +16,14 @@ static inline int __wt_log_cmp(WT_LSN *lsn1, WT_LSN *lsn2); static inline int __wt_log_cmp(WT_LSN *lsn1, WT_LSN *lsn2) { - WT_LSN l1, l2; + uint64_t l1, l2; /* * Read LSNs into local variables so that we only read each field * once and all comparisons are on the same values. */ - l1 = *(volatile WT_LSN *)lsn1; - l2 = *(volatile WT_LSN *)lsn2; + l1 = ((volatile WT_LSN *)lsn1)->u.file_offset; + l2 = ((volatile WT_LSN *)lsn2)->u.file_offset; - /* - * If the file numbers are different we don't need to compare the - * offset. - */ - if (l1.file != l2.file) - return (l1.file < l2.file ? -1 : 1); - /* - * If the file numbers are the same, compare the offset. - */ - if (l1.offset != l2.offset) - return (l1.offset < l2.offset ? -1 : 1); - return (0); + return (l1 < l2 ? -1 : (l1 > l2 ? 1 : 0)); } diff --git a/src/include/wiredtiger.in b/src/include/wiredtiger.in index 676f95d9b05..cbf628019db 100644 --- a/src/include/wiredtiger.in +++ b/src/include/wiredtiger.in @@ -72,7 +72,6 @@ struct __wt_event_handler; typedef struct __wt_event_handler WT_EVENT_HANDLER; struct __wt_extension_api; typedef struct __wt_extension_api WT_EXTENSION_API; struct __wt_extractor; typedef struct __wt_extractor WT_EXTRACTOR; struct __wt_item; typedef struct __wt_item WT_ITEM; -struct __wt_lsn; typedef struct __wt_lsn WT_LSN; struct __wt_session; typedef struct __wt_session WT_SESSION; #if defined(SWIGJAVA) @@ -126,22 +125,6 @@ struct __wt_item { #endif }; -/* - * We rely on this structure being aligned at 64 bits by the compiler, - * if we were paranoid we could add an unused field to ensure the padding - * is correct. - * - * NOTE: If you change the contents of this structure you must also update - * the macros in log.h. - */ -/*! - * A log sequence number, representing a position in the transaction log. - */ -struct __wt_lsn { - uint32_t file; /*!< Log file number */ - wt_off_t offset; /*!< Log file offset */ -}; - /*! * The maximum packed size of a 64-bit integer. The ::wiredtiger_struct_pack * function will pack single long integers into at most this many bytes. diff --git a/src/include/wt_internal.h b/src/include/wt_internal.h index 54b5dfd19f4..806a5afce0f 100644 --- a/src/include/wt_internal.h +++ b/src/include/wt_internal.h @@ -218,6 +218,8 @@ struct __wt_lsm_worker_args; typedef struct __wt_lsm_worker_args WT_LSM_WORKER_ARGS; struct __wt_lsm_worker_cookie; typedef struct __wt_lsm_worker_cookie WT_LSM_WORKER_COOKIE; +struct __wt_lsn; + typedef struct __wt_lsn WT_LSN; struct __wt_multi; typedef struct __wt_multi WT_MULTI; struct __wt_myslot; diff --git a/src/log/log.c b/src/log/log.c index 9c3269c474c..791317ce0a8 100644 --- a/src/log/log.c +++ b/src/log/log.c @@ -105,7 +105,7 @@ __wt_log_force_sync(WT_SESSION_IMPL *session, WT_LSN *min_lsn) * LSN has moved into a later log file and there should be a * log file ready to close. */ - while (log->sync_lsn.file < min_lsn->file) { + while (log->sync_lsn.lsn_file < min_lsn->lsn_file) { WT_ERR(__wt_cond_signal(session, S2C(session)->log_file_cond)); WT_ERR(__wt_cond_wait(session, log->log_sync_cond, 10000)); @@ -116,10 +116,11 @@ __wt_log_force_sync(WT_SESSION_IMPL *session, WT_LSN *min_lsn) * Sync the directory if the log file entry hasn't been written * into the directory. */ - if (log->sync_dir_lsn.file < min_lsn->file) { + if (log->sync_dir_lsn.lsn_file < min_lsn->lsn_file) { WT_ERR(__wt_verbose(session, WT_VERB_LOG, "log_force_sync: sync directory %s to LSN %d/%lu", - log->log_dir_fh->name, min_lsn->file, min_lsn->offset)); + log->log_dir_fh->name, + min_lsn->lsn_file, min_lsn->lsn_offset)); WT_ERR(__wt_directory_sync_fh(session, log->log_dir_fh)); log->sync_dir_lsn = *min_lsn; WT_STAT_FAST_CONN_INCR(session, log_sync_dir); @@ -130,7 +131,7 @@ __wt_log_force_sync(WT_SESSION_IMPL *session, WT_LSN *min_lsn) if (__wt_log_cmp(&log->sync_lsn, min_lsn) < 0) { WT_ERR(__wt_verbose(session, WT_VERB_LOG, "log_force_sync: sync %s to LSN %d/%lu", - log->log_fh->name, min_lsn->file, min_lsn->offset)); + log->log_fh->name, min_lsn->lsn_file, min_lsn->lsn_offset)); WT_ERR(__wt_fsync(session, log->log_fh)); log->sync_lsn = *min_lsn; WT_STAT_FAST_CONN_INCR(session, log_sync); @@ -174,7 +175,7 @@ __wt_log_needs_recovery(WT_SESSION_IMPL *session, WT_LSN *ckp_lsn, bool *recp) * we can skip recovery. */ WT_RET(__wt_curlog_open(session, "log:", NULL, &c)); - c->set_key(c, ckp_lsn->file, ckp_lsn->offset, 0); + c->set_key(c, ckp_lsn->lsn_file, ckp_lsn->lsn_offset, 0); if ((ret = c->search(c)) == 0) { while ((ret = c->next(c)) == 0) { /* @@ -278,7 +279,7 @@ __wt_log_get_all_files(WT_SESSION_IMPL *session, /* Filter out any files that are below the checkpoint LSN. */ for (max = 0, i = 0; i < count; ) { WT_ERR(__wt_log_extract_lognum(session, files[i], &id)); - if (active_only && id < log->ckpt_lsn.file) { + if (active_only && id < log->ckpt_lsn.lsn_file) { __wt_free(session, files[i]); files[i] = files[count - 1]; files[--count] = NULL; @@ -459,8 +460,8 @@ __log_size_fit(WT_SESSION_IMPL *session, WT_LSN *lsn, uint64_t recsize) conn = S2C(session); log = conn->log; - return (lsn->offset == WT_LOG_FIRST_RECORD || - lsn->offset + (wt_off_t)recsize < conn->log_file_max); + return (lsn->lsn_offset == WT_LOG_FIRST_RECORD || + lsn->lsn_offset + (wt_off_t)recsize < conn->log_file_max); } /* @@ -559,7 +560,8 @@ __log_fill(WT_SESSION_IMPL *session, WT_STAT_FAST_CONN_INCRV(session, log_bytes_written, logrec->len); if (lsnp != NULL) { *lsnp = myslot->slot->slot_start_lsn; - lsnp->offset += (wt_off_t)myslot->offset; + WT_SET_LSN_OFFSET(lsnp, + lsnp->lsn_offset + (uint32_t)myslot->offset); } err: if (ret != 0 && myslot->slot->slot_error == 0) @@ -830,8 +832,7 @@ __log_newfile(WT_SESSION_IMPL *session, bool conn_open, bool *created) * We need to setup the LSNs. Set the end LSN and alloc LSN to * the end of the header. */ - log->alloc_lsn.file = log->fileid; - log->alloc_lsn.offset = WT_LOG_FIRST_RECORD; + WT_SET_LSN(&log->alloc_lsn, log->fileid, WT_LOG_FIRST_RECORD); end_lsn = log->alloc_lsn; /* @@ -891,7 +892,7 @@ __wt_log_acquire(WT_SESSION_IMPL *session, uint64_t recsize, WT_LOGSLOT *slot) * Pre-allocate on the first real write into the log file, if it * was just created (i.e. not pre-allocated). */ - if (log->alloc_lsn.offset == WT_LOG_FIRST_RECORD && created_log) + if (log->alloc_lsn.lsn_offset == WT_LOG_FIRST_RECORD && created_log) WT_RET(__log_prealloc(session, log->log_fh)); /* * Initialize the slot for activation. @@ -932,8 +933,9 @@ __log_truncate(WT_SESSION_IMPL *session, /* * Truncate the log file to the given LSN. */ - WT_ERR(__log_openfile(session, false, &log_fh, file_prefix, lsn->file)); - WT_ERR(__wt_ftruncate(session, log_fh, lsn->offset)); + WT_ERR(__log_openfile(session, + false, &log_fh, file_prefix, lsn->lsn_file)); + WT_ERR(__wt_ftruncate(session, log_fh, lsn->lsn_offset)); WT_ERR(__wt_fsync(session, log_fh)); WT_ERR(__wt_close(session, &log_fh)); @@ -947,7 +949,8 @@ __log_truncate(WT_SESSION_IMPL *session, WT_LOG_FILENAME, &logfiles, &logcount)); for (i = 0; i < logcount; i++) { WT_ERR(__wt_log_extract_lognum(session, logfiles[i], &lognum)); - if (lognum > lsn->file && lognum < log->trunc_lsn.file) { + if (lognum > lsn->lsn_file && + lognum < log->trunc_lsn.lsn_file) { WT_ERR(__log_openfile(session, false, &log_fh, file_prefix, lognum)); /* @@ -1112,10 +1115,8 @@ __wt_log_open(WT_SESSION_IMPL *session) if (firstlog == UINT32_MAX) { WT_ASSERT(session, logcount == 0); WT_INIT_LSN(&log->first_lsn); - } else { - log->first_lsn.file = firstlog; - log->first_lsn.offset = 0; - } + } else + WT_SET_LSN(&log->first_lsn, firstlog, 0); /* * Start logging at the beginning of the next log file, no matter @@ -1347,7 +1348,7 @@ __wt_log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot, bool *freep) * sync operations. The most recent one will set the LSN to the * beginning of our file. */ - if (log->sync_lsn.file < slot->slot_end_lsn.file || + if (log->sync_lsn.lsn_file < slot->slot_end_lsn.lsn_file || __wt_spin_trylock(session, &log->log_sync_lock) != 0) { WT_ERR(__wt_cond_wait( session, log->log_sync_cond, 10000)); @@ -1367,12 +1368,12 @@ __wt_log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot, bool *freep) * now if needed. */ if (F_ISSET(slot, WT_SLOT_SYNC_DIR) && - (log->sync_dir_lsn.file < sync_lsn.file)) { + (log->sync_dir_lsn.lsn_file < sync_lsn.lsn_file)) { WT_ASSERT(session, log->log_dir_fh != NULL); WT_ERR(__wt_verbose(session, WT_VERB_LOG, - "log_release: sync directory %s to LSN %d/%lu", + "log_release: sync directory %s to LSN %u/%lu", log->log_dir_fh->name, - sync_lsn.file, sync_lsn.offset)); + sync_lsn.lsn_file, sync_lsn.lsn_offset)); WT_ERR(__wt_directory_sync_fh( session, log->log_dir_fh)); log->sync_dir_lsn = sync_lsn; @@ -1385,8 +1386,9 @@ __wt_log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot, bool *freep) if (F_ISSET(slot, WT_SLOT_SYNC) && __wt_log_cmp(&log->sync_lsn, &slot->slot_end_lsn) < 0) { WT_ERR(__wt_verbose(session, WT_VERB_LOG, - "log_release: sync log %s to LSN %d/%lu", - log->log_fh->name, sync_lsn.file, sync_lsn.offset)); + "log_release: sync log %s to LSN %u/%lu", + log->log_fh->name, + sync_lsn.lsn_file, sync_lsn.lsn_offset)); WT_STAT_FAST_CONN_INCR(session, log_sync); WT_ERR(__wt_fsync(session, log->log_fh)); log->sync_lsn = sync_lsn; @@ -1450,8 +1452,8 @@ __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags, if (LF_ISSET(WT_LOGSCAN_RECOVER)) WT_RET(__wt_verbose(session, WT_VERB_LOG, - "__wt_log_scan truncating to %u/%" PRIuMAX, - log->trunc_lsn.file, (uintmax_t)log->trunc_lsn.offset)); + "__wt_log_scan truncating to %u/%u", + log->trunc_lsn.lsn_file, log->trunc_lsn.lsn_offset)); if (log != NULL) { allocsize = log->allocsize; @@ -1469,8 +1471,8 @@ __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags, "choose either a start LSN or a start flag"); /* Offsets must be on allocation boundaries. */ - if (lsnp->offset % allocsize != 0 || - lsnp->file > log->fileid) + if (lsnp->lsn_offset % allocsize != 0 || + lsnp->lsn_file > log->fileid) return (WT_NOTFOUND); /* @@ -1510,14 +1512,13 @@ __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags, lastlog = WT_MAX(lastlog, lognum); firstlog = WT_MIN(firstlog, lognum); } - start_lsn.file = firstlog; - end_lsn.file = lastlog; - start_lsn.offset = end_lsn.offset = 0; + WT_SET_LSN(&start_lsn, firstlog, 0); + WT_SET_LSN(&end_lsn, lastlog, 0); __wt_log_files_free(session, logfiles, logcount); logfiles = NULL; } WT_ERR(__log_openfile( - session, false, &log_fh, WT_LOG_FILENAME, start_lsn.file)); + session, false, &log_fh, WT_LOG_FILENAME, start_lsn.lsn_file)); WT_ERR(__wt_filesize(session, log_fh, &log_size)); rd_lsn = start_lsn; @@ -1525,7 +1526,7 @@ __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags, WT_ERR(__wt_scr_alloc(session, 0, &decryptitem)); WT_ERR(__wt_scr_alloc(session, 0, &uncitem)); for (;;) { - if (rd_lsn.offset + allocsize > log_size) { + if (rd_lsn.lsn_offset + allocsize > log_size) { advance: /* * If we read the last record, go to the next file. @@ -1539,16 +1540,15 @@ advance: if (LF_ISSET(WT_LOGSCAN_RECOVER)) WT_ERR(__log_truncate(session, &rd_lsn, WT_LOG_FILENAME, 1)); - rd_lsn.file++; - rd_lsn.offset = 0; + WT_SET_LSN(&rd_lsn, rd_lsn.lsn_file + 1, 0); /* * Avoid an error message when we reach end of log * by checking here. */ - if (rd_lsn.file > end_lsn.file) + if (rd_lsn.lsn_file > end_lsn.lsn_file) break; WT_ERR(__log_openfile(session, - false, &log_fh, WT_LOG_FILENAME, rd_lsn.file)); + false, &log_fh, WT_LOG_FILENAME, rd_lsn.lsn_file)); WT_ERR(__wt_filesize(session, log_fh, &log_size)); eol = false; continue; @@ -1558,7 +1558,7 @@ advance: */ WT_ASSERT(session, buf->memsize >= allocsize); WT_ERR(__wt_read(session, - log_fh, rd_lsn.offset, (size_t)allocsize, buf->mem)); + log_fh, rd_lsn.lsn_offset, (size_t)allocsize, buf->mem)); /* * First 4 bytes is the real record length. See if we * need to read more than the allocation size. We expect @@ -1579,7 +1579,7 @@ advance: */ if (reclen == 0) { WT_ERR(__log_has_hole( - session, log_fh, rd_lsn.offset, &eol)); + session, log_fh, rd_lsn.lsn_offset, &eol)); if (eol) /* Found a hole. This LSN is the end. */ break; @@ -1593,15 +1593,15 @@ advance: * The log file end could be the middle of this * log record. */ - if (rd_lsn.offset + rdup_len > log_size) + if (rd_lsn.lsn_offset + rdup_len > log_size) goto advance; /* * We need to round up and read in the full padded * record, especially for direct I/O. */ WT_ERR(__wt_buf_grow(session, buf, rdup_len)); - WT_ERR(__wt_read(session, - log_fh, rd_lsn.offset, (size_t)rdup_len, buf->mem)); + WT_ERR(__wt_read(session, log_fh, + rd_lsn.lsn_offset, (size_t)rdup_len, buf->mem)); WT_STAT_FAST_CONN_INCR(session, log_scan_rereads); } /* @@ -1637,8 +1637,9 @@ advance: */ WT_STAT_FAST_CONN_INCR(session, log_scan_records); next_lsn = rd_lsn; - next_lsn.offset += (wt_off_t)rdup_len; - if (rd_lsn.offset != 0) { + WT_SET_LSN_OFFSET(&next_lsn, + next_lsn.lsn_offset + rdup_len); + if (rd_lsn.lsn_offset != 0) { /* * We need to manage the different buffers here. * Buf is the buffer this function uses to read from @@ -2062,7 +2063,8 @@ __wt_log_flush(WT_SESSION_IMPL *session, uint32_t flags) WT_RET(__wt_log_flush_lsn(session, &lsn, false)); WT_RET(__wt_verbose(session, WT_VERB_LOG, - "log_flush: flags %d LSN %d/%lu", flags, lsn.file, lsn.offset)); + "log_flush: flags %d LSN %u/%lu", + flags, lsn.lsn_file, lsn.lsn_offset)); /* * If the user wants write-no-sync, there is nothing more to do. * If the user wants background sync, set the LSN and we're done. diff --git a/src/log/log_slot.c b/src/log/log_slot.c index 760e8888de6..97ff2c9b626 100644 --- a/src/log/log_slot.c +++ b/src/log/log_slot.c @@ -31,8 +31,8 @@ __wt_log_slot_activate(WT_SESSION_IMPL *session, WT_LOGSLOT *slot) * are reset when the slot is freed. See log_slot_free. */ slot->slot_start_lsn = slot->slot_end_lsn = log->alloc_lsn; - slot->slot_start_offset = log->alloc_lsn.offset; - slot->slot_last_offset = log->alloc_lsn.offset; + slot->slot_start_offset = log->alloc_lsn.lsn_offset; + slot->slot_last_offset = log->alloc_lsn.lsn_offset; slot->slot_fh = log->log_fh; slot->slot_error = 0; slot->slot_unbuffered = 0; @@ -96,14 +96,16 @@ retry: slot->slot_end_lsn = slot->slot_start_lsn; end_offset = WT_LOG_SLOT_JOINED_BUFFERED(old_state) + slot->slot_unbuffered; - slot->slot_end_lsn.offset += (wt_off_t)end_offset; + WT_SET_LSN_OFFSET(&slot->slot_end_lsn, + slot->slot_end_lsn.lsn_offset + end_offset); WT_STAT_FAST_CONN_INCRV(session, log_slot_consolidated, end_offset); /* * XXX Would like to change so one piece of code advances the LSN. */ log->alloc_lsn = slot->slot_end_lsn; - WT_ASSERT(session, log->alloc_lsn.file >= log->write_lsn.file); + WT_ASSERT(session, + log->alloc_lsn.lsn_file >= log->write_lsn.lsn_file); return (0); } diff --git a/src/meta/meta_ckpt.c b/src/meta/meta_ckpt.c index f7da8525639..0bc71c33f66 100644 --- a/src/meta/meta_ckpt.c +++ b/src/meta/meta_ckpt.c @@ -451,7 +451,7 @@ __wt_meta_ckptlist_set(WT_SESSION_IMPL *session, if (ckptlsn != NULL) WT_ERR(__wt_buf_catfmt(session, buf, ",checkpoint_lsn=(%" PRIu32 ",%" PRIuMAX ")", - ckptlsn->file, (uintmax_t)ckptlsn->offset)); + ckptlsn->lsn_file, (uintmax_t)ckptlsn->lsn_offset)); WT_ERR(__ckpt_set(session, fname, buf->mem)); err: __wt_scr_free(session, &buf); diff --git a/src/txn/txn_log.c b/src/txn/txn_log.c index 4c4a7fb3132..8ffacb459ab 100644 --- a/src/txn/txn_log.c +++ b/src/txn/txn_log.c @@ -266,14 +266,16 @@ __wt_txn_checkpoint_logread( WT_LSN *ckpt_lsn) { WT_ITEM ckpt_snapshot; + uint32_t ckpt_file, ckpt_offset; u_int ckpt_nsnapshot; - const char *fmt = WT_UNCHECKED_STRING(IQIU); + const char *fmt = WT_UNCHECKED_STRING(IIIU); WT_RET(__wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt, - &ckpt_lsn->file, &ckpt_lsn->offset, + &ckpt_file, &ckpt_offset, &ckpt_nsnapshot, &ckpt_snapshot)); WT_UNUSED(ckpt_nsnapshot); WT_UNUSED(ckpt_snapshot); + WT_SET_LSN(ckpt_lsn, ckpt_file, ckpt_offset); *pp = end; return (0); } @@ -294,7 +296,7 @@ __wt_txn_checkpoint_log( uint8_t *end, *p; size_t recsize; uint32_t i, rectype = WT_LOGREC_CHECKPOINT; - const char *fmt = WT_UNCHECKED_STRING(IIQIU); + const char *fmt = WT_UNCHECKED_STRING(IIIIU); txn = &session->txn; ckpt_lsn = &txn->ckpt_lsn; @@ -350,13 +352,13 @@ __wt_txn_checkpoint_log( /* Write the checkpoint log record. */ WT_ERR(__wt_struct_size(session, &recsize, fmt, - rectype, ckpt_lsn->file, ckpt_lsn->offset, + rectype, ckpt_lsn->lsn_file, ckpt_lsn->lsn_offset, txn->ckpt_nsnapshot, ckpt_snapshot)); WT_ERR(__wt_logrec_alloc(session, recsize, &logrec)); WT_ERR(__wt_struct_pack(session, (uint8_t *)logrec->data + logrec->size, recsize, fmt, - rectype, ckpt_lsn->file, ckpt_lsn->offset, + rectype, ckpt_lsn->lsn_file, ckpt_lsn->lsn_offset, txn->ckpt_nsnapshot, ckpt_snapshot)); logrec->size += (uint32_t)recsize; WT_ERR(__wt_log_write(session, logrec, lsnp, @@ -465,12 +467,11 @@ __txn_printlog(WT_SESSION_IMPL *session, { FILE *out; WT_LOG_RECORD *logrec; - WT_LSN ckpt_lsn; WT_TXN_PRINTLOG_ARGS *args; const uint8_t *end, *p; const char *msg; uint64_t txnid; - uint32_t fileid, rectype; + uint32_t fileid, lsnfile, lsnoffset, rectype; int32_t start; bool compressed; @@ -490,8 +491,8 @@ __txn_printlog(WT_SESSION_IMPL *session, WT_RET(__wt_fprintf(out, ",\n")); WT_RET(__wt_fprintf(out, - " { \"lsn\" : [%" PRIu32 ",%" PRId64 "],\n", - lsnp->file, lsnp->offset)); + " { \"lsn\" : [%" PRIu32 ",%" PRIu32 "],\n", + lsnp->lsn_file, lsnp->lsn_offset)); WT_RET(__wt_fprintf(out, " \"hdr_flags\" : \"%s\",\n", compressed ? "compressed" : "")); WT_RET(__wt_fprintf(out, @@ -503,11 +504,11 @@ __txn_printlog(WT_SESSION_IMPL *session, switch (rectype) { case WT_LOGREC_CHECKPOINT: WT_RET(__wt_struct_unpack(session, p, WT_PTRDIFF(end, p), - WT_UNCHECKED_STRING(IQ), &ckpt_lsn.file, &ckpt_lsn.offset)); + WT_UNCHECKED_STRING(II), &lsnfile, &lsnoffset)); WT_RET(__wt_fprintf(out, " \"type\" : \"checkpoint\",\n")); WT_RET(__wt_fprintf(out, - " \"ckpt_lsn\" : [%" PRIu32 ",%" PRId64 "]\n", - ckpt_lsn.file, ckpt_lsn.offset)); + " \"ckpt_lsn\" : [%" PRIu32 ",%" PRIu32 "]\n", + lsnfile, lsnoffset)); break; case WT_LOGREC_COMMIT: diff --git a/src/txn/txn_recover.c b/src/txn/txn_recover.c index 8051d059d7e..5b9bda91a0c 100644 --- a/src/txn/txn_recover.c +++ b/src/txn/txn_recover.c @@ -91,9 +91,9 @@ __recovery_cursor(WT_SESSION_IMPL *session, WT_RECOVERY *r, WT_ERR(__recovery_cursor( \ (session), (r), (lsnp), (fileid), false, (cp))); \ WT_ERR(__wt_verbose((session), WT_VERB_RECOVERY, \ - "%s op %d to file %d at LSN %u/%" PRIuMAX, \ + "%s op %d to file %d at LSN %u/%u", \ (cursor == NULL) ? "Skipping" : "Applying", \ - optype, fileid, lsnp->file, (uintmax_t)lsnp->offset)); \ + optype, fileid, lsnp->lsn_file, lsnp->lsn_offset)); \ if (cursor == NULL) \ break @@ -303,8 +303,7 @@ __recovery_setup_file(WT_RECOVERY *r, const char *uri, const char *config) { WT_CONFIG_ITEM cval; WT_LSN lsn; - intmax_t offset; - uint32_t fileid; + uint32_t fileid, lsnfile, lsnoffset; WT_RET(__wt_config_getones(r->session, config, "id", &cval)); fileid = (uint32_t)cval.val; @@ -326,8 +325,8 @@ __recovery_setup_file(WT_RECOVERY *r, const char *uri, const char *config) if (cval.type != WT_CONFIG_ITEM_STRUCT) WT_INIT_LSN(&lsn); else if (sscanf(cval.str, - "(%" SCNu32 ",%" SCNdMAX ")", &lsn.file, &offset) == 2) - lsn.offset = offset; + "(%" SCNu32 ",%" SCNu32 ")", &lsnfile, &lsnoffset) == 2) + WT_SET_LSN(&lsn, lsnfile, lsnoffset); else WT_RET_MSG(r->session, EINVAL, "Failed to parse checkpoint LSN '%.*s'", @@ -335,8 +334,8 @@ __recovery_setup_file(WT_RECOVERY *r, const char *uri, const char *config) r->files[fileid].ckpt_lsn = lsn; WT_RET(__wt_verbose(r->session, WT_VERB_RECOVERY, - "Recovering %s with id %u @ (%" PRIu32 ", %" PRIu64 ")", - uri, fileid, lsn.file, lsn.offset)); + "Recovering %s with id %u @ (%" PRIu32 ", %" PRIu32 ")", + uri, fileid, lsn.lsn_file, lsn.lsn_offset)); return (0); @@ -485,8 +484,8 @@ __wt_txn_recover(WT_SESSION_IMPL *session) */ r.metadata_only = false; WT_ERR(__wt_verbose(session, WT_VERB_RECOVERY, - "Main recovery loop: starting at %u/%" PRIuMAX, - r.ckpt_lsn.file, (uintmax_t)r.ckpt_lsn.offset)); + "Main recovery loop: starting at %u/%u", + r.ckpt_lsn.lsn_file, r.ckpt_lsn.lsn_offset)); WT_ERR(__wt_log_needs_recovery(session, &r.ckpt_lsn, &needs_rec)); /* * Check if the database was shut down cleanly. If not |