From: Serge Petrenko via Tarantool-patches <tarantool-patches@dev.tarantool.org> To: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>, gorcunov@gmail.com Cc: tarantool-patches@dev.tarantool.org Subject: Re: [Tarantool-patches] [PATCH v2] recovery: make it yield when positioning in a WAL Date: Thu, 13 May 2021 13:11:41 +0300 [thread overview] Message-ID: <d5e3c1dd-ad28-c117-843e-95e4f053d4f2@tarantool.org> (raw) In-Reply-To: <b85edc01-7977-ed22-0359-f6caea3aa959@tarantool.org> 12.05.2021 23:36, Vladislav Shpilevoy пишет: > Hi! Thanks for the patch! > > See 4 comments below. > > On 12.05.2021 13:29, Serge Petrenko wrote: Thanks for the review! >> We had various places in box.cc and relay.cc which counted processed >> rows and yielded every now and then. These yields didn't cover cases, >> when recovery has to position inside a long WAL file: >> >> For example, when tarantool exits without leaving an empty WAL file >> which'll be used to recover instance vclock on restart. In this case >> the instance freezes while processing the last availabe WAL in order > 1. availabe -> available. Fixed. > >> diff --git a/changelogs/unreleased/gh-5979-recovery-ligs.md b/changelogs/unreleased/gh-5979-recovery-ligs.md >> new file mode 100644 >> index 000000000..86abfd66a >> --- /dev/null >> +++ b/changelogs/unreleased/gh-5979-recovery-ligs.md >> @@ -0,0 +1,11 @@ >> +# bugfix/core >> + >> +* Now tarantool yields when scanning `.xlog` files for the latest applied vclock >> + and when finding the right place in `.xlog`s to start recovering. This means >> + that the instance is responsive right after `box.cfg` call even when an empty >> + `.xlog` was not created on previous exit. >> + Also this prevents relay from timing out when a freshly subscribed replica >> + needs rows from the end of a relatively long (hundreds of MBs) `.xlog` >> + (gh-5979). > 2. Maybe an empty line here? Could simplify reading a bit. Ok. Just noticed, the file had a strange name, so changed it as well. > >> +* The counter in `x.yM rows processed` log messages does not reset on each new >> + recovered `xlog` anymore. >> diff --git a/src/box/box.cc b/src/box/box.cc >> index 59925962d..8a7b8593d 100644 >> --- a/src/box/box.cc >> +++ b/src/box/box.cc >> @@ -610,15 +597,28 @@ end_error: >> diag_raise(); >> } >> >> +static struct wal_stream wal_stream; >> + >> +/** >> + * Plan a yield in recovery stream. Wal stream will execute it as soon as it's >> + * ready. >> + */ >> +static void >> +wal_stream_schedule_yield(void) > 3. Since now you have an object owning the callback, you > could pass it as a first argument, like 'this' in C++, > and like apply_row() does. Then you wouldn't need the > global wal_stream. Indeed. Fixed. > >> +{ >> + wal_stream.has_yield = true; >> + wal_stream_try_yield(&wal_stream); >> +} >> diff --git a/src/box/xstream.h b/src/box/xstream.h >> index d29ff4213..d27de09a3 100644 >> --- a/src/box/xstream.h >> +++ b/src/box/xstream.h >> @@ -41,16 +41,40 @@ extern "C" { >> struct xrow_header; >> struct xstream; >> >> +/** >> + * A type for a callback invoked by recovery after some batch of rows is >> + * processed. Is used mostly to unblock the event loop every now and then. >> + */ >> +typedef void (*schedule_yield_f)(void); > 4. How about moving closer to the consistency and calling it > xstream_yield_f/xstream_schedule_yield_f? So it has xstream_ prefix > like xstream_write_f does. I thought of xstream_schedule_yield_f, but that's too long. Let it be xstream_yield_f. Here's the incremental diff: ========================================== diff --git a/changelogs/unreleased/gh-5979-recovery-ligs.md b/changelogs/unreleased/gh-5979-recovery-yield.md similarity index 99% rename from changelogs/unreleased/gh-5979-recovery-ligs.md rename to changelogs/unreleased/gh-5979-recovery-yield.md index 86abfd66a..71bec5669 100644 --- a/changelogs/unreleased/gh-5979-recovery-ligs.md +++ b/changelogs/unreleased/gh-5979-recovery-yield.md @@ -7,5 +7,6 @@ Also this prevents relay from timing out when a freshly subscribed replica needs rows from the end of a relatively long (hundreds of MBs) `.xlog` (gh-5979). + * The counter in `x.yM rows processed` log messages does not reset on each new recovered `xlog` anymore. diff --git a/src/box/box.cc b/src/box/box.cc index 8a7b8593d..c10e0d8bf 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -597,17 +597,16 @@ end_error: diag_raise(); } -static struct wal_stream wal_stream; - /** * Plan a yield in recovery stream. Wal stream will execute it as soon as it's * ready. */ static void -wal_stream_schedule_yield(void) +wal_stream_schedule_yield(struct xstream *base) { - wal_stream.has_yield = true; - wal_stream_try_yield(&wal_stream); + struct wal_stream *stream = container_of(base, struct wal_stream, base); + stream->has_yield = true; + wal_stream_try_yield(stream); } static void @@ -3124,6 +3123,7 @@ local_recovery(const struct tt_uuid *instance_uuid, say_info("instance uuid %s", tt_uuid_str(&INSTANCE_UUID)); + struct wal_stream wal_stream; wal_stream_create(&wal_stream); auto stream_guard = make_scoped_guard([&]{ wal_stream_abort(&wal_stream); @@ -3131,7 +3131,8 @@ local_recovery(const struct tt_uuid *instance_uuid, struct recovery *recovery; bool is_force_recovery = cfg_geti("force_recovery"); - recovery = recovery_new(wal_dir(), is_force_recovery, checkpoint_vclock); + recovery = recovery_new(wal_dir(), is_force_recovery, + checkpoint_vclock); /* * Make sure we report the actual recovery position diff --git a/src/box/recovery.cc b/src/box/recovery.cc index e5b88fcc2..1476622c3 100644 --- a/src/box/recovery.cc +++ b/src/box/recovery.cc @@ -142,7 +142,7 @@ recovery_scan(struct recovery *r, struct vclock *end_vclock, while (xlog_cursor_next(&cursor, &row, true) == 0) { vclock_follow_xrow(end_vclock, &row); if (++stream->row_count % WAL_ROWS_PER_YIELD == 0) - xstream_schedule_yield(stream); + xstream_yield(stream); } xlog_cursor_close(&cursor, false); @@ -250,7 +250,7 @@ recover_xlog(struct recovery *r, struct xstream *stream, while (xlog_cursor_next_xc(&r->cursor, &row, r->wal_dir.force_recovery) == 0) { if (++stream->row_count % WAL_ROWS_PER_YIELD == 0) { - xstream_schedule_yield(stream); + xstream_yield(stream); } if (stream->row_count % 100000 == 0) say_info("%.1fM rows processed", diff --git a/src/box/relay.cc b/src/box/relay.cc index 81ac35bf2..efc201e80 100644 --- a/src/box/relay.cc +++ b/src/box/relay.cc @@ -262,8 +262,9 @@ relay_new(struct replica *replica) /** A callback recovery calls every now and then to unblock the event loop. */ static void -relay_yield(void) +relay_yield(struct xstream *stream) { + (void) stream; fiber_sleep(0); } diff --git a/src/box/xstream.h b/src/box/xstream.h index d27de09a3..b3c771eba 100644 --- a/src/box/xstream.h +++ b/src/box/xstream.h @@ -45,36 +45,36 @@ struct xstream; * A type for a callback invoked by recovery after some batch of rows is * processed. Is used mostly to unblock the event loop every now and then. */ -typedef void (*schedule_yield_f)(void); +typedef void (*xstream_yield_f)(struct xstream *); typedef void (*xstream_write_f)(struct xstream *, struct xrow_header *); struct xstream { xstream_write_f write; - schedule_yield_f schedule_yield; + xstream_yield_f yield; uint64_t row_count; }; static inline void xstream_create(struct xstream *xstream, xstream_write_f write, - schedule_yield_f schedule_yield) + xstream_yield_f yield) { xstream->write = write; - xstream->schedule_yield = schedule_yield; + xstream->yield = yield; xstream->row_count = 0; } static inline void -xstream_schedule_yield(struct xstream *stream) +xstream_yield(struct xstream *stream) { - stream->schedule_yield(); + stream->yield(stream); } static inline void xstream_reset(struct xstream *stream) { stream->row_count = 0; - xstream_schedule_yield(stream); + xstream_yield(stream); } int ========================================== -- Serge Petrenko
next prev parent reply other threads:[~2021-05-13 10:11 UTC|newest] Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-05-12 11:29 Serge Petrenko via Tarantool-patches 2021-05-12 20:36 ` Vladislav Shpilevoy via Tarantool-patches 2021-05-13 10:11 ` Serge Petrenko via Tarantool-patches [this message] 2021-05-13 11:21 ` Vladislav Shpilevoy via Tarantool-patches 2021-05-13 13:37 ` Serge Petrenko via Tarantool-patches 2021-05-13 13:54 ` Kirill Yukhin via Tarantool-patches
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=d5e3c1dd-ad28-c117-843e-95e4f053d4f2@tarantool.org \ --to=tarantool-patches@dev.tarantool.org \ --cc=gorcunov@gmail.com \ --cc=sergepetrenko@tarantool.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v2] recovery: make it yield when positioning in a WAL' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox