]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dsync: If incremental sync fails because of desync, log the reason why
authorTimo Sirainen <tss@iki.fi>
Mon, 12 May 2014 10:21:28 +0000 (13:21 +0300)
committerTimo Sirainen <tss@iki.fi>
Mon, 12 May 2014 10:21:28 +0000 (13:21 +0300)
src/doveadm/dsync/dsync-brain-mailbox.c
src/doveadm/dsync/dsync-transaction-log-scan.c
src/doveadm/dsync/dsync-transaction-log-scan.h

index 4055721a613e5ccb8c185bc148ad488a407dd83e..79d592e105b051c39a6882d6716313292b0c589c 100644 (file)
@@ -230,6 +230,8 @@ int dsync_brain_sync_mailbox_open(struct dsync_brain *brain,
        enum dsync_mailbox_exporter_flags exporter_flags = 0;
        uint32_t last_common_uid, highest_wanted_uid;
        uint64_t last_common_modseq, last_common_pvt_modseq;
+       const char *desync_reason = "";
+       bool pvt_too_old;
        int ret;
 
        i_assert(brain->log_scan == NULL);
@@ -245,31 +247,52 @@ int dsync_brain_sync_mailbox_open(struct dsync_brain *brain,
                                              highest_wanted_uid,
                                              last_common_modseq,
                                              last_common_pvt_modseq,
-                                             &brain->log_scan);
+                                             &brain->log_scan, &pvt_too_old);
        if (ret < 0) {
                i_error("Failed to read transaction log for mailbox %s",
                        mailbox_get_vname(brain->box));
                brain->failed = TRUE;
                return -1;
        }
+       if (ret == 0) {
+               if (pvt_too_old) {
+                       desync_reason = t_strdup_printf(
+                               "Private modseq %llu no longer in transaction log",
+                               (unsigned long long)last_common_pvt_modseq);
+               } else {
+                       desync_reason = t_strdup_printf(
+                               "Modseq %llu no longer in transaction log",
+                               (unsigned long long)last_common_modseq);
+               }
+       }
 
        if (last_common_uid != 0) {
                mailbox_get_open_status(brain->box, STATUS_UIDNEXT |
                                        STATUS_HIGHESTMODSEQ |
                                        STATUS_HIGHESTPVTMODSEQ, &status);
-               if (status.uidnext < last_common_uid ||
-                   status.highest_modseq < last_common_modseq ||
-                   status.highest_pvt_modseq < last_common_pvt_modseq) {
-                       /* last_common_* is higher than our current ones.
-                          incremental sync state is stale, we need to do
-                          a full resync */
+               /* if last_common_* is higher than our current ones it means
+                  that the incremental sync state is stale and we need to do
+                  a full resync */
+               if (status.uidnext < last_common_uid) {
+                       desync_reason = t_strdup_printf("uidnext %u < %u",
+                               status.uidnext, last_common_uid);
+                       ret = 0;
+               } else if (status.highest_modseq < last_common_modseq) {
+                       desync_reason = t_strdup_printf("highest_modseq %llu < %llu",
+                               (unsigned long long)status.highest_modseq,
+                               (unsigned long long)last_common_modseq);
+                       ret = 0;
+               } else if (status.highest_pvt_modseq < last_common_pvt_modseq) {
+                       desync_reason = t_strdup_printf("highest_pvt_modseq %llu < %llu",
+                               (unsigned long long)status.highest_pvt_modseq,
+                               (unsigned long long)last_common_pvt_modseq);
                        ret = 0;
                }
        }
        if (ret == 0) {
                i_warning("Failed to do incremental sync for mailbox %s, "
-                         "retry with a full sync",
-                         mailbox_get_vname(brain->box));
+                         "retry with a full sync (%s)",
+                         mailbox_get_vname(brain->box), desync_reason);
                brain->changes_during_sync = TRUE;
                brain->require_full_resync = TRUE;
                return 0;
index bf766afd1d5c1b911279504400b4033c793de77a..cf9d8dacdb5721879062106d5591e0e7431912a7 100644 (file)
@@ -506,12 +506,15 @@ int dsync_transaction_log_scan_init(struct mail_index_view *view,
                                    struct mail_index_view *pvt_view,
                                    uint32_t highest_wanted_uid,
                                    uint64_t modseq, uint64_t pvt_modseq,
-                                   struct dsync_transaction_log_scan **scan_r)
+                                   struct dsync_transaction_log_scan **scan_r,
+                                   bool *pvt_too_old_r)
 {
        struct dsync_transaction_log_scan *ctx;
        pool_t pool;
        int ret, ret2;
 
+       *pvt_too_old_r = FALSE;
+
        pool = pool_alloconly_create(MEMPOOL_GROWING"dsync transaction log scan",
                                     10240);
        ctx = p_new(pool, struct dsync_transaction_log_scan, 1);
@@ -528,8 +531,10 @@ int dsync_transaction_log_scan_init(struct mail_index_view *view,
        if (pvt_view != NULL) {
                if ((ret2 = dsync_log_scan(ctx, pvt_view, pvt_modseq, TRUE)) < 0)
                        return -1;
-               if (ret2 == 0)
+               if (ret2 == 0) {
                        ret = 0;
+                       *pvt_too_old_r = TRUE;
+               }
        }
 
        *scan_r = ctx;
index ed75d0b2e69b802af124fb77504692af51eaac81..458b7751944115be72cf77f6305c1355744ce2e2 100644 (file)
@@ -14,7 +14,8 @@ int dsync_transaction_log_scan_init(struct mail_index_view *view,
                                    struct mail_index_view *pvt_view,
                                    uint32_t highest_wanted_uid,
                                    uint64_t modseq, uint64_t pvt_modseq,
-                                   struct dsync_transaction_log_scan **scan_r);
+                                   struct dsync_transaction_log_scan **scan_r,
+                                   bool *pvt_too_old_r);
 HASH_TABLE_TYPE(dsync_uid_mail_change)
 dsync_transaction_log_scan_get_hash(struct dsync_transaction_log_scan *scan);
 HASH_TABLE_TYPE(dsync_attr_change)