From d6d985e8154b88e9bd66d8296d5d42d110486100 Mon Sep 17 00:00:00 2001 From: Konstantin Osipov <kostja@tarantool.org> Date: Fri, 16 Jan 2015 20:29:12 +0300 Subject: [PATCH] Convert recovery_new() to use exceptions. --- src/box/box.cc | 71 +++++++++++++++++++++++------------------- src/box/recovery.cc | 30 +++++++++--------- src/box/replication.cc | 15 ++++----- 3 files changed, 63 insertions(+), 53 deletions(-) diff --git a/src/box/box.cc b/src/box/box.cc index 2371de06a2..ca114c8dd1 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -391,7 +391,6 @@ void box_init() { box_check_config(); - title("loading", NULL); replication_prefork(cfg_gets("snap_dir"), cfg_gets("wal_dir")); stat_init(); @@ -399,7 +398,6 @@ box_init() tuple_init(cfg_getd("slab_alloc_arena"), cfg_geti("slab_alloc_minimal"), cfg_getd("slab_alloc_factor")); - engine_init(); schema_init(); @@ -410,37 +408,48 @@ box_init() * as a default session user when running triggers. */ session_init(); - - /* recovery initialization */ - recovery = recovery_new(cfg_gets("snap_dir"), cfg_gets("wal_dir"), - recover_row, NULL, box_snapshot_cb, cfg_geti("rows_per_wal")); - recovery_set_remote(recovery, cfg_gets("replication_source")); - recovery_update_io_rate_limit(recovery, - cfg_getd("snap_io_rate_limit")); - recovery_setup_panic(recovery, - cfg_geti("panic_on_snap_error"), - cfg_geti("panic_on_wal_error")); - stat_base = stat_register(iproto_type_strs, IPROTO_TYPE_STAT_MAX); - if (recovery_has_data(recovery)) { - /* Process existing snapshot */ - recover_snap(recovery); - space_end_recover_snapshot(); - } else if (recovery_has_remote(recovery)) { - /* Initialize a new replica */ - replica_bootstrap(recovery); - space_end_recover_snapshot(); - snapshot_save(recovery); - } else { - /* Initialize the first server of a new cluster */ - recovery_bootstrap(recovery); - box_set_cluster_uuid(); - box_set_server_uuid(); - space_end_recover_snapshot(); - snapshot_save(recovery); + title("loading", NULL); + + try { + + /* recovery initialization */ + recovery = recovery_new(cfg_gets("snap_dir"), + cfg_gets("wal_dir"), + recover_row, NULL, + box_snapshot_cb, + cfg_geti("rows_per_wal")); + recovery_set_remote(recovery, + cfg_gets("replication_source")); + recovery_update_io_rate_limit(recovery, + cfg_getd("snap_io_rate_limit")); + recovery_setup_panic(recovery, + cfg_geti("panic_on_snap_error"), + cfg_geti("panic_on_wal_error")); + + if (recovery_has_data(recovery)) { + /* Process existing snapshot */ + recover_snap(recovery); + space_end_recover_snapshot(); + } else if (recovery_has_remote(recovery)) { + /* Initialize a new replica */ + replica_bootstrap(recovery); + space_end_recover_snapshot(); + snapshot_save(recovery); + } else { + /* Initialize the first server of a new cluster */ + recovery_bootstrap(recovery); + box_set_cluster_uuid(); + box_set_server_uuid(); + space_end_recover_snapshot(); + snapshot_save(recovery); + } + fiber_gc(); + } catch (Exception *e) { + e->log(); + panic("can't scan a data directory"); } - fiber_gc(); title("orphan", NULL); recovery_follow_local(recovery, @@ -448,7 +457,6 @@ box_init() title("hot_standby", NULL); const char *listen = cfg_gets("listen"); - /* * application server configuration). */ @@ -465,7 +473,6 @@ box_init() iobuf_set_readahead(cfg_geti("readahead")); } - void box_atfork() { diff --git a/src/box/recovery.cc b/src/box/recovery.cc index f7ce5d6954..68b19d72b7 100644 --- a/src/box/recovery.cc +++ b/src/box/recovery.cc @@ -121,6 +121,7 @@ fill_lsn(struct recovery_state *r, struct xrow_header *row) if (row == NULL || row->server_id == 0) { /* Local request */ int64_t lsn = vclock_inc(&r->vclock, r->server_id); + /* row is NULL if wal_mode = NONE */ if (row != NULL) { row->server_id = r->server_id; row->lsn = lsn; @@ -158,6 +159,11 @@ recovery_new(const char *snap_dirname, const char *wal_dirname, { struct recovery_state *r = (struct recovery_state *) calloc(1, sizeof(*r)); + + auto guard = make_scoped_guard([=]{ + free(r); + }); + recovery_update_mode(r, WAL_NONE); assert(rows_per_wal > 1); @@ -179,21 +185,17 @@ recovery_new(const char *snap_dirname, const char *wal_dirname, vclock_create(&r->vclock); - try { - xdir_scan(&r->snap_dir); - /** - * Avoid scanning WAL dir before we recovered - * the snapshot and know server UUID - this will - * make sure the scan skips files with wrong - * UUID, see replication/cluster.test for - * details. - */ - xdir_check(&r->wal_dir); - } catch (Exception *e) { - e->log(); - panic("can't scan a data directory"); - } + xdir_scan(&r->snap_dir); + /** + * Avoid scanning WAL dir before we recovered + * the snapshot and know server UUID - this will + * make sure the scan skips files with wrong + * UUID, see replication/cluster.test for + * details. + */ + xdir_check(&r->wal_dir); + guard.is_active = false; return r; } diff --git a/src/box/replication.cc b/src/box/replication.cc index dd54ab0167..34c0b46f7b 100644 --- a/src/box/replication.cc +++ b/src/box/replication.cc @@ -749,20 +749,21 @@ replication_relay_loop(struct relay *relay) sio_setfl(relay->sock, O_NONBLOCK, 0); /* Initialize the recovery process */ - struct recovery_state *r; - r = recovery_new(cfg_snap_dir, cfg_wal_dir, - replication_relay_send_row, - NULL, NULL, INT32_MAX); - r->relay = *relay; /* copy relay state to recovery */ - int rc = EXIT_SUCCESS; + struct recovery_state *r = NULL; try { + r = recovery_new(cfg_snap_dir, cfg_wal_dir, + replication_relay_send_row, + NULL, NULL, INT32_MAX); + r->relay = *relay; /* copy relay state to recovery */ + assert(r->relay.type == IPROTO_SUBSCRIBE); replication_relay_subscribe(r); } catch (Exception *e) { say_error("relay error: %s", e->errmsg()); rc = EXIT_FAILURE; } - recovery_delete(r); + if (r) + recovery_delete(r); exit(rc); } -- GitLab