diff --git a/include/admin.h b/include/admin.h index ec89f00bbfd189d9b52547aaa6cd1e355136e4e0..28de68c8207aa55dd0346669ee686afa7220da7e 100644 --- a/include/admin.h +++ b/include/admin.h @@ -28,6 +28,6 @@ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -int admin_init(void); +int admin_init(const char *bind_ipaddr, int admin_port); #endif /* TARANTOOL_ADMIN_H_INCLUDED */ diff --git a/include/recovery.h b/include/recovery.h index aaffab17f5bed002eb3917936e3d8ff9d1cabdc7..4f92bb3f24273af8af465f1ed2071c43865bc3ea 100644 --- a/include/recovery.h +++ b/include/recovery.h @@ -108,9 +108,7 @@ extern struct recovery_state *recovery_state; void recovery_init(const char *snap_dirname, const char *xlog_dirname, row_handler row_handler, void *row_handler_param, - int rows_per_wal, const char *wal_mode, - double wal_fsync_delay, - int flags); + int rows_per_wal, int flags); void recovery_update_mode(struct recovery_state *r, const char *wal_mode, double fsync_delay); void recovery_update_io_rate_limit(struct recovery_state *r, diff --git a/include/tarantool.h b/include/tarantool.h index a80218ce046fb12adc93d14eb89e55b478a59202..a5bbfb4215c10cc60e412bdf3f5ffff3f0426a48 100644 --- a/include/tarantool.h +++ b/include/tarantool.h @@ -55,6 +55,7 @@ extern bool init_storage, booting; extern char *binary_filename; extern char *custom_proc_title; i32 reload_cfg(struct tbuf *out); +void show_cfg(struct tbuf *out); int snapshot(void * /* ev */, int /* events */); const char *tarantool_version(void); double tarantool_uptime(void); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5681bc660baeada50356560d9092f2820f590f1e..dd88ac6c0a40244727949da7da1021328bc2e63e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -75,7 +75,6 @@ set (recompiled_sources ${CMAKE_SOURCE_DIR}/src/lua/init.m ${CMAKE_SOURCE_DIR}/src/say.m ${CMAKE_SOURCE_DIR}/src/assoc.m - ${CMAKE_SOURCE_DIR}/src/admin.m ${CMAKE_SOURCE_DIR}/src/replication.m ${CMAKE_SOURCE_DIR}/src/fiber.m) @@ -94,6 +93,7 @@ set (common_sources stat.m log_io.m recovery.m + admin.m cpu_feature.m replica.m iproto.m diff --git a/src/admin.m b/src/admin.m index 517e1586bfac8657290d1fa4e9073ef89836d0b9..9da50c51ab234660a3eeb6673eb658e483ca0211 100644 --- a/src/admin.m +++ b/src/admin.m @@ -42,7 +42,6 @@ #include <tarantool.h> #include "lua/init.h" #include <recovery.h> -#include TARANTOOL_CONFIG #include <tbuf.h> #include <util.h> #include <errinj.h> @@ -72,7 +71,7 @@ static const char *help = static const char *unknown_command = "unknown command. try typing help." CRLF; -#line 76 "src/admin.m" +#line 75 "src/admin.m" static const int admin_start = 1; static const int admin_first_final = 135; static const int admin_error = 0; @@ -80,7 +79,7 @@ static const int admin_error = 0; static const int admin_en_main = 1; -#line 75 "src/admin.rl" +#line 74 "src/admin.rl" struct salloc_stat_admin_cb_ctx { @@ -217,12 +216,12 @@ admin_dispatch(struct coio *coio, struct iobuf *iobuf, lua_State *L) p = in->pos; -#line 221 "src/admin.m" +#line 220 "src/admin.m" { cs = admin_start; } -#line 226 "src/admin.m" +#line 225 "src/admin.m" { if ( p == pe ) goto _test_eof; @@ -285,15 +284,15 @@ case 6: } goto st0; tr13: -#line 320 "src/admin.rl" +#line 307 "src/admin.rl" {slab_validate(); ok(out);} goto st135; tr20: -#line 308 "src/admin.rl" +#line 295 "src/admin.rl" {return -1;} goto st135; tr25: -#line 235 "src/admin.rl" +#line 222 "src/admin.rl" { start(out); tbuf_append(out, help, strlen(help)); @@ -301,9 +300,9 @@ tr25: } goto st135; tr36: -#line 294 "src/admin.rl" +#line 281 "src/admin.rl" {strend = p;} -#line 241 "src/admin.rl" +#line 228 "src/admin.rl" { strstart[strend-strstart]='\0'; start(out); @@ -312,7 +311,7 @@ tr36: } goto st135; tr43: -#line 248 "src/admin.rl" +#line 235 "src/admin.rl" { if (reload_cfg(err)) fail(out, err); @@ -321,11 +320,11 @@ tr43: } goto st135; tr67: -#line 318 "src/admin.rl" +#line 305 "src/admin.rl" {coredump(60); ok(out);} goto st135; tr76: -#line 255 "src/admin.rl" +#line 242 "src/admin.rl" { int ret = snapshot(NULL, 0); @@ -340,9 +339,9 @@ tr76: } goto st135; tr98: -#line 304 "src/admin.rl" +#line 291 "src/admin.rl" { state = false; } -#line 268 "src/admin.rl" +#line 255 "src/admin.rl" { strstart[strend-strstart] = '\0'; if (errinj_set_byname(strstart, state)) { @@ -354,9 +353,9 @@ tr98: } goto st135; tr101: -#line 303 "src/admin.rl" +#line 290 "src/admin.rl" { state = true; } -#line 268 "src/admin.rl" +#line 255 "src/admin.rl" { strstart[strend-strstart] = '\0'; if (errinj_set_byname(strstart, state)) { @@ -368,35 +367,23 @@ tr101: } goto st135; tr117: -#line 211 "src/admin.rl" +#line 210 "src/admin.rl" { - tarantool_cfg_iterator_t *i; - char *key, *value; - start(out); - tbuf_printf(out, "configuration:" CRLF); - i = tarantool_cfg_iterator_init(); - while ((key = tarantool_cfg_iterator_next(i, &cfg, &value)) != NULL) { - if (value) { - tbuf_printf(out, " %s: \"%s\"" CRLF, key, value); - free(value); - } else { - tbuf_printf(out, " %s: (null)" CRLF, key); - } - } + show_cfg(out); end(out); } goto st135; tr131: -#line 311 "src/admin.rl" +#line 298 "src/admin.rl" {start(out); fiber_info(out); end(out);} goto st135; tr137: -#line 310 "src/admin.rl" +#line 297 "src/admin.rl" {start(out); tarantool_info(out); end(out);} goto st135; tr146: -#line 229 "src/admin.rl" +#line 216 "src/admin.rl" { start(out); errinj_info(out); @@ -404,33 +391,33 @@ tr146: } goto st135; tr152: -#line 314 "src/admin.rl" +#line 301 "src/admin.rl" {start(out); palloc_stat(out); end(out);} goto st135; tr160: -#line 313 "src/admin.rl" +#line 300 "src/admin.rl" {start(out); show_slab(out); end(out);} goto st135; tr164: -#line 315 "src/admin.rl" +#line 302 "src/admin.rl" {start(out); show_stat(out);end(out);} goto st135; st135: if ( ++p == pe ) goto _test_eof135; case 135: -#line 423 "src/admin.m" +#line 410 "src/admin.m" goto st0; tr14: -#line 320 "src/admin.rl" +#line 307 "src/admin.rl" {slab_validate(); ok(out);} goto st7; tr21: -#line 308 "src/admin.rl" +#line 295 "src/admin.rl" {return -1;} goto st7; tr26: -#line 235 "src/admin.rl" +#line 222 "src/admin.rl" { start(out); tbuf_append(out, help, strlen(help)); @@ -438,9 +425,9 @@ tr26: } goto st7; tr37: -#line 294 "src/admin.rl" +#line 281 "src/admin.rl" {strend = p;} -#line 241 "src/admin.rl" +#line 228 "src/admin.rl" { strstart[strend-strstart]='\0'; start(out); @@ -449,7 +436,7 @@ tr37: } goto st7; tr44: -#line 248 "src/admin.rl" +#line 235 "src/admin.rl" { if (reload_cfg(err)) fail(out, err); @@ -458,11 +445,11 @@ tr44: } goto st7; tr68: -#line 318 "src/admin.rl" +#line 305 "src/admin.rl" {coredump(60); ok(out);} goto st7; tr77: -#line 255 "src/admin.rl" +#line 242 "src/admin.rl" { int ret = snapshot(NULL, 0); @@ -477,9 +464,9 @@ tr77: } goto st7; tr99: -#line 304 "src/admin.rl" +#line 291 "src/admin.rl" { state = false; } -#line 268 "src/admin.rl" +#line 255 "src/admin.rl" { strstart[strend-strstart] = '\0'; if (errinj_set_byname(strstart, state)) { @@ -491,9 +478,9 @@ tr99: } goto st7; tr102: -#line 303 "src/admin.rl" +#line 290 "src/admin.rl" { state = true; } -#line 268 "src/admin.rl" +#line 255 "src/admin.rl" { strstart[strend-strstart] = '\0'; if (errinj_set_byname(strstart, state)) { @@ -505,35 +492,23 @@ tr102: } goto st7; tr118: -#line 211 "src/admin.rl" +#line 210 "src/admin.rl" { - tarantool_cfg_iterator_t *i; - char *key, *value; - start(out); - tbuf_printf(out, "configuration:" CRLF); - i = tarantool_cfg_iterator_init(); - while ((key = tarantool_cfg_iterator_next(i, &cfg, &value)) != NULL) { - if (value) { - tbuf_printf(out, " %s: \"%s\"" CRLF, key, value); - free(value); - } else { - tbuf_printf(out, " %s: (null)" CRLF, key); - } - } + show_cfg(out); end(out); } goto st7; tr132: -#line 311 "src/admin.rl" +#line 298 "src/admin.rl" {start(out); fiber_info(out); end(out);} goto st7; tr138: -#line 310 "src/admin.rl" +#line 297 "src/admin.rl" {start(out); tarantool_info(out); end(out);} goto st7; tr147: -#line 229 "src/admin.rl" +#line 216 "src/admin.rl" { start(out); errinj_info(out); @@ -541,22 +516,22 @@ tr147: } goto st7; tr153: -#line 314 "src/admin.rl" +#line 301 "src/admin.rl" {start(out); palloc_stat(out); end(out);} goto st7; tr161: -#line 313 "src/admin.rl" +#line 300 "src/admin.rl" {start(out); show_slab(out); end(out);} goto st7; tr165: -#line 315 "src/admin.rl" +#line 302 "src/admin.rl" {start(out); show_stat(out);end(out);} goto st7; st7: if ( ++p == pe ) goto _test_eof7; case 7: -#line 560 "src/admin.m" +#line 535 "src/admin.m" if ( (*p) == 10 ) goto st135; goto st0; @@ -709,28 +684,28 @@ case 23: } goto tr33; tr33: -#line 294 "src/admin.rl" +#line 281 "src/admin.rl" {strstart = p;} goto st24; st24: if ( ++p == pe ) goto _test_eof24; case 24: -#line 720 "src/admin.m" +#line 695 "src/admin.m" switch( (*p) ) { case 10: goto tr36; case 13: goto tr37; } goto st24; tr34: -#line 294 "src/admin.rl" +#line 281 "src/admin.rl" {strstart = p;} goto st25; st25: if ( ++p == pe ) goto _test_eof25; case 25: -#line 734 "src/admin.m" +#line 709 "src/admin.m" switch( (*p) ) { case 10: goto tr36; case 13: goto tr37; @@ -1180,28 +1155,28 @@ case 73: goto tr91; goto st0; tr91: -#line 302 "src/admin.rl" +#line 289 "src/admin.rl" { strstart = p; } goto st74; st74: if ( ++p == pe ) goto _test_eof74; case 74: -#line 1191 "src/admin.m" +#line 1166 "src/admin.m" if ( (*p) == 32 ) goto tr92; if ( 33 <= (*p) && (*p) <= 126 ) goto st74; goto st0; tr92: -#line 302 "src/admin.rl" +#line 289 "src/admin.rl" { strend = p; } goto st75; st75: if ( ++p == pe ) goto _test_eof75; case 75: -#line 1205 "src/admin.m" +#line 1180 "src/admin.m" switch( (*p) ) { case 32: goto st75; case 111: goto st76; @@ -1893,7 +1868,7 @@ case 134: _out: {} } -#line 326 "src/admin.rl" +#line 313 "src/admin.rl" in->pos = pe; @@ -1930,11 +1905,11 @@ admin_handler(va_list ap) } void -admin_init(void) +admin_init(const char *bind_ipaddr, int admin_port) { static struct coio_service admin; - coio_service_init(&admin, "admin", cfg.bind_ipaddr, - cfg.admin_port, admin_handler, NULL); + coio_service_init(&admin, "admin", bind_ipaddr, + admin_port, admin_handler, NULL); evio_service_start(&admin.evio_service); } diff --git a/src/admin.rl b/src/admin.rl index cef2a70e5116ea4ccda1870bd6064a00a0245a62..2bbf3aff44c67aa0ee067beb5eb8820cee9fbb0e 100644 --- a/src/admin.rl +++ b/src/admin.rl @@ -40,7 +40,6 @@ #include <tarantool.h> #include "lua/init.h" #include <recovery.h> -#include TARANTOOL_CONFIG #include <tbuf.h> #include <util.h> #include <errinj.h> @@ -209,20 +208,8 @@ admin_dispatch(struct coio *coio, struct iobuf *iobuf, lua_State *L) %%{ action show_configuration { - tarantool_cfg_iterator_t *i; - char *key, *value; - start(out); - tbuf_printf(out, "configuration:" CRLF); - i = tarantool_cfg_iterator_init(); - while ((key = tarantool_cfg_iterator_next(i, &cfg, &value)) != NULL) { - if (value) { - tbuf_printf(out, " %s: \"%s\"" CRLF, key, value); - free(value); - } else { - tbuf_printf(out, " %s: (null)" CRLF, key); - } - } + show_cfg(out); end(out); } @@ -359,11 +346,11 @@ admin_handler(va_list ap) } void -admin_init(void) +admin_init(const char *bind_ipaddr, int admin_port) { static struct coio_service admin; - coio_service_init(&admin, "admin", cfg.bind_ipaddr, - cfg.admin_port, admin_handler, NULL); + coio_service_init(&admin, "admin", bind_ipaddr, + admin_port, admin_handler, NULL); evio_service_start(&admin.evio_service); } diff --git a/src/box/box.h b/src/box/box.h index 7fb12efb31165d1b8dc5444be3f35782488b61ef..32ae1c9c5f841820c0fe6f9119913c0d6c5cd316 100644 --- a/src/box/box.h +++ b/src/box/box.h @@ -33,8 +33,7 @@ struct txn; struct tbuf; struct port; -typedef void (*box_process_func)(struct txn *, - struct port *, u32, struct tbuf *); +typedef void (*box_process_func)(struct port *, u32, struct tbuf *); extern box_process_func box_process; #endif /* INCLUDES_TARANTOOL_BOX_H */ diff --git a/src/box/box.m b/src/box/box.m index 219b5f091c947ed2210d51be830d10f6fca0983d..1b368e7cb5c7d835e9aabc29f02bb91633f7053c 100644 --- a/src/box/box.m +++ b/src/box/box.m @@ -31,7 +31,7 @@ #include <cfg/warning.h> #include <errcode.h> -#include <fiber.h> +#include "palloc.h" #include <recovery.h> #include <log_io.h> #include <pickle.h> @@ -49,13 +49,11 @@ #include "txn.h" #include "coio.h" -static void box_process_replica(struct txn *txn, struct port *port, +static void box_process_replica(struct port *port, u32 op, struct tbuf *request_data); -static void box_process_ro(struct txn *txn, struct port *port, +static void box_process_ro(struct port *port, u32 op, struct tbuf *request_data); -static void box_process_ro(struct txn *txn, struct port *port, - u32 op, struct tbuf *request_data); -static void box_process_rw(struct txn *txn, struct port *port, +static void box_process_rw(struct port *port, u32 op, struct tbuf *request_data); box_process_func box_process = box_process_ro; @@ -79,9 +77,10 @@ box_snap_row(const struct tbuf *t) } static void -box_process_rw(struct txn *txn, struct port *port, +box_process_rw(struct port *port, u32 op, struct tbuf *data) { + struct txn *txn = txn_begin(); ev_tstamp start = ev_now(), stop; @try { @@ -103,49 +102,44 @@ box_process_rw(struct txn *txn, struct port *port, } static void -box_process_replica(struct txn *txn, struct port *port, - u32 op, struct tbuf *request_data) +box_process_replica(struct port *port, u32 op, struct tbuf *request_data) { if (!request_is_select(op)) { - txn_rollback(txn); tnt_raise(ClientError, :ER_NONMASTER, cfg.replication_source); } - return box_process_rw(txn, port, op, request_data); + return box_process_rw(port, op, request_data); } static void -box_process_ro(struct txn *txn, struct port *port, +box_process_ro(struct port *port, u32 op, struct tbuf *request_data) { - if (!request_is_select(op)) { - txn_rollback(txn); + if (!request_is_select(op)) tnt_raise(LoggedError, :ER_SECONDARY); - } - return box_process_rw(txn, port, op, request_data); + return box_process_rw(port, op, request_data); } - - static void iproto_primary_port_handler(struct obuf *out, u32 op, struct tbuf *request_data) { - box_process(txn_begin(), port_iproto_create(out), op, request_data); + box_process(port_iproto_create(out), op, request_data); } static void iproto_secondary_port_handler(struct obuf *out, u32 op, struct tbuf *request_data) { - box_process_ro(txn_begin(), port_iproto_create(out), op, request_data); + box_process_ro(port_iproto_create(out), op, request_data); } + static void box_xlog_sprint(struct tbuf *buf, const struct tbuf *t) { struct header_v11 *row = header_v11(t); - struct tbuf *b = palloc(fiber->gc_pool, sizeof(*b)); + struct tbuf *b = palloc(buf->pool, sizeof(*b)); b->data = t->data + sizeof(struct header_v11); b->size = row->len; u16 tag, op; @@ -302,9 +296,7 @@ recover_row(void *param __attribute__((unused)), struct tbuf *t) recover_snap_row(t); } else if (tag == XLOG) { u16 op = read_u16(t); - struct txn *txn = txn_begin(); - txn->txn_flags |= BOX_NOT_STORE; - box_process_rw(txn, &port_null, op, t); + box_process_rw(&port_null, op, t); } else { say_error("unknown row tag: %i", (int)tag); return -1; @@ -373,6 +365,9 @@ box_leave_local_standby_mode(void *data __attribute__((unused))) { recovery_finalize(recovery_state); + recovery_update_mode(recovery_state, cfg.wal_mode, + cfg.wal_fsync_delay); + box_enter_master_or_replica_mode(&cfg); } @@ -487,8 +482,7 @@ mod_init(void) /* recovery initialization */ recovery_init(cfg.snap_dir, cfg.wal_dir, recover_row, NULL, - cfg.rows_per_wal, cfg.wal_mode, - cfg.wal_fsync_delay, + cfg.rows_per_wal, init_storage ? RECOVER_READONLY : 0); recovery_update_io_rate_limit(recovery_state, cfg.snap_io_rate_limit); recovery_setup_panic(recovery_state, cfg.panic_on_snap_error, cfg.panic_on_wal_error); diff --git a/src/box/box_lua.m b/src/box/box_lua.m index 617bada74c8298e2ce758ddfcea70267c85deb49..6bf6cec5369e6dc7d4d0f4540b06a566db414362 100644 --- a/src/box/box_lua.m +++ b/src/box/box_lua.m @@ -1123,10 +1123,9 @@ static int lbox_process(lua_State *L) int top = lua_gettop(L); /* to know how much is added by rw_callback */ size_t allocated_size = palloc_allocated(fiber->gc_pool); - struct txn *txn = txn_begin(); struct port *port_lua = port_lua_create(L); @try { - box_process(txn, port_lua, op, &req); + box_process(port_lua, op, &req); } @finally { /* * This only works as long as port_lua doesn't diff --git a/src/box/memcached.m b/src/box/memcached.m index e562fac93675f1a5843c57358b20e5f9a86c234b..5c1a71cc7beabb212a41586238b1f68353160124 100644 --- a/src/box/memcached.m +++ b/src/box/memcached.m @@ -118,7 +118,7 @@ store(void *key, u32 exptime, u32 flags, u32 bytes, const char *data) * Use a box dispatch wrapper which handles correctly * read-only/read-write modes. */ - box_process(txn_begin(), &port_null, REPLACE, req); + box_process(&port_null, REPLACE, req); } static void @@ -133,7 +133,7 @@ delete(void *key) tbuf_append(req, &key_len, sizeof(key_len)); tbuf_append_field(req, key); - box_process(txn_begin(), &port_null, DELETE, req); + box_process(&port_null, DELETE, req); } static struct tuple * diff --git a/src/iobuf.m b/src/iobuf.m index 0c414f7c0142699b63778ce1b88461b2fa18fd19..85050a02c8442cdfe4999889763a489f295e6abe 100644 --- a/src/iobuf.m +++ b/src/iobuf.m @@ -150,7 +150,7 @@ obuf_dup(struct obuf *buf, void *data, size_t size) * @pre buf->pos points at an array of allocated buffers. * The array ends with a zero-initialized buffer. */ - if (iov->iov_len + size > capacity) { + while (iov->iov_len + size > capacity) { /* * The data doesn't fit into this buffer. * It could be because the buffer is not @@ -158,13 +158,14 @@ obuf_dup(struct obuf *buf, void *data, size_t size) * Copy as much as possible into already * allocated buffers. */ - while (iov->iov_len < capacity) { + if (iov->iov_len < capacity) { /* * This buffer is allocated, but can't * fit all the data. Copy as much data as * possible. */ size_t fill = capacity - iov->iov_len; + assert(fill < size); memcpy(iov->iov_base + iov->iov_len, data, fill); iov->iov_len += fill; @@ -172,22 +173,27 @@ obuf_dup(struct obuf *buf, void *data, size_t size) data += fill; size -= fill; - if (size == 0) /* Nothing more to do. */ - return; buf->pos++; iov = &buf->iov[buf->pos]; capacity = buf->capacity[buf->pos]; + /* + * Check if the remainder can fit + * without allocations. + */ + } else { + assert(capacity == 0); + /** + * Still some data to copy. We have to get + * a new buffer. Before we allocate + * a buffer for this position, ensure + * there is an unallocated buffer in the + * next one, since it works as an end + * marker for the loop above. + */ + obuf_init_pos(buf, buf->pos + 1); + obuf_alloc_pos(buf, buf->pos, size); + break; } - assert(capacity == 0); - /** - * Still some data to copy. We have to get a new - * buffer. Before we allocate a buffer for this - * position, ensure there is an unallocated buffer - * in the next one, since it works as an end marker - * for the loop above. - */ - obuf_init_pos(buf, buf->pos + 1); - obuf_alloc_pos(buf, buf->pos, size); } memcpy(iov->iov_base + iov->iov_len, data, size); iov->iov_len += size; diff --git a/src/iproto.m b/src/iproto.m index b892725d864361c731693494f52f23d2ea0a1826..5d625740bfd23c943149f68d9b2d53b709833b27 100644 --- a/src/iproto.m +++ b/src/iproto.m @@ -35,6 +35,8 @@ #include <say.h> #include "coio_buf.h" #include "tbuf.h" +#include "box/box.h" +#include "box/port.h" const uint32_t msg_ping = 0xff00; diff --git a/src/recovery.m b/src/recovery.m index 5d1cb4607cbe595987ffc93c70f8c1a836018962..1af7f72ea8a0bbaa6046d0717106065e7369de77 100644 --- a/src/recovery.m +++ b/src/recovery.m @@ -114,6 +114,15 @@ wait_lsn_set(struct wait_lsn *wait_lsn, int64_t lsn) wait_lsn->lsn = lsn; } + +/* Alert the waiter, if any. */ +static inline void +wakeup_lsn_waiter(struct recovery_state *r) +{ + if (r->wait_lsn.waiter && r->confirmed_lsn >= r->wait_lsn.lsn) + fiber_wakeup(r->wait_lsn.waiter); +} + void confirm_lsn(struct recovery_state *r, int64_t lsn, bool is_commit) { @@ -130,18 +139,26 @@ confirm_lsn(struct recovery_state *r, int64_t lsn, bool is_commit) r->confirmed_lsn = lsn; } } else { + /* + * There can be holes in + * confirmed_lsn, in case of disk write failure, but + * wal_writer never confirms LSNs out order. + */ assert(false); say_error("LSN is used twice or COMMIT order is broken: " "confirmed: %jd, new: %jd", (intmax_t) r->confirmed_lsn, (intmax_t) lsn); } - /* - * Alert the waiter, if any. There can be holes in - * confirmed_lsn, in case of disk write failure, but - * wal_writer never confirms LSNs out order. - */ - if (r->wait_lsn.waiter && r->confirmed_lsn >= r->wait_lsn.lsn) - fiber_call(r->wait_lsn.waiter); + wakeup_lsn_waiter(r); +} + +void +set_lsn(struct recovery_state *r, int64_t lsn) +{ + r->lsn = lsn; + r->confirmed_lsn = lsn; + say_debug("set_lsn(%p, %" PRIi64, r, r->lsn); + wakeup_lsn_waiter(r); } /** Wait until the given LSN makes its way to disk. */ @@ -167,13 +184,6 @@ next_lsn(struct recovery_state *r) return r->lsn; } -void -set_lsn(struct recovery_state *r, int64_t lsn) -{ - r->lsn = lsn; - say_debug("set_lsn(%p, %" PRIi64, r, r->lsn); - confirm_lsn(r, r->lsn, true); -} /* }}} */ @@ -189,13 +199,12 @@ recovery_stop_local(struct recovery_state *r); void recovery_init(const char *snap_dirname, const char *wal_dirname, row_handler row_handler, void *row_handler_param, - int rows_per_wal, const char *wal_mode, - double wal_fsync_delay, int flags) + int rows_per_wal, int flags) { assert(recovery_state == NULL); recovery_state = p0alloc(eter_pool, sizeof(struct recovery_state)); struct recovery_state *r = recovery_state; - recovery_update_mode(r, wal_mode, wal_fsync_delay); + recovery_update_mode(r, "none", 0); if (rows_per_wal <= 1) panic("unacceptable value of 'rows_per_wal'"); @@ -209,7 +218,6 @@ recovery_init(const char *snap_dirname, const char *wal_dirname, r->wal_dir->dirname = strdup(wal_dirname); r->wal_dir->open_wflags = r->wal_mode == WAL_FSYNC ? WAL_SYNC_FLAG : 0; r->rows_per_wal = rows_per_wal; - r->wal_fsync_delay = wal_fsync_delay; wait_lsn_clear(&r->wait_lsn); r->flags = flags; } diff --git a/src/replication.m b/src/replication.m index 557de40e581660d31572118dfe7ca364924a0c35..a404a3abaab341ea31e48963fd4bb6f5fb63593b 100644 --- a/src/replication.m +++ b/src/replication.m @@ -646,8 +646,7 @@ replication_relay_loop(int client_sock) /* Initialize the recovery process */ recovery_init(cfg.snap_dir, cfg.wal_dir, replication_relay_send_row, (void *)(intptr_t) client_sock, - INT32_MAX, "fsync_delay", 0, - RECOVER_READONLY); + INT32_MAX, RECOVER_READONLY); /* * Note that recovery starts with lsn _NEXT_ to * the confirmed one. diff --git a/src/tarantool.m b/src/tarantool.m index 2645af068f5b041b0ddaec933987eff41ad9ed8f..a805c32a855cdded9d2e906dd38e709ae8510adf 100644 --- a/src/tarantool.m +++ b/src/tarantool.m @@ -253,6 +253,25 @@ reload_cfg(struct tbuf *out) return 0; } +/** Print the configuration file in YAML format. */ +void +show_cfg(struct tbuf *out) +{ + tarantool_cfg_iterator_t *i; + char *key, *value; + + tbuf_printf(out, "configuration:" CRLF); + i = tarantool_cfg_iterator_init(); + while ((key = tarantool_cfg_iterator_next(i, &cfg, &value)) != NULL) { + if (value) { + tbuf_printf(out, " %s: \"%s\"" CRLF, key, value); + free(value); + } else { + tbuf_printf(out, " %s: (null)" CRLF, key); + } + } +} + const char * tarantool_version(void) { @@ -811,7 +830,7 @@ main(int argc, char **argv) tarantool_L = tarantool_lua_init(); mod_init(); tarantool_lua_load_cfg(tarantool_L, &cfg); - admin_init(); + admin_init(cfg.bind_ipaddr, cfg.admin_port); replication_init(); /* * Load user init script. The script should have access