diff --git a/src/box/recovery.cc b/src/box/recovery.cc index 65e75414f615b5ac879d6cfcb27ef0ca35f8be21..25aefd6474e107fc831b80d14b334e8b938861b3 100644 --- a/src/box/recovery.cc +++ b/src/box/recovery.cc @@ -246,40 +246,29 @@ void recover_remaining_wals(struct recovery *r, struct xstream *stream, struct vclock *stop_vclock) { + struct vclock *clock; + int64_t old_signature, new_signature; + + if (r->cursor.state != XLOG_CURSOR_CLOSED) { + /* If there's a WAL open, recover from it first. */ + assert(r->cursor.state != XLOG_CURSOR_EOF); + clock = vclockset_match(&r->wal_dir.index, &r->vclock); + goto recover_current_wal; + } + /* - * Sic: it could be tempting to put xdir_scan() inside - * this function. This would slow down relay quite a bit, - * since xdir_scan() would be invoked on every relay - * row. + * There is no current WAL or we reached the end of one. + * Look for new WALs. */ - struct vclock *last = vclockset_last(&r->wal_dir.index); - if (last == NULL) { - if (r->cursor.state != XLOG_CURSOR_CLOSED) { - say_error("file `%s' was deleted under our feet", - r->cursor.name); - recovery_close_log(r); - } - /** Nothing to do. */ + clock = vclockset_last(&r->wal_dir.index); + old_signature = clock != NULL ? vclock_sum(clock) : -1; + xdir_scan_xc(&r->wal_dir); + clock = vclockset_last(&r->wal_dir.index); + new_signature = clock != NULL ? vclock_sum(clock) : -1; + if (new_signature <= old_signature) { + /* No new WAL appeared, nothing to do. */ return; } - assert(vclockset_next(&r->wal_dir.index, last) == NULL); - - /* If the caller already opened WAL for us, recover from it first */ - struct vclock *clock; - if (r->cursor.state != XLOG_CURSOR_CLOSED) { - clock = vclockset_match(&r->wal_dir.index, - &r->cursor.meta.vclock); - if (clock != NULL && - vclock_compare(clock, &r->cursor.meta.vclock) == 0) - goto recover_current_wal; - /* - * The current WAL has disappeared under our feet - - * assume anything can happen in production and go - * on. - */ - say_error("file `%s' was deleted under our feet", - r->cursor.name); - } for (clock = vclockset_match(&r->wal_dir.index, &r->vclock); clock != NULL; @@ -311,16 +300,12 @@ recover_remaining_wals(struct recovery *r, struct xstream *stream, say_info("recover from `%s'", r->cursor.name); recover_current_wal: - if (r->cursor.state != XLOG_CURSOR_EOF) - recover_xlog(r, stream, stop_vclock); - /** - * Keep the last log open to remember recovery - * position. This speeds up recovery in local hot - * standby mode, since we don't have to re-open - * and re-scan the last log in recovery_finalize(). - */ + recover_xlog(r, stream, stop_vclock); } + if (r->cursor.state == XLOG_CURSOR_EOF) + recovery_close_log(r); + if (stop_vclock != NULL && vclock_compare(&r->vclock, stop_vclock) != 0) tnt_raise(XlogGapError, &r->vclock, stop_vclock); @@ -332,7 +317,6 @@ recovery_finalize(struct recovery *r, struct xstream *stream) { recovery_stop_local(r); - xdir_scan_xc(&r->wal_dir); recover_remaining_wals(r, stream, NULL); recovery_close_log(r); @@ -489,29 +473,18 @@ recovery_follow_f(va_list ap) */ int64_t start, end; do { - start = r->cursor.state != XLOG_CURSOR_CLOSED ? - vclock_sum(&r->cursor.meta.vclock) : 0; - /* - * If there is no current WAL, or we reached - * an end of one, look for new WALs. - */ - if (r->cursor.state == XLOG_CURSOR_CLOSED - || r->cursor.state == XLOG_CURSOR_EOF) - xdir_scan_xc(&r->wal_dir); + start = vclock_sum(&r->vclock); recover_remaining_wals(r, stream, NULL); - end = r->cursor.state != XLOG_CURSOR_CLOSED ? - vclock_sum(&r->cursor.meta.vclock) : 0; + end = vclock_sum(&r->vclock); /* * Continue, given there's been progress *and* there is a * chance new WALs have appeared since. * Sic: end * is < start (is 0) if someone deleted all logs * on the filesystem. */ - } while (end > start && - (r->cursor.state == XLOG_CURSOR_CLOSED || - r->cursor.state == XLOG_CURSOR_EOF)); + } while (end > start && r->cursor.state == XLOG_CURSOR_CLOSED); subscription.set_log_path(r->cursor.state != XLOG_CURSOR_CLOSED ? r->cursor.name: NULL); @@ -539,7 +512,6 @@ recovery_follow_local(struct recovery *r, struct xstream *stream, * Scan wal_dir and recover all existing at the moment xlogs. * Blocks until finished. */ - xdir_scan_xc(&r->wal_dir); recover_remaining_wals(r, stream, NULL); /* * Start 'hot_standby' background fiber to follow xlog changes. diff --git a/src/box/relay.cc b/src/box/relay.cc index ee82b80a0d8a74982b6026dae289c2df5201898b..d6acc993fe470de95bf54754d4d112ac8a6f4beb 100644 --- a/src/box/relay.cc +++ b/src/box/relay.cc @@ -183,7 +183,6 @@ relay_final_join_f(va_list ap) /* Send all WALs until stop_vclock */ assert(relay->stream.write != NULL); - xdir_scan_xc(&relay->r->wal_dir); recover_remaining_wals(relay->r, &relay->stream, &relay->stop_vclock); assert(vclock_compare(&relay->r->vclock, &relay->stop_vclock) == 0); return 0;