Mercurial > dovecot > core-2.2
changeset 17609:16d4cf2c0d65
lib-index: Don't update log_file_tail_offset unnecessarily.
Update it only if we're already writing to transaction log anyway or if
we're required to update the offset because mail_index_sync_commit() has
increased it past non-external transactions (this is especially important
with mdbox map index).
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 07 Jul 2014 16:21:08 +0300 |
parents | 6b512716b37e |
children | 320a224ad353 |
files | src/lib-index/mail-index-sync.c src/lib-index/mail-index-transaction-export.c src/lib-index/mail-index-transaction-private.h src/lib-index/mail-index-transaction-update.c src/lib-index/mail-transaction-log-append.c src/lib-index/mail-transaction-log-file.c src/lib-index/mail-transaction-log.h src/lib-index/test-mail-transaction-log-append.c |
diffstat | 8 files changed, 37 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-index-sync.c Mon Jul 07 13:24:22 2014 +0300 +++ b/src/lib-index/mail-index-sync.c Mon Jul 07 16:21:08 2014 +0300 @@ -751,9 +751,12 @@ mail_transaction_log_set_mailbox_sync_pos(ctx->index->log, seq, offset); /* If tail offset has changed, make sure it gets written to - transaction log. */ - if (ctx->last_tail_offset != offset) + transaction log. do this only if we're required to changes. */ + if (ctx->last_tail_seq != seq || + ctx->last_tail_offset < offset) { ctx->ext_trans->log_updates = TRUE; + ctx->ext_trans->tail_offset_changed = TRUE; + } } static bool mail_index_sync_want_index_write(struct mail_index *index)
--- a/src/lib-index/mail-index-transaction-export.c Mon Jul 07 13:24:22 2014 +0300 +++ b/src/lib-index/mail-index-transaction-export.c Mon Jul 07 16:21:08 2014 +0300 @@ -476,12 +476,8 @@ &null4, 4); } - /* Update the tail offsets only when committing the sync transaction. - Other transactions may not know the latest tail offset and might - end up shrinking it. (Alternatively the shrinking tail offsets could - just be ignored, which would probably work fine too.) */ - append_ctx->append_sync_offset = t->sync_transaction; - + append_ctx->index_sync_transaction = t->sync_transaction; + append_ctx->tail_offset_changed = t->tail_offset_changed; append_ctx->want_fsync = (t->view->index->fsync_mask & change_mask) != 0 || (t->flags & MAIL_INDEX_TRANSACTION_FLAG_FSYNC) != 0;
--- a/src/lib-index/mail-index-transaction-private.h Mon Jul 07 13:24:22 2014 +0300 +++ b/src/lib-index/mail-index-transaction-private.h Mon Jul 07 16:21:08 2014 +0300 @@ -93,6 +93,7 @@ unsigned int index_deleted:1; unsigned int index_undeleted:1; unsigned int commit_deleted_index:1; + unsigned int tail_offset_changed:1; /* non-extension updates. flag updates don't change this because they may be added and removed, so be sure to check that the updates array is non-empty also. */
--- a/src/lib-index/mail-index-transaction-update.c Mon Jul 07 13:24:22 2014 +0300 +++ b/src/lib-index/mail-index-transaction-update.c Mon Jul 07 16:21:08 2014 +0300 @@ -101,6 +101,7 @@ t->index_undeleted = FALSE; t->log_updates = FALSE; t->log_ext_updates = FALSE; + t->tail_offset_changed = FALSE; } void mail_index_transaction_set_log_updates(struct mail_index_transaction *t)
--- a/src/lib-index/mail-transaction-log-append.c Mon Jul 07 13:24:22 2014 +0300 +++ b/src/lib-index/mail-transaction-log-append.c Mon Jul 07 16:21:08 2014 +0300 @@ -122,9 +122,22 @@ buffer_t buf; unsigned char update_data[sizeof(*u) + sizeof(offset)]; - if (file->max_tail_offset == file->sync_offset) { - if (ctx->output->used == 0 && - file->saved_tail_offset == file->max_tail_offset) { + if (!ctx->index_sync_transaction) { + /* this is a non-syncing transaction. update the tail offset + only if we're already writing something else to transaction + log anyway. */ + i_assert(!ctx->tail_offset_changed); + /* FIXME: For now we never do this update, because it would + cause errors about shrinking tail offsets with old Dovecot + versions. This is anyway just an optimization, so it doesn't + matter all that much if we don't do it here. Finish this + in v2.3. */ + /*if (ctx->output->used == 0)*/ + return; + } else if (file->max_tail_offset == file->sync_offset) { + /* we're synced all the way to tail offset, so this sync + transaction can also be included in the same tail offset. */ + if (ctx->output->used == 0 && !ctx->tail_offset_changed) { /* nothing to write here after all (e.g. all unchanged flag updates were dropped by export) */ return; @@ -137,6 +150,10 @@ file->max_tail_offset += ctx->output->used + sizeof(*hdr) + sizeof(*u) + sizeof(offset); ctx->sync_includes_this = TRUE; + } else { + /* This is a syncing transaction. Since we're finishing a sync, + we may need to update the tail offset even if we don't have + anything else to do. */ } offset = file->max_tail_offset; @@ -189,9 +206,7 @@ buffer_delete(ctx->output, 0, boundary_size); } - if (ctx->append_sync_offset) - log_append_sync_offset_if_needed(ctx); - + log_append_sync_offset_if_needed(ctx); if (log_buffer_write(ctx) < 0) return -1; file->sync_highest_modseq = ctx->new_highest_modseq;
--- a/src/lib-index/mail-transaction-log-file.c Mon Jul 07 13:24:22 2014 +0300 +++ b/src/lib-index/mail-transaction-log-file.c Mon Jul 07 16:21:08 2014 +0300 @@ -957,20 +957,8 @@ sizeof(tail_offset)); if (tail_offset < file->saved_tail_offset) { - if (file->sync_offset < file->saved_tail_sync_offset) { - /* saved_tail_offset was already set in header, - but we still had to resync the file to find - modseqs. ignore this record. */ - return 1; - } - mail_index_set_error(file->log->index, - "Transaction log file %s seq %u: " - "log_file_tail_offset update shrank it " - "(%u vs %"PRIuUOFF_T" " - "sync_offset=%"PRIuUOFF_T")", - file->filepath, file->hdr.file_seq, - tail_offset, file->saved_tail_offset, - file->sync_offset); + /* ignore shrinking tail offsets */ + return 1; } else { file->saved_tail_offset = tail_offset; if (tail_offset > file->max_tail_offset)
--- a/src/lib-index/mail-transaction-log.h Mon Jul 07 13:24:22 2014 +0300 +++ b/src/lib-index/mail-transaction-log.h Mon Jul 07 16:21:08 2014 +0300 @@ -176,7 +176,10 @@ uint64_t new_highest_modseq; unsigned int transaction_count; - unsigned int append_sync_offset:1; + /* same as mail_index_transaction->sync_transaction */ + unsigned int index_sync_transaction:1; + /* same as mail_index_transaction->tail_offset_changed */ + unsigned int tail_offset_changed:1; unsigned int sync_includes_this:1; unsigned int want_fsync:1; };
--- a/src/lib-index/test-mail-transaction-log-append.c Mon Jul 07 13:24:22 2014 +0300 +++ b/src/lib-index/test-mail-transaction-log-append.c Mon Jul 07 16:21:08 2014 +0300 @@ -97,7 +97,7 @@ test_begin("transaction log append: append_sync_offset only"); test_assert(mail_transaction_log_append_begin(log->index, 0, &ctx) == 0); - ctx->append_sync_offset = TRUE; + ctx->index_sync_transaction = TRUE; file->max_tail_offset = 123; test_assert(mail_transaction_log_append_commit(&ctx) == 0);