diff --git a/src/box/box.cc b/src/box/box.cc index 6be2207c39c3d72d760603af269941c09c185ad9..34f85014c35a3eddf18b3b6a47203c09f014ef6e 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -1224,10 +1224,7 @@ bootstrap_cluster(void) /* Add a surrogate server id for snapshot rows */ vclock_add_server(&recovery->vclock, 0); - /* Process bootstrap.bin */ - struct xstream bootstrap_stream; - xstream_create(&bootstrap_stream, apply_row); - recovery_bootstrap(recovery, &bootstrap_stream); + engine_bootstrap(); uint32_t server_id = 1; diff --git a/src/box/engine.cc b/src/box/engine.cc index 866e529c51974d33931d1f533114ab57240a0b48..6d68993ab1acd4e28a2bcb51a6ad54bd6125448c 100644 --- a/src/box/engine.cc +++ b/src/box/engine.cc @@ -268,6 +268,15 @@ engine_recover_to_checkpoint(int64_t checkpoint_id) } } +void +engine_bootstrap() +{ + Engine *engine; + engine_foreach(engine) { + engine->bootstrap(); + } +} + void engine_begin_join() { diff --git a/src/box/engine.h b/src/box/engine.h index 69b2f8b1bda9b636cb23134ec2ba56e68c582bfd..a54d0d99cd2524f8f153bb10920fa0a869362fee 100644 --- a/src/box/engine.h +++ b/src/box/engine.h @@ -134,6 +134,10 @@ class Engine { * binary log. */ virtual void endRecovery(); + /** + * Bootstrap an empty data directory + */ + virtual void bootstrap() {} /** * Notify engine about a JOIN start (slave-side) */ @@ -240,6 +244,12 @@ engine_id(Handler *space) void engine_recover_to_checkpoint(int64_t checkpoint_id); +/** + * Initialize an empty data directory + */ +void +engine_bootstrap(); + /** * Called at the start of JOIN routine * on the replica. diff --git a/src/box/memtx_engine.cc b/src/box/memtx_engine.cc index 16ae1df7f55898a113f996a67adb6ca5122ccaf9..009de80047f0cf6d69f3b0eaa0c14a2ace16b9af 100644 --- a/src/box/memtx_engine.cc +++ b/src/box/memtx_engine.cc @@ -44,6 +44,7 @@ #include "iproto_constants.h" #include "xrow.h" #include "xstream.h" +#include "bootstrap.h" #include "cluster.h" #include "relay.h" #include "schema.h" @@ -997,6 +998,29 @@ MemtxEngine::commit(struct txn *txn, int64_t signature) } } +void +MemtxEngine::bootstrap() +{ + /* Recover from bootstrap.snap */ + say_info("initializing an empty data directory"); + struct xdir dir; + xdir_create(&dir, "", SNAP, &uuid_nil); + FILE *f = fmemopen((void *) &bootstrap_bin, + sizeof(bootstrap_bin), "r"); + struct xlog *snap = xlog_open_stream_xc(&dir, 0, f, "bootstrap.snap"); + struct xlog_cursor cursor; + xlog_cursor_open(&cursor, snap); + auto guard = make_scoped_guard([&]{ + xlog_cursor_close(&cursor); + xlog_close(snap); + xdir_destroy(&dir); + }); + + struct xrow_header row; + while (xlog_cursor_next_xc(&cursor, &row) == 0) + recoverSnapshotRow(&row); +} + void MemtxEngine::beginJoin() { diff --git a/src/box/memtx_engine.h b/src/box/memtx_engine.h index 6ca9201794a3dfb5c18eb883df02644af6a6c21f..b8a2a4386fc4e35d073354ad76645f25e6c9bd4d 100644 --- a/src/box/memtx_engine.h +++ b/src/box/memtx_engine.h @@ -59,6 +59,7 @@ struct MemtxEngine: public Engine { virtual void rollback(struct txn *txn) override; virtual void prepare(struct txn *txn) override; virtual void commit(struct txn *txn, int64_t signature) override; + virtual void bootstrap() override; virtual void beginJoin() override; virtual void recoverToCheckpoint(int64_t lsn) override; virtual void endRecovery() override; diff --git a/src/box/recovery.cc b/src/box/recovery.cc index f5faba506f29df466c77498da5f7cd663f18d4c0..2bf68c37648f7c9606f1c8f26d57a49a30e3a54d 100644 --- a/src/box/recovery.cc +++ b/src/box/recovery.cc @@ -32,7 +32,6 @@ #include "scoped_guard.h" #include "fiber.h" -#include "bootstrap.h" #include "xlog.h" #include "xrow.h" #include "xstream.h" @@ -247,25 +246,6 @@ recover_xlog(struct recovery *r, struct xstream *stream, struct xlog *l, } } -void -recovery_bootstrap(struct recovery *r, struct xstream *stream) -{ - /* Recover from bootstrap.snap */ - say_info("initializing an empty data directory"); - struct xdir dir; - xdir_create(&dir, "", SNAP, &uuid_nil); - const char *filename = "bootstrap.snap"; - FILE *f = fmemopen((void *) &bootstrap_bin, - sizeof(bootstrap_bin), "r"); - struct xlog *snap = xlog_open_stream_xc(&dir, 0, f, filename); - auto guard = make_scoped_guard([&]{ - xlog_close(snap); - xdir_destroy(&dir); - }); - /** The snapshot must have a EOF marker. */ - recover_xlog(r, stream, snap, NULL); -} - /** * Find out if there are new .xlog files since the current * LSN, and read them all up. diff --git a/src/box/recovery.h b/src/box/recovery.h index 61a7b3c598efd9233d9c39129bc4a515d084f339..7efda2a35c0f8efde85bc3b130a0c0291451e63f 100644 --- a/src/box/recovery.h +++ b/src/box/recovery.h @@ -72,9 +72,6 @@ recovery_delete(struct recovery *r); void recovery_exit(struct recovery *r); -void -recovery_bootstrap(struct recovery *r, struct xstream *stream); - void recovery_follow_local(struct recovery *r, struct xstream *stream, const char *name, ev_tstamp wal_dir_rescan_delay);