From: Timo Sirainen Date: Mon, 7 Jul 2014 13:21:08 +0000 (+0300) Subject: lib-index: Don't update log_file_tail_offset unnecessarily. X-Git-Tag: 2.2.14.rc1~261 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=082e82792b8ac33ad42beac510441b37a3c50737;p=thirdparty%2Fdovecot%2Fcore.git 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). --- diff --git a/src/lib-index/mail-index-sync.c b/src/lib-index/mail-index-sync.c index b5263b6a7d..42a9b1388d 100644 --- a/src/lib-index/mail-index-sync.c +++ b/src/lib-index/mail-index-sync.c @@ -751,9 +751,12 @@ mail_index_sync_update_mailbox_offset(struct mail_index_sync_ctx *ctx) 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) diff --git a/src/lib-index/mail-index-transaction-export.c b/src/lib-index/mail-index-transaction-export.c index 2ad8565950..fd628eb316 100644 --- a/src/lib-index/mail-index-transaction-export.c +++ b/src/lib-index/mail-index-transaction-export.c @@ -476,12 +476,8 @@ void mail_index_transaction_export(struct mail_index_transaction *t, &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; diff --git a/src/lib-index/mail-index-transaction-private.h b/src/lib-index/mail-index-transaction-private.h index 421c7ff6ba..8b51e7f655 100644 --- a/src/lib-index/mail-index-transaction-private.h +++ b/src/lib-index/mail-index-transaction-private.h @@ -93,6 +93,7 @@ struct mail_index_transaction { 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. */ diff --git a/src/lib-index/mail-index-transaction-update.c b/src/lib-index/mail-index-transaction-update.c index 354829d3a4..1b14d149ef 100644 --- a/src/lib-index/mail-index-transaction-update.c +++ b/src/lib-index/mail-index-transaction-update.c @@ -101,6 +101,7 @@ void mail_index_transaction_reset_v(struct mail_index_transaction *t) 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) diff --git a/src/lib-index/mail-transaction-log-append.c b/src/lib-index/mail-transaction-log-append.c index aeb2fc53a3..20eb6b0e2d 100644 --- a/src/lib-index/mail-transaction-log-append.c +++ b/src/lib-index/mail-transaction-log-append.c @@ -122,9 +122,22 @@ log_append_sync_offset_if_needed(struct mail_transaction_log_append_ctx *ctx) 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 @@ log_append_sync_offset_if_needed(struct mail_transaction_log_append_ctx *ctx) 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 @@ mail_transaction_log_append_locked(struct mail_transaction_log_append_ctx *ctx) 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; diff --git a/src/lib-index/mail-transaction-log-file.c b/src/lib-index/mail-transaction-log-file.c index f32b735ac6..161d0665a6 100644 --- a/src/lib-index/mail-transaction-log-file.c +++ b/src/lib-index/mail-transaction-log-file.c @@ -957,20 +957,8 @@ log_file_track_mailbox_sync_offset_hdr(struct mail_transaction_log_file *file, 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) diff --git a/src/lib-index/mail-transaction-log.h b/src/lib-index/mail-transaction-log.h index 69e9b7139d..96f3fd278e 100644 --- a/src/lib-index/mail-transaction-log.h +++ b/src/lib-index/mail-transaction-log.h @@ -176,7 +176,10 @@ struct mail_transaction_log_append_ctx { 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; }; diff --git a/src/lib-index/test-mail-transaction-log-append.c b/src/lib-index/test-mail-transaction-log-append.c index 9d10d649b4..4e29a9aa83 100644 --- a/src/lib-index/test-mail-transaction-log-append.c +++ b/src/lib-index/test-mail-transaction-log-append.c @@ -97,7 +97,7 @@ static void test_append_sync_offset(struct mail_transaction_log *log) 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);