diff --git a/.gitmodules b/.gitmodules index 89aca4dd78a1265477cc88ca3b918b142cc15d1e..118dcc251b6b79b782b2923a948d8d8748a4bc96 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "third_party/luajit"] path = third_party/luajit url = http://luajit.org/git/luajit-2.0.git +[submodule "test/lib/tarantool-python"] + path = test/lib/tarantool-python + url = https://github.com/mailru/tarantool-python.git diff --git a/CMakeLists.txt b/CMakeLists.txt index b41beac1987c3ec7b35ae0333160cf888a9cc31d..31d4b0cbfb9b5abeac7c5a838b82866a52d2dfc3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,6 +84,7 @@ if (HAVE_SENDFILE) check_prototype_definition(sendfile "ssize_t sendfile(int out_fd, int in_fd, off_t * offset, size_t count)" "0" "sys/sendfile.h" HAVE_SENDFILE_LINUX) check_prototype_definition(sendfile "int sendfile(int fd, int s, off_t offset, size_t nbytes, struct sf_hdtr *hdtr, off_t *sbytes, int flags)" "0" "" HAVE_SENDFILE_BSD) endif() +check_function_exists(open_memstream HAVE_OPEN_MEMSTREAM) # # Some versions of GNU libc define non-portable __libc_stack_end diff --git a/cfg/warning.c b/cfg/warning.c index 5be6034d498b9d2f13683ea871d1c76ee423c620..c2a9ecd24ef1d1831ad7b305e4ee6559a7a06d5d 100644 --- a/cfg/warning.c +++ b/cfg/warning.c @@ -1,16 +1,17 @@ #include "warning.h" -#include <tbuf.h> +#include <stdio.h> #include <stdarg.h> -struct tbuf *cfg_out = NULL; +FILE *cfg_out; +char *cfg_log; +size_t cfg_logsize; /** This is a callback function used by the generated * configuration file parser (tarantool_{box, feeder, ...}_cfg.c) * to complain when something wrong happens. */ - void out_warning(ConfettyError v, const char *format, ...) { @@ -18,7 +19,8 @@ out_warning(ConfettyError v, const char *format, ...) (void)v; /* make gcc happy */ va_start(ap, format); - tbuf_vprintf(cfg_out, format, ap); - tbuf_printf(cfg_out, ".\n"); + vfprintf(cfg_out, format, ap); + fprintf(cfg_out, ".\n"); + fflush(cfg_out); va_end(ap); } diff --git a/cfg/warning.h b/cfg/warning.h index 646688b498fb6635a2e34616cfd463b6157531e9..d41252a984065c789295f8092bd9fa9e5da10624 100644 --- a/cfg/warning.h +++ b/cfg/warning.h @@ -3,7 +3,10 @@ #include "prscfg.h" -extern struct tbuf *cfg_out; +/** Begin logging - must be called before load_cfg() . */ +extern FILE *cfg_out; +extern char *cfg_log; +extern size_t cfg_logsize; void out_warning(ConfettyError r, const char *format, ...); diff --git a/client/tarantool/tc.c b/client/tarantool/tc.c index e42708d67ef882df2a725d680a10f10bc913fbde..db59b30fa288975da51fde21aed3986d3b82c51a 100644 --- a/client/tarantool/tc.c +++ b/client/tarantool/tc.c @@ -45,9 +45,14 @@ #include "client/tarantool/tc.h" #include "client/tarantool/tc_cli.h" #include "client/tarantool/tc_print.h" +#include "client/tarantool/tc_store.h" +#include "client/tarantool/tc_query.h" #include "client/tarantool/tc_print_snap.h" #include "client/tarantool/tc_print_xlog.h" -#include "client/tarantool/tc_store.h" + +#define TC_DEFAULT_PORT 33013 +#define TC_DEFAULT_PORT 33013 +#define TC_ERR_CMD "---\nunknown command. try typing help.\n...\n" struct tc tc; @@ -79,6 +84,8 @@ void tc_error(char *fmt, ...) { static void tc_connect(void) { + if (tc.opt.port == 0) + tc.opt.port = TC_DEFAULT_PORT; /* allocating stream */ tc.net = tnt_net(NULL); if (tc.net == NULL) @@ -95,12 +102,43 @@ static void tc_connect(void) tc_error("%s", tnt_strerror(tc.net)); } +static char *send_cmd(char *cmd) +{ + size_t size = 0; + char *reply = NULL; + if (tc_admin_query(&tc.admin, cmd) == -1) + tc_error("cannot send query"); + if (tc_admin_reply(&tc.admin, &reply, &size) == -1) + tc_error("cannot recv query"); + if (strncmp(reply, TC_ERR_CMD, size) == 0) { + free(reply); + return NULL; + } + return reply; +} + +static int get_primary_port() +{ + int port = 0; + char *reply = send_cmd("box.cfg.primary_port"); + if (reply == NULL) + reply = send_cmd("lua box.cfg.primary_port"); + if (reply != NULL) { + sscanf(reply, "---\n - %d\n...", &port); + free(reply); + } + return port; +} + static void tc_connect_admin(void) { + if (tc_admin_connect(&tc.admin, tc.opt.host, tc.opt.port_admin) == -1) tc_error("admin console connection failed"); + if (tc.opt.port == 0) + tc.opt.port = get_primary_port(); } static void tc_validate(void) @@ -108,12 +146,11 @@ static void tc_validate(void) tc.opt.xlog_printer = tc_print_getxlogcb(tc.opt.format); tc.opt.snap_printer = tc_print_getsnapcb(tc.opt.format); if (tc.opt.xlog_printer == NULL) - return tc_error("unsupported output xlog format '%s'", + tc_error("unsupported output xlog format '%s'", tc.opt.format); if (tc.opt.snap_printer == NULL) - return tc_error("unsupported output snap format '%s'", + tc_error("unsupported output snap format '%s'", tc.opt.format); - if (tc.opt.format && strcmp(tc.opt.format, "raw") == 0) tc.opt.raw = 1; } @@ -144,13 +181,13 @@ int main(int argc, char *argv[]) rc = tc_store_play(); break; case TC_OPT_CMD: - tc_connect(); tc_connect_admin(); + tc_connect(); rc = tc_cli_cmdv(); break; case TC_OPT_INTERACTIVE: - tc_connect(); tc_connect_admin(); + tc_connect(); tc_cli_motd(); rc = tc_cli(); break; diff --git a/client/tarantool/tc_buf.c b/client/tarantool/tc_buf.c index b4556bb796078d1b86f5b54a84b2146268e22c87..4826ed1361294867c03afb24155875d829d138a5 100644 --- a/client/tarantool/tc_buf.c +++ b/client/tarantool/tc_buf.c @@ -37,9 +37,10 @@ /* Strip trailing ws from (char*) */ size_t strip_end_ws(char *str) { size_t last = 0; - for (size_t i = 0; str[i] != 0; ++i) + for (size_t i = 0; str[i] != 0; ++i) { if (!isspace(str[i])) last = i + 1; + } str[last] = '\0'; return last; } @@ -49,16 +50,18 @@ int tc_buf(struct tc_buf *buf) { buf->size = TC_BUF_INIT_SIZE; buf->used = 0; buf->data = (char *)malloc(buf->size); - if (buf->data == NULL) + if (buf->data == NULL) { return -1; + } return 0; } /* Append len bytes of memory from str pointed memory */ int tc_buf_append(struct tc_buf *buf, void *str, size_t len) { if (buf->size - buf->used < len) { - if (buf->size < len) + if (buf->size < len) { buf->size = len; + } buf->size *= TC_BUF_MULTIPLIER; char *nd = (char *)realloc(buf->data, buf->size); if (nd == NULL) @@ -112,6 +115,26 @@ int tc_buf_str_append(struct tc_buf *buf, char *str, size_t len) { return 0; } +/* Remove last num symbols from STR */ +size_t tc_buf_str_delete(struct tc_buf *buf, size_t len) { + size_t ret = tc_buf_delete(buf, len + 1); /* Remove '\0' + len */ + if (tc_buf_append(buf, (void *)"\0", 1)) + return 0; + return ret; +} + +/* + * Make admin command from multiline command + * and delete delimiter (last num bytes) + */ +void tc_buf_cmdfy(struct tc_buf *buf, size_t num) { + tc_buf_str_delete(buf, num); + for (int i = 0; i < buf->used; ++i) { + if (buf->data[i] == '\n') + buf->data[i] = ' '; + } +} + /* Remove trailing ws from STR */ int tc_buf_str_stripws(struct tc_buf *buf) { if (buf->data) { diff --git a/client/tarantool/tc_buf.h b/client/tarantool/tc_buf.h index 52383666e7a7adf1cd869c1e96ff3a4e197d781d..3e528c20d7742a424aa9a4c417f81a5d8f7ddd39 100644 --- a/client/tarantool/tc_buf.h +++ b/client/tarantool/tc_buf.h @@ -40,12 +40,15 @@ struct tc_buf { int tc_buf(struct tc_buf *buf); void *tc_buf_realloc(void *data, size_t size); int tc_buf_append(struct tc_buf *buf, void *str, size_t len); -size_t tc_buf_delete(struct tc_buf *buf, size_t len); +size_t tc_buf_delete(struct tc_buf *buf, size_t num); int tc_buf_isempty(struct tc_buf *buf); void tc_buf_clear(struct tc_buf *buf); void tc_buf_free(struct tc_buf *buf); int tc_buf_str(struct tc_buf *buf); int tc_buf_str_append(struct tc_buf *buf, char *str, size_t len); +size_t tc_buf_str_delete(struct tc_buf *buf, size_t num); int tc_buf_str_stripws(struct tc_buf *buf); int tc_buf_str_isempty(struct tc_buf *buf); + +void tc_buf_cmdfy(struct tc_buf *buf, size_t num); diff --git a/client/tarantool/tc_cli.c b/client/tarantool/tc_cli.c index f6ea1ea346f90abe240f8a6fcf1c164a926ef4c4..53fda89668654c5590b5b94f9cf9352dcc7f1d25 100644 --- a/client/tarantool/tc_cli.c +++ b/client/tarantool/tc_cli.c @@ -109,7 +109,6 @@ static struct tnt_lex_keyword tc_lex_keywords[] = { "notee", 5, TC_NOTEE }, { "loadfile", 8, TC_LOADFILE }, { "setopt", 6, TC_SETOPT}, - { "delim", 5, TC_SETOPT_DELIM}, { "delimiter", 9, TC_SETOPT_DELIM}, { NULL, 0, TNT_TK_NONE } }; @@ -125,13 +124,13 @@ tc_cmd_usage(void) { char usage[] = "---\n" - "- console client commands\n" - "- - help\n" - " - tee 'path'\n" - " - notee\n" - " - loadfile 'path'\n" - " - setopt key=val\n" - " - (possible pairs: delim[iter]=\'string\')\n" + "console client commands:\n" + " - help\n" + " - tee 'path'\n" + " - notee\n" + " - loadfile 'path'\n" + " - setopt key val\n" + " - (possible pairs: delimiter 'string')\n" "...\n"; tc_printf("%s", usage); } @@ -225,6 +224,17 @@ tc_cmd_loadfile(char *path, int *reconnect) return rc; } +static void replace_newline(char *cmd) { + int len = strlen(cmd); + int offset = 0; + for (int i = 0; i < len - 1; ++i) + if (cmd[i] == '\\' && cmd[i + 1] == 'n') + cmd[i++ - offset++] = '\n'; + else if (offset != 0) + cmd[i - offset] = cmd[i]; + cmd[len - offset] = '\0'; +} + static enum tc_cli_cmd_ret tc_cmd_try(char *cmd, size_t size, int *reconnect) { @@ -263,8 +273,10 @@ tc_cmd_try(char *cmd, size_t size, int *reconnect) case TC_SETOPT: switch (tnt_lex(&lex, &tk)) { case TC_SETOPT_DELIM: - if (tnt_lex(&lex, &tk) == '=' && - tnt_lex(&lex, &tk) == TNT_TK_STRING) { + if (tnt_lex(&lex, &tk) != '=') { + tnt_lex_push(&lex, tk); + } + if (tnt_lex(&lex, &tk) == TNT_TK_STRING) { if (!TNT_TK_S(tk)->size) { tc.opt.delim = ""; tc.opt.delim_len = 0; @@ -277,11 +289,12 @@ tc_cmd_try(char *cmd, size_t size, int *reconnect) strncpy(temp, (const char *)TNT_TK_S(tk)->data, TNT_TK_S(tk)->size + 1); + replace_newline(temp); tc.opt.delim = temp; tc.opt.delim_len = strlen(tc.opt.delim); } else { tc_printf("---\n"); - tc_printf(" - Expected: setopt delim[iter]='string'\n"); + tc_printf(" - Expected `setopt delimiter 'string'`\n"); tc_printf("---\n"); } break; @@ -381,9 +394,9 @@ static char* tc_cli_readline_pipe() { ungetc(c_t, stdin); wctomb(str + pos++, 0); break; - } - else + } else { pos += wctomb(str + pos, c); + } } if (pos == 1 && c == WEOF) { free(str); @@ -394,7 +407,6 @@ static char* tc_cli_readline_pipe() { static int check_delim(char* str, size_t len, size_t sep_len) { const char *sep = tc.opt.delim; - len = strip_end_ws(str); if (sep_len == 0) return 1; if (len < sep_len) @@ -403,8 +415,6 @@ static int check_delim(char* str, size_t len, size_t sep_len) { for (i = len; sep_len > 0; --sep_len, --i) if (str[i - 1] != sep[sep_len - 1]) return 0; - str[i] = '\0'; - len = strip_end_ws(str); return 1; } @@ -434,44 +444,44 @@ int tc_cli(void) if (isatty(STDIN_FILENO)) { snprintf(prompt_delim, sizeof(prompt_delim), "%*s> ", prompt_len, "-"); - part_cmd = readline(!tc_buf_str_isempty(&cmd) ? prompt_delim - : prompt); + part_cmd = readline(! tc_buf_str_isempty(&cmd) + ? prompt_delim + : prompt); } else { clearerr(stdin); part_cmd = tc_cli_readline_pipe(); } if (!part_cmd) break; - size_t part_cmd_len = strlen(part_cmd); - int delim_exists = check_delim(part_cmd, - part_cmd_len, - tc.opt.delim_len); if (tc_buf_str_append(&cmd, part_cmd, strlen(part_cmd))) tc_error(TC_REALLOCATION_ERROR, cmd.size); + int delim_exists = check_delim( cmd.data, + cmd.used - 1, + tc.opt.delim_len); + if (tc_buf_str_append(&cmd, "\n", 1)) /* Append '\n' to the STR */ + tc_error(TC_REALLOCATION_ERROR, + cmd.size); free(part_cmd); - if (!delim_exists && !feof(stdin)) { - if (tc_buf_str_append(&cmd, " ", 1)) - tc_error(TC_REALLOCATION_ERROR, - cmd.size); + if (!delim_exists && !feof(stdin)) /* If still without delimiter and not EOF */ continue; - } - tc_buf_str_stripws(&cmd); + tc_buf_str_delete(&cmd, 1); /* Delete last appended '\n' */ + if (isatty(STDIN_FILENO)) /* Enable history on readline use only */ + add_history(cmd.data); + tc_buf_cmdfy(&cmd, tc.opt.delim_len); /* Create admin cmd from STR */ if (delim_exists && tc_buf_str_isempty(&cmd)) - goto next; + goto next; /* If empty - don't send to server, it crashes */ tc_print_cmd2tee(cmd.used != 1 ? prompt_delim : prompt, cmd.data, cmd.used - 1); enum tc_cli_cmd_ret ret = tc_cli_cmd(cmd.data, cmd.used - 1); - if (isatty(STDIN_FILENO)) - add_history(cmd.data); next: tc_buf_clear(&cmd); if (ret == TC_CLI_EXIT || feof(stdin)) { tc_buf_free(&cmd); break; } -} + } /* updating history file */ write_history(history); diff --git a/client/tarantool/tc_opt.c b/client/tarantool/tc_opt.c index 93d0f4a00836edaf073efdbc0eb4d4245088ee24..c0096a275caf313d3acaa3e4fa7a65ade1dfec5a 100644 --- a/client/tarantool/tc_opt.c +++ b/client/tarantool/tc_opt.c @@ -37,7 +37,6 @@ #define TC_DEFAULT_HOST "localhost" -#define TC_DEFAULT_PORT 33013 #define TC_DEFAULT_PORT_ADMIN 33015 /* supported cli options */ @@ -116,7 +115,7 @@ enum tc_opt_mode tc_opt_init(struct tc_opt *opt, int argc, char **argv) /* server port */ const char *arg = NULL; - opt->port = TC_DEFAULT_PORT; + opt->port = 0; if (gopt_arg(tc_options, 'p', &arg)) opt->port = atoi(arg); diff --git a/client/tarantool/tc_print_snap.c b/client/tarantool/tc_print_snap.c index e08d183994722288657c9d7687efafa98f7cbadb..41dd902845f48f63ffd23fe94c9329c73d0db804 100644 --- a/client/tarantool/tc_print_snap.c +++ b/client/tarantool/tc_print_snap.c @@ -34,9 +34,7 @@ static void tc_printer_snap_tarantool( struct tnt_log_row_snap_v11 *row, struct tnt_tuple *tu) { - tc_printf("tag: %"PRIu16", cookie: %"PRIu64", space: %"PRIu32"\n", - row->tag, - row->cookie, + tc_printf("space: %"PRIu32" ", row->space); tc_print_tuple(tu); diff --git a/client/tarantool/tc_print_xlog.c b/client/tarantool/tc_print_xlog.c index 57f48513cd957f02eea149a2e3b01d3865c573b3..542f3952854c4769d6aff3e5094a875736f5d8c1 100644 --- a/client/tarantool/tc_print_xlog.c +++ b/client/tarantool/tc_print_xlog.c @@ -63,11 +63,14 @@ static void tc_printer_xlog_tarantool(struct tnt_log_header_v11 *hdr, struct tnt_request *r) { - tc_printf("%s lsn: %"PRIu64", time: %f, len: %"PRIu32"\n", + tc_printf("%s, lsn: %"PRIu64", time: %lf, len: %"PRIu32", space: " + "%"PRIu32" ", tc_query_type(r->h.type), hdr->lsn, hdr->tm, - hdr->len); + hdr->len, + r->r.insert.h.ns + ); switch (r->h.type) { case TNT_OP_INSERT: tc_print_tuple(&r->r.insert.t); diff --git a/cmake/BuildMisc.cmake b/cmake/BuildMisc.cmake index 8484ee83d2565344acbc502f7a57f5196bde3884..bf35f3a900fb52708aecea61c48641bb01e4c9bc 100644 --- a/cmake/BuildMisc.cmake +++ b/cmake/BuildMisc.cmake @@ -21,6 +21,11 @@ macro(libmisc_build) ) endif() + if (NOT HAVE_OPEN_MEMSTREAM) + list(APPEND misc_src + ${PROJECT_SOURCE_DIR}/third_party/open_memstream.c + ) + endif() if (NOT TARGET_OS_DEBIAN_FREEBSD) if (TARGET_OS_FREEBSD) set_source_files_properties( diff --git a/doc/user/configuration-reference.xml b/doc/user/configuration-reference.xml index 06a3533e500ff17ea4893508aaf2b206e1df5a19..0e341bb56353b686299f5bbbdf7d9320acf156b5 100644 --- a/doc/user/configuration-reference.xml +++ b/doc/user/configuration-reference.xml @@ -102,7 +102,7 @@ Tarantool 1.4.0-69-g45551dd <para><option>--check-config</option></para> <para>Check the configuration file for errors. This option is normally used on the command line - before <quote>reload configuration</quote> + before <quote>box.cfg.reload()</quote> is issued on the administrative port, to ensure that the new configuration is valid. When configuration is indeed correct, the program produces no output and returns <literal>0</literal>. @@ -130,16 +130,11 @@ Tarantool 1.4.0-69-g45551dd </option></para> <para>Initialize the directory, specified in <emphasis>vardir</emphasis> configuration option by creating an empty snapshot file in - it. If <filename>vardir</filename> doesn't contain at - least one snapshot, the server does not start. There is no - <quote>magic</quote> with automatic initialization of - <filename>vardir</filename> on boot to make - potential system errors more noticeable. For example, if the - operating system reboots and fails to mount the partition on - which <filename>vardir</filename> is expected to reside, the - <filename>rc.d</filename> or <command>service</command> script - responsible for server restart will also fail, thanks to this - option. + it. Prior to Tarantool 1.6, if <filename>vardir</filename> + didn't contain at least one snapshot, the server did not + start. Starting from 1.6, the initial storage file is + created automatically when starting in a clean data + directory. </para> </listitem> </itemizedlist> @@ -185,7 +180,7 @@ Tarantool 1.4.0-69-g45551dd <para> To facilitate centralized and automated configuration management, runtime configuration modifications are supported - solely through <olink targetptr="reload-configuration"/> + solely through <olink targetptr="box.cfg.reload"/> administrative statement. Thus, the procedure to change Tarantool configuration at runtime is to edit the configuration file. This ensures that, should the @@ -197,7 +192,7 @@ Tarantool 1.4.0-69-g45551dd such settings will be highlighted in this reference. If the same setting is given more than once, the latest occurrence takes effect. - You can always invoke <olink targetptr="show-configuration"/> + You can always invoke <olink targetptr="box.cfg.show"/> from the administrative console to show the current configuration. </para> @@ -532,7 +527,7 @@ tarantool_box: primary@sessions pri:33013 sec:33014 adm:33015</programlisting> <entry>no</entry> <entry>yes</entry> <entry>Reduce the throttling effect of <olink - targetptr="save-snapshot"/> on the INSERT/UPDATE/DELETE + targetptr="box.snapshot"/> on the INSERT/UPDATE/DELETE performance by setting a limit on how many megabytes per second it can write to disk. The same can be achieved by splitting <olink @@ -622,7 +617,7 @@ tarantool_box: primary@sessions pri:33013 sec:33014 adm:33015</programlisting> on <olink targetptr="primary_port"/>. This parameter is dynamic, that is, to enter master mode, simply set the value to an empty string and issue <olink - targetptr="reload-configuration"/>.</entry> + targetptr="box.cfg.reload"/>.</entry> </row> </tbody> diff --git a/doc/user/language-reference.xml b/doc/user/language-reference.xml index 02782b180f6749c6ae94751a11ca7d76dc84d0a1..1e3b97fdfdac9b8543de6ecb6886b12b74573323 100644 --- a/doc/user/language-reference.xml +++ b/doc/user/language-reference.xml @@ -54,7 +54,7 @@ client automatically selects the correct port for you with help of a simple regular expression. SELECTs, UPDATEs, INSERTs, DELETEs and CALLs are sent to the primary port. - SHOW, RELOAD, SAVE and other statements are sent to the administrative port. + Lua commands are sent to the administrative port. </para> <section xml:id="data-manipulation"> @@ -123,15 +123,13 @@ <section xml:id="administrative-console"> <title>Administrative console</title> <para> - The administrative console uses a simple text protocol. - All commands are case-insensitive. - You can connect to the administrative port using any - <command>telnet</command> client, or a tool like + The administrative console is simply an outlet of the Tarantool + Lua interpreter. You can connect to the administrative port + using any <command>telnet</command> client, or a tool like <command>rlwrap</command>, if access to readline features is desired. Additionally, <command>tarantool</command>, the - SQL-capable command line client, - understands all administrative statements - and automatically directs them to the administrative port. + SQL-capable command line client, automatically distinguishes + SQL and Lua statements and directs them to the appropriate port. The server response to an administrative command, even though it is always in plain text, can be quite complex. It is encoded using YAML markup to simplify automated parsing. @@ -144,41 +142,44 @@ <variablelist> <varlistentry> - <term xml:id="save-snapshot" xreflabel="SAVE SNAPSHOT"> - <emphasis role="tntadmin">save snapshot</emphasis> + <term xml:id="box.snapshot" xreflabel="box.snapshot()"> + <emphasis role="tntadmin">box.snapshot()</emphasis> </term> <listitem><para> Take a snapshot of all data and store it in <filename><olink targetptr="snap_dir"/>/<latest-lsn>.snap</filename>. - To take a snapshot, Tarantool forks and quickly - <function>munmap(2)</function>s all memory except the area - where tuples are stored. Since all modern operating systems support - virtual memory copy-on-write, this effectively creates a - consistent snapshot of all tuples in the child process, - which is then written to disk tuple by tuple. Since a - snapshot is written sequentially, you can expect a very + To take a snapshot, Tarantool first enters the delayed + garbage collection mode for all data. In this mode, + tuples which were allocated before the snapshot has + started are not freed until the snapshot has finished. + To preserve consistency of the primary key, used to + iterate over tuples, a copy-on-write technique is employed. + If the master process changes part of a primary key, + the corresponding process page is split, and the snapshot + process obtains an old copy of the page. Since a + snapshot is written sequentially, one can expect a very high write performance (averaging to 80MB/second on modern disks), which means an average database instance gets saved in a matter of minutes. Note, that as long as there - are any changes to the parent memory through concurrent + are any changes to the parent index memory through concurrent updates, there are going to be page splits, and therefore - you need to have some extra free memory to run this - command. 15%-30% of <olink targetptr="slab_alloc_arena"/> + one needs to have some extra free memory to run this + command. 10% of <olink targetptr="slab_alloc_arena"/> is, on average, sufficient. This statement waits until a snapshot is taken and returns operation result. For example: -<programlisting>localhost> show info +<programlisting>localhost> box.info() --- info: version: "1.4.6" lsn: 843301 ... -localhost> save snapshot +localhost> box.snapshot() --- ok ... -localhost> save snapshot +localhost> box.snapshot() --- fail: can't save snapshot, errno 17 (File exists) ... @@ -189,7 +190,7 @@ fail: can't save snapshot, errno 17 (File exists) write ahead log. Once a snapshot is taken, old WALs can be deleted as long as all replicas are up to date. But the WAL which was current at the time <emphasis - role="tntadmin">save snapshot</emphasis> started must be + role="tntadmin">box.snapshot()</emphasis> started must be kept for recovery, since it still contains log records written after the start of <emphasis role="tntadmin">save snapshot</emphasis>. @@ -206,8 +207,8 @@ fail: can't save snapshot, errno 17 (File exists) <varlistentry> - <term xml:id="reload-configuration" xreflabel="RELOAD CONFIGURATION"> - <emphasis role="tntadmin">reload configuration</emphasis> + <term xml:id="box.cfg.reload" xreflabel="box.cfg.reload()"> + <emphasis role="tntadmin">box.cfg.reload()</emphasis> </term> <listitem><para> Re-read the configuration file. If the file contains @@ -219,8 +220,8 @@ fail: can't save snapshot, errno 17 (File exists) </varlistentry> <varlistentry> - <term xml:id="show-configuration" xreflabel="SHOW CONFIGURATION"> - <emphasis role="tntadmin">show configuration</emphasis> + <term xml:id="box.cfg.show" xreflabel="box.cfg()"> + <emphasis role="tntadmin">box.cfg()</emphasis> </term> <listitem><para> Show the current settings. Displays all settings, @@ -230,12 +231,12 @@ fail: can't save snapshot, errno 17 (File exists) </varlistentry> <varlistentry> - <term xml:id="show-info" xreflabel="SHOW INFO"> - <emphasis role="tntadmin">show info</emphasis> + <term xml:id="box.info" xreflabel="box.info()"> + <emphasis role="tntadmin">box.info()</emphasis> </term> <listitem><para> <programlisting> -localhost> show info +localhost> box.info() --- info: version: "1.4.5-128-ga91962c" @@ -272,15 +273,15 @@ info: </varlistentry> <varlistentry> - <term xml:id="show-stat" xreflabel="SHOW STAT"> - <emphasis role="tntadmin">show stat</emphasis> + <term xml:id="box.stat.show" xreflabel="box.stat()"> + <emphasis role="tntadmin">box.stat()</emphasis> </term> <listitem><para> Show the average number of requests per second, and the total number of requests since startup, broken down by request type: INSERT or SELECT or UPDATE or DELETE." <programlisting> -localhost> show stat +localhost> box.stat() --- statistics: INSERT: { rps: 139 , total: 48207694 } @@ -293,8 +294,8 @@ statistics: </varlistentry> <varlistentry> - <term xml:id="show-slab" xreflabel="SHOW SLAB"> - <emphasis role="tntadmin">show slab</emphasis> + <term xml:id="box.slab.info" xreflabel="box.slab.info()"> + <emphasis role="tntadmin">box.slab.info()</emphasis> </term> <listitem> <para> @@ -319,19 +320,8 @@ statistics: </varlistentry> <varlistentry> - <term xml:id="show-palloc" xreflabel="SHOW PALLOC"> - <emphasis role="tntadmin">show palloc</emphasis> - </term> - <listitem><para> - A pool allocator is used for temporary memory, when - serving client requests. Every fiber has its own - temporary pool. Shows the current state of pools of all fibers. - </para></listitem> - </varlistentry> - - <varlistentry> - <term xml:id="save-coredump" xreflabel="SAVE COREDUMP"> - <emphasis role="tntadmin">save coredump</emphasis> + <term xml:id="box.coredump" xreflabel="box.coredump()"> + <emphasis role="tntadmin">box.coredump()</emphasis> </term> <listitem><para> Fork and dump a core. Since Tarantool stores all tuples @@ -341,8 +331,8 @@ statistics: </varlistentry> <varlistentry> - <term xml:id="show-fiber" xreflabel="SHOW FIBER"> - <emphasis role="tntadmin">show fiber</emphasis> + <term xml:id="box.fiber.info" xreflabel="box.fiber.info()"> + <emphasis role="tntadmin">box.fiber.info()</emphasis> </term> <listitem><para> Show all running fibers, with their stack. @@ -351,11 +341,11 @@ statistics: </varlistentry> <varlistentry> - <term xml:id="lua-command" xreflabel="LUA ..."> - <emphasis role="tntadmin">lua ...</emphasis> + <term xml:id="lua-command"> + <emphasis role="tntadmin">...</emphasis> </term> <listitem><para> - Execute a chunk of Lua code. This can be used to define, + Execute any chunk of Lua code. This can be used to define, invoke, debug and drop <olink targetptr="stored-procedures">stored procedures</olink>, inspect server environment, perform automated diff --git a/doc/user/persistence-architecture.xml b/doc/user/persistence-architecture.xml index 2c9cc0272d2721fa660920b13dbe4c62f474f5a2..c98e280fb398a0b067faa917342d005cb09e4f7e 100644 --- a/doc/user/persistence-architecture.xml +++ b/doc/user/persistence-architecture.xml @@ -91,7 +91,7 @@ possible to turn the write ahead log completely off, by setting <olink targetptr="wal_mode"/> to <emphasis>none</emphasis>. Even without the write ahead log it's still possible to take a persistent copy of the entire data set with -<olink targetptr="save-snapshot"/>. +<olink targetptr="box.snapshot"/>. </para> diff --git a/doc/user/preface.xml b/doc/user/preface.xml index d1878e68b88a4f3eb8a043a1bd91df3e83c27053..b208307440759e28c99f69e432cee1e9345356c3 100644 --- a/doc/user/preface.xml +++ b/doc/user/preface.xml @@ -39,11 +39,11 @@ A simple solution is employed: the server <emphasis role="strong">can be requested to save a concise snapshot</emphasis> of - its current data. The underlying operating system's - <quote>copy-on-write</quote> feature is employed to take the - snapshot in a quick, resource-savvy and non-blocking manner. - The <quote>copy-on-write</quote> technique guarantees that - snapshotting has minimal impact on server performance. + its current data. A combination of delayed garbage collection + for data pages and <quote>copy-on-write</quote> technique for + index pages is employed to provide the snapshot process + with a consistent read view, so that the snapshot is taken + in a quick, resource-savvy and non-blocking manner. </para> <para> diff --git a/doc/user/replication.xml b/doc/user/replication.xml index 66ee093f08752f3fc691b68989b12b6b7852a36f..7cb912f98d5f1a5ddea6b170c517e183c4d7d180 100644 --- a/doc/user/replication.xml +++ b/doc/user/replication.xml @@ -101,7 +101,7 @@ <note><simpara> Replication parameters are "dynamic", which allows the replica to become a master and vice versa with help of - <olink targetptr="reload-configuration"/> statement. + <olink targetptr="box.cfg.reload"/> statement. </simpara></note> </section> @@ -152,7 +152,7 @@ <listitem> <para> Record the replica's LSN, by issuing <olink - targetptr="show-info"/>. This LSN may prove useful if + targetptr="box.info"/>. This LSN may prove useful if there are updates on the master that never reached the replica. </para> diff --git a/doc/user/stored-procedures.xml b/doc/user/stored-procedures.xml index a756ca3f60dbb24fd1994796f0c7b6e350881398..d13e140dcbfd58a1f814886fafe2601307f1cc04 100644 --- a/doc/user/stored-procedures.xml +++ b/doc/user/stored-procedures.xml @@ -34,7 +34,7 @@ <para> Procedures can be invoked from the administrative console and using the binary protocol, for example: -<programlisting><computeroutput>localhost> lua function f1() return 'hello' end +<programlisting><computeroutput>localhost> function f1() return 'hello' end --- ... localhost> call f1() @@ -57,15 +57,15 @@ Found 1 tuple: administrative console, the newly created <code language="Pascal">function f1()</code> can be called there too: -<programlisting><computeroutput>localhost> lua f1() +<programlisting><computeroutput>localhost> f1() --- - hello ... -localhost> lua 1+2 +localhost> 1+2 --- - 3 ... -localhost> lua "hello".." world" +localhost> "hello".." world" --- - hello world ... @@ -127,11 +127,11 @@ expirationd.run_task("exprd space 0", 0, is_expired, purge, within the system. </para> <para> - There is a single global instance of the Lua interpreter, which is - shared across all connections. Anything prefixed with - <code>lua </code> on the administrative console is sent - directly to this interpreter. Any change of the interpreter - state is immediately available to all client connections. + There is a single global instance of the Lua interpreter, + which is shared across all connections. Any command typed + entered on the on the administrative console is sent directly + to this interpreter. Any change of the interpreter state is + immediately available to all client connections. </para> <para> Each connection, however, is using its own Lua @@ -169,10 +169,10 @@ function f1(a) return type(a), s end kostja@atlas:~$ tarantool -localhost> lua dofile('arg.lua') +localhost> dofile('arg.lua') --- ... -localhost> lua f1('1234') +localhost> f1('1234') --- - string - 0x31 0x32 0x33 0x34 @@ -181,7 +181,7 @@ localhost> call f1('1234') Call OK, 2 rows affected ['string'] ['0x31 0x32 0x33 0x34 '] -localhost> lua f1(1234) +localhost> f1(1234) --- - number - 1234 @@ -199,7 +199,7 @@ Call OK, 2 rows affected <para>In addition to conventional method invocation, Lua provides object-oriented syntax. Access to the latter is available on the administrative console only: -<programlisting><computeroutput>localhost> lua box.space[0]:truncate() +<programlisting><computeroutput>localhost> box.space[0]:truncate() --- ... localhost> call box.space[0]:truncate() @@ -225,14 +225,14 @@ error: 1:15 expected '(' Similarly, an error which has occurred inside Tarantool (observed on the client as an error code), when happens during execution of a Lua procedure, produces a genuine Lua error: -<programlisting><computeroutput>localhost> lua function f1() error("oops") end +<programlisting><computeroutput>localhost> function f1() error("oops") end --- ... localhost> call f1() Call ERROR, Lua error: [string "function f1() error("oops") end"]:1: oops (ER_PROC_LUA) localhost> call box.insert('99', 1, 'test') Call ERROR, Space 99 is disabled (ER_SPACE_DISABLED) -localhost> lua pcall(box.insert, 99, 1, 'test') +localhost> pcall(box.insert, 99, 1, 'test') --- - false - Space 99 is disabled @@ -245,7 +245,7 @@ localhost> lua pcall(box.insert, 99, 1, 'test') <code>box</code> Lua library. The contents of the library can be inspected at runtime: -<programlisting><computeroutput>localhost> lua for k, v in pairs(box) do print(k, ": ", type(v)) end +<programlisting><computeroutput>localhost> for k, v in pairs(box) do print(k, ": ", type(v)) end --- fiber: table space: table @@ -291,15 +291,15 @@ pack: function arithmetics as in the built-in number type. <bridgehead renderas="sect4">Example</bridgehead> <programlisting> -localhost> lua tonumber64('123456789'), tonumber64(123456789) +localhost> tonumber64('123456789'), tonumber64(123456789) --- - 123456789 - 123456789 ... -localhost> lua i=tonumber64(1) +localhost> i=tonumber64(1) --- ... -localhost> lua type(i), type(i*2), type(i/2), i, i*2, i/2 +localhost> type(i), type(i*2), type(i/2), i, i*2, i/2 --- - cdata - cdata @@ -407,11 +407,11 @@ Call OK, 1 rows affected localhost> call box.select(0, 0, 'test') Call OK, 1 rows affected ['test', 'my first tuple'] -localhost> lua box.insert(5, 'testtest', 'firstname', 'lastname') +localhost> box.insert(5, 'testtest', 'firstname', 'lastname') --- - 'testtest': {'firstname', 'lastname'} ... -localhost> lua box.select(5, 1, 'firstname', 'lastname') +localhost> box.select(5, 1, 'firstname', 'lastname') --- - 'testtest': {'firstname', 'lastname'} ... @@ -509,31 +509,31 @@ localhost> lua box.select(5, 1, 'firstname', 'lastname') Returns the updated tuple. <bridgehead renderas="sect4">Example</bridgehead> <programlisting> -localhost> lua box.insert(0, 0, 'hello world') +localhost> box.insert(0, 0, 'hello world') --- - 0: {'hello world'} ... -localhost> lua box.update(0, 0, '+p', 1, 1) -- add value 1 to field #1 +localhost> box.update(0, 0, '+p', 1, 1) -- add value 1 to field #1 --- error: 'Field type does not match one required by operation: expected a 32-bit or 64-bit int' ... -localhost> lua box.update(0, 0, '+p', 0, 2) -- add value 2 to field 0 +localhost> box.update(0, 0, '+p', 0, 2) -- add value 2 to field 0 --- - 2: {'hello world'} ... -localhost> lua box.update(0, 2, '!p', 1, 'Bienvenue tout le monde!') +localhost> box.update(0, 2, '!p', 1, 'Bienvenue tout le monde!') --- - 2: {'Bienvenue tout le monde!', 'hello world'} ... -localhost> lua box.update(0, 2, '#p', 2, 1) +localhost> box.update(0, 2, '#p', 2, 1) --- - 2: {'Bienvenue tout le monde!'} ... -localhost> lua box.insert(0, 3, 'crocodile', 'giraffe', 'baobab', 'bamblebee', 'hippopotamus', 'rhino') +localhost> box.insert(0, 3, 'crocodile', 'giraffe', 'baobab', 'bamblebee', 'hippopotamus', 'rhino') --- - 3: {'crocodile', 'giraffe', 'baobab', 'bamblebee', 'hippopotamus', 'rhino'} ... -localhost> lua box.update(0, 3, '#p', 3, 2) +localhost> box.update(0, 3, '#p', 3, 2) --- - 3: {'crocodile', 'giraffe', 'hippopotamus', 'rhino'} ... @@ -609,26 +609,26 @@ localhost> insert into t4 values ('2', '2') Insert OK, 1 rows affected localhost> insert into t4 values ('3', '3') Insert OK, 1 rows affected -ocalhost> lua box.select_range(4, 0, 10) +ocalhost> box.select_range(4, 0, 10) --- - '3': {'3'} - '0': {'0'} - '1': {'1'} - '2': {'2'} ... -localhost> lua box.select_range(4, 1, 10) +localhost> box.select_range(4, 1, 10) --- - '0': {'0'} - '1': {'1'} - '2': {'2'} - '3': {'3'} ... -localhost> lua box.select_range(4, 1, 2) +localhost> box.select_range(4, 1, 2) --- - '0': {'0'} - '1': {'1'} ... -localhost> lua box.select_range(4, 1, 2, '1') +localhost> box.select_range(4, 1, 2, '1') --- - '1': {'1'} - '2': {'2'} @@ -679,23 +679,23 @@ localhost> insert into t4 values ('2', '2') Insert OK, 1 rows affected localhost> insert into t4 values ('3', '3') Insert OK, 1 rows affected -localhost> lua box.select_reverse_range(4, 0, 10) +localhost> box.select_reverse_range(4, 0, 10) --- error: 'Illegal parameters, hash iterator is forward only ... -localhost> lua box.select_reverse_range(4, 1, 10) +localhost> box.select_reverse_range(4, 1, 10) --- - '3': {'3'} - '2': {'2'} - '1': {'1'} - '0': {'0'} ... -localhost> lua box.select_reverse_range(4, 1, 2) +localhost> box.select_reverse_range(4, 1, 2) --- - '3': {'3'} - '2': {'2'} ... -localhost> lua box.select_reverse_range(4, 1, 2, '1') +localhost> box.select_reverse_range(4, 1, 2, '1') --- - '1': {'1'} - '0': {'0'} @@ -782,27 +782,27 @@ localhost> lua box.select_reverse_range(4, 1, 2, '1') Unknown format specifier. <bridgehead renderas="sect4">Example</bridgehead> <programlisting> -localhost> lua box.insert(0, 0, 'hello world') +localhost> box.insert(0, 0, 'hello world') --- - 0: {'hello world'} ... -localhost> lua box.update(0, 0, "=p", 1, 'bye world') +localhost> box.update(0, 0, "=p", 1, 'bye world') --- - 0: {'bye world'} ... -localhost> lua box.update(0, 0, ":p", 1, box.pack('ppp', 0, 3, 'hello')) +localhost> box.update(0, 0, ":p", 1, box.pack('ppp', 0, 3, 'hello')) --- - 0: {'hello world'} ... -localhost> lua box.update(0, 0, "=p", 1, 4) +localhost> box.update(0, 0, "=p", 1, 4) --- - 0: {4} ... -localhost> lua box.update(0, 0, "+p", 1, 4) +localhost> box.update(0, 0, "+p", 1, 4) --- - 0: {8} ... -localhost> lua box.update(0, 0, "^p", 1, 4) +localhost> box.update(0, 0, "^p", 1, 4) --- - 0: {12} ... @@ -815,40 +815,40 @@ localhost> lua box.update(0, 0, "^p", 1, 4) <listitem><para> Counterpart to <code>box.pack()</code>. <bridgehead renderas="sect4">Example</bridgehead> -<programlisting>localhost> lua tuple=box.replace(2, 0) +<programlisting>localhost> tuple=box.replace(2, 0) --- ... -localhost> lua string.len(tuple[0]) +localhost> string.len(tuple[0]) --- - 4 ... -localhost> lua box.unpack('i', tuple[0]) +localhost> box.unpack('i', tuple[0]) --- - 0 ... -localhost> lua box.unpack('bsil', box.pack('bsil', 255, 65535, 4294967295, tonumber64('18446744073709551615'))) +localhost> box.unpack('bsil', box.pack('bsil', 255, 65535, 4294967295, tonumber64('18446744073709551615'))) --- - 255 - 65535 - 4294967295 - 18446744073709551615 ... -localhost> lua num, str, num64 = box.unpack('ppp', box.pack('ppp', 666, 'string', tonumber64('666666666666666'))) +localhost> num, str, num64 = box.unpack('ppp', box.pack('ppp', 666, 'string', tonumber64('666666666666666'))) --- ... -localhost> lua print(box.unpack('i', num)); +localhost> print(box.unpack('i', num)); --- 666 ... -localhost> lua print(str); +localhost> print(str); --- string ... -localhost> lua print(box.unpack('l', num64)) +localhost> print(box.unpack('l', num64)) --- 666666666666666 ... -localhost> lua box.unpack('=p', box.pack('=p', 1, '666')) +localhost> box.unpack('=p', box.pack('=p', 1, '666')) --- - 1 - 666 @@ -890,20 +890,20 @@ Note: the administrative console output must be YAML-compatible. an arbitrary piece of Lua code, without having to introduce changes to the global Lua environment. <bridgehead renderas="sect4">Example</bridgehead> -<programlisting>lua box.dostring('abc') +<programlisting>box.dostring('abc') --- error: '[string "abc"]:1: ''='' expected near ''<eof>''' ... -lua box.dostring('return 1') +box.dostring('return 1') --- - 1 ... -lua box.dostring('return ...', 'hello', 'world') +box.dostring('return ...', 'hello', 'world') --- - hello - world ... -lua box.dostring('local f = function(key) t=box.select(0, 0, key); if t ~= nil then return t[0] else return nil end end return f(...)', 0) +box.dostring('local f = function(key) t=box.select(0, 0, key); if t ~= nil then return t[0] else return nil end end return f(...)', 0) --- - nil ... @@ -964,7 +964,7 @@ lua box.dostring('local f = function(key) t=box.select(0, 0, key); if t ~= nil t </para> <bridgehead renderas="sect4">Example</bridgehead> <programlisting> - lua box.uuid_hex() + box.uuid_hex() --- - a4f29fa0eb6d11e19f7737696d7fa8ff ... @@ -994,7 +994,7 @@ lua box.dostring('local f = function(key) t=box.select(0, 0, key); if t ~= nil t </para> <bridgehead renderas="sect4">Example</bridgehead> <programlisting> - lua box.raise(box.error.ER_WAL_IO, 'Wal I/O error') + box.raise(box.error.ER_WAL_IO, 'Wal I/O error') --- error: 'Wal I/O error' ... @@ -1012,11 +1012,11 @@ lua box.dostring('local f = function(key) t=box.select(0, 0, key); if t ~= nil t NUM or NUM64 primary key index of type TREE. </para> <bridgehead renderas="sect4">Example</bridgehead> - <programlisting>localhost> lua box.auto_increment(0, "I am a duplicate") + <programlisting>localhost> box.auto_increment(0, "I am a duplicate") --- - 1: {'I am a duplicate'} ... -localhost> lua box.auto_increment(0, "I am a duplicate") +localhost> box.auto_increment(0, "I am a duplicate") --- - 2: {'I am a duplicate'} ... @@ -1037,11 +1037,11 @@ localhost> lua box.auto_increment(0, "I am a duplicate") new counter value back. </para> <bridgehead renderas="sect4">Example</bridgehead> - <programlisting>localhost> lua box.counter.inc(0, 'top.mail.ru') + <programlisting>localhost> box.counter.inc(0, 'top.mail.ru') --- - 1 ... -localhost> lua box.counter.inc(0, 'top.mail.ru') +localhost> box.counter.inc(0, 'top.mail.ru') --- - 2 ...</programlisting> @@ -1058,11 +1058,11 @@ localhost> lua box.counter.inc(0, 'top.mail.ru') drops to 0, the tuple is deleted. </para> <bridgehead renderas="sect4">Example</bridgehead> - <programlisting>localhost> lua box.counter.dec(0, 'top.mail.ru') + <programlisting>localhost> box.counter.dec(0, 'top.mail.ru') --- - 1 ... -localhost> lua box.counter.dec(0, 'top.mail.ru') +localhost> box.counter.dec(0, 'top.mail.ru') --- - 0 ...</programlisting> @@ -1086,23 +1086,23 @@ localhost> lua box.counter.dec(0, 'top.mail.ru') <listitem><para> <bridgehead renderas="sect4">Example</bridgehead> <programlisting> -localhost> lua t=box.insert(0, 1, 'abc', 'cde', 'efg', 'ghq', 'qkl') +localhost> t=box.insert(0, 1, 'abc', 'cde', 'efg', 'ghq', 'qkl') --- ... -localhost> lua #t +localhost> #t --- - 6 ... -localhost> lua t[1], t[5] +localhost> t[1], t[5] --- - abc - qkl ... -localhost> lua t[6] +localhost> t[6] --- error: 'Lua error: [string "return t[6]"]:1: box.tuple: index 6 is out of bounds (0..5)' ... -localhost> lua for k,v in t:pairs() do print(v) end +localhost> for k,v in t:pairs() do print(v) end --- abc @@ -1111,7 +1111,7 @@ efg ghq qkl ... -localhost> lua t:unpack() +localhost> t:unpack() --- - - abc @@ -1120,58 +1120,58 @@ localhost> lua t:unpack() - ghq - qkl ... -localhost> lua t:slice(1, 2) +localhost> t:slice(1, 2) --- - abc ... -localhost> lua t:slice(1, 3) +localhost> t:slice(1, 3) --- - abc - cde ... -localhost> lua t:slice(1, -1) +localhost> t:slice(1, -1) --- - abc - cde - efg - ghq ... -localhost> lua t:transform(1, 3) +localhost> t:transform(1, 3) --- - 1: {'ghq', 'qkl'} ... -localhost> lua t:transform(0, 1, 'zyx') +localhost> t:transform(0, 1, 'zyx') --- - 'zyx': {'abc', 'cde', 'efg', 'ghq', 'qkl'} ... -localhost> lua t:transform(-1, 1, 'zyx') +localhost> t:transform(-1, 1, 'zyx') --- - 1: {'abc', 'cde', 'efg', 'ghq', 'zyx'} ... -localhost> lua t=box.insert(0, 'abc', 'def', 'abc') +localhost> t=box.insert(0, 'abc', 'def', 'abc') --- ... -localhost> lua t:find('abc') +localhost> t:find('abc') --- - 0 ... -localhost> lua t:findall('abc') +localhost> t:findall('abc') --- - 0 - 2 ... -localhost> lua t:find(1, 'abc') +localhost> t:find(1, 'abc') --- - 2 ... -localhost> lua t = box.tuple.new('abc') +localhost> t = box.tuple.new('abc') --- ... -localhost> lua t +localhost> t --- - 'abc': {} ... -localhost> lua t:bsize() +localhost> t:bsize() --- - 4 ... @@ -1186,7 +1186,7 @@ localhost> lua t:bsize() Construct a new tuple from a Lua table or a scalar. </para> <bridgehead renderas="sect4">Example</bridgehead> - <programlisting>localhost> lua box.tuple.new({tonumber64('18446744073709551615'), 'string', 1}) + <programlisting>localhost> box.tuple.new({tonumber64('18446744073709551615'), 'string', 1}) --- - 18446744073709551615: {'string', 1} ... @@ -1222,35 +1222,35 @@ localhost> lua t:bsize() </variablelist> <bridgehead renderas="sect4">Example</bridgehead> <programlisting> -lua box.cjson.encode(123) +box.cjson.encode(123) --- - 123 ... -lua box.cjson.encode({123}) +box.cjson.encode({123}) --- - [123] ... -lua box.cjson.encode({123, 234, 345}) +box.cjson.encode({123, 234, 345}) --- - [123,234,345] ... -lua box.cjson.encode({abc = 234, cde = 345}) +box.cjson.encode({abc = 234, cde = 345}) --- - {"cde":345,"abc":234} ... -lua box.cjson.encode({hello = { 'world' } }) +box.cjson.encode({hello = { 'world' } }) --- - {"hello":["world"]} ... -lua box.cjson.decode('123') +box.cjson.decode('123') --- - 123 ... -lua box.cjson.decode('[123, "hello"]')[2] +box.cjson.decode('[123, "hello"]')[2] --- - hello ... -lua box.cjson.decode('{"hello": "world"}').hello +box.cjson.decode('{"hello": "world"}').hello --- - world ... @@ -1418,7 +1418,7 @@ lua box.cjson.decode('{"hello": "world"}').hello </simpara> <bridgehead renderas="sect4">Example</bridgehead> <programlisting> -localhost> lua for k,v in box.space[0]:pairs() do print(v) end +localhost> for k,v in box.space[0]:pairs() do print(v) end --- 1: {'hello'} 2: {'my '} @@ -1560,19 +1560,19 @@ localhost> INSERT INTO t0 VALUES (5, 2, 1) Insert OK, 1 rows affected localhost> INSERT INTO t0 VALUES (6, 2, 2) Insert OK, 1 rows affected -localhost> lua it = box.space[0].index[1]:iterator(box.index.EQ, 1); print(it(), " ", it(), " ", it()); +localhost> it = box.space[0].index[1]:iterator(box.index.EQ, 1); print(it(), " ", it(), " ", it()); --- 1: {1, 0} 2: {1, 1} 3: {1, 2} ... -localhost> lua it = box.space[0].index[1]:iterator(box.index.EQ, 1, 2); print(it(), " ", it(), " ", it()); +localhost> it = box.space[0].index[1]:iterator(box.index.EQ, 1, 2); print(it(), " ", it(), " ", it()); --- 3: {1, 2} nil nil ... -localhost> lua i = box.space[0].index[1]:iterator(box.index.GE, 2, 1); print(it(), " ", it(), " ", it()); +localhost> i = box.space[0].index[1]:iterator(box.index.GE, 2, 1); print(it(), " ", it(), " ", it()); --- 5: {2, 1} 6: {2, 2} nil ... -localhost> lua for v in box.space[0].index[1]:iterator(box.index.ALL) do print(v) end +localhost> for v in box.space[0].index[1]:iterator(box.index.ALL) do print(v) end --- 1: {1, 0} 2: {1, 1} @@ -1581,7 +1581,7 @@ localhost> lua for v in box.space[0].index[1]:iterator(box.index.ALL) do print(v 5: {2, 1} 6: {2, 2} ... -localhost> lua i = box.space[0].index[0]:iterator(box.index.LT, 1); +localhost> i = box.space[0].index[0]:iterator(box.index.LT, 1); --- error: 'Iterator type is not supported' </programlisting> @@ -2587,7 +2587,7 @@ self:insert("1", "Hello", "World") <varlistentry> <term><emphasis role="lua">box.cfg</emphasis></term> <listitem><bridgehead renderas="sect4">Example</bridgehead><programlisting> -localhost> lua for k, v in pairs(box.cfg) do print(k, " = ", v) end +localhost> for k, v in pairs(box.cfg) do print(k, " = ", v) end --- io_collect_interval = 0 pid_file = box.pid @@ -2624,7 +2624,7 @@ logger = cat - >> tarantool.log </simpara> <bridgehead renderas="sect4">Example</bridgehead><programlisting> -localhost> lua for k,v in pairs(box.info()) do print(k, ": ", v) end +localhost> for k,v in pairs(box.info()) do print(k, ": ", v) end --- version: 1.4.7-92-g4ba95ca status: primary @@ -2646,47 +2646,47 @@ config: /home/unera/work/tarantool/test/box/tarantool_good.cfg </term> <listitem> <bridgehead renderas="sect4">Example</bridgehead><programlisting> -localhost> lua box.info.pid +localhost> box.info.pid --- - 1747 ... -localhost> lua box.info.logger_pid +localhost> box.info.logger_pid --- - 1748 ... -localhost> lua box.info.version +localhost> box.info.version --- - 1.4.7-92-g4ba95ca ... -localhost> lua box.info.config +localhost> box.info.config --- - /home/unera/work/tarantool/test/box/tarantool_good.cfg ... -localhost> lua box.info.uptime +localhost> box.info.uptime --- - 3672 ... -localhost> lua box.info.lsn +localhost> box.info.lsn --- - 1712 ... -localhost> lua box.info.status +localhost> box.info.status --- - primary ... -localhost> lua box.info.recovery_lag +localhost> box.info.recovery_lag --- - 0.000 ... -localhost> lua box.info.recovery_last_update +localhost> box.info.recovery_last_update --- - 1306964594.980 ... -localhost> lua box.info.snapshot_pid +localhost> box.info.snapshot_pid --- - 0 ... -localhost> lua for k, v in pairs(box.info.build) do print(k .. ': ', v) end +localhost> for k, v in pairs(box.info.build) do print(k .. ': ', v) end --- flags: -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -DCORO_ASM -fno-omit-frame-pointer -fno-stack-protector -fexceptions -funwind-tables -fgnu89-inline -pthread -Wno-sign-compare -Wno-strict-aliasing -std=gnu99 -Wall -Wextra -Werror target: Linux-x86_64-Debug @@ -2703,20 +2703,20 @@ options: cmake . -DCMAKE_INSTALL_PREFIX=/usr/local -DENABLE_STATIC=OFF -DENABLE_ <varlistentry> <term><emphasis role="lua">box.slab</emphasis></term> <listitem><bridgehead renderas="sect4">Example</bridgehead><programlisting> -localhost> lua box.slab.arena_used +localhost> box.slab.arena_used --- - 4194304 ... -localhost> lua box.slab.arena_size +localhost> box.slab.arena_size --- - 104857600 ... -localhost> lua for k, v in pairs(box.slab.slabs) do print(k) end +localhost> for k, v in pairs(box.slab.slabs) do print(k) end --- 64 128 ... -localhost> lua for k, v in pairs(box.slab.slabs[64]) do print(k, ':', v) end +localhost> for k, v in pairs(box.slab.slabs[64]) do print(k, ':', v) end --- items:1 bytes_used:160 @@ -2735,15 +2735,15 @@ bytes_free:4194144 <varlistentry> <term><emphasis role="lua">box.stat</emphasis></term> <listitem><bridgehead renderas="sect4">Example</bridgehead><programlisting> -localhost> lua box.stat -- a virtual table +localhost> box.stat -- a virtual table --- - table: 0x41a07a08 ... -localhost> lua box.stat() -- a full table (the same) +localhost> box.stat() -- a full table (the same) --- - table: 0x41a0ebb0 ... -localhost> lua for k, v in pairs(box.stat()) do print(k) end +localhost> for k, v in pairs(box.stat()) do print(k) end --- DELETE SELECT @@ -2752,17 +2752,17 @@ CALL UPDATE DELETE_1_3 ... -localhost> lua for k, v in pairs(box.stat().DELETE) do print(k, ': ', v) end +localhost> for k, v in pairs(box.stat().DELETE) do print(k, ': ', v) end --- total: 23210 rps: 22 ... -localhost> lua for k, v in pairs(box.stat.DELETE) do print(k, ': ', v) end -- the same +localhost> for k, v in pairs(box.stat.DELETE) do print(k, ': ', v) end -- the same --- total: 23210 rps: 22 ... -localhost> lua for k, v in pairs(box.stat.SELECT) do print(k, ': ', v) end +localhost> for k, v in pairs(box.stat.SELECT) do print(k, ': ', v) end --- total: 34553330 rps: 23 diff --git a/doc/user/target.db b/doc/user/target.db index 20f40ca7c43174e05619797a04dda854575bb851..67cd80f8010b858f4ff9a5f57c4119eb30023375 100644 --- a/doc/user/target.db +++ b/doc/user/target.db @@ -1,5 +1,7 @@ -<div element="book" href="#tarantool-user-guide" number="" targetptr="tarantool-user-guide"><ttl>Tarantool User Guide, version 1.5.1-28-g4f96b1a</ttl><xreftext>Tarantool User Guide, version 1.5.1-28-g4f96b1a</xreftext><div element="chapter" href="#preface" number="1" targetptr="preface"><ttl>Preface</ttl><xreftext>Chapter 1, <i>Preface</i></xreftext><div element="section" href="#tarantool-overview" number="" targetptr="tarantool-overview"><ttl>Tarantool: an overview</ttl><xreftext>the section called “Tarantool: an overviewâ€</xreftext></div><div element="section" href="#manual-conventions" number="" targetptr="manual-conventions"><ttl>Conventions</ttl><xreftext>the section called “Conventionsâ€</xreftext></div><div element="section" href="#reporting-bugs" number="" targetptr="reporting-bugs"><ttl>Reporting bugs</ttl><xreftext>the section called “Reporting bugsâ€</xreftext></div></div><div element="chapter" href="#getting-started" number="2" targetptr="getting-started"><ttl>Getting started</ttl><xreftext>Chapter 2, <i>Getting started</i></xreftext></div><div element="chapter" href="#data-and-persistence" number="3" targetptr="data-and-persistence"><ttl>Data model and data persistence</ttl><xreftext>Chapter 3, <i>Data model and data persistence</i></xreftext><div element="section" href="#dynamic-data-model" number="" targetptr="dynamic-data-model"><ttl>Dynamic data model</ttl><xreftext>the section called “Dynamic data modelâ€</xreftext></div><div element="section" href="#data-persistence" number="" targetptr="data-persistence"><ttl>Data persistence</ttl><xreftext>the section called “Data persistenceâ€</xreftext></div></div><div element="chapter" href="#language-reference" number="4" targetptr="language-reference"><ttl>Language reference</ttl><xreftext>Chapter 4, <i>Language reference</i></xreftext><div element="section" href="#data-manipulation" number="" targetptr="data-manipulation"><ttl>Data manipulation</ttl><xreftext>the section called “Data manipulationâ€</xreftext><div element="section" href="#memcached-protocol" number="" targetptr="memcached-protocol"><ttl>Memcached protocol</ttl><xreftext>the section called “Memcached protocolâ€</xreftext></div></div><div element="section" href="#administrative-console" number="" targetptr="administrative-console"><ttl>Administrative console</ttl><xreftext>the section called “Administrative consoleâ€</xreftext><obj element="term" href="#save-snapshot" number="" targetptr="save-snapshot"><ttl>???TITLE???</ttl><xreftext>SAVE SNAPSHOT</xreftext></obj><obj element="term" href="#reload-configuration" number="" targetptr="reload-configuration"><ttl>???TITLE???</ttl><xreftext>RELOAD CONFIGURATION</xreftext></obj><obj element="term" href="#show-configuration" number="" targetptr="show-configuration"><ttl>???TITLE???</ttl><xreftext>SHOW CONFIGURATION</xreftext></obj><obj element="term" href="#show-info" number="" targetptr="show-info"><ttl>???TITLE???</ttl><xreftext>SHOW INFO</xreftext></obj><obj element="term" href="#show-stat" number="" targetptr="show-stat"><ttl>???TITLE???</ttl><xreftext>SHOW STAT</xreftext></obj><obj element="term" href="#show-slab" number="" targetptr="show-slab"><ttl>???TITLE???</ttl><xreftext>SHOW SLAB</xreftext></obj><obj element="term" href="#show-palloc" number="" targetptr="show-palloc"><ttl>???TITLE???</ttl><xreftext>SHOW PALLOC</xreftext></obj><obj element="term" href="#save-coredump" number="" targetptr="save-coredump"><ttl>???TITLE???</ttl><xreftext>SAVE COREDUMP</xreftext></obj><obj element="term" href="#show-fiber" number="" targetptr="show-fiber"><ttl>???TITLE???</ttl><xreftext>SHOW FIBER</xreftext></obj><obj element="term" href="#lua-command" number="" targetptr="lua-command"><ttl>???TITLE???</ttl><xreftext>LUA ...</xreftext></obj></div><div element="section" href="#stored-procedures" number="" targetptr="stored-procedures"><ttl>Writing stored procedures in Lua</ttl><xreftext>the section called “Writing stored procedures in Luaâ€</xreftext><obj element="filename" href="#init.lua" number="" targetptr="init.lua"><ttl>???TITLE???</ttl><xreftext>init.lua</xreftext></obj><obj element="term" href="#tonumber64" number="" targetptr="tonumber64"><ttl>???TITLE???</ttl><xreftext>tonumber64</xreftext></obj><div element="section" href="#sp-box" number="" targetptr="sp-box"><ttl>Package <code class="code">box</code></ttl><xreftext>the section called “Package <code class="code">box</code>â€</xreftext><obj element="variablelist" href="#box" number="" targetptr="box"><ttl>???TITLE???</ttl><xreftext>box</xreftext></obj><obj element="emphasis" href="#box.process" number="" targetptr="box.process"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.select" number="" targetptr="box.select"><ttl>???TITLE???</ttl><xreftext>box.select</xreftext></obj><obj element="emphasis" href="#box.insert" number="" targetptr="box.insert"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.select_limit" number="" targetptr="box.select_limit"><ttl>???TITLE???</ttl><xreftext>box.select_limit</xreftext></obj><obj element="emphasis" href="#box.replace" number="" targetptr="box.replace"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.update" number="" targetptr="box.update"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.delete" number="" targetptr="box.delete"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.select_range" number="" targetptr="box.select_range"><ttl>???TITLE???</ttl><xreftext>box.select_range</xreftext></obj><obj element="emphasis" href="#box.select_reverse_range" number="" targetptr="box.select_reverse_range"><ttl>???TITLE???</ttl><xreftext>box.select_reverse_range</xreftext></obj></div><div element="section" href="#sp-box-tuple" number="" targetptr="sp-box-tuple"><ttl>Package <code class="code">box.tuple</code></ttl><xreftext>the section called “Package <code class="code">box.tuple</code>â€</xreftext><obj element="variablelist" href="#box.tuple" number="" targetptr="box.tuple"><ttl>???TITLE???</ttl><xreftext>box.tuple</xreftext></obj></div><div element="section" href="#sp-box-cjson" number="" targetptr="sp-box-cjson"><ttl>Package <code class="code">box.cjson</code></ttl><xreftext>the section called “Package <code class="code">box.cjson</code>â€</xreftext><obj element="variablelist" href="#box.cjson" number="" targetptr="box.cjson"><ttl>???TITLE???</ttl><xreftext>box.cjson</xreftext></obj></div><div element="section" href="#sp-box-space" number="" targetptr="sp-box-space"><ttl>Package <code class="code">box.space</code></ttl><xreftext>the section called “Package <code class="code">box.space</code>â€</xreftext><obj element="variablelist" href="#box.space" number="" targetptr="box.space"><ttl>???TITLE???</ttl><xreftext>box.space</xreftext></obj><obj element="emphasis" href="#box.space.select_range" number="" targetptr="box.space.select_range"><ttl>???TITLE???</ttl><xreftext>box.space[i].select_range()</xreftext></obj><obj element="emphasis" href="#box.space.select_reverse_range" number="" targetptr="box.space.select_reverse_range"><ttl>???TITLE???</ttl><xreftext>box.space.select_reverse_range</xreftext></obj></div><div element="section" href="#sp-box-index" number="" targetptr="sp-box-index"><ttl>Package <code class="code">box.index</code></ttl><xreftext>the section called “Package <code class="code">box.index</code>â€</xreftext><obj element="variablelist" href="#box.index" number="" targetptr="box.index"><ttl>???TITLE???</ttl><xreftext>box.index</xreftext></obj><obj element="emphasis" href="#box.index.iterator" number="" targetptr="box.index.iterator"><ttl>???TITLE???</ttl><xreftext>box.index.iterator(type, ...)</xreftext></obj><obj element="para" href="#iterator-consistency" number="" targetptr="iterator-consistency"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="para" href="#iterator-types" number="" targetptr="iterator-types"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="table" href="#idp25487136" number="4.1"><ttl>Common iterator types</ttl><xreftext>Table 4.1, “Common iterator typesâ€</xreftext></obj><obj element="table" href="#idp25263056" number="4.2"><ttl>TREE iterator types</ttl><xreftext>Table 4.2, “TREE iterator typesâ€</xreftext></obj><obj element="table" href="#idp25506032" number="4.3"><ttl>BITSET iterator types</ttl><xreftext>Table 4.3, “BITSET iterator typesâ€</xreftext></obj></div><div element="section" href="#sp-box-fiber" number="" targetptr="sp-box-fiber"><ttl>Package <code class="code">box.fiber</code></ttl><xreftext>the section called “Package <code class="code">box.fiber</code>â€</xreftext><obj element="variablelist" href="#box.fiber" number="" targetptr="box.fiber"><ttl>???TITLE???</ttl><xreftext>???TITLE???</xreftext></obj><obj element="emphasis" href="#box.fiber.id" number="" targetptr="box.fiber.id"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.self" number="" targetptr="box.fiber.self"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.find" number="" targetptr="box.fiber.find"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.create" number="" targetptr="box.fiber.create"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.resume" number="" targetptr="box.fiber.resume"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.yield" number="" targetptr="box.fiber.yield"><ttl>???TITLE???</ttl><xreftext>box.fiber.yield(...)</xreftext></obj><obj element="emphasis" href="#box.fiber.detach" number="" targetptr="box.fiber.detach"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.wrap" number="" targetptr="box.fiber.wrap"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.sleep" number="" targetptr="box.fiber.sleep"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.status" number="" targetptr="box.fiber.status"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.cancel" number="" targetptr="box.fiber.cancel"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.testcancel" number="" targetptr="box.fiber.testcancel"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj></div><div element="section" href="#sp-box-session" number="" targetptr="sp-box-session"><ttl>Package <code class="code">box.session</code></ttl><xreftext>the section called “Package <code class="code">box.session</code>â€</xreftext></div><div element="section" href="#sp-box-ipc" number="" targetptr="sp-box-ipc"><ttl>Package <code class="code">box.ipc</code> — inter procedure communication</ttl><xreftext>the section called “Package <code class="code">box.ipc</code> — inter procedure communicationâ€</xreftext><obj element="variablelist" href="#box.ipc" number="" targetptr="box.ipc"><ttl>???TITLE???</ttl><xreftext>???TITLE???</xreftext></obj></div><div element="section" href="#sp-box-socket" number="" targetptr="sp-box-socket"><ttl>Package <code class="code">box.socket</code> — TCP and UDP sockets</ttl><xreftext>the section called “Package <code class="code">box.socket</code> — TCP and UDP socketsâ€</xreftext><obj element="variablelist" href="#box.socket" number="" targetptr="box.socket"><ttl>???TITLE???</ttl><xreftext>???TITLE???</xreftext></obj><obj element="table" href="#idp25417104" number="4.4"><ttl><code class="code">readline()</code> returns</ttl><xreftext>Table 4.4, “<code class="code">readline()</code> returnsâ€</xreftext></obj></div><div element="section" href="#sp-box-net-box" number="" targetptr="sp-box-net-box"><ttl>Package <code class="code">box.net.box</code> — working with networked Tarantool peers</ttl><xreftext>the section called “Package <code class="code">box.net.box</code> — working with networked Tarantool peersâ€</xreftext><obj element="variablelist" href="#box.net.box" number="" targetptr="box.net.box"><ttl>???TITLE???</ttl><xreftext>???TITLE???</xreftext></obj><obj element="emphasis" href="#box.net.box.new" number="" targetptr="box.net.box.new"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.ping" number="" targetptr="box.net.box.ping"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.close" number="" targetptr="box.net.box.close"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.select" number="" targetptr="box.net.box.select"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.select_limit" number="" targetptr="box.net.box.select_limit"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.select_range" number="" targetptr="box.net.box.select_range"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.insert" number="" targetptr="box.net.box.insert"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.replace" number="" targetptr="box.net.box.replace"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.update" number="" targetptr="box.net.box.update"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.delete" number="" targetptr="box.net.box.delete"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.call" number="" targetptr="box.net.box.call"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.timeout" number="" targetptr="box.net.box.timeout"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj></div><div element="section" href="#sp-box-cfg" number="" targetptr="sp-box-cfg"><ttl>Packages <code class="code">box.cfg</code>, +<div element="book" href="#tarantool-user-guide" number="" targetptr="tarantool-user-guide"><ttl>Tarantool User Guide, version 1.6.0-200-gcc37c54</ttl><xreftext>Tarantool User Guide, version 1.6.0-200-gcc37c54</xreftext><div element="chapter" href="#preface" number="1" targetptr="preface"><ttl>Preface</ttl><xreftext>Chapter 1, <i>Preface</i></xreftext><div element="section" href="#tarantool-overview" number="" targetptr="tarantool-overview"><ttl>Tarantool: an overview</ttl><xreftext>the section called “Tarantool: an overviewâ€</xreftext></div><div element="section" href="#manual-conventions" number="" targetptr="manual-conventions"><ttl>Conventions</ttl><xreftext>the section called “Conventionsâ€</xreftext></div><div element="section" href="#reporting-bugs" number="" targetptr="reporting-bugs"><ttl>Reporting bugs</ttl><xreftext>the section called “Reporting bugsâ€</xreftext></div></div><div element="chapter" href="#getting-started" number="2" targetptr="getting-started"><ttl>Getting started</ttl><xreftext>Chapter 2, <i>Getting started</i></xreftext></div><div element="chapter" href="#data-and-persistence" number="3" targetptr="data-and-persistence"><ttl>Data model and data persistence</ttl><xreftext>Chapter 3, <i>Data model and data persistence</i></xreftext><div element="section" href="#dynamic-data-model" number="" targetptr="dynamic-data-model"><ttl>Dynamic data model</ttl><xreftext>the section called “Dynamic data modelâ€</xreftext></div><div element="section" href="#data-persistence" number="" targetptr="data-persistence"><ttl>Data persistence</ttl><xreftext>the section called “Data persistenceâ€</xreftext></div></div><div element="chapter" href="#language-reference" number="4" targetptr="language-reference"><ttl>Language reference</ttl><xreftext>Chapter 4, <i>Language reference</i></xreftext><div element="section" href="#data-manipulation" number="" targetptr="data-manipulation"><ttl>Data manipulation</ttl><xreftext>the section called “Data manipulationâ€</xreftext></div><div element="section" href="#administrative-console" number="" targetptr="administrative-console"><ttl>Administrative console</ttl><xreftext>the section called “Administrative consoleâ€</xreftext><obj element="term" href="#box.snapshot" number="" targetptr="box.snapshot"><ttl>???TITLE???</ttl><xreftext>box.snapshot()</xreftext></obj><obj element="term" href="#box.cfg.reload" number="" targetptr="box.cfg.reload"><ttl>???TITLE???</ttl><xreftext>box.cfg.reload()</xreftext></obj><obj element="term" href="#box.cfg.show" number="" targetptr="box.cfg.show"><ttl>???TITLE???</ttl><xreftext>box.cfg()</xreftext></obj><obj element="term" href="#box.info" number="" targetptr="box.info"><ttl>???TITLE???</ttl><xreftext>box.info()</xreftext></obj><obj element="term" href="#box.stat.show" number="" targetptr="box.stat.show"><ttl>???TITLE???</ttl><xreftext>box.stat()</xreftext></obj><obj element="term" href="#box.slab.info" number="" targetptr="box.slab.info"><ttl>???TITLE???</ttl><xreftext>box.slab.info()</xreftext></obj><obj element="term" href="#box.coredump" number="" targetptr="box.coredump"><ttl>???TITLE???</ttl><xreftext>box.coredump()</xreftext></obj><obj element="term" href="#box.fiber.info" number="" targetptr="box.fiber.info"><ttl>???TITLE???</ttl><xreftext>box.fiber.info()</xreftext></obj><obj element="term" href="#lua-command" number="" targetptr="lua-command"><ttl>???TITLE???</ttl><xreftext> + <span class="tntadmin">...</span> + </xreftext></obj></div><div element="section" href="#stored-procedures" number="" targetptr="stored-procedures"><ttl>Writing stored procedures in Lua</ttl><xreftext>the section called “Writing stored procedures in Luaâ€</xreftext><obj element="filename" href="#init.lua" number="" targetptr="init.lua"><ttl>???TITLE???</ttl><xreftext>init.lua</xreftext></obj><obj element="term" href="#tonumber64" number="" targetptr="tonumber64"><ttl>???TITLE???</ttl><xreftext>tonumber64</xreftext></obj><div element="section" href="#sp-box" number="" targetptr="sp-box"><ttl>Package <code class="code">box</code></ttl><xreftext>the section called “Package <code class="code">box</code>â€</xreftext><obj element="variablelist" href="#box" number="" targetptr="box"><ttl>???TITLE???</ttl><xreftext>box</xreftext></obj><obj element="emphasis" href="#box.process" number="" targetptr="box.process"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.select" number="" targetptr="box.select"><ttl>???TITLE???</ttl><xreftext>box.select</xreftext></obj><obj element="emphasis" href="#box.insert" number="" targetptr="box.insert"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.select_limit" number="" targetptr="box.select_limit"><ttl>???TITLE???</ttl><xreftext>box.select_limit</xreftext></obj><obj element="emphasis" href="#box.replace" number="" targetptr="box.replace"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.update" number="" targetptr="box.update"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.delete" number="" targetptr="box.delete"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.select_range" number="" targetptr="box.select_range"><ttl>???TITLE???</ttl><xreftext>box.select_range</xreftext></obj><obj element="emphasis" href="#box.select_reverse_range" number="" targetptr="box.select_reverse_range"><ttl>???TITLE???</ttl><xreftext>box.select_reverse_range</xreftext></obj></div><div element="section" href="#sp-box-tuple" number="" targetptr="sp-box-tuple"><ttl>Package <code class="code">box.tuple</code></ttl><xreftext>the section called “Package <code class="code">box.tuple</code>â€</xreftext><obj element="variablelist" href="#box.tuple" number="" targetptr="box.tuple"><ttl>???TITLE???</ttl><xreftext>box.tuple</xreftext></obj></div><div element="section" href="#sp-box-cjson" number="" targetptr="sp-box-cjson"><ttl>Package <code class="code">box.cjson</code></ttl><xreftext>the section called “Package <code class="code">box.cjson</code>â€</xreftext><obj element="variablelist" href="#box.cjson" number="" targetptr="box.cjson"><ttl>???TITLE???</ttl><xreftext>box.cjson</xreftext></obj></div><div element="section" href="#sp-box-space" number="" targetptr="sp-box-space"><ttl>Package <code class="code">box.space</code></ttl><xreftext>the section called “Package <code class="code">box.space</code>â€</xreftext><obj element="variablelist" href="#box.space" number="" targetptr="box.space"><ttl>???TITLE???</ttl><xreftext>box.space</xreftext></obj><obj element="emphasis" href="#box.space.select_range" number="" targetptr="box.space.select_range"><ttl>???TITLE???</ttl><xreftext>box.space[i].select_range()</xreftext></obj><obj element="emphasis" href="#box.space.select_reverse_range" number="" targetptr="box.space.select_reverse_range"><ttl>???TITLE???</ttl><xreftext>box.space.select_reverse_range</xreftext></obj></div><div element="section" href="#sp-box-index" number="" targetptr="sp-box-index"><ttl>Package <code class="code">box.index</code></ttl><xreftext>the section called “Package <code class="code">box.index</code>â€</xreftext><obj element="variablelist" href="#box.index" number="" targetptr="box.index"><ttl>???TITLE???</ttl><xreftext>box.index</xreftext></obj><obj element="emphasis" href="#box.index.iterator" number="" targetptr="box.index.iterator"><ttl>???TITLE???</ttl><xreftext>box.index.iterator(type, ...)</xreftext></obj><obj element="para" href="#iterator-consistency" number="" targetptr="iterator-consistency"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="para" href="#iterator-types" number="" targetptr="iterator-types"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="table" href="#idp261792" number="4.1"><ttl>Common iterator types</ttl><xreftext>Table 4.1, “Common iterator typesâ€</xreftext></obj><obj element="table" href="#idp435056" number="4.2"><ttl>TREE iterator types</ttl><xreftext>Table 4.2, “TREE iterator typesâ€</xreftext></obj><obj element="table" href="#idp452512" number="4.3"><ttl>BITSET iterator types</ttl><xreftext>Table 4.3, “BITSET iterator typesâ€</xreftext></obj></div><div element="section" href="#sp-box-fiber" number="" targetptr="sp-box-fiber"><ttl>Package <code class="code">box.fiber</code></ttl><xreftext>the section called “Package <code class="code">box.fiber</code>â€</xreftext><obj element="variablelist" href="#box.fiber" number="" targetptr="box.fiber"><ttl>???TITLE???</ttl><xreftext>???TITLE???</xreftext></obj><obj element="emphasis" href="#box.fiber.id" number="" targetptr="box.fiber.id"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.self" number="" targetptr="box.fiber.self"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.find" number="" targetptr="box.fiber.find"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.create" number="" targetptr="box.fiber.create"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.resume" number="" targetptr="box.fiber.resume"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.yield" number="" targetptr="box.fiber.yield"><ttl>???TITLE???</ttl><xreftext>box.fiber.yield(...)</xreftext></obj><obj element="emphasis" href="#box.fiber.detach" number="" targetptr="box.fiber.detach"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.wrap" number="" targetptr="box.fiber.wrap"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.sleep" number="" targetptr="box.fiber.sleep"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.status" number="" targetptr="box.fiber.status"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.cancel" number="" targetptr="box.fiber.cancel"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.testcancel" number="" targetptr="box.fiber.testcancel"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj></div><div element="section" href="#sp-box-session" number="" targetptr="sp-box-session"><ttl>Package <code class="code">box.session</code></ttl><xreftext>the section called “Package <code class="code">box.session</code>â€</xreftext></div><div element="section" href="#sp-box-ipc" number="" targetptr="sp-box-ipc"><ttl>Package <code class="code">box.ipc</code> — inter procedure communication</ttl><xreftext>the section called “Package <code class="code">box.ipc</code> — inter procedure communicationâ€</xreftext><obj element="variablelist" href="#box.ipc" number="" targetptr="box.ipc"><ttl>???TITLE???</ttl><xreftext>???TITLE???</xreftext></obj></div><div element="section" href="#sp-box-socket" number="" targetptr="sp-box-socket"><ttl>Package <code class="code">box.socket</code> — TCP and UDP sockets</ttl><xreftext>the section called “Package <code class="code">box.socket</code> — TCP and UDP socketsâ€</xreftext><obj element="variablelist" href="#box.socket" number="" targetptr="box.socket"><ttl>???TITLE???</ttl><xreftext>???TITLE???</xreftext></obj><obj element="table" href="#idp737616" number="4.4"><ttl><code class="code">readline()</code> returns</ttl><xreftext>Table 4.4, “<code class="code">readline()</code> returnsâ€</xreftext></obj></div><div element="section" href="#sp-box-net-box" number="" targetptr="sp-box-net-box"><ttl>Package <code class="code">box.net.box</code> — working with networked Tarantool peers</ttl><xreftext>the section called “Package <code class="code">box.net.box</code> — working with networked Tarantool peersâ€</xreftext><obj element="variablelist" href="#box.net.box" number="" targetptr="box.net.box"><ttl>???TITLE???</ttl><xreftext>???TITLE???</xreftext></obj><obj element="emphasis" href="#box.net.box.new" number="" targetptr="box.net.box.new"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.ping" number="" targetptr="box.net.box.ping"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.close" number="" targetptr="box.net.box.close"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.select" number="" targetptr="box.net.box.select"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.select_limit" number="" targetptr="box.net.box.select_limit"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.select_range" number="" targetptr="box.net.box.select_range"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.insert" number="" targetptr="box.net.box.insert"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.replace" number="" targetptr="box.net.box.replace"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.update" number="" targetptr="box.net.box.update"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.delete" number="" targetptr="box.net.box.delete"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.call" number="" targetptr="box.net.box.call"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.timeout" number="" targetptr="box.net.box.timeout"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj></div><div element="section" href="#sp-box-cfg" number="" targetptr="sp-box-cfg"><ttl>Packages <code class="code">box.cfg</code>, <code class="code">box.info</code>, <code class="code">box.slab</code> and <code class="code">box.stat</code>: server introspection</ttl><xreftext>the section called “Packages <code class="code">box.cfg</code>, <code class="code">box.info</code>, <code class="code">box.slab</code> and - <code class="code">box.stat</code>: server introspectionâ€</xreftext><obj element="code" href="#box.cfg" number="" targetptr="box.cfg"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="code" href="#box.stat" number="" targetptr="box.stat"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj></div><div element="section" href="#sp-limitations" number="" targetptr="sp-limitations"><ttl>Limitation of stored procedures</ttl><xreftext>the section called “Limitation of stored proceduresâ€</xreftext></div></div><div element="section" href="#triggers" number="" targetptr="triggers"><ttl>Defining triggers in Lua</ttl><xreftext>the section called “Defining triggers in Luaâ€</xreftext><div element="section" href="#sp-box-session-triggers" number="" targetptr="sp-box-session-triggers"><ttl>Triggers on connect and disconnect</ttl><xreftext>session triggers</xreftext></div></div></div><div element="chapter" href="#replication" number="5" targetptr="replication"><ttl>Replication</ttl><xreftext>Chapter 5, <i>Replication</i></xreftext><div element="section" href="#replication-architecture" number="" targetptr="replication-architecture"><ttl>Replication architecture</ttl><xreftext>the section called “Replication architectureâ€</xreftext></div><div element="section" href="#setting-up-the-master" number="" targetptr="setting-up-the-master"><ttl>Setting up the master</ttl><xreftext>the section called “Setting up the masterâ€</xreftext></div><div element="section" href="#settin-up-a-replica" number="" targetptr="settin-up-a-replica"><ttl>Setting up a replica</ttl><xreftext>the section called “Setting up a replicaâ€</xreftext></div><div element="section" href="#recovering-from-a-degraded-state" number="" targetptr="recovering-from-a-degraded-state"><ttl>Recovering from a degraded state</ttl><xreftext>the section called “Recovering from a degraded stateâ€</xreftext></div></div><div element="chapter" href="#server-administration" number="6" targetptr="server-administration"><ttl>Server administration</ttl><xreftext>Chapter 6, <i>Server administration</i></xreftext><div element="section" href="#signal-handling" number="" targetptr="signal-handling"><ttl>Server signal handling</ttl><xreftext>the section called “Server signal handlingâ€</xreftext></div><div element="section" href="#os-install-notes" number="" targetptr="os-install-notes"><ttl>System-specific administration notes</ttl><xreftext>the section called “System-specific administration notesâ€</xreftext><div element="section" href="#Debian" number="" targetptr="Debian"><ttl>Debian GNU/Linux and Ubuntu</ttl><xreftext>the section called “Debian GNU/Linux and Ubuntuâ€</xreftext></div><div element="section" href="#rpm-based-distros" number="" targetptr="rpm-based-distros"><ttl>Fedora, RHEL, CentOS</ttl><xreftext>the section called “Fedora, RHEL, CentOSâ€</xreftext></div><div element="section" href="#FreeBSD" number="" targetptr="FreeBSD"><ttl>FreeBSD</ttl><xreftext>the section called “FreeBSDâ€</xreftext></div><div element="section" href="#mac-os-x" number="" targetptr="mac-os-x"><ttl>Mac OS X</ttl><xreftext>the section called “Mac OS Xâ€</xreftext></div></div></div><div element="chapter" href="#configuration-reference" number="7" targetptr="configuration-reference"><ttl>Configuration reference</ttl><xreftext>Chapter 7, <i>Configuration reference</i></xreftext><div element="section" href="#command-line-options" number="" targetptr="command-line-options"><ttl>Command line options</ttl><xreftext>the section called “Command line optionsâ€</xreftext><obj element="listitem" href="#help-option" number="" targetptr="help-option"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="listitem" href="#version-option" number="" targetptr="version-option"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="listitem" href="#config-option" number="" targetptr="config-option"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="option" href="#init-storage-option" number="" targetptr="init-storage-option"><ttl>???TITLE???</ttl><xreftext>--init-storage</xreftext></obj></div><div element="section" href="#option-file" number="" targetptr="option-file"><ttl>The option file</ttl><xreftext>option file</xreftext><obj element="table" href="#idp25900960" number="7.1"><ttl>Basic parameters</ttl><xreftext>Table 7.1, “Basic parametersâ€</xreftext></obj><obj element="entry" href="#work_dir" number="" targetptr="work_dir"><ttl>???TITLE???</ttl><xreftext>work_dir</xreftext></obj><obj element="entry" href="#script_dir" number="" targetptr="script_dir"><ttl>???TITLE???</ttl><xreftext>script_dir</xreftext></obj><obj element="entry" href="#wal_dir" number="" targetptr="wal_dir"><ttl>???TITLE???</ttl><xreftext>wal_dir</xreftext></obj><obj element="entry" href="#snap_dir" number="" targetptr="snap_dir"><ttl>???TITLE???</ttl><xreftext>snap_dir</xreftext></obj><obj element="entry" href="#bind_ipaddr" number="" targetptr="bind_ipaddr"><ttl>???TITLE???</ttl><xreftext>bind_ipaddr</xreftext></obj><obj element="entry" href="#primary_port" number="" targetptr="primary_port"><ttl>???TITLE???</ttl><xreftext>primary_port</xreftext></obj><obj element="entry" href="#secondary_port" number="" targetptr="secondary_port"><ttl>???TITLE???</ttl><xreftext>secondary_port</xreftext></obj><obj element="entry" href="#admin_port" number="" targetptr="admin_port"><ttl>???TITLE???</ttl><xreftext>admin_port</xreftext></obj><obj element="entry" href="#custom_proc_title" number="" targetptr="custom_proc_title"><ttl>???TITLE???</ttl><xreftext>custom_proc_title</xreftext></obj><obj element="table" href="#idp25959344" number="7.2"><ttl>Configuring the storage</ttl><xreftext>Table 7.2, “Configuring the storageâ€</xreftext></obj><obj element="anchor" href="#slab_alloc_arena" number="" targetptr="slab_alloc_arena"><ttl>???TITLE???</ttl><xreftext>slab_alloc_arena</xreftext></obj><obj element="para" href="#space" number="" targetptr="space"><ttl>???TITLE???</ttl><xreftext>the section called “The option fileâ€</xreftext></obj><obj element="table" href="#idp25995312" number="7.3"><ttl>Binary logging and snapshots</ttl><xreftext>Table 7.3, “Binary logging and snapshotsâ€</xreftext></obj><obj element="entry" href="#rows_per_wal" number="" targetptr="rows_per_wal"><ttl>???TITLE???</ttl><xreftext>rows_per_wal</xreftext></obj><obj element="entry" href="#wal_mode" number="" targetptr="wal_mode"><ttl>???TITLE???</ttl><xreftext>wal_mode</xreftext></obj><obj element="table" href="#idp26030640" number="7.4"><ttl>Replication</ttl><xreftext>Table 7.4, “Replicationâ€</xreftext></obj><obj element="entry" href="#replication_port" number="" targetptr="replication_port"><ttl>???TITLE???</ttl><xreftext>replication_port</xreftext></obj><obj element="entry" href="#replication_source" number="" targetptr="replication_source"><ttl>???TITLE???</ttl><xreftext>replication_source</xreftext></obj><obj element="table" href="#idp26049680" number="7.5"><ttl>Networking</ttl><xreftext>Table 7.5, “Networkingâ€</xreftext></obj><obj element="table" href="#idp26069008" number="7.6"><ttl>Logging</ttl><xreftext>Table 7.6, “Loggingâ€</xreftext></obj><obj element="table" href="#idp26093904" number="7.7"><ttl>Memcached protocol support</ttl><xreftext>Table 7.7, “Memcached protocol supportâ€</xreftext></obj><obj element="anchor" href="#memcached_port" number="" targetptr="memcached_port"><ttl>???TITLE???</ttl><xreftext>memcached_port</xreftext></obj><obj element="anchor" href="#memcached_space" number="" targetptr="memcached_space"><ttl>???TITLE???</ttl><xreftext>memcached_space</xreftext></obj><obj element="anchor" href="#memcached_expire" number="" targetptr="memcached_expire"><ttl>???TITLE???</ttl><xreftext>memcached_expire</xreftext></obj></div></div><div element="chapter" href="#connectors" number="8" targetptr="connectors"><ttl>Connectors</ttl><xreftext>Chapter 8, <i>Connectors</i></xreftext><div element="section" href="#connector-c" number="" targetptr="connector-c"><ttl>C</ttl><xreftext>the section called “Câ€</xreftext></div><div element="section" href="#connector-node.js" number="" targetptr="connector-node.js"><ttl>node.js</ttl><xreftext>the section called “node.jsâ€</xreftext></div><div element="section" href="#connector-perl" number="" targetptr="connector-perl"><ttl>Perl</ttl><xreftext>the section called “Perlâ€</xreftext></div><div element="section" href="#connector-php" number="" targetptr="connector-php"><ttl>PHP</ttl><xreftext>the section called “PHPâ€</xreftext></div><div element="section" href="#connector-python" number="" targetptr="connector-python"><ttl>Python</ttl><xreftext>the section called “Pythonâ€</xreftext></div><div element="section" href="#connector-ruby" number="" targetptr="connector-ruby"><ttl>Ruby</ttl><xreftext>the section called “Rubyâ€</xreftext></div></div><div element="appendix" href="#proctitle" number="A" targetptr="proctitle"><ttl>Server process titles</ttl><xreftext>Appendix A, <i>Server process titles</i></xreftext></div><div element="appendix" href="#errcode" number="B" targetptr="errcode"><ttl>List of error codes</ttl><xreftext>Appendix B, <i>List of error codes</i></xreftext><obj element="term" href="#ER_NONMASTER" number="" targetptr="ER_NONMASTER"><ttl>???TITLE???</ttl><xreftext>ER_NONMASTER</xreftext></obj><obj element="term" href="#ER_ILLEGAL_PARAMS" number="" targetptr="ER_ILLEGAL_PARAMS"><ttl>???TITLE???</ttl><xreftext>ER_ILLEGAL_PARAMS</xreftext></obj><obj element="term" href="#ER_MEMORY_ISSUE" number="" targetptr="ER_MEMORY_ISSUE"><ttl>???TITLE???</ttl><xreftext>ER_MEMORY_ISSUE</xreftext></obj><obj element="term" href="#ER_WAL_IO" number="" targetptr="ER_WAL_IO"><ttl>???TITLE???</ttl><xreftext>ER_WAL_IO</xreftext></obj><obj element="term" href="#ER_INDEX_VIOLATION" number="" targetptr="ER_INDEX_VIOLATION"><ttl>???TITLE???</ttl><xreftext>ER_INDEX_VIOLATION</xreftext></obj><obj element="term" href="#ER_KEY_PART_COUNT" number="" targetptr="ER_KEY_PART_COUNT"><ttl>???TITLE???</ttl><xreftext>ER_KEY_PART_COUNT</xreftext></obj><obj element="term" href="#ER_NO_SUCH_SPACE" number="" targetptr="ER_NO_SUCH_SPACE"><ttl>???TITLE???</ttl><xreftext>ER_NO_SUCH_SPACE</xreftext></obj><obj element="term" href="#ER_NO_SUCH_INDEX" number="" targetptr="ER_NO_SUCH_INDEX"><ttl>???TITLE???</ttl><xreftext>ER_NO_SUCH_INDEX</xreftext></obj><obj element="term" href="#ER_PROC_LUA" number="" targetptr="ER_PROC_LUA"><ttl>???TITLE???</ttl><xreftext>ER_PROC_LUA</xreftext></obj><obj element="term" href="#ER_FIBER_STACK" number="" targetptr="ER_FIBER_STACK"><ttl>???TITLE???</ttl><xreftext>ER_FIBER_STACK</xreftext></obj></div></div> + <code class="code">box.stat</code>: server introspectionâ€</xreftext><obj element="code" href="#box.cfg" number="" targetptr="box.cfg"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="code" href="#box.stat" number="" targetptr="box.stat"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj></div><div element="section" href="#sp-limitations" number="" targetptr="sp-limitations"><ttl>Limitation of stored procedures</ttl><xreftext>the section called “Limitation of stored proceduresâ€</xreftext></div></div><div element="section" href="#triggers" number="" targetptr="triggers"><ttl>Defining triggers in Lua</ttl><xreftext>the section called “Defining triggers in Luaâ€</xreftext><div element="section" href="#sp-box-session-triggers" number="" targetptr="sp-box-session-triggers"><ttl>Triggers on connect and disconnect</ttl><xreftext>session triggers</xreftext></div></div></div><div element="chapter" href="#replication" number="5" targetptr="replication"><ttl>Replication</ttl><xreftext>Chapter 5, <i>Replication</i></xreftext><div element="section" href="#replication-architecture" number="" targetptr="replication-architecture"><ttl>Replication architecture</ttl><xreftext>the section called “Replication architectureâ€</xreftext></div><div element="section" href="#setting-up-the-master" number="" targetptr="setting-up-the-master"><ttl>Setting up the master</ttl><xreftext>the section called “Setting up the masterâ€</xreftext></div><div element="section" href="#settin-up-a-replica" number="" targetptr="settin-up-a-replica"><ttl>Setting up a replica</ttl><xreftext>the section called “Setting up a replicaâ€</xreftext></div><div element="section" href="#recovering-from-a-degraded-state" number="" targetptr="recovering-from-a-degraded-state"><ttl>Recovering from a degraded state</ttl><xreftext>the section called “Recovering from a degraded stateâ€</xreftext></div></div><div element="chapter" href="#server-administration" number="6" targetptr="server-administration"><ttl>Server administration</ttl><xreftext>Chapter 6, <i>Server administration</i></xreftext><div element="section" href="#signal-handling" number="" targetptr="signal-handling"><ttl>Server signal handling</ttl><xreftext>the section called “Server signal handlingâ€</xreftext></div><div element="section" href="#os-install-notes" number="" targetptr="os-install-notes"><ttl>System-specific administration notes</ttl><xreftext>the section called “System-specific administration notesâ€</xreftext><div element="section" href="#Debian" number="" targetptr="Debian"><ttl>Debian GNU/Linux and Ubuntu</ttl><xreftext>the section called “Debian GNU/Linux and Ubuntuâ€</xreftext></div><div element="section" href="#rpm-based-distros" number="" targetptr="rpm-based-distros"><ttl>Fedora, RHEL, CentOS</ttl><xreftext>the section called “Fedora, RHEL, CentOSâ€</xreftext></div><div element="section" href="#FreeBSD" number="" targetptr="FreeBSD"><ttl>FreeBSD</ttl><xreftext>the section called “FreeBSDâ€</xreftext></div><div element="section" href="#mac-os-x" number="" targetptr="mac-os-x"><ttl>Mac OS X</ttl><xreftext>the section called “Mac OS Xâ€</xreftext></div></div></div><div element="chapter" href="#configuration-reference" number="7" targetptr="configuration-reference"><ttl>Configuration reference</ttl><xreftext>Chapter 7, <i>Configuration reference</i></xreftext><div element="section" href="#command-line-options" number="" targetptr="command-line-options"><ttl>Command line options</ttl><xreftext>the section called “Command line optionsâ€</xreftext><obj element="listitem" href="#help-option" number="" targetptr="help-option"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="listitem" href="#version-option" number="" targetptr="version-option"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="listitem" href="#config-option" number="" targetptr="config-option"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="option" href="#init-storage-option" number="" targetptr="init-storage-option"><ttl>???TITLE???</ttl><xreftext>--init-storage</xreftext></obj></div><div element="section" href="#option-file" number="" targetptr="option-file"><ttl>The option file</ttl><xreftext>option file</xreftext><obj element="table" href="#idp1267792" number="7.1"><ttl>Basic parameters</ttl><xreftext>Table 7.1, “Basic parametersâ€</xreftext></obj><obj element="entry" href="#work_dir" number="" targetptr="work_dir"><ttl>???TITLE???</ttl><xreftext>work_dir</xreftext></obj><obj element="entry" href="#script_dir" number="" targetptr="script_dir"><ttl>???TITLE???</ttl><xreftext>script_dir</xreftext></obj><obj element="entry" href="#wal_dir" number="" targetptr="wal_dir"><ttl>???TITLE???</ttl><xreftext>wal_dir</xreftext></obj><obj element="entry" href="#snap_dir" number="" targetptr="snap_dir"><ttl>???TITLE???</ttl><xreftext>snap_dir</xreftext></obj><obj element="entry" href="#bind_ipaddr" number="" targetptr="bind_ipaddr"><ttl>???TITLE???</ttl><xreftext>bind_ipaddr</xreftext></obj><obj element="entry" href="#primary_port" number="" targetptr="primary_port"><ttl>???TITLE???</ttl><xreftext>primary_port</xreftext></obj><obj element="entry" href="#secondary_port" number="" targetptr="secondary_port"><ttl>???TITLE???</ttl><xreftext>secondary_port</xreftext></obj><obj element="entry" href="#admin_port" number="" targetptr="admin_port"><ttl>???TITLE???</ttl><xreftext>admin_port</xreftext></obj><obj element="entry" href="#custom_proc_title" number="" targetptr="custom_proc_title"><ttl>???TITLE???</ttl><xreftext>custom_proc_title</xreftext></obj><obj element="table" href="#idp1325952" number="7.2"><ttl>Configuring the storage</ttl><xreftext>Table 7.2, “Configuring the storageâ€</xreftext></obj><obj element="anchor" href="#slab_alloc_arena" number="" targetptr="slab_alloc_arena"><ttl>???TITLE???</ttl><xreftext>slab_alloc_arena</xreftext></obj><obj element="para" href="#space" number="" targetptr="space"><ttl>???TITLE???</ttl><xreftext>the section called “The option fileâ€</xreftext></obj><obj element="table" href="#idp1361984" number="7.3"><ttl>Binary logging and snapshots</ttl><xreftext>Table 7.3, “Binary logging and snapshotsâ€</xreftext></obj><obj element="entry" href="#rows_per_wal" number="" targetptr="rows_per_wal"><ttl>???TITLE???</ttl><xreftext>rows_per_wal</xreftext></obj><obj element="entry" href="#wal_mode" number="" targetptr="wal_mode"><ttl>???TITLE???</ttl><xreftext>wal_mode</xreftext></obj><obj element="table" href="#idp1397376" number="7.4"><ttl>Replication</ttl><xreftext>Table 7.4, “Replicationâ€</xreftext></obj><obj element="entry" href="#replication_port" number="" targetptr="replication_port"><ttl>???TITLE???</ttl><xreftext>replication_port</xreftext></obj><obj element="entry" href="#replication_source" number="" targetptr="replication_source"><ttl>???TITLE???</ttl><xreftext>replication_source</xreftext></obj><obj element="table" href="#idp1416416" number="7.5"><ttl>Networking</ttl><xreftext>Table 7.5, “Networkingâ€</xreftext></obj><obj element="table" href="#idp1435744" number="7.6"><ttl>Logging</ttl><xreftext>Table 7.6, “Loggingâ€</xreftext></obj></div></div><div element="chapter" href="#connectors" number="8" targetptr="connectors"><ttl>Connectors</ttl><xreftext>Chapter 8, <i>Connectors</i></xreftext><div element="section" href="#connector-c" number="" targetptr="connector-c"><ttl>C</ttl><xreftext>the section called “Câ€</xreftext></div><div element="section" href="#connector-node.js" number="" targetptr="connector-node.js"><ttl>node.js</ttl><xreftext>the section called “node.jsâ€</xreftext></div><div element="section" href="#connector-perl" number="" targetptr="connector-perl"><ttl>Perl</ttl><xreftext>the section called “Perlâ€</xreftext></div><div element="section" href="#connector-php" number="" targetptr="connector-php"><ttl>PHP</ttl><xreftext>the section called “PHPâ€</xreftext></div><div element="section" href="#connector-python" number="" targetptr="connector-python"><ttl>Python</ttl><xreftext>the section called “Pythonâ€</xreftext></div><div element="section" href="#connector-ruby" number="" targetptr="connector-ruby"><ttl>Ruby</ttl><xreftext>the section called “Rubyâ€</xreftext></div></div><div element="appendix" href="#proctitle" number="A" targetptr="proctitle"><ttl>Server process titles</ttl><xreftext>Appendix A, <i>Server process titles</i></xreftext></div><div element="appendix" href="#errcode" number="B" targetptr="errcode"><ttl>List of error codes</ttl><xreftext>Appendix B, <i>List of error codes</i></xreftext><obj element="term" href="#ER_NONMASTER" number="" targetptr="ER_NONMASTER"><ttl>???TITLE???</ttl><xreftext>ER_NONMASTER</xreftext></obj><obj element="term" href="#ER_ILLEGAL_PARAMS" number="" targetptr="ER_ILLEGAL_PARAMS"><ttl>???TITLE???</ttl><xreftext>ER_ILLEGAL_PARAMS</xreftext></obj><obj element="term" href="#ER_MEMORY_ISSUE" number="" targetptr="ER_MEMORY_ISSUE"><ttl>???TITLE???</ttl><xreftext>ER_MEMORY_ISSUE</xreftext></obj><obj element="term" href="#ER_WAL_IO" number="" targetptr="ER_WAL_IO"><ttl>???TITLE???</ttl><xreftext>ER_WAL_IO</xreftext></obj><obj element="term" href="#ER_INDEX_VIOLATION" number="" targetptr="ER_INDEX_VIOLATION"><ttl>???TITLE???</ttl><xreftext>ER_INDEX_VIOLATION</xreftext></obj><obj element="term" href="#ER_KEY_PART_COUNT" number="" targetptr="ER_KEY_PART_COUNT"><ttl>???TITLE???</ttl><xreftext>ER_KEY_PART_COUNT</xreftext></obj><obj element="term" href="#ER_NO_SUCH_SPACE" number="" targetptr="ER_NO_SUCH_SPACE"><ttl>???TITLE???</ttl><xreftext>ER_NO_SUCH_SPACE</xreftext></obj><obj element="term" href="#ER_NO_SUCH_INDEX" number="" targetptr="ER_NO_SUCH_INDEX"><ttl>???TITLE???</ttl><xreftext>ER_NO_SUCH_INDEX</xreftext></obj><obj element="term" href="#ER_PROC_LUA" number="" targetptr="ER_PROC_LUA"><ttl>???TITLE???</ttl><xreftext>ER_PROC_LUA</xreftext></obj><obj element="term" href="#ER_FIBER_STACK" number="" targetptr="ER_FIBER_STACK"><ttl>???TITLE???</ttl><xreftext>ER_FIBER_STACK</xreftext></obj><obj element="term" href="#ER_UPDATE_FIELD" number="" targetptr="ER_UPDATE_FIELD"><ttl>???TITLE???</ttl><xreftext>ER_UPDATE_FIELD</xreftext></obj></div></div> diff --git a/extra/rpm.spec.in b/extra/rpm.spec.in index e4bd7025604cb938e9415555cb6024197dbf9c88..9c436f2eb2c2947ce9bfe4ba7dfb69edacd32ea8 100644 --- a/extra/rpm.spec.in +++ b/extra/rpm.spec.in @@ -9,6 +9,7 @@ Release: @RPM_PACKAGE_RELEASE@ Group: Applications/Databases Summary: Tarantool - an efficient in-memory data store License: BSD +Requires: libgcc >= 4.1.2-50 URL: http://tarantool.org Source0: @RPM_PACKAGE_SOURCE_FILE_NAME@ %description @@ -60,10 +61,10 @@ make %{?_smp_mflags} make DESTDIR=%{buildroot} install %post -groupadd tarantool -useradd -r -g tarantool tarantool +groupadd tarantool > /dev/null 2>&1 +useradd -r -g tarantool tarantool > /dev/null 2>&1 # Performe a single instance setup -/usr/bin/tarantool_deploy.sh --yes 1.1 +/usr/bin/tarantool_deploy.sh --yes --quiet 1.1 %preun diff --git a/extra/tarantool_box b/extra/tarantool_box old mode 100755 new mode 100644 index 3538a99ba62876fdcda6ebc65dacec0f33621885..ae855b504310969ade272925979ce9c727b4631b --- a/extra/tarantool_box +++ b/extra/tarantool_box @@ -32,8 +32,30 @@ then exit fi +checkactive() { + if [ -f ${WRAP_PIDFILE} ] + then + ps -p $(cat ${WRAP_PIDFILE}) >/dev/null 2>&1 + if [ $? -eq 0 ]; then + echo -n "(instance is active)" + echo_failure + exit 1 + fi + fi + if [ -f ${PIDFILE} ] + then + ps -p $(cat ${PIDFILE}) >/dev/null 2>&1 + if [ $? -eq 0 ]; then + echo -n "(instance is active)" + echo_failure + exit 1 + fi + fi +} + start() { echo -n $"Starting ${INST}: " + checkactive /usr/bin/${INST}.sh ${OPTIONS} >> /var/${INST}/logs/init.log 2>&1 RETVAL=${?} if [ ${RETVAL} -eq 0 ] diff --git a/extra/tarantool_deploy.sh b/extra/tarantool_deploy.sh index 6a35356fb416baaf5b89b6f28233976b79131197..0a992fecf891a7413ad4db907e5035df12212ba1 100755 --- a/extra/tarantool_deploy.sh +++ b/extra/tarantool_deploy.sh @@ -35,6 +35,7 @@ act_prompt=1 act_status=0 act_debug=0 act_dry=0 +act_quiet=0 error() { echo "$prompt_name error: $*" 1>&2 @@ -115,6 +116,9 @@ deploy() { # setup startup script try "ln -s \"${prefix_etc}/init.d/tarantool_box\" \"${prefix_etc}/init.d/tarantool_box$id\"" + + # register service + [ -x /sbin/chkconfig ] && try "/sbin/chkconfig --add tarantool_box$id" } deploy_check() { @@ -123,7 +127,7 @@ deploy_check() { if [ $deploy_exists -eq 1 ]; then grep "^\(${id}\)$" $deploy_cfg > /dev/null if [ $? -eq 0 ]; then - log "Instance '${id}' is already deployed." + [ $act_quiet -eq 0 ] && log "Instance '${id}' is already deployed." exit 0 fi fi @@ -152,6 +156,7 @@ deploy_name="" while [ $# -ge 1 ]; do case $1 in --yes) act_prompt=0; shift 1 ;; + --quiet) act_quiet=1; shift 1 ;; --prefix) prefix=$2; shift 2 ;; --prefix_var) prefix_var=$2; shift 2 ;; --prefix_etc) prefix_etc=$2; shift 2 ;; @@ -173,6 +178,16 @@ deploy_exists=0 # check deployment configuration file [ -f $deploy_cfg ] && deploy_exists=1 +# do migration from old deployment (if necessary) +if [ $deploy_exists -eq 0 ]; then + deploy_cfg_old="/usr/local/etc/tarantool_deploy.cfg" + if [ -f $deploy_cfg_old ]; then + mkdir -p /etc/tarantool + cp /usr/local/etc/tarantool* "${prefix_etc}/tarantool/" + deploy_exists=1 + fi +fi + # display status if [ $act_status -ne 0 ]; then if [ $deploy_exists -eq 0 ]; then diff --git a/include/errcode.h b/include/errcode.h index 256b1e2c89a04ef7077802bd0a6289015585d2d9..19cba8326572ac4fd80d4c0841b186165acdcfd1 100644 --- a/include/errcode.h +++ b/include/errcode.h @@ -84,7 +84,7 @@ enum { TNT_ERRMSG_MAX = 512 }; /* 29 */_(ER_LAST_DROP, 2, "Can't drop the primary key in a system space, space id %u") \ /* 30 */_(ER_DROP_PRIMARY_KEY, 2, "Can't drop primary key in space %u while secondary keys exist") \ /* 31 */_(ER_SPACE_ARITY, 2, "Tuple field count %u does not match space %u arity %u") \ - /* 32 */_(ER_UNUSED32, 2, "Unused32") \ + /* 32 */_(ER_INDEX_ARITY, 2, "Tuple field count %u is less than required by a defined index (expected %u)") \ /* 33 */_(ER_UNUSED33, 2, "Unused33") \ /* 34 */_(ER_UNUSED34, 2, "Unused34") \ /* 35 */_(ER_UNUSED35, 2, "Unused35") \ @@ -125,14 +125,22 @@ extern struct errcode_record tnt_error_codes[]; static inline const char *tnt_errcode_str(uint32_t errcode) { + if (errcode >= tnt_error_codes_enum_MAX) { + /* Unknown error code - can be triggered using box.raise() */ + return "ER_UNKNOWN"; + } return tnt_error_codes[errcode].errstr; } /** Return a 4-byte numeric error code, with status flags. */ + static inline uint32_t tnt_errcode_val(uint32_t errcode) { + if (errcode >= tnt_error_codes_enum_MAX) + return (errcode << 8) | 2; /* non-recoverable */ + return (errcode << 8) | tnt_error_codes[errcode].errflags; } @@ -141,6 +149,9 @@ static inline uint32_t tnt_errcode_val(uint32_t errcode) static inline const char *tnt_errcode_desc(uint32_t errcode) { + if (errcode >= tnt_error_codes_enum_MAX) + return ""; + return tnt_error_codes[errcode].errdesc; } diff --git a/include/fiber.h b/include/fiber.h index e49b900e1f0deea3d92b8334811a6e9ef6db476d..b8396a5f8e80f771879fe863b259803330b230d6 100644 --- a/include/fiber.h +++ b/include/fiber.h @@ -106,6 +106,7 @@ struct fiber { va_list f_data; uint32_t flags; struct fiber *waiter; + uint64_t cookie; }; extern __thread struct fiber *fiber; @@ -161,16 +162,16 @@ void fiber_testcancel(void); bool fiber_setcancellable(bool enable); void fiber_sleep(ev_tstamp s); struct tbuf; -void fiber_info(struct tbuf *out); void fiber_schedule(ev_watcher *watcher, int event __attribute__((unused))); /** - * Attach this fiber to a session identified by sid. + * Attach this fiber to a session identified by sid and to a cookie. */ static inline void -fiber_set_sid(struct fiber *f, uint32_t sid) +fiber_set_sid(struct fiber *f, uint32_t sid, uint64_t cookie) { f->sid = sid; + f->cookie = cookie; } typedef int (*fiber_stat_cb)(struct fiber *f, void *ctx); diff --git a/include/log_io.h b/include/log_io.h index ecb463137341769cc88093618c21c50514566199..a0bf7c12e70003b5c9c96e644b7dcff9fa2acd95 100644 --- a/include/log_io.h +++ b/include/log_io.h @@ -149,7 +149,7 @@ struct wal_row { } __attribute__((packed)); void -wal_row_fill(struct wal_row *row, int64_t lsn, +wal_row_fill(struct wal_row *row, int64_t lsn, uint64_t cookie, const char *metadata, size_t metadata_len, const char *data, size_t data_len); diff --git a/include/qbuf.h b/include/qbuf.h new file mode 100644 index 0000000000000000000000000000000000000000..3feb743171dad86433c961097fa556b5d036cadd --- /dev/null +++ b/include/qbuf.h @@ -0,0 +1,102 @@ +#ifndef TARANTOOL_QBUF_H_INCLUDED +#define TARANTOOL_QBUF_H_INCLUDED +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <stdlib.h> + +#define QBUF_WATERMARK (512 * sizeof(void*)) + +struct qbuf { + char *buf; + size_t bottom; /* advanced by batch free */ + size_t top; + size_t size; /* total buffer size */ +}; + +static inline int +qbuf_init(struct qbuf *q, size_t size) { + q->size = size; + q->bottom = 0; + q->top = 0; + q->buf = (char*)malloc(size); + return (q->buf == NULL ? -1 : 0); +} + +static inline void +qbuf_free(struct qbuf *q) { + if (q->buf) { + free(q->buf); + q->buf = NULL; + } +} + +static inline int +qbuf_n(struct qbuf *q) { + return (q->top - q->bottom) / sizeof(void*); +} + +#ifndef unlikely +# define unlikely __builtin_expect(!! (EXPR), 0) +#endif + +static inline int +qbuf_push(struct qbuf *q, void *ptr) +{ + /* reduce memory allocation and memmove + * effect by reusing free pointers buffer space only after the + * watermark frees reached. */ + if (unlikely(q->bottom >= QBUF_WATERMARK)) { + memmove(q->buf, q->buf + q->bottom, q->bottom); + q->top -= q->bottom; + q->bottom = 0; + } + if (unlikely((q->top + sizeof(void*)) > q->size)) { + size_t newsize = q->size * 2; + char *ptr = (char*)realloc((void*)q->buf, newsize); + if (unlikely(ptr == NULL)) + return -1; + q->buf = ptr; + q->size = newsize; + } + memcpy(q->buf + q->top, (char*)&ptr, sizeof(ptr)); + q->top += sizeof(void*); + return 0; +} + +static inline void* +qbuf_pop(struct qbuf *q) { + if (unlikely(q->bottom == q->top)) + return NULL; + void *ret = *(void**)(q->buf + q->bottom); + q->bottom += sizeof(void*); + return ret; +} + +#endif diff --git a/include/recovery.h b/include/recovery.h index e34f977d7c321417a55d74e022f788b938e5660d..7de791abf2bca9adb722fda3a7170f837bf1bbac 100644 --- a/include/recovery.h +++ b/include/recovery.h @@ -96,7 +96,7 @@ struct recovery_state { */ row_handler *row_handler; void *row_handler_param; - int snap_io_rate_limit; + uint64_t snap_io_rate_limit; int rows_per_wal; double wal_fsync_delay; struct wait_lsn wait_lsn; @@ -119,7 +119,7 @@ void recover_snap(struct recovery_state *); void recover_existing_wals(struct recovery_state *); void recovery_follow_local(struct recovery_state *r, ev_tstamp wal_dir_rescan_delay); void recovery_finalize(struct recovery_state *r); -int wal_write(struct recovery_state *r, int64_t lsn, +int wal_write(struct recovery_state *r, int64_t lsn, uint64_t cookie, uint16_t op, const char *data, uint32_t len); void recovery_setup_panic(struct recovery_state *r, bool on_snap_error, bool on_wal_error); diff --git a/include/salloc.h b/include/salloc.h index 4b7e5e97e427490dcb1a07a1517c59399dd4cef2..773bdd08719d5938ff002774a650a4d050e33efd 100644 --- a/include/salloc.h +++ b/include/salloc.h @@ -38,7 +38,9 @@ bool salloc_init(size_t size, size_t minimal, double factor); void salloc_free(void); void *salloc(size_t size, const char *what); void sfree(void *ptr); +void sfree_delayed(void *ptr); void slab_validate(); +void salloc_protect(void); /** Statistics on utilization of a single slab class. */ struct slab_cache_stats { diff --git a/include/session.h b/include/session.h index 5aaf652589bd24d6c0764d917dccf43f346dd34a..60719cbc17848cefa169c1857a3918c7c567019e 100644 --- a/include/session.h +++ b/include/session.h @@ -51,7 +51,7 @@ * trigger fails or runs out of resources. */ uint32_t -session_create(int fd); +session_create(int fd, uint64_t cookie); /** * Destroy a session. diff --git a/include/tarantool.h b/include/tarantool.h index a32850acf2e7ec8c319df578f1fe377079e217f7..6740c7d1a327159bf71507fec23f885932d5dcf7 100644 --- a/include/tarantool.h +++ b/include/tarantool.h @@ -45,7 +45,7 @@ extern char *cfg_filename_fullpath; extern bool booting; extern char *binary_filename; extern char *custom_proc_title; -int reload_cfg(struct tbuf *out); +int reload_cfg(); void show_cfg(struct tbuf *out); int snapshot(void); const char *tarantool_version(void); diff --git a/include/tarantool/config.h.cmake b/include/tarantool/config.h.cmake index bd43b709e20cdd0fb59d6b14395d6ae77e7b2803..1a601756ba494765f8536f386defd179eefc23ee 100644 --- a/include/tarantool/config.h.cmake +++ b/include/tarantool/config.h.cmake @@ -112,6 +112,8 @@ #cmakedefine HAVE_PRCTL_H 1 +#cmakedefine HAVE_OPEN_MEMSTREAM 1 + /* * predefined /etc directory prefix. */ diff --git a/include/tarantool/util.h b/include/tarantool/util.h index 1fb6ce0895c4fe0687d54f735377beda7bd809e2..18d9476de595c27dfb6a376b905af2e356b79209 100644 --- a/include/tarantool/util.h +++ b/include/tarantool/util.h @@ -187,6 +187,14 @@ void * memrchr(const void *s, int c, size_t n); #endif /* HAVE_MEMRCHR */ +#ifndef HAVE_OPEN_MEMSTREAM +/* Declare open_memstream(). */ +#include <stdio.h> +FILE * +open_memstream(char **ptr, size_t *sizeloc); +#endif /* HAVE_OPEN_MEMSTREAM */ + + #if defined(__cplusplus) } /* extern "C" */ #endif /* defined(__cplusplus) */ diff --git a/src/admin.cc b/src/admin.cc index a0a74501ef296bb983ffe4c8da6dc17764e1a028..e5786ae1340c8aa710788c5d0af7a2cd74e55695 100644 --- a/src/admin.cc +++ b/src/admin.cc @@ -78,6 +78,7 @@ static void admin_handler(va_list ap) { struct ev_io coio = va_arg(ap, struct ev_io); + struct sockaddr_in *addr = va_arg(ap, struct sockaddr_in *); struct iobuf *iobuf = va_arg(ap, struct iobuf *); lua_State *L = lua_newthread(tarantool_L); int coro_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX); @@ -95,7 +96,7 @@ admin_handler(va_list ap) * a remote client: it's used in Lua * stored procedures. */ - session_create(coio.fd); + session_create(coio.fd, *(uint64_t *) addr); for (;;) { if (admin_dispatch(&coio, iobuf, L) < 0) diff --git a/src/admin.rl b/src/admin.rl new file mode 100644 index 0000000000000000000000000000000000000000..59e5e06d3cfc9b68d298323fe1504546561f31aa --- /dev/null +++ b/src/admin.rl @@ -0,0 +1,387 @@ +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <stdio.h> +#include <string.h> +#include <stdbool.h> +#include <unistd.h> +#include <stdlib.h> + +#include <fiber.h> +#include <palloc.h> +#include <salloc.h> +#include <say.h> +#include <stat.h> +#include <tarantool.h> +#include "lua/init.h" +#include <recovery.h> +#include <tbuf.h> +#include "tarantool/util.h" +#include <errinj.h> +#include "coio_buf.h" + +extern "C" { +#include <lua.h> +#include <lauxlib.h> +#include <lualib.h> +} + +#include "box/box.h" +#include "lua/init.h" +#include "session.h" +#include "scoped_guard.h" + +static const char *help = + "available commands:" CRLF + " - help" CRLF + " - exit" CRLF + " - show info" CRLF + " - show fiber" CRLF + " - show configuration" CRLF + " - show slab" CRLF + " - show palloc" CRLF + " - show stat" CRLF + " - show plugins" CRLF + " - save coredump" CRLF + " - save snapshot" CRLF + " - lua command" CRLF + " - reload configuration" CRLF + " - show injections (debug mode only)" CRLF + " - set injection <name> <state> (debug mode only)" CRLF; + +static const char *unknown_command = "unknown command. try typing help." CRLF; + +%%{ + machine admin; + write data; +}%% + +struct salloc_stat_admin_cb_ctx { + int64_t total_used; + struct tbuf *out; +}; + +static int +salloc_stat_admin_cb(const struct slab_cache_stats *cstat, void *cb_ctx) +{ + struct salloc_stat_admin_cb_ctx *ctx = (struct salloc_stat_admin_cb_ctx *) cb_ctx; + + tbuf_printf(ctx->out, + " - { item_size: %- 5i, slabs: %- 3i, items: %- 11" PRIi64 + ", bytes_used: %- 12" PRIi64 + ", bytes_free: %- 12" PRIi64 " }" CRLF, + (int)cstat->item_size, + (int)cstat->slabs, + cstat->items, + cstat->bytes_used, + cstat->bytes_free); + + ctx->total_used += cstat->bytes_used; + return 0; +} + +static void +show_slab(struct tbuf *out) +{ + struct salloc_stat_admin_cb_ctx cb_ctx; + struct slab_arena_stats astat; + + cb_ctx.total_used = 0; + cb_ctx.out = out; + + tbuf_printf(out, "slab statistics:\n classes:" CRLF); + + salloc_stat(salloc_stat_admin_cb, &astat, &cb_ctx); + + tbuf_printf(out, " items_used: %.2f%%" CRLF, + (double)cb_ctx.total_used / astat.size * 100); + tbuf_printf(out, " arena_used: %.2f%%" CRLF, + (double)astat.used / astat.size * 100); +} + +static void +end(struct tbuf *out) +{ + tbuf_printf(out, "..." CRLF); +} + +static void +start(struct tbuf *out) +{ + tbuf_printf(out, "---" CRLF); +} + +static void +ok(struct tbuf *out) +{ + start(out); + tbuf_printf(out, "ok" CRLF); + end(out); +} + +static void +fail(struct tbuf *out, struct tbuf *err) +{ + start(out); + tbuf_printf(out, "fail:%.*s" CRLF, err->size, (char *)err->data); + end(out); +} + +static void +tarantool_info(struct tbuf *out) +{ + tbuf_printf(out, "info:" CRLF); + tbuf_printf(out, " version: \"%s\"" CRLF, tarantool_version()); + tbuf_printf(out, " uptime: %i" CRLF, (int)tarantool_uptime()); + tbuf_printf(out, " pid: %i" CRLF, getpid()); + tbuf_printf(out, " logger_pid: %i" CRLF, logger_pid); + tbuf_printf(out, " snapshot_pid: %i" CRLF, snapshot_pid); + tbuf_printf(out, " lsn: %" PRIi64 CRLF, + recovery_state->confirmed_lsn); + tbuf_printf(out, " recovery_lag: %.3f" CRLF, + recovery_state->remote ? + recovery_state->remote->recovery_lag : 0); + tbuf_printf(out, " recovery_last_update: %.3f" CRLF, + recovery_state->remote ? + recovery_state->remote->recovery_last_update_tstamp :0); + box_info(out); + const char *path = cfg_filename_fullpath; + if (path == NULL) + path = cfg_filename; + tbuf_printf(out, " config: \"%s\"" CRLF, path); +} + +static int +show_stat_item(const char *name, int rps, int64_t total, void *ctx) +{ + struct tbuf *buf = (struct tbuf *) ctx; + int name_len = strlen(name); + tbuf_printf(buf, + " %s:%*s{ rps: %- 6i, total: %- 12" PRIi64 " }" CRLF, + name, 1 + stat_max_name_len - name_len, " ", rps, total); + return 0; +} + +void +show_stat(struct tbuf *buf) +{ + tbuf_printf(buf, "statistics:" CRLF); + stat_foreach(show_stat_item, buf); +} + +static int +admin_dispatch(struct ev_io *coio, struct iobuf *iobuf, lua_State *L) +{ + struct ibuf *in = &iobuf->in; + struct tbuf *out = tbuf_new(fiber->gc_pool); + struct tbuf *err = tbuf_new(fiber->gc_pool); + int cs; + char *p, *pe; + char *strstart, *strend; + bool state; + + while ((pe = (char *) memchr(in->pos, '\n', in->end - in->pos)) == NULL) { + if (coio_bread(coio, in, 1) <= 0) + return -1; + } + + pe++; + p = in->pos; + + %%{ + action show_plugins { + start(out); + show_plugins_stat(out); + end(out); + } + + action show_configuration { + start(out); + show_cfg(out); + end(out); + } + + action show_injections { + start(out); + errinj_info(out); + end(out); + } + + action help { + start(out); + tbuf_append(out, help, strlen(help)); + end(out); + } + + action lua { + strstart[strend-strstart]='\0'; + start(out); + tarantool_lua(L, out, strstart); + end(out); + } + + action reload_configuration { + if (reload_cfg(err)) + fail(out, err); + else + ok(out); + } + + action save_snapshot { + int ret = snapshot(); + + if (ret == 0) + ok(out); + else { + tbuf_printf(err, " can't save snapshot, errno %d (%s)", + ret, strerror(ret)); + + fail(out, err); + } + } + + action set_injection { + strstart[strend-strstart] = '\0'; + if (errinj_set_byname(strstart, state)) { + tbuf_printf(err, "can't find error injection '%s'", strstart); + fail(out, err); + } else { + ok(out); + } + } + + eol = "\n" | "\r\n"; + show = "sh"("o"("w")?)?; + info = "in"("f"("o")?)?; + check = "ch"("e"("c"("k")?)?)?; + configuration = "co"("n"("f"("i"("g"("u"("r"("a"("t"("i"("o"("n")?)?)?)?)?)?)?)?)?)?)?; + fiber = "fi"("b"("e"("r")?)?)?; + slab = "sl"("a"("b")?)?; + mod = "mo"("d")?; + palloc = "pa"("l"("l"("o"("c")?)?)?)?; + stat = "st"("a"("t")?)?; + plugins = "plugins"; + + help = "h"("e"("l"("p")?)?)?; + exit = "e"("x"("i"("t")?)?)? | "q"("u"("i"("t")?)?)?; + save = "sa"("v"("e")?)?; + coredump = "co"("r"("e"("d"("u"("m"("p")?)?)?)?)?)?; + snapshot = "sn"("a"("p"("s"("h"("o"("t")?)?)?)?)?)?; + string = [^\r\n]+ >{strstart = p;} %{strend = p;}; + reload = "re"("l"("o"("a"("d")?)?)?)?; + lua = "lu"("a")?; + + set = "se"("t")?; + injection = "in"("j"("e"("c"("t"("i"("o"("n")?)?)?)?)?)?)?; + injections = injection"s"; + namech = alnum | punct; + name = namech+ >{ strstart = p; } %{ strend = p; }; + state_on = "on" %{ state = true; }; + state_off = "of"("f")? %{ state = false; }; + state = state_on | state_off; + + commands = (help %help | + exit %{return -1;} | + lua " "+ string %lua | + show " "+ info %{start(out); tarantool_info(out); end(out);} | + show " "+ fiber %{start(out); fiber_info(out); end(out);} | + show " "+ configuration %show_configuration | + show " "+ slab %{start(out); show_slab(out); end(out);} | + show " "+ palloc %{start(out); palloc_stat(out); end(out);} | + show " "+ stat %{start(out); show_stat(out);end(out);} | + show " "+ injections %show_injections | + show " "+ plugins %show_plugins | + set " "+ injection " "+ name " "+ state %set_injection | + save " "+ coredump %{coredump(60); ok(out);} | + save " "+ snapshot %save_snapshot | + check " "+ slab %{slab_validate(); ok(out);} | + reload " "+ configuration %reload_configuration); + + main := commands eol; + write init; + write exec; + }%% + + in->pos = pe; + + if (p != pe) { + start(out); + tbuf_append(out, unknown_command, strlen(unknown_command)); + end(out); + } + + coio_write(coio, out->data, out->size); + return 0; +} + +static void +admin_handler(va_list ap) +{ + struct ev_io coio = va_arg(ap, struct ev_io); + struct sockaddr_in *addr = va_arg(ap, struct sockaddr_in *); + struct iobuf *iobuf = va_arg(ap, struct iobuf *); + lua_State *L = lua_newthread(tarantool_L); + int coro_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX); + + auto scoped_guard = make_scoped_guard([&] { + luaL_unref(tarantool_L, LUA_REGISTRYINDEX, coro_ref); + evio_close(&coio); + iobuf_delete(iobuf); + session_destroy(fiber->sid); + }); + + /* + * Admin and iproto connections must have a + * session object, representing the state of + * a remote client: it's used in Lua + * stored procedures. + */ + session_create(coio.fd, *(uint64_t *) addr); + for (;;) { + if (admin_dispatch(&coio, iobuf, L) < 0) + return; + iobuf_gc(iobuf); + fiber_gc(); + } +} + +void +admin_init(const char *bind_ipaddr, int admin_port) +{ + static struct coio_service admin; + coio_service_init(&admin, "admin", bind_ipaddr, + admin_port, admin_handler, NULL); + evio_service_start(&admin.evio_service); +} + +/* + * Local Variables: + * mode: c + * End: + * vim: syntax=objc + */ diff --git a/src/box/alter.cc b/src/box/alter.cc index 1a46a8177313f7c76d4f24206d95ded54ba683c0..f83f41a8adc26ed0e7119cdd10e5c269f82c46b8 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -35,16 +35,18 @@ #include "scoped_guard.h" #include <new> /* for placement new */ #include <stdio.h> /* snprintf() */ +#include <ctype.h> /** _space columns */ -#define ID 0 -#define ARITY 1 -#define NAME 2 +#define ID 0 +#define ARITY 1 +#define NAME 2 +#define FLAGS 3 /** _index columns */ -#define INDEX_ID 1 -#define INDEX_TYPE 3 -#define INDEX_IS_UNIQUE 4 -#define INDEX_PART_COUNT 5 +#define INDEX_ID 1 +#define INDEX_TYPE 3 +#define INDEX_IS_UNIQUE 4 +#define INDEX_PART_COUNT 5 /* {{{ Auxiliary functions and methods. */ @@ -94,6 +96,28 @@ key_def_new_from_tuple(struct tuple *tuple) return key_def; } +static void +space_def_init_flags(struct space_def *def, struct tuple *tuple) +{ + /* default values of flags */ + def->temporary = false; + + /* there is no property in the space */ + if (tuple->field_count <= FLAGS) + return; + + const char *flags = tuple_field_cstr(tuple, FLAGS); + while (flags && *flags) { + while (isspace(*flags)) /* skip space */ + flags++; + if (strncmp(flags, "temporary", strlen("temporary")) == 0) + def->temporary = true; + flags = strchr(flags, ','); + if (flags) + flags++; + } +} + /** * Fill space_def structure from struct tuple. */ @@ -105,6 +129,8 @@ space_def_create_from_tuple(struct space_def *def, struct tuple *tuple, def->arity = tuple_field_u32(tuple, ARITY); int n = snprintf(def->name, sizeof(def->name), "%s", tuple_field_cstr(tuple, NAME)); + + space_def_init_flags(def, tuple); space_def_check(def, n, errcode); if (errcode != ER_ALTER_SPACE && def->id >= SC_SYSTEM_ID_MIN && def->id < SC_SYSTEM_ID_MAX) { @@ -260,14 +286,15 @@ alter_space_commit(struct trigger *trigger, void * /* event */) space_swap_index(alter->old_space, alter->new_space, index_id(old_index), - index_id(new_index)); + index_id(new_index), + false); } } /* * Commit alter ops, this will move the changed * indexes into their new places. */ - struct AlterSpaceOp *op; + class AlterSpaceOp *op; rlist_foreach_entry(op, &alter->ops, link) { op->commit(alter); } @@ -307,7 +334,7 @@ alter_space_rollback(struct trigger *trigger, void * /* event */) op->rollback(alter); space_remove_trigger(alter); #endif - struct AlterSpaceOp *op; + class AlterSpaceOp *op; rlist_foreach_entry(op, &alter->ops, link) op->rollback(alter); alter_space_delete(alter); @@ -375,7 +402,7 @@ alter_space_do(struct txn *txn, struct alter_space *alter, * Allow for a separate prepare step so that some ops * can be optimized. */ - struct AlterSpaceOp *op, *tmp; + class AlterSpaceOp *op, *tmp; rlist_foreach_entry_safe(op, &alter->ops, link, tmp) op->prepare(alter); /* @@ -448,6 +475,13 @@ ModifySpace::prepare(struct alter_space *alter) (unsigned) def.id, "can not change arity on a non-empty space"); } + if (def.temporary != alter->old_space->def.temporary && + alter->old_space->engine.state != READY_NO_KEYS && + space_size(alter->old_space) > 0) { + tnt_raise(ClientError, ER_ALTER_SPACE, + (unsigned) space_id(alter->old_space), + "can not switch temporary flag on a non-empty space"); + } } /** Amend the definition of the new space. */ @@ -563,7 +597,7 @@ ModifyIndex::commit(struct alter_space *alter) { /* Move the old index to the new place but preserve */ space_swap_index(alter->old_space, alter->new_space, - old_key_def->iid, new_key_def->iid); + old_key_def->iid, new_key_def->iid, true); } ModifyIndex::~ModifyIndex() @@ -781,11 +815,17 @@ AddIndex::alter(struct alter_space *alter) new_index->endBuild(); /* Build the new index. */ struct tuple *tuple; + struct tuple_format *format = alter->new_space->format; + char *field_map = ((char *) palloc(fiber->gc_pool, + format->field_map_size) + + format->field_map_size); while ((tuple = it->next(it))) { /* - * @todo: - * tuple_format_validate(alter->new_space->format, - * tuple) + * Check that the tuple is OK according to the + * new format. + */ + tuple_init_field_map(format, tuple, (uint32_t *) field_map); + /* * @todo: better message if there is a duplicate. */ struct tuple *old_tuple = diff --git a/src/box/box.cc b/src/box/box.cc index e98dd0ab6220bd45727b46d161bec3076fcc3481..5099d52680de8677959c7d009cfda26e171b7d6e 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -258,7 +258,7 @@ void box_free(void) { schema_free(); - tuple_free(); + tuple_format_free(); } void @@ -267,7 +267,7 @@ box_init() title("loading"); atexit(box_free); - tuple_init(); + tuple_format_init(); schema_init(); /* recovery initialization */ @@ -318,6 +318,8 @@ struct snapshot_space_param { static void snapshot_space(struct space *sp, void *udata) { + if (space_is_temporary(sp)) + return; struct tuple *tuple; struct snapshot_space_param *ud = (struct snapshot_space_param *) udata; Index *pk = space_index(sp, 0); diff --git a/src/box/box_lua.cc b/src/box/box_lua.cc index 01959b2f5ae5f75abef5b9aa2887dba279b7567e..868ec4fd93724fde3d6a7162a5fc628ba87a235f 100644 --- a/src/box/box_lua.cc +++ b/src/box/box_lua.cc @@ -714,7 +714,7 @@ static int lbox_index_tostring(struct lua_State *L) { Index *index = lua_checkindex(L, 1); - lua_pushfstring(L, "index %d", (int) index_id(index)); + lua_pushfstring(L, " index %d", (int) index_id(index)); return 1; } diff --git a/src/box/box_lua_space.cc b/src/box/box_lua_space.cc index edc3c5aa28748a7a97058873ea09454ded864188..4a153a45d52eb3821dc03e1e0e678062692dc3e6 100644 --- a/src/box/box_lua_space.cc +++ b/src/box/box_lua_space.cc @@ -57,13 +57,18 @@ lbox_fillspace(struct lua_State *L, struct space *space, int i) lua_pushnumber(L, space_id(space)); lua_settable(L, i); + /* space.is_temp */ + lua_pushstring(L, "temporary"); + lua_pushboolean(L, space_is_temporary(space)); + lua_settable(L, i); + /* space.name */ lua_pushstring(L, "name"); lua_pushstring(L, space_name(space)); lua_settable(L, i); lua_pushstring(L, "enabled"); - lua_pushboolean(L, space->engine.state != READY_NO_KEYS); + lua_pushboolean(L, space_index(space, 0) != 0); lua_settable(L, i); lua_getfield(L, i, "index"); diff --git a/src/box/key_def.cc b/src/box/key_def.cc index 07d4b248261e3bcb41ba65c1cfe91f83926e5488..03d363f07e9e42b38fd876b2c6c4f5f2979973ee 100644 --- a/src/box/key_def.cc +++ b/src/box/key_def.cc @@ -45,7 +45,7 @@ key_def_new(uint32_t space_id, uint32_t iid, const char *name, tnt_raise(LoggedError, ER_MEMORY_ISSUE, sz, "struct key_def", "malloc"); } - int n = snprintf(def->name, sizeof(def->name) - 1, "%s", name); + int n = snprintf(def->name, sizeof(def->name), "%s", name); if (n >= sizeof(def->name)) { free(def); tnt_raise(LoggedError, ER_MODIFY_INDEX, @@ -124,6 +124,12 @@ key_def_check(struct key_def *key_def) (unsigned) key_def->space_id, "index id too big"); } + if (key_def->iid == 0 && key_def->is_unique == false) { + tnt_raise(ClientError, ER_MODIFY_INDEX, + (unsigned) key_def->iid, + (unsigned) key_def->space_id, + "primary key must be unique"); + } if (key_def->part_count == 0) { tnt_raise(ClientError, ER_MODIFY_INDEX, (unsigned) key_def->iid, diff --git a/src/box/key_def.h b/src/box/key_def.h index 56bfc26dff50a2472b9bcd69ad2638bf5044fdc2..ee0f61c98a55df6e0646615bcbd752facde145f2 100644 --- a/src/box/key_def.h +++ b/src/box/key_def.h @@ -194,6 +194,13 @@ struct space_def { */ uint32_t arity; char name[BOX_NAME_MAX + 1]; + /** + * The space is a temporary: + * - it is empty at server start + * - changes are not written to WAL + * - changes are not part of a snapshot + */ + bool temporary; }; /** Check space definition structure for errors. */ diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua index af74cdf35872c55bf07a1ed443f0eab5de575b29..ca07fc2cf81f7ce0780a6878cfb8fb767db960c9 100644 --- a/src/box/lua/schema.lua +++ b/src/box/lua/schema.lua @@ -13,6 +13,9 @@ box.schema.space.create = function(name, options) options = {} end local if_not_exists = options.if_not_exists + + local temporary = options.temporary and "temporary" or "" + if box.space[name] then if options.if_not_exists then return box.space[name], "not created" @@ -35,7 +38,7 @@ box.schema.space.create = function(name, options) if options.arity == nil then options.arity = 0 end - _space:insert(id, options.arity, name) + _space:insert(id, options.arity, name, temporary) return box.space[id], "created" end box.schema.create_space = box.schema.space.create @@ -93,7 +96,29 @@ box.schema.index.drop = function(space_id, index_id) end box.schema.index.rename = function(space_id, index_id, name) local _index = box.space[box.schema.INDEX_ID] - _index:update({space_id, index_id}, "=p", 3, name) + _index:update({space_id, index_id}, "=p", 2, name) +end +box.schema.index.alter = function(space_id, index_id, options) + if options == nil then + return + end + local ops = "" + local args = {} + local function add_op(op, opno) + if op then + ops = ops.."=p" + table.insert(args, opno) + table.insert(args, op) + end + end + add_op(options.id, 1) + add_op(options.name, 2) + add_op(options.type, 3) + if options.unique ~= nil then + add_op(options.unique and 1 or 0, 4) + end + local _index = box.space[box.schema.INDEX_ID] + _index:update({space_id, index_id}, ops, unpack(args)) end function box.schema.space.bless(space) @@ -162,9 +187,18 @@ function box.schema.space.bless(space) end return unpack(range) end + index_mt.select = function(index, ...) + return box.select(index.n, index.id, ...) + end index_mt.drop = function(index) return box.schema.index.drop(index.n, index.id) end + index_mt.rename = function(index, name) + return box.schema.index.rename(index.n, index.id, name) + end + index_mt.alter= function(index, options) + return box.schema.index.alter(index.n, index.id, options) + end -- local space_mt = {} space_mt.len = function(space) return space.index[0]:len() end diff --git a/src/box/schema.cc b/src/box/schema.cc index 065f28ec10c5dfc5de59a2d76afa3f00255fe820..3b69278e0f219a4e9a4a3d740f2dc6b02f8c927c 100644 --- a/src/box/schema.cc +++ b/src/box/schema.cc @@ -217,7 +217,7 @@ schema_init() * (and re-created) first. */ /* _schema - key/value space with schema description */ - struct space_def def = { SC_SCHEMA_ID, 0, "_schema" }; + struct space_def def = { SC_SCHEMA_ID, 0, "_schema", false }; struct key_def *key_def = key_def_new(def.id, 0 /* index id */, "primary", /* name */ diff --git a/src/box/space.cc b/src/box/space.cc index 849053f1ffa54009e35f79799a66b63710a17e42..644f279fe105a2954a7ae6d811cf6fdc8978f01c 100644 --- a/src/box/space.cc +++ b/src/box/space.cc @@ -307,11 +307,17 @@ space_dump_def(const struct space *space, struct rlist *key_list) void space_swap_index(struct space *lhs, struct space *rhs, uint32_t lhs_id, - uint32_t rhs_id) + uint32_t rhs_id, bool keep_key_def) { Index *tmp = lhs->index_map[lhs_id]; lhs->index_map[lhs_id] = rhs->index_map[rhs_id]; rhs->index_map[rhs_id] = tmp; + if (keep_key_def) { + struct key_def *tmp = lhs->index_map[lhs_id]->key_def; + lhs->index_map[lhs_id]->key_def = + rhs->index_map[rhs_id]->key_def; + rhs->index_map[rhs_id]->key_def = tmp; + } } extern "C" void diff --git a/src/box/space.h b/src/box/space.h index 4932abf478943d2b192337da9ec126d81a178056..c62558e6c57cab21a1d0085f02205e7fce5fdc37 100644 --- a/src/box/space.h +++ b/src/box/space.h @@ -130,6 +130,11 @@ space_id(struct space *space) { return space->def.id; } static inline const char * space_name(struct space *space) { return space->def.name; } + +/** Return true if space is temporary. */ +static inline bool +space_is_temporary(struct space *space) { return space->def.temporary; } + /** * @brief A single method to handle REPLACE, DELETE and UPDATE. * @@ -259,7 +264,7 @@ space_dump_def(const struct space *space, struct rlist *key_list); */ void space_swap_index(struct space *lhs, struct space *rhs, uint32_t lhs_id, - uint32_t rhs_id); + uint32_t rhs_id, bool keep_key_def); /** Rebuild index map in a space after a series of swap index. */ void diff --git a/src/box/tuple.cc b/src/box/tuple.cc index a6b56b16aeea83f8732438e8fa812bb94681daaf..f3471fd4ba5f24ef1105a8cadf5a4388b6a9aea0 100644 --- a/src/box/tuple.cc +++ b/src/box/tuple.cc @@ -216,19 +216,19 @@ tuple_format_new(struct rlist *key_list) * Validate a new tuple format and initialize tuple-local * format data. */ -static inline void -tuple_init_field_map(struct tuple *tuple, struct tuple_format *format) +void +tuple_init_field_map(struct tuple_format *format, struct tuple *tuple, uint32_t *field_map) { /* Check to see if the tuple has a sufficient number of fields. */ if (tuple->field_count < format->field_count) - tnt_raise(IllegalParams, - "tuple must have all indexed fields"); + tnt_raise(ClientError, ER_INDEX_ARITY, + (unsigned) tuple->field_count, + (unsigned) format->field_count); int32_t *offset = format->offset; enum field_type *type = format->types; enum field_type *end = format->types + format->field_count; const char *pos = tuple->data; - uint32_t *field_map = (uint32_t *) tuple; uint32_t i = 0; for (; type < end; offset++, type++, i++) { @@ -251,6 +251,16 @@ tuple_init_field_map(struct tuple *tuple, struct tuple_format *format) } } +/** + * Incremented on every snapshot and is used to distinguish tuples + * which were created after start of a snapshot (these tuples can + * be freed right away, since they are not used for snapshot) or + * before start of a snapshot (these tuples can be freed only + * after the snapshot has finished, otherwise it'll write bad data + * to the snapshot file). + */ +extern uint32_t snapshot_version; + /** Allocate a tuple */ struct tuple * tuple_alloc(struct tuple_format *format, size_t size) @@ -260,6 +270,7 @@ tuple_alloc(struct tuple_format *format, size_t size) struct tuple *tuple = (struct tuple *)(ptr + format->field_map_size); tuple->refs = 0; + tuple->version = snapshot_version; tuple->bsize = size; tuple->format_id = tuple_format_id(format); tuple_format_ref(format, 1); @@ -280,7 +291,10 @@ tuple_delete(struct tuple *tuple) struct tuple_format *format = tuple_format(tuple); char *ptr = (char *) tuple - format->field_map_size; tuple_format_ref(format, -1); - sfree(ptr); + if (tuple->version == snapshot_version) + sfree(ptr); + else + sfree_delayed(ptr); } /** @@ -457,7 +471,7 @@ tuple_update(struct tuple_format *format, try { tuple_update_execute(update, new_tuple->data); - tuple_init_field_map(new_tuple, format); + tuple_init_field_map(format, new_tuple, (uint32_t *)new_tuple); } catch (const Exception&) { tuple_delete(new_tuple); throw; @@ -494,7 +508,7 @@ tuple_new(struct tuple_format *format, uint32_t field_count, new_tuple->field_count = field_count; memcpy(new_tuple->data, end - tuple_len, tuple_len); try { - tuple_init_field_map(new_tuple, format); + tuple_init_field_map(format, new_tuple, (uint32_t *)new_tuple); } catch (...) { tuple_delete(new_tuple); throw; @@ -632,7 +646,7 @@ tuple_compare_with_key(const struct tuple *tuple, const char *key, } void -tuple_init() +tuple_format_init() { tuple_format_ber = tuple_format_new(&rlist_nil); /* Make sure this one stays around. */ @@ -640,7 +654,7 @@ tuple_init() } void -tuple_free() +tuple_format_free() { /* Clear recycled ids. */ while (recycled_format_ids != FORMAT_ID_NIL) { diff --git a/src/box/tuple.h b/src/box/tuple.h index 0297dc7677fc3d2b4eb8aa1c57497b85a528123c..0d360c695328f1868c59f3731844b565b51205d5 100644 --- a/src/box/tuple.h +++ b/src/box/tuple.h @@ -133,6 +133,8 @@ tuple_format_ref(struct tuple_format *format, int count) */ struct tuple { + /** snapshot generation version */ + uint32_t version; /** reference counter */ uint16_t refs; /** format identifier */ @@ -353,6 +355,10 @@ tuple_next_cstr(struct tuple_iterator *it); void tuple_print(struct tbuf *buf, const struct tuple *tuple); +void +tuple_init_field_map(struct tuple_format *format, + struct tuple *tuple, uint32_t *field_map); + struct tuple * tuple_update(struct tuple_format *new_format, void *(*region_alloc)(void *, size_t), void *alloc_ctx, @@ -431,10 +437,10 @@ tuple_to_luabuf(struct tuple *tuple, struct luaL_Buffer *b); /** Initialize tuple library */ void -tuple_init(); +tuple_format_init(); /** Cleanup tuple library */ void -tuple_free(); +tuple_format_free(); #endif /* TARANTOOL_BOX_TUPLE_H_INCLUDED */ diff --git a/src/box/txn.cc b/src/box/txn.cc index 96f4f2316c911b13a682a5e2a80fbd972f466fa7..414b57fae31f09ede9329ef824c0d680dd9ff63b 100644 --- a/src/box/txn.cc +++ b/src/box/txn.cc @@ -82,12 +82,13 @@ txn_begin() void txn_commit(struct txn *txn) { - if (txn->old_tuple || txn->new_tuple) { + if ((txn->old_tuple || txn->new_tuple) && + !space_is_temporary(txn->space)) { int64_t lsn = next_lsn(recovery_state); ev_tstamp start = ev_now(), stop; - int res = wal_write(recovery_state, lsn, txn->op, - txn->data, txn->len); + int res = wal_write(recovery_state, lsn, fiber->cookie, + txn->op, txn->data, txn->len); stop = ev_now(); if (stop - start > cfg.too_long_threshold) { diff --git a/src/coio.cc b/src/coio.cc index 677b726a1ead2d0d9aa86150b7b6181f71db3f57..3d143d9a2f0a0b43c449127463adb221b3486185 100644 --- a/src/coio.cc +++ b/src/coio.cc @@ -568,7 +568,7 @@ coio_service_on_accept(struct evio_service *evio_service, * Start the created fiber. It becomes the coio object owner * and will have to close it and free before termination. */ - fiber_call(f, coio, iobuf, service->handler_param); + fiber_call(f, coio, addr, iobuf, service->handler_param); } void diff --git a/src/fiber.cc b/src/fiber.cc index eebd8fa5e9ab66de1f443a38a6831a086fc6e711..75442cfd43aceb0eb5cc2318f1e251a364bed7d0 100644 --- a/src/fiber.cc +++ b/src/fiber.cc @@ -489,34 +489,6 @@ fiber_destroy_all() fiber_destroy(f); } - -static void -fiber_info_print(struct tbuf *out, struct fiber *fiber) -{ - void *stack_top = (char *) fiber->coro.stack + fiber->coro.stack_size; - tbuf_printf(out, " - fid: %i" CRLF, fiber->fid); - tbuf_printf(out, " - csw: %i" CRLF, fiber->csw); - tbuf_printf(out, " - name: %s" CRLF, fiber_name(fiber)); - tbuf_printf(out, " - stack: %p" CRLF, stack_top); -#ifdef ENABLE_BACKTRACE - tbuf_printf(out, " - backtrace:" CRLF "%s", - backtrace(fiber->last_stack_frame, - fiber->coro.stack, fiber->coro.stack_size)); -#endif /* ENABLE_BACKTRACE */ -} - -void -fiber_info(struct tbuf *out) -{ - struct fiber *fiber; - - tbuf_printf(out, "fibers:" CRLF); - rlist_foreach_entry(fiber, &fibers, link) - fiber_info_print(out, fiber); - rlist_foreach_entry(fiber, &zombie_fibers, link) - fiber_info_print(out, fiber); -} - void fiber_init(void) { diff --git a/src/iproto.cc b/src/iproto.cc index cc401a5c24ce66ec25b9cdd2cc326b32758855e8..4a6a273231df6c0bd4ff35713f77db237adb07b6 100644 --- a/src/iproto.cc +++ b/src/iproto.cc @@ -218,6 +218,9 @@ iproto_queue_init(struct iproto_queue *i_queue, static inline uint32_t iproto_session_id(struct iproto_session *session); +static inline uint64_t +iproto_session_cookie(struct iproto_session *session); + /** A handler to process all queued requests. */ static void iproto_queue_handler(va_list ap) @@ -227,7 +230,7 @@ iproto_queue_handler(va_list ap) restart: while (iproto_dequeue_request(i_queue, &request)) { - fiber_set_sid(fiber, iproto_session_id(request.session)); + fiber_set_sid(fiber, iproto_session_id(request.session), iproto_session_cookie(request.session)); request.process(&request); } iproto_cache_fiber(&request_queue); @@ -274,6 +277,7 @@ struct iproto_session struct ev_io output; /** Session id. */ uint32_t sid; + uint64_t cookie; }; SLIST_HEAD(, iproto_session) iproto_session_cache = @@ -302,6 +306,12 @@ iproto_session_id(struct iproto_session *session) return session->sid; } +static inline uint64_t +iproto_session_cookie(struct iproto_session *session) +{ + return session->cookie; +} + static void iproto_session_on_input(struct ev_io *watcher, int revents __attribute__((unused))); @@ -319,7 +329,8 @@ static void iproto_process_disconnect(struct iproto_request *request); static struct iproto_session * -iproto_session_create(const char *name, int fd, box_process_func *param) +iproto_session_create(const char *name, int fd, struct sockaddr_in *addr, + box_process_func *param) { struct iproto_session *session; if (SLIST_EMPTY(&iproto_session_cache)) { @@ -339,6 +350,7 @@ iproto_session_create(const char *name, int fd, box_process_func *param) session->parse_size = 0; session->write_pos = obuf_create_svp(&session->iobuf[0]->out); session->sid = 0; + session->cookie = *(uint64_t *) addr; return session; } @@ -694,7 +706,7 @@ iproto_process_connect(struct iproto_request *request) struct iobuf *iobuf = request->iobuf; int fd = session->input.fd; try { /* connect. */ - session->sid = session_create(fd); + session->sid = session_create(fd, session->cookie); } catch (const ClientError& e) { iproto_reply_error(&iobuf->out, request->header, e); try { @@ -723,7 +735,7 @@ iproto_process_connect(struct iproto_request *request) static void iproto_process_disconnect(struct iproto_request *request) { - fiber_set_sid(fiber, request->session->sid); + fiber_set_sid(fiber, request->session->sid, request->session->cookie); /* Runs the trigger, which may yield. */ iproto_session_destroy(request->session); } @@ -744,7 +756,7 @@ iproto_on_accept(struct evio_service *service, int fd, box_process_func *process_fun = (box_process_func*) service->on_accept_param; - session = iproto_session_create(name, fd, process_fun); + session = iproto_session_create(name, fd, addr, process_fun); iproto_enqueue_request(&request_queue, session, session->iobuf[0], &dummy_header, iproto_process_connect); diff --git a/src/log_io.cc b/src/log_io.cc index fda032c5fb1fb779af4037b4534133665ffd9afd..cae77c86d9889b807a4308a875a15c4f1f82fd43 100644 --- a/src/log_io.cc +++ b/src/log_io.cc @@ -53,13 +53,13 @@ row_header_sign(struct row_header *header) } void -wal_row_fill(struct wal_row *row, int64_t lsn, +wal_row_fill(struct wal_row *row, int64_t lsn, uint64_t cookie, const char *metadata, size_t metadata_len, const char *data, size_t data_len) { row->marker = row_marker; row->tag = WAL; /* unused. */ - row->cookie = 0; /* unused. */ + row->cookie = cookie; memcpy(row->data, metadata, metadata_len); memcpy(row->data + metadata_len, data, data_len); row_header_fill(&row->header, lsn, metadata_len + data_len + diff --git a/src/lua/fiber.cc b/src/lua/fiber.cc index da0fd2ae7d62784fb0236e96f5e08017056916e6..baf5f94ec6fa85a101b37d6827511cc5c3e87058 100644 --- a/src/lua/fiber.cc +++ b/src/lua/fiber.cc @@ -311,6 +311,7 @@ lbox_fiber_gc(struct lua_State *L) return 0; } +#ifdef ENABLE_BACKTRACE static int fiber_backtrace_cb(int frameno, void *frameret, const char *func, size_t offset, void *cb_ctx) { @@ -326,6 +327,7 @@ fiber_backtrace_cb(int frameno, void *frameret, const char *func, size_t offset, lua_settable(L, -3); return 0; } +#endif static int lbox_fiber_statof(struct fiber *f, void *cb_ctx) @@ -380,7 +382,7 @@ lbox_fiber_detach(struct lua_State *L) /* Request a detach. */ lua_pushinteger(L, DETACH); /* A detached fiber has no associated session. */ - fiber_set_sid(fiber, 0); + fiber_set_sid(fiber, 0, 0); fiber_yield_to(caller); return 0; } @@ -501,7 +503,7 @@ lbox_fiber_create(struct lua_State *L) struct fiber *f = fiber_new("lua", box_lua_fiber_run); /* Preserve the session in a child fiber. */ - fiber_set_sid(f, fiber->sid); + fiber_set_sid(f, fiber->sid, fiber->cookie); /* Initially the fiber is cancellable */ f->flags |= FIBER_USER_MODE | FIBER_CANCELLABLE; @@ -762,6 +764,8 @@ lbox_fiber_self(struct lua_State *L) static int lbox_fiber_find(struct lua_State *L) { + if (lua_gettop(L) != 1) + luaL_error(L, "fiber.find(id): bad arguments"); int fid = lua_tointeger(L, -1); struct fiber *f = fiber_find(fid); if (f) diff --git a/src/lua/init.cc b/src/lua/init.cc index fe63c71452a750d1ef33f6761dbf28436048229d..80002b45588778792609cb33846b4a43d1dc4db0 100644 --- a/src/lua/init.cc +++ b/src/lua/init.cc @@ -71,6 +71,7 @@ static RLIST_HEAD(loaded_plugins); extern "C" { #include <cfg/tarantool_box_cfg.h> +#include <cfg/warning.h> } /* extern "C" */ /** @@ -708,9 +709,8 @@ is_string(const char *str) static int lbox_cfg_reload(struct lua_State *L) { - struct tbuf *err = tbuf_new(fiber->gc_pool); - if (reload_cfg(err)) - luaL_error(L, err->data); + if (reload_cfg()) + luaL_error(L, cfg_log); lua_pushstring(L, "ok"); return 1; } diff --git a/src/memcached-grammar.cc b/src/memcached-grammar.cc deleted file mode 100644 index 6012b829a50758f6cf0f14aa177b77e0aee954ce..0000000000000000000000000000000000000000 --- a/src/memcached-grammar.cc +++ /dev/null @@ -1,3671 +0,0 @@ - -#line 1 "src/memcached-grammar.rl" -/* - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the - * following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#line 34 "src/memcached-grammar.cc" -static const int memcached_start = 1; -static const int memcached_first_final = 197; -static const int memcached_error = 0; - -static const int memcached_en_main = 1; - - -#line 33 "src/memcached-grammar.rl" - - -static int __attribute__((noinline)) -memcached_dispatch(struct ev_io *coio, struct iobuf *iobuf) -{ - int cs; - char *p, *pe; - char *fstart; - struct tbuf *keys = tbuf_new(fiber->gc_pool); - const char *key; - bool append, show_cas; - int incr_sign; - uint64_t cas, incr; - uint32_t flags, exptime, bytes; - bool noreply = false; - char *data = NULL; - bool done = false; - uintptr_t flush_delay = 0; - size_t keys_count = 0; - struct ibuf *in = &iobuf->in; - struct obuf *out = &iobuf->out; - /* Savepoint for 'noreply' */ - struct obuf_svp obuf_svp = obuf_create_svp(out); - - p = in->pos; - pe = in->end; - - say_debug("memcached_dispatch '%.*s'", MIN((int)(pe - p), 40) , p); - - -#line 73 "src/memcached-grammar.cc" - { - cs = memcached_start; - } - -#line 78 "src/memcached-grammar.cc" - { - if ( p == pe ) - goto _test_eof; - switch ( cs ) - { -case 1: - switch( (*p) ) { - case 65: goto st2; - case 67: goto st44; - case 68: goto st67; - case 70: goto st103; - case 71: goto st124; - case 73: goto st132; - case 80: goto st136; - case 81: goto st143; - case 82: goto st148; - case 83: goto st172; - case 97: goto st2; - case 99: goto st44; - case 100: goto st67; - case 102: goto st103; - case 103: goto st124; - case 105: goto st132; - case 112: goto st136; - case 113: goto st143; - case 114: goto st148; - case 115: goto st172; - } - goto st0; -st0: -cs = 0; - goto _out; -st2: - if ( ++p == pe ) - goto _test_eof2; -case 2: - switch( (*p) ) { - case 68: goto st3; - case 80: goto st22; - case 100: goto st3; - case 112: goto st22; - } - goto st0; -st3: - if ( ++p == pe ) - goto _test_eof3; -case 3: - switch( (*p) ) { - case 68: goto st4; - case 100: goto st4; - } - goto st0; -st4: - if ( ++p == pe ) - goto _test_eof4; -case 4: - if ( (*p) == 32 ) - goto st5; - goto st0; -st5: - if ( ++p == pe ) - goto _test_eof5; -case 5: - switch( (*p) ) { - case 13: goto st0; - case 32: goto st5; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st0; - goto tr15; -tr15: -#line 222 "src/memcached-grammar.rl" - { - fstart = p; - for (; p < pe && *p != ' ' && *p != '\r' && *p != '\n'; p++); - if ( *p == ' ' || *p == '\r' || *p == '\n') { - tbuf_store_field(keys, fstart, p - fstart); - keys_count++; - p--; - } else - p = fstart; - } - goto st6; -st6: - if ( ++p == pe ) - goto _test_eof6; -case 6: -#line 166 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto st7; - goto st0; -st7: - if ( ++p == pe ) - goto _test_eof7; -case 7: - if ( (*p) == 32 ) - goto st7; - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr17; - goto st0; -tr17: -#line 221 "src/memcached-grammar.rl" - { fstart = p; } - goto st8; -st8: - if ( ++p == pe ) - goto _test_eof8; -case 8: -#line 187 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto tr18; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st8; - goto st0; -tr18: -#line 244 "src/memcached-grammar.rl" - {flags = memcached_natoq(fstart, p);} - goto st9; -st9: - if ( ++p == pe ) - goto _test_eof9; -case 9: -#line 201 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto st9; - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr21; - goto st0; -tr21: -#line 221 "src/memcached-grammar.rl" - { fstart = p; } - goto st10; -st10: - if ( ++p == pe ) - goto _test_eof10; -case 10: -#line 215 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto tr22; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st10; - goto st0; -tr22: -#line 237 "src/memcached-grammar.rl" - { - exptime = memcached_natoq(fstart, p); - if (exptime > 0 && exptime <= 60*60*24*30) - exptime = exptime + ev_now(); - } - goto st11; -st11: - if ( ++p == pe ) - goto _test_eof11; -case 11: -#line 233 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto st11; - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr25; - goto st0; -tr25: -#line 221 "src/memcached-grammar.rl" - { fstart = p; } - goto st12; -st12: - if ( ++p == pe ) - goto _test_eof12; -case 12: -#line 247 "src/memcached-grammar.cc" - switch( (*p) ) { - case 10: goto tr26; - case 13: goto tr27; - case 32: goto tr28; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st12; - goto st0; -tr26: -#line 245 "src/memcached-grammar.rl" - {bytes = memcached_natoq(fstart, p);} -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 250 "src/memcached-grammar.rl" - { - size_t parsed = p - in->pos; - while (ibuf_size(in) - parsed < bytes + 2) { - size_t to_read = bytes + 2 - (pe - p); - if (coio_bread(coio, in, to_read) < to_read) - return -1; /* premature EOF */ - } - /* - * Buffered read may have reallocated the - * buffer. - */ - p = in->pos + parsed; - pe = in->end; - - data = p; - - if (strncmp((char *)(p + bytes), "\r\n", 2) == 0) { - p += bytes + 2; - } else { - goto exit; - } - } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 68 "src/memcached-grammar.rl" - { - key = tbuf_read_field(keys); - struct tuple *tuple = memcached_find(key); - if (tuple != NULL && !memcached_is_expired(tuple)) - obuf_dup(out, "NOT_STORED\r\n", 12); - else - STORE; - } - goto st197; -tr30: -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 250 "src/memcached-grammar.rl" - { - size_t parsed = p - in->pos; - while (ibuf_size(in) - parsed < bytes + 2) { - size_t to_read = bytes + 2 - (pe - p); - if (coio_bread(coio, in, to_read) < to_read) - return -1; /* premature EOF */ - } - /* - * Buffered read may have reallocated the - * buffer. - */ - p = in->pos + parsed; - pe = in->end; - - data = p; - - if (strncmp((char *)(p + bytes), "\r\n", 2) == 0) { - p += bytes + 2; - } else { - goto exit; - } - } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 68 "src/memcached-grammar.rl" - { - key = tbuf_read_field(keys); - struct tuple *tuple = memcached_find(key); - if (tuple != NULL && !memcached_is_expired(tuple)) - obuf_dup(out, "NOT_STORED\r\n", 12); - else - STORE; - } - goto st197; -tr39: -#line 281 "src/memcached-grammar.rl" - { noreply = true; } -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 250 "src/memcached-grammar.rl" - { - size_t parsed = p - in->pos; - while (ibuf_size(in) - parsed < bytes + 2) { - size_t to_read = bytes + 2 - (pe - p); - if (coio_bread(coio, in, to_read) < to_read) - return -1; /* premature EOF */ - } - /* - * Buffered read may have reallocated the - * buffer. - */ - p = in->pos + parsed; - pe = in->end; - - data = p; - - if (strncmp((char *)(p + bytes), "\r\n", 2) == 0) { - p += bytes + 2; - } else { - goto exit; - } - } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 68 "src/memcached-grammar.rl" - { - key = tbuf_read_field(keys); - struct tuple *tuple = memcached_find(key); - if (tuple != NULL && !memcached_is_expired(tuple)) - obuf_dup(out, "NOT_STORED\r\n", 12); - else - STORE; - } - goto st197; -tr58: -#line 245 "src/memcached-grammar.rl" - {bytes = memcached_natoq(fstart, p);} -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 250 "src/memcached-grammar.rl" - { - size_t parsed = p - in->pos; - while (ibuf_size(in) - parsed < bytes + 2) { - size_t to_read = bytes + 2 - (pe - p); - if (coio_bread(coio, in, to_read) < to_read) - return -1; /* premature EOF */ - } - /* - * Buffered read may have reallocated the - * buffer. - */ - p = in->pos + parsed; - pe = in->end; - - data = p; - - if (strncmp((char *)(p + bytes), "\r\n", 2) == 0) { - p += bytes + 2; - } else { - goto exit; - } - } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 97 "src/memcached-grammar.rl" - { - struct tbuf *b; - const char *field; - uint32_t field_len; - - key = tbuf_read_field(keys); - struct tuple *tuple = memcached_find(key); - if (tuple == NULL) { - obuf_dup(out, "NOT_STORED\r\n", 12); - } else { - field = tuple_field(tuple, 3, &field_len); - b = tbuf_new(fiber->gc_pool); - if (append) { - tbuf_append(b, field, field_len); - tbuf_append(b, data, bytes); - } else { - tbuf_append(b, data, bytes); - tbuf_append(b, field, field_len); - } - - bytes += field_len; - data = b->data; - STORE; - } - } - goto st197; -tr62: -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 250 "src/memcached-grammar.rl" - { - size_t parsed = p - in->pos; - while (ibuf_size(in) - parsed < bytes + 2) { - size_t to_read = bytes + 2 - (pe - p); - if (coio_bread(coio, in, to_read) < to_read) - return -1; /* premature EOF */ - } - /* - * Buffered read may have reallocated the - * buffer. - */ - p = in->pos + parsed; - pe = in->end; - - data = p; - - if (strncmp((char *)(p + bytes), "\r\n", 2) == 0) { - p += bytes + 2; - } else { - goto exit; - } - } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 97 "src/memcached-grammar.rl" - { - struct tbuf *b; - const char *field; - uint32_t field_len; - - key = tbuf_read_field(keys); - struct tuple *tuple = memcached_find(key); - if (tuple == NULL) { - obuf_dup(out, "NOT_STORED\r\n", 12); - } else { - field = tuple_field(tuple, 3, &field_len); - b = tbuf_new(fiber->gc_pool); - if (append) { - tbuf_append(b, field, field_len); - tbuf_append(b, data, bytes); - } else { - tbuf_append(b, data, bytes); - tbuf_append(b, field, field_len); - } - - bytes += field_len; - data = b->data; - STORE; - } - } - goto st197; -tr71: -#line 281 "src/memcached-grammar.rl" - { noreply = true; } -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 250 "src/memcached-grammar.rl" - { - size_t parsed = p - in->pos; - while (ibuf_size(in) - parsed < bytes + 2) { - size_t to_read = bytes + 2 - (pe - p); - if (coio_bread(coio, in, to_read) < to_read) - return -1; /* premature EOF */ - } - /* - * Buffered read may have reallocated the - * buffer. - */ - p = in->pos + parsed; - pe = in->end; - - data = p; - - if (strncmp((char *)(p + bytes), "\r\n", 2) == 0) { - p += bytes + 2; - } else { - goto exit; - } - } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 97 "src/memcached-grammar.rl" - { - struct tbuf *b; - const char *field; - uint32_t field_len; - - key = tbuf_read_field(keys); - struct tuple *tuple = memcached_find(key); - if (tuple == NULL) { - obuf_dup(out, "NOT_STORED\r\n", 12); - } else { - field = tuple_field(tuple, 3, &field_len); - b = tbuf_new(fiber->gc_pool); - if (append) { - tbuf_append(b, field, field_len); - tbuf_append(b, data, bytes); - } else { - tbuf_append(b, data, bytes); - tbuf_append(b, field, field_len); - } - - bytes += field_len; - data = b->data; - STORE; - } - } - goto st197; -tr91: -#line 246 "src/memcached-grammar.rl" - {cas = memcached_natoq(fstart, p);} -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 250 "src/memcached-grammar.rl" - { - size_t parsed = p - in->pos; - while (ibuf_size(in) - parsed < bytes + 2) { - size_t to_read = bytes + 2 - (pe - p); - if (coio_bread(coio, in, to_read) < to_read) - return -1; /* premature EOF */ - } - /* - * Buffered read may have reallocated the - * buffer. - */ - p = in->pos + parsed; - pe = in->end; - - data = p; - - if (strncmp((char *)(p + bytes), "\r\n", 2) == 0) { - p += bytes + 2; - } else { - goto exit; - } - } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 86 "src/memcached-grammar.rl" - { - key = tbuf_read_field(keys); - struct tuple *tuple = memcached_find(key); - if (tuple == NULL || memcached_is_expired(tuple)) - obuf_dup(out, "NOT_FOUND\r\n", 11); - else if (memcached_meta(tuple)->cas != cas) - obuf_dup(out, "EXISTS\r\n", 8); - else - STORE; - } - goto st197; -tr95: -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 250 "src/memcached-grammar.rl" - { - size_t parsed = p - in->pos; - while (ibuf_size(in) - parsed < bytes + 2) { - size_t to_read = bytes + 2 - (pe - p); - if (coio_bread(coio, in, to_read) < to_read) - return -1; /* premature EOF */ - } - /* - * Buffered read may have reallocated the - * buffer. - */ - p = in->pos + parsed; - pe = in->end; - - data = p; - - if (strncmp((char *)(p + bytes), "\r\n", 2) == 0) { - p += bytes + 2; - } else { - goto exit; - } - } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 86 "src/memcached-grammar.rl" - { - key = tbuf_read_field(keys); - struct tuple *tuple = memcached_find(key); - if (tuple == NULL || memcached_is_expired(tuple)) - obuf_dup(out, "NOT_FOUND\r\n", 11); - else if (memcached_meta(tuple)->cas != cas) - obuf_dup(out, "EXISTS\r\n", 8); - else - STORE; - } - goto st197; -tr105: -#line 281 "src/memcached-grammar.rl" - { noreply = true; } -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 250 "src/memcached-grammar.rl" - { - size_t parsed = p - in->pos; - while (ibuf_size(in) - parsed < bytes + 2) { - size_t to_read = bytes + 2 - (pe - p); - if (coio_bread(coio, in, to_read) < to_read) - return -1; /* premature EOF */ - } - /* - * Buffered read may have reallocated the - * buffer. - */ - p = in->pos + parsed; - pe = in->end; - - data = p; - - if (strncmp((char *)(p + bytes), "\r\n", 2) == 0) { - p += bytes + 2; - } else { - goto exit; - } - } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 86 "src/memcached-grammar.rl" - { - key = tbuf_read_field(keys); - struct tuple *tuple = memcached_find(key); - if (tuple == NULL || memcached_is_expired(tuple)) - obuf_dup(out, "NOT_FOUND\r\n", 11); - else if (memcached_meta(tuple)->cas != cas) - obuf_dup(out, "EXISTS\r\n", 8); - else - STORE; - } - goto st197; -tr118: -#line 247 "src/memcached-grammar.rl" - {incr = memcached_natoq(fstart, p);} -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 123 "src/memcached-grammar.rl" - { - struct meta *m; - struct tbuf *b; - const char *field; - uint32_t field_len; - uint64_t value; - - key = tbuf_read_field(keys); - struct tuple *tuple = memcached_find(key); - if (tuple == NULL || memcached_is_expired(tuple)) { - obuf_dup(out, "NOT_FOUND\r\n", 11); - } else { - m = memcached_meta(tuple); - field = tuple_field(tuple, 3, &field_len); - - if (memcached_is_numeric(field, field_len)) { - value = memcached_natoq(field, - field + field_len); - - if (incr_sign > 0) { - value += incr; - } else { - if (incr > value) - value = 0; - else - value -= incr; - } - - exptime = m->exptime; - flags = m->flags; - - b = tbuf_new(fiber->gc_pool); - tbuf_printf(b, "%" PRIu64, value); - data = b->data; - bytes = b->size; - - stats.cmd_set++; - try { - memcached_store(key, exptime, flags, bytes, data); - stats.total_items++; - obuf_dup(out, b->data, b->size); - obuf_dup(out, "\r\n", 2); - } catch (const ClientError& e) { - obuf_dup(out, "SERVER_ERROR ", 13); - obuf_dup(out, e.errmsg(), strlen(e.errmsg())); - obuf_dup(out, "\r\n", 2); - } - } else { - obuf_dup(out, "CLIENT_ERROR cannot increment or decrement non-numeric value\r\n", 62); - } - } - - } - goto st197; -tr122: -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 123 "src/memcached-grammar.rl" - { - struct meta *m; - struct tbuf *b; - const char *field; - uint32_t field_len; - uint64_t value; - - key = tbuf_read_field(keys); - struct tuple *tuple = memcached_find(key); - if (tuple == NULL || memcached_is_expired(tuple)) { - obuf_dup(out, "NOT_FOUND\r\n", 11); - } else { - m = memcached_meta(tuple); - field = tuple_field(tuple, 3, &field_len); - - if (memcached_is_numeric(field, field_len)) { - value = memcached_natoq(field, - field + field_len); - - if (incr_sign > 0) { - value += incr; - } else { - if (incr > value) - value = 0; - else - value -= incr; - } - - exptime = m->exptime; - flags = m->flags; - - b = tbuf_new(fiber->gc_pool); - tbuf_printf(b, "%" PRIu64, value); - data = b->data; - bytes = b->size; - - stats.cmd_set++; - try { - memcached_store(key, exptime, flags, bytes, data); - stats.total_items++; - obuf_dup(out, b->data, b->size); - obuf_dup(out, "\r\n", 2); - } catch (const ClientError& e) { - obuf_dup(out, "SERVER_ERROR ", 13); - obuf_dup(out, e.errmsg(), strlen(e.errmsg())); - obuf_dup(out, "\r\n", 2); - } - } else { - obuf_dup(out, "CLIENT_ERROR cannot increment or decrement non-numeric value\r\n", 62); - } - } - - } - goto st197; -tr132: -#line 281 "src/memcached-grammar.rl" - { noreply = true; } -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 123 "src/memcached-grammar.rl" - { - struct meta *m; - struct tbuf *b; - const char *field; - uint32_t field_len; - uint64_t value; - - key = tbuf_read_field(keys); - struct tuple *tuple = memcached_find(key); - if (tuple == NULL || memcached_is_expired(tuple)) { - obuf_dup(out, "NOT_FOUND\r\n", 11); - } else { - m = memcached_meta(tuple); - field = tuple_field(tuple, 3, &field_len); - - if (memcached_is_numeric(field, field_len)) { - value = memcached_natoq(field, - field + field_len); - - if (incr_sign > 0) { - value += incr; - } else { - if (incr > value) - value = 0; - else - value -= incr; - } - - exptime = m->exptime; - flags = m->flags; - - b = tbuf_new(fiber->gc_pool); - tbuf_printf(b, "%" PRIu64, value); - data = b->data; - bytes = b->size; - - stats.cmd_set++; - try { - memcached_store(key, exptime, flags, bytes, data); - stats.total_items++; - obuf_dup(out, b->data, b->size); - obuf_dup(out, "\r\n", 2); - } catch (const ClientError& e) { - obuf_dup(out, "SERVER_ERROR ", 13); - obuf_dup(out, e.errmsg(), strlen(e.errmsg())); - obuf_dup(out, "\r\n", 2); - } - } else { - obuf_dup(out, "CLIENT_ERROR cannot increment or decrement non-numeric value\r\n", 62); - } - } - - } - goto st197; -tr141: -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 177 "src/memcached-grammar.rl" - { - key = tbuf_read_field(keys); - struct tuple *tuple = memcached_find(key); - if (tuple == NULL || memcached_is_expired(tuple)) { - obuf_dup(out, "NOT_FOUND\r\n", 11); - } else { - try { - memcached_delete(key); - obuf_dup(out, "DELETED\r\n", 9); - } - catch (const ClientError& e) { - obuf_dup(out, "SERVER_ERROR ", 13); - obuf_dup(out, e.errmsg(), strlen(e.errmsg())); - obuf_dup(out, "\r\n", 2); - } - } - } - goto st197; -tr146: -#line 237 "src/memcached-grammar.rl" - { - exptime = memcached_natoq(fstart, p); - if (exptime > 0 && exptime <= 60*60*24*30) - exptime = exptime + ev_now(); - } -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 177 "src/memcached-grammar.rl" - { - key = tbuf_read_field(keys); - struct tuple *tuple = memcached_find(key); - if (tuple == NULL || memcached_is_expired(tuple)) { - obuf_dup(out, "NOT_FOUND\r\n", 11); - } else { - try { - memcached_delete(key); - obuf_dup(out, "DELETED\r\n", 9); - } - catch (const ClientError& e) { - obuf_dup(out, "SERVER_ERROR ", 13); - obuf_dup(out, e.errmsg(), strlen(e.errmsg())); - obuf_dup(out, "\r\n", 2); - } - } - } - goto st197; -tr157: -#line 281 "src/memcached-grammar.rl" - { noreply = true; } -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 177 "src/memcached-grammar.rl" - { - key = tbuf_read_field(keys); - struct tuple *tuple = memcached_find(key); - if (tuple == NULL || memcached_is_expired(tuple)) { - obuf_dup(out, "NOT_FOUND\r\n", 11); - } else { - try { - memcached_delete(key); - obuf_dup(out, "DELETED\r\n", 9); - } - catch (const ClientError& e) { - obuf_dup(out, "SERVER_ERROR ", 13); - obuf_dup(out, e.errmsg(), strlen(e.errmsg())); - obuf_dup(out, "\r\n", 2); - } - } - } - goto st197; -tr169: -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 206 "src/memcached-grammar.rl" - { - struct fiber *f = fiber_new("flush_all", - memcached_flush_all); - fiber_call(f, flush_delay); - obuf_dup(out, "OK\r\n", 4); - } - goto st197; -tr174: -#line 248 "src/memcached-grammar.rl" - {flush_delay = memcached_natoq(fstart, p);} -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 206 "src/memcached-grammar.rl" - { - struct fiber *f = fiber_new("flush_all", - memcached_flush_all); - fiber_call(f, flush_delay); - obuf_dup(out, "OK\r\n", 4); - } - goto st197; -tr185: -#line 281 "src/memcached-grammar.rl" - { noreply = true; } -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 206 "src/memcached-grammar.rl" - { - struct fiber *f = fiber_new("flush_all", - memcached_flush_all); - fiber_call(f, flush_delay); - obuf_dup(out, "OK\r\n", 4); - } - goto st197; -tr195: -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 195 "src/memcached-grammar.rl" - { - try { - memcached_get(out, keys_count, keys, show_cas); - } catch (const ClientError& e) { - obuf_rollback_to_svp(out, &obuf_svp); - obuf_dup(out, "SERVER_ERROR ", 13); - obuf_dup(out, e.errmsg(), strlen(e.errmsg())); - obuf_dup(out, "\r\n", 2); - } - } - goto st197; -tr213: -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 217 "src/memcached-grammar.rl" - { - return -1; - } - goto st197; -tr233: -#line 245 "src/memcached-grammar.rl" - {bytes = memcached_natoq(fstart, p);} -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 250 "src/memcached-grammar.rl" - { - size_t parsed = p - in->pos; - while (ibuf_size(in) - parsed < bytes + 2) { - size_t to_read = bytes + 2 - (pe - p); - if (coio_bread(coio, in, to_read) < to_read) - return -1; /* premature EOF */ - } - /* - * Buffered read may have reallocated the - * buffer. - */ - p = in->pos + parsed; - pe = in->end; - - data = p; - - if (strncmp((char *)(p + bytes), "\r\n", 2) == 0) { - p += bytes + 2; - } else { - goto exit; - } - } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 77 "src/memcached-grammar.rl" - { - key = tbuf_read_field(keys); - struct tuple *tuple = memcached_find(key); - if (tuple == NULL || memcached_is_expired(tuple)) - obuf_dup(out, "NOT_STORED\r\n", 12); - else - STORE; - } - goto st197; -tr237: -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 250 "src/memcached-grammar.rl" - { - size_t parsed = p - in->pos; - while (ibuf_size(in) - parsed < bytes + 2) { - size_t to_read = bytes + 2 - (pe - p); - if (coio_bread(coio, in, to_read) < to_read) - return -1; /* premature EOF */ - } - /* - * Buffered read may have reallocated the - * buffer. - */ - p = in->pos + parsed; - pe = in->end; - - data = p; - - if (strncmp((char *)(p + bytes), "\r\n", 2) == 0) { - p += bytes + 2; - } else { - goto exit; - } - } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 77 "src/memcached-grammar.rl" - { - key = tbuf_read_field(keys); - struct tuple *tuple = memcached_find(key); - if (tuple == NULL || memcached_is_expired(tuple)) - obuf_dup(out, "NOT_STORED\r\n", 12); - else - STORE; - } - goto st197; -tr246: -#line 281 "src/memcached-grammar.rl" - { noreply = true; } -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 250 "src/memcached-grammar.rl" - { - size_t parsed = p - in->pos; - while (ibuf_size(in) - parsed < bytes + 2) { - size_t to_read = bytes + 2 - (pe - p); - if (coio_bread(coio, in, to_read) < to_read) - return -1; /* premature EOF */ - } - /* - * Buffered read may have reallocated the - * buffer. - */ - p = in->pos + parsed; - pe = in->end; - - data = p; - - if (strncmp((char *)(p + bytes), "\r\n", 2) == 0) { - p += bytes + 2; - } else { - goto exit; - } - } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 77 "src/memcached-grammar.rl" - { - key = tbuf_read_field(keys); - struct tuple *tuple = memcached_find(key); - if (tuple == NULL || memcached_is_expired(tuple)) - obuf_dup(out, "NOT_STORED\r\n", 12); - else - STORE; - } - goto st197; -tr263: -#line 245 "src/memcached-grammar.rl" - {bytes = memcached_natoq(fstart, p);} -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 250 "src/memcached-grammar.rl" - { - size_t parsed = p - in->pos; - while (ibuf_size(in) - parsed < bytes + 2) { - size_t to_read = bytes + 2 - (pe - p); - if (coio_bread(coio, in, to_read) < to_read) - return -1; /* premature EOF */ - } - /* - * Buffered read may have reallocated the - * buffer. - */ - p = in->pos + parsed; - pe = in->end; - - data = p; - - if (strncmp((char *)(p + bytes), "\r\n", 2) == 0) { - p += bytes + 2; - } else { - goto exit; - } - } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 63 "src/memcached-grammar.rl" - { - key = tbuf_read_field(keys); - STORE; - } - goto st197; -tr267: -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 250 "src/memcached-grammar.rl" - { - size_t parsed = p - in->pos; - while (ibuf_size(in) - parsed < bytes + 2) { - size_t to_read = bytes + 2 - (pe - p); - if (coio_bread(coio, in, to_read) < to_read) - return -1; /* premature EOF */ - } - /* - * Buffered read may have reallocated the - * buffer. - */ - p = in->pos + parsed; - pe = in->end; - - data = p; - - if (strncmp((char *)(p + bytes), "\r\n", 2) == 0) { - p += bytes + 2; - } else { - goto exit; - } - } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 63 "src/memcached-grammar.rl" - { - key = tbuf_read_field(keys); - STORE; - } - goto st197; -tr276: -#line 281 "src/memcached-grammar.rl" - { noreply = true; } -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 250 "src/memcached-grammar.rl" - { - size_t parsed = p - in->pos; - while (ibuf_size(in) - parsed < bytes + 2) { - size_t to_read = bytes + 2 - (pe - p); - if (coio_bread(coio, in, to_read) < to_read) - return -1; /* premature EOF */ - } - /* - * Buffered read may have reallocated the - * buffer. - */ - p = in->pos + parsed; - pe = in->end; - - data = p; - - if (strncmp((char *)(p + bytes), "\r\n", 2) == 0) { - p += bytes + 2; - } else { - goto exit; - } - } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 63 "src/memcached-grammar.rl" - { - key = tbuf_read_field(keys); - STORE; - } - goto st197; -tr281: -#line 279 "src/memcached-grammar.rl" - { p++; } -#line 273 "src/memcached-grammar.rl" - { - done = true; - stats.bytes_read += p - in->pos; - in->pos = p; - } -#line 213 "src/memcached-grammar.rl" - { - memcached_print_stats(out); - } - goto st197; -st197: - if ( ++p == pe ) - goto _test_eof197; -case 197: -#line 1347 "src/memcached-grammar.cc" - goto st0; -tr27: -#line 245 "src/memcached-grammar.rl" - {bytes = memcached_natoq(fstart, p);} - goto st13; -tr40: -#line 281 "src/memcached-grammar.rl" - { noreply = true; } - goto st13; -st13: - if ( ++p == pe ) - goto _test_eof13; -case 13: -#line 1361 "src/memcached-grammar.cc" - if ( (*p) == 10 ) - goto tr30; - goto st0; -tr28: -#line 245 "src/memcached-grammar.rl" - {bytes = memcached_natoq(fstart, p);} - goto st14; -st14: - if ( ++p == pe ) - goto _test_eof14; -case 14: -#line 1373 "src/memcached-grammar.cc" - switch( (*p) ) { - case 32: goto st14; - case 78: goto st15; - case 110: goto st15; - } - goto st0; -st15: - if ( ++p == pe ) - goto _test_eof15; -case 15: - switch( (*p) ) { - case 79: goto st16; - case 111: goto st16; - } - goto st0; -st16: - if ( ++p == pe ) - goto _test_eof16; -case 16: - switch( (*p) ) { - case 82: goto st17; - case 114: goto st17; - } - goto st0; -st17: - if ( ++p == pe ) - goto _test_eof17; -case 17: - switch( (*p) ) { - case 69: goto st18; - case 101: goto st18; - } - goto st0; -st18: - if ( ++p == pe ) - goto _test_eof18; -case 18: - switch( (*p) ) { - case 80: goto st19; - case 112: goto st19; - } - goto st0; -st19: - if ( ++p == pe ) - goto _test_eof19; -case 19: - switch( (*p) ) { - case 76: goto st20; - case 108: goto st20; - } - goto st0; -st20: - if ( ++p == pe ) - goto _test_eof20; -case 20: - switch( (*p) ) { - case 89: goto st21; - case 121: goto st21; - } - goto st0; -st21: - if ( ++p == pe ) - goto _test_eof21; -case 21: - switch( (*p) ) { - case 10: goto tr39; - case 13: goto tr40; - } - goto st0; -st22: - if ( ++p == pe ) - goto _test_eof22; -case 22: - switch( (*p) ) { - case 80: goto st23; - case 112: goto st23; - } - goto st0; -st23: - if ( ++p == pe ) - goto _test_eof23; -case 23: - switch( (*p) ) { - case 69: goto st24; - case 101: goto st24; - } - goto st0; -st24: - if ( ++p == pe ) - goto _test_eof24; -case 24: - switch( (*p) ) { - case 78: goto st25; - case 110: goto st25; - } - goto st0; -st25: - if ( ++p == pe ) - goto _test_eof25; -case 25: - switch( (*p) ) { - case 68: goto st26; - case 100: goto st26; - } - goto st0; -st26: - if ( ++p == pe ) - goto _test_eof26; -case 26: - if ( (*p) == 32 ) - goto tr45; - goto st0; -tr45: -#line 287 "src/memcached-grammar.rl" - {append = true; } - goto st27; -tr209: -#line 288 "src/memcached-grammar.rl" - {append = false;} - goto st27; -st27: - if ( ++p == pe ) - goto _test_eof27; -case 27: -#line 1498 "src/memcached-grammar.cc" - switch( (*p) ) { - case 13: goto st0; - case 32: goto st27; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st0; - goto tr46; -tr46: -#line 222 "src/memcached-grammar.rl" - { - fstart = p; - for (; p < pe && *p != ' ' && *p != '\r' && *p != '\n'; p++); - if ( *p == ' ' || *p == '\r' || *p == '\n') { - tbuf_store_field(keys, fstart, p - fstart); - keys_count++; - p--; - } else - p = fstart; - } - goto st28; -st28: - if ( ++p == pe ) - goto _test_eof28; -case 28: -#line 1523 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto st29; - goto st0; -st29: - if ( ++p == pe ) - goto _test_eof29; -case 29: - if ( (*p) == 32 ) - goto st29; - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr49; - goto st0; -tr49: -#line 221 "src/memcached-grammar.rl" - { fstart = p; } - goto st30; -st30: - if ( ++p == pe ) - goto _test_eof30; -case 30: -#line 1544 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto tr50; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st30; - goto st0; -tr50: -#line 244 "src/memcached-grammar.rl" - {flags = memcached_natoq(fstart, p);} - goto st31; -st31: - if ( ++p == pe ) - goto _test_eof31; -case 31: -#line 1558 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto st31; - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr53; - goto st0; -tr53: -#line 221 "src/memcached-grammar.rl" - { fstart = p; } - goto st32; -st32: - if ( ++p == pe ) - goto _test_eof32; -case 32: -#line 1572 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto tr54; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st32; - goto st0; -tr54: -#line 237 "src/memcached-grammar.rl" - { - exptime = memcached_natoq(fstart, p); - if (exptime > 0 && exptime <= 60*60*24*30) - exptime = exptime + ev_now(); - } - goto st33; -st33: - if ( ++p == pe ) - goto _test_eof33; -case 33: -#line 1590 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto st33; - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr57; - goto st0; -tr57: -#line 221 "src/memcached-grammar.rl" - { fstart = p; } - goto st34; -st34: - if ( ++p == pe ) - goto _test_eof34; -case 34: -#line 1604 "src/memcached-grammar.cc" - switch( (*p) ) { - case 10: goto tr58; - case 13: goto tr59; - case 32: goto tr60; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st34; - goto st0; -tr59: -#line 245 "src/memcached-grammar.rl" - {bytes = memcached_natoq(fstart, p);} - goto st35; -tr72: -#line 281 "src/memcached-grammar.rl" - { noreply = true; } - goto st35; -st35: - if ( ++p == pe ) - goto _test_eof35; -case 35: -#line 1625 "src/memcached-grammar.cc" - if ( (*p) == 10 ) - goto tr62; - goto st0; -tr60: -#line 245 "src/memcached-grammar.rl" - {bytes = memcached_natoq(fstart, p);} - goto st36; -st36: - if ( ++p == pe ) - goto _test_eof36; -case 36: -#line 1637 "src/memcached-grammar.cc" - switch( (*p) ) { - case 32: goto st36; - case 78: goto st37; - case 110: goto st37; - } - goto st0; -st37: - if ( ++p == pe ) - goto _test_eof37; -case 37: - switch( (*p) ) { - case 79: goto st38; - case 111: goto st38; - } - goto st0; -st38: - if ( ++p == pe ) - goto _test_eof38; -case 38: - switch( (*p) ) { - case 82: goto st39; - case 114: goto st39; - } - goto st0; -st39: - if ( ++p == pe ) - goto _test_eof39; -case 39: - switch( (*p) ) { - case 69: goto st40; - case 101: goto st40; - } - goto st0; -st40: - if ( ++p == pe ) - goto _test_eof40; -case 40: - switch( (*p) ) { - case 80: goto st41; - case 112: goto st41; - } - goto st0; -st41: - if ( ++p == pe ) - goto _test_eof41; -case 41: - switch( (*p) ) { - case 76: goto st42; - case 108: goto st42; - } - goto st0; -st42: - if ( ++p == pe ) - goto _test_eof42; -case 42: - switch( (*p) ) { - case 89: goto st43; - case 121: goto st43; - } - goto st0; -st43: - if ( ++p == pe ) - goto _test_eof43; -case 43: - switch( (*p) ) { - case 10: goto tr71; - case 13: goto tr72; - } - goto st0; -st44: - if ( ++p == pe ) - goto _test_eof44; -case 44: - switch( (*p) ) { - case 65: goto st45; - case 97: goto st45; - } - goto st0; -st45: - if ( ++p == pe ) - goto _test_eof45; -case 45: - switch( (*p) ) { - case 83: goto st46; - case 115: goto st46; - } - goto st0; -st46: - if ( ++p == pe ) - goto _test_eof46; -case 46: - if ( (*p) == 32 ) - goto st47; - goto st0; -st47: - if ( ++p == pe ) - goto _test_eof47; -case 47: - switch( (*p) ) { - case 13: goto st0; - case 32: goto st47; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st0; - goto tr76; -tr76: -#line 222 "src/memcached-grammar.rl" - { - fstart = p; - for (; p < pe && *p != ' ' && *p != '\r' && *p != '\n'; p++); - if ( *p == ' ' || *p == '\r' || *p == '\n') { - tbuf_store_field(keys, fstart, p - fstart); - keys_count++; - p--; - } else - p = fstart; - } - goto st48; -st48: - if ( ++p == pe ) - goto _test_eof48; -case 48: -#line 1760 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto st49; - goto st0; -st49: - if ( ++p == pe ) - goto _test_eof49; -case 49: - if ( (*p) == 32 ) - goto st49; - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr78; - goto st0; -tr78: -#line 221 "src/memcached-grammar.rl" - { fstart = p; } - goto st50; -st50: - if ( ++p == pe ) - goto _test_eof50; -case 50: -#line 1781 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto tr79; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st50; - goto st0; -tr79: -#line 244 "src/memcached-grammar.rl" - {flags = memcached_natoq(fstart, p);} - goto st51; -st51: - if ( ++p == pe ) - goto _test_eof51; -case 51: -#line 1795 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto st51; - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr82; - goto st0; -tr82: -#line 221 "src/memcached-grammar.rl" - { fstart = p; } - goto st52; -st52: - if ( ++p == pe ) - goto _test_eof52; -case 52: -#line 1809 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto tr83; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st52; - goto st0; -tr83: -#line 237 "src/memcached-grammar.rl" - { - exptime = memcached_natoq(fstart, p); - if (exptime > 0 && exptime <= 60*60*24*30) - exptime = exptime + ev_now(); - } - goto st53; -st53: - if ( ++p == pe ) - goto _test_eof53; -case 53: -#line 1827 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto st53; - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr86; - goto st0; -tr86: -#line 221 "src/memcached-grammar.rl" - { fstart = p; } - goto st54; -st54: - if ( ++p == pe ) - goto _test_eof54; -case 54: -#line 1841 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto tr87; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st54; - goto st0; -tr87: -#line 245 "src/memcached-grammar.rl" - {bytes = memcached_natoq(fstart, p);} - goto st55; -st55: - if ( ++p == pe ) - goto _test_eof55; -case 55: -#line 1855 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto st55; - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr90; - goto st0; -tr90: -#line 221 "src/memcached-grammar.rl" - { fstart = p; } - goto st56; -st56: - if ( ++p == pe ) - goto _test_eof56; -case 56: -#line 1869 "src/memcached-grammar.cc" - switch( (*p) ) { - case 10: goto tr91; - case 13: goto tr92; - case 32: goto tr93; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st56; - goto st0; -tr106: -#line 281 "src/memcached-grammar.rl" - { noreply = true; } - goto st57; -tr92: -#line 246 "src/memcached-grammar.rl" - {cas = memcached_natoq(fstart, p);} - goto st57; -st57: - if ( ++p == pe ) - goto _test_eof57; -case 57: -#line 1890 "src/memcached-grammar.cc" - if ( (*p) == 10 ) - goto tr95; - goto st0; -tr93: -#line 246 "src/memcached-grammar.rl" - {cas = memcached_natoq(fstart, p);} - goto st58; -st58: - if ( ++p == pe ) - goto _test_eof58; -case 58: -#line 1902 "src/memcached-grammar.cc" - switch( (*p) ) { - case 10: goto tr95; - case 13: goto st57; - case 32: goto st58; - case 78: goto st59; - case 110: goto st59; - } - goto st0; -st59: - if ( ++p == pe ) - goto _test_eof59; -case 59: - switch( (*p) ) { - case 79: goto st60; - case 111: goto st60; - } - goto st0; -st60: - if ( ++p == pe ) - goto _test_eof60; -case 60: - switch( (*p) ) { - case 82: goto st61; - case 114: goto st61; - } - goto st0; -st61: - if ( ++p == pe ) - goto _test_eof61; -case 61: - switch( (*p) ) { - case 69: goto st62; - case 101: goto st62; - } - goto st0; -st62: - if ( ++p == pe ) - goto _test_eof62; -case 62: - switch( (*p) ) { - case 80: goto st63; - case 112: goto st63; - } - goto st0; -st63: - if ( ++p == pe ) - goto _test_eof63; -case 63: - switch( (*p) ) { - case 76: goto st64; - case 108: goto st64; - } - goto st0; -st64: - if ( ++p == pe ) - goto _test_eof64; -case 64: - switch( (*p) ) { - case 89: goto st65; - case 121: goto st65; - } - goto st0; -st65: - if ( ++p == pe ) - goto _test_eof65; -case 65: - switch( (*p) ) { - case 10: goto tr105; - case 13: goto tr106; - case 32: goto tr107; - } - goto st0; -tr107: -#line 281 "src/memcached-grammar.rl" - { noreply = true; } - goto st66; -st66: - if ( ++p == pe ) - goto _test_eof66; -case 66: -#line 1983 "src/memcached-grammar.cc" - switch( (*p) ) { - case 10: goto tr95; - case 13: goto st57; - case 32: goto st66; - } - goto st0; -st67: - if ( ++p == pe ) - goto _test_eof67; -case 67: - switch( (*p) ) { - case 69: goto st68; - case 101: goto st68; - } - goto st0; -st68: - if ( ++p == pe ) - goto _test_eof68; -case 68: - switch( (*p) ) { - case 67: goto st69; - case 76: goto st85; - case 99: goto st69; - case 108: goto st85; - } - goto st0; -st69: - if ( ++p == pe ) - goto _test_eof69; -case 69: - switch( (*p) ) { - case 82: goto st70; - case 114: goto st70; - } - goto st0; -st70: - if ( ++p == pe ) - goto _test_eof70; -case 70: - if ( (*p) == 32 ) - goto tr113; - goto st0; -tr113: -#line 296 "src/memcached-grammar.rl" - {incr_sign = -1;} - goto st71; -tr202: -#line 295 "src/memcached-grammar.rl" - {incr_sign = 1; } - goto st71; -st71: - if ( ++p == pe ) - goto _test_eof71; -case 71: -#line 2038 "src/memcached-grammar.cc" - switch( (*p) ) { - case 13: goto st0; - case 32: goto st71; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st0; - goto tr114; -tr114: -#line 222 "src/memcached-grammar.rl" - { - fstart = p; - for (; p < pe && *p != ' ' && *p != '\r' && *p != '\n'; p++); - if ( *p == ' ' || *p == '\r' || *p == '\n') { - tbuf_store_field(keys, fstart, p - fstart); - keys_count++; - p--; - } else - p = fstart; - } - goto st72; -st72: - if ( ++p == pe ) - goto _test_eof72; -case 72: -#line 2063 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto st73; - goto st0; -st73: - if ( ++p == pe ) - goto _test_eof73; -case 73: - if ( (*p) == 32 ) - goto st73; - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr117; - goto st0; -tr117: -#line 221 "src/memcached-grammar.rl" - { fstart = p; } - goto st74; -st74: - if ( ++p == pe ) - goto _test_eof74; -case 74: -#line 2084 "src/memcached-grammar.cc" - switch( (*p) ) { - case 10: goto tr118; - case 13: goto tr119; - case 32: goto tr120; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st74; - goto st0; -tr133: -#line 281 "src/memcached-grammar.rl" - { noreply = true; } - goto st75; -tr119: -#line 247 "src/memcached-grammar.rl" - {incr = memcached_natoq(fstart, p);} - goto st75; -st75: - if ( ++p == pe ) - goto _test_eof75; -case 75: -#line 2105 "src/memcached-grammar.cc" - if ( (*p) == 10 ) - goto tr122; - goto st0; -tr120: -#line 247 "src/memcached-grammar.rl" - {incr = memcached_natoq(fstart, p);} - goto st76; -st76: - if ( ++p == pe ) - goto _test_eof76; -case 76: -#line 2117 "src/memcached-grammar.cc" - switch( (*p) ) { - case 10: goto tr122; - case 13: goto st75; - case 32: goto st76; - case 78: goto st77; - case 110: goto st77; - } - goto st0; -st77: - if ( ++p == pe ) - goto _test_eof77; -case 77: - switch( (*p) ) { - case 79: goto st78; - case 111: goto st78; - } - goto st0; -st78: - if ( ++p == pe ) - goto _test_eof78; -case 78: - switch( (*p) ) { - case 82: goto st79; - case 114: goto st79; - } - goto st0; -st79: - if ( ++p == pe ) - goto _test_eof79; -case 79: - switch( (*p) ) { - case 69: goto st80; - case 101: goto st80; - } - goto st0; -st80: - if ( ++p == pe ) - goto _test_eof80; -case 80: - switch( (*p) ) { - case 80: goto st81; - case 112: goto st81; - } - goto st0; -st81: - if ( ++p == pe ) - goto _test_eof81; -case 81: - switch( (*p) ) { - case 76: goto st82; - case 108: goto st82; - } - goto st0; -st82: - if ( ++p == pe ) - goto _test_eof82; -case 82: - switch( (*p) ) { - case 89: goto st83; - case 121: goto st83; - } - goto st0; -st83: - if ( ++p == pe ) - goto _test_eof83; -case 83: - switch( (*p) ) { - case 10: goto tr132; - case 13: goto tr133; - case 32: goto tr134; - } - goto st0; -tr134: -#line 281 "src/memcached-grammar.rl" - { noreply = true; } - goto st84; -st84: - if ( ++p == pe ) - goto _test_eof84; -case 84: -#line 2198 "src/memcached-grammar.cc" - switch( (*p) ) { - case 10: goto tr122; - case 13: goto st75; - case 32: goto st84; - } - goto st0; -st85: - if ( ++p == pe ) - goto _test_eof85; -case 85: - switch( (*p) ) { - case 69: goto st86; - case 101: goto st86; - } - goto st0; -st86: - if ( ++p == pe ) - goto _test_eof86; -case 86: - switch( (*p) ) { - case 84: goto st87; - case 116: goto st87; - } - goto st0; -st87: - if ( ++p == pe ) - goto _test_eof87; -case 87: - switch( (*p) ) { - case 69: goto st88; - case 101: goto st88; - } - goto st0; -st88: - if ( ++p == pe ) - goto _test_eof88; -case 88: - if ( (*p) == 32 ) - goto st89; - goto st0; -st89: - if ( ++p == pe ) - goto _test_eof89; -case 89: - switch( (*p) ) { - case 13: goto st0; - case 32: goto st89; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st0; - goto tr140; -tr140: -#line 222 "src/memcached-grammar.rl" - { - fstart = p; - for (; p < pe && *p != ' ' && *p != '\r' && *p != '\n'; p++); - if ( *p == ' ' || *p == '\r' || *p == '\n') { - tbuf_store_field(keys, fstart, p - fstart); - keys_count++; - p--; - } else - p = fstart; - } - goto st90; -st90: - if ( ++p == pe ) - goto _test_eof90; -case 90: -#line 2267 "src/memcached-grammar.cc" - switch( (*p) ) { - case 10: goto tr141; - case 13: goto st91; - case 32: goto st92; - } - goto st0; -tr147: -#line 237 "src/memcached-grammar.rl" - { - exptime = memcached_natoq(fstart, p); - if (exptime > 0 && exptime <= 60*60*24*30) - exptime = exptime + ev_now(); - } - goto st91; -tr158: -#line 281 "src/memcached-grammar.rl" - { noreply = true; } - goto st91; -st91: - if ( ++p == pe ) - goto _test_eof91; -case 91: -#line 2290 "src/memcached-grammar.cc" - if ( (*p) == 10 ) - goto tr141; - goto st0; -st92: - if ( ++p == pe ) - goto _test_eof92; -case 92: - switch( (*p) ) { - case 10: goto tr141; - case 13: goto st91; - case 32: goto st92; - case 78: goto st95; - case 110: goto st95; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr144; - goto st0; -tr144: -#line 221 "src/memcached-grammar.rl" - { fstart = p; } - goto st93; -st93: - if ( ++p == pe ) - goto _test_eof93; -case 93: -#line 2316 "src/memcached-grammar.cc" - switch( (*p) ) { - case 10: goto tr146; - case 13: goto tr147; - case 32: goto tr148; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st93; - goto st0; -tr148: -#line 237 "src/memcached-grammar.rl" - { - exptime = memcached_natoq(fstart, p); - if (exptime > 0 && exptime <= 60*60*24*30) - exptime = exptime + ev_now(); - } - goto st94; -st94: - if ( ++p == pe ) - goto _test_eof94; -case 94: -#line 2337 "src/memcached-grammar.cc" - switch( (*p) ) { - case 10: goto tr141; - case 13: goto st91; - case 32: goto st94; - case 78: goto st95; - case 110: goto st95; - } - goto st0; -st95: - if ( ++p == pe ) - goto _test_eof95; -case 95: - switch( (*p) ) { - case 79: goto st96; - case 111: goto st96; - } - goto st0; -st96: - if ( ++p == pe ) - goto _test_eof96; -case 96: - switch( (*p) ) { - case 82: goto st97; - case 114: goto st97; - } - goto st0; -st97: - if ( ++p == pe ) - goto _test_eof97; -case 97: - switch( (*p) ) { - case 69: goto st98; - case 101: goto st98; - } - goto st0; -st98: - if ( ++p == pe ) - goto _test_eof98; -case 98: - switch( (*p) ) { - case 80: goto st99; - case 112: goto st99; - } - goto st0; -st99: - if ( ++p == pe ) - goto _test_eof99; -case 99: - switch( (*p) ) { - case 76: goto st100; - case 108: goto st100; - } - goto st0; -st100: - if ( ++p == pe ) - goto _test_eof100; -case 100: - switch( (*p) ) { - case 89: goto st101; - case 121: goto st101; - } - goto st0; -st101: - if ( ++p == pe ) - goto _test_eof101; -case 101: - switch( (*p) ) { - case 10: goto tr157; - case 13: goto tr158; - case 32: goto tr159; - } - goto st0; -tr159: -#line 281 "src/memcached-grammar.rl" - { noreply = true; } - goto st102; -st102: - if ( ++p == pe ) - goto _test_eof102; -case 102: -#line 2418 "src/memcached-grammar.cc" - switch( (*p) ) { - case 10: goto tr141; - case 13: goto st91; - case 32: goto st102; - } - goto st0; -st103: - if ( ++p == pe ) - goto _test_eof103; -case 103: - switch( (*p) ) { - case 76: goto st104; - case 108: goto st104; - } - goto st0; -st104: - if ( ++p == pe ) - goto _test_eof104; -case 104: - switch( (*p) ) { - case 85: goto st105; - case 117: goto st105; - } - goto st0; -st105: - if ( ++p == pe ) - goto _test_eof105; -case 105: - switch( (*p) ) { - case 83: goto st106; - case 115: goto st106; - } - goto st0; -st106: - if ( ++p == pe ) - goto _test_eof106; -case 106: - switch( (*p) ) { - case 72: goto st107; - case 104: goto st107; - } - goto st0; -st107: - if ( ++p == pe ) - goto _test_eof107; -case 107: - if ( (*p) == 95 ) - goto st108; - goto st0; -st108: - if ( ++p == pe ) - goto _test_eof108; -case 108: - switch( (*p) ) { - case 65: goto st109; - case 97: goto st109; - } - goto st0; -st109: - if ( ++p == pe ) - goto _test_eof109; -case 109: - switch( (*p) ) { - case 76: goto st110; - case 108: goto st110; - } - goto st0; -st110: - if ( ++p == pe ) - goto _test_eof110; -case 110: - switch( (*p) ) { - case 76: goto st111; - case 108: goto st111; - } - goto st0; -st111: - if ( ++p == pe ) - goto _test_eof111; -case 111: - switch( (*p) ) { - case 10: goto tr169; - case 13: goto st112; - case 32: goto st113; - } - goto st0; -tr186: -#line 281 "src/memcached-grammar.rl" - { noreply = true; } - goto st112; -tr175: -#line 248 "src/memcached-grammar.rl" - {flush_delay = memcached_natoq(fstart, p);} - goto st112; -st112: - if ( ++p == pe ) - goto _test_eof112; -case 112: -#line 2517 "src/memcached-grammar.cc" - if ( (*p) == 10 ) - goto tr169; - goto st0; -st113: - if ( ++p == pe ) - goto _test_eof113; -case 113: - switch( (*p) ) { - case 10: goto tr169; - case 13: goto st112; - case 32: goto st113; - case 78: goto st116; - case 110: goto st116; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr172; - goto st0; -tr172: -#line 221 "src/memcached-grammar.rl" - { fstart = p; } - goto st114; -st114: - if ( ++p == pe ) - goto _test_eof114; -case 114: -#line 2543 "src/memcached-grammar.cc" - switch( (*p) ) { - case 10: goto tr174; - case 13: goto tr175; - case 32: goto tr176; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st114; - goto st0; -tr176: -#line 248 "src/memcached-grammar.rl" - {flush_delay = memcached_natoq(fstart, p);} - goto st115; -st115: - if ( ++p == pe ) - goto _test_eof115; -case 115: -#line 2560 "src/memcached-grammar.cc" - switch( (*p) ) { - case 10: goto tr169; - case 13: goto st112; - case 32: goto st115; - case 78: goto st116; - case 110: goto st116; - } - goto st0; -st116: - if ( ++p == pe ) - goto _test_eof116; -case 116: - switch( (*p) ) { - case 79: goto st117; - case 111: goto st117; - } - goto st0; -st117: - if ( ++p == pe ) - goto _test_eof117; -case 117: - switch( (*p) ) { - case 82: goto st118; - case 114: goto st118; - } - goto st0; -st118: - if ( ++p == pe ) - goto _test_eof118; -case 118: - switch( (*p) ) { - case 69: goto st119; - case 101: goto st119; - } - goto st0; -st119: - if ( ++p == pe ) - goto _test_eof119; -case 119: - switch( (*p) ) { - case 80: goto st120; - case 112: goto st120; - } - goto st0; -st120: - if ( ++p == pe ) - goto _test_eof120; -case 120: - switch( (*p) ) { - case 76: goto st121; - case 108: goto st121; - } - goto st0; -st121: - if ( ++p == pe ) - goto _test_eof121; -case 121: - switch( (*p) ) { - case 89: goto st122; - case 121: goto st122; - } - goto st0; -st122: - if ( ++p == pe ) - goto _test_eof122; -case 122: - switch( (*p) ) { - case 10: goto tr185; - case 13: goto tr186; - case 32: goto tr187; - } - goto st0; -tr187: -#line 281 "src/memcached-grammar.rl" - { noreply = true; } - goto st123; -st123: - if ( ++p == pe ) - goto _test_eof123; -case 123: -#line 2641 "src/memcached-grammar.cc" - switch( (*p) ) { - case 10: goto tr169; - case 13: goto st112; - case 32: goto st123; - } - goto st0; -st124: - if ( ++p == pe ) - goto _test_eof124; -case 124: - switch( (*p) ) { - case 69: goto st125; - case 101: goto st125; - } - goto st0; -st125: - if ( ++p == pe ) - goto _test_eof125; -case 125: - switch( (*p) ) { - case 84: goto st126; - case 116: goto st126; - } - goto st0; -st126: - if ( ++p == pe ) - goto _test_eof126; -case 126: - switch( (*p) ) { - case 32: goto tr191; - case 83: goto st131; - case 115: goto st131; - } - goto st0; -tr191: -#line 292 "src/memcached-grammar.rl" - {show_cas = false;} - goto st127; -tr198: -#line 293 "src/memcached-grammar.rl" - {show_cas = true;} - goto st127; -st127: - if ( ++p == pe ) - goto _test_eof127; -case 127: -#line 2688 "src/memcached-grammar.cc" - switch( (*p) ) { - case 13: goto st0; - case 32: goto st127; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st0; - goto tr193; -tr193: -#line 222 "src/memcached-grammar.rl" - { - fstart = p; - for (; p < pe && *p != ' ' && *p != '\r' && *p != '\n'; p++); - if ( *p == ' ' || *p == '\r' || *p == '\n') { - tbuf_store_field(keys, fstart, p - fstart); - keys_count++; - p--; - } else - p = fstart; - } - goto st128; -st128: - if ( ++p == pe ) - goto _test_eof128; -case 128: -#line 2713 "src/memcached-grammar.cc" - switch( (*p) ) { - case 10: goto tr195; - case 13: goto st129; - case 32: goto st130; - } - goto st0; -st129: - if ( ++p == pe ) - goto _test_eof129; -case 129: - if ( (*p) == 10 ) - goto tr195; - goto st0; -st130: - if ( ++p == pe ) - goto _test_eof130; -case 130: - switch( (*p) ) { - case 9: goto st0; - case 10: goto tr195; - case 13: goto st129; - case 32: goto st130; - } - goto tr193; -st131: - if ( ++p == pe ) - goto _test_eof131; -case 131: - if ( (*p) == 32 ) - goto tr198; - goto st0; -st132: - if ( ++p == pe ) - goto _test_eof132; -case 132: - switch( (*p) ) { - case 78: goto st133; - case 110: goto st133; - } - goto st0; -st133: - if ( ++p == pe ) - goto _test_eof133; -case 133: - switch( (*p) ) { - case 67: goto st134; - case 99: goto st134; - } - goto st0; -st134: - if ( ++p == pe ) - goto _test_eof134; -case 134: - switch( (*p) ) { - case 82: goto st135; - case 114: goto st135; - } - goto st0; -st135: - if ( ++p == pe ) - goto _test_eof135; -case 135: - if ( (*p) == 32 ) - goto tr202; - goto st0; -st136: - if ( ++p == pe ) - goto _test_eof136; -case 136: - switch( (*p) ) { - case 82: goto st137; - case 114: goto st137; - } - goto st0; -st137: - if ( ++p == pe ) - goto _test_eof137; -case 137: - switch( (*p) ) { - case 69: goto st138; - case 101: goto st138; - } - goto st0; -st138: - if ( ++p == pe ) - goto _test_eof138; -case 138: - switch( (*p) ) { - case 80: goto st139; - case 112: goto st139; - } - goto st0; -st139: - if ( ++p == pe ) - goto _test_eof139; -case 139: - switch( (*p) ) { - case 69: goto st140; - case 101: goto st140; - } - goto st0; -st140: - if ( ++p == pe ) - goto _test_eof140; -case 140: - switch( (*p) ) { - case 78: goto st141; - case 110: goto st141; - } - goto st0; -st141: - if ( ++p == pe ) - goto _test_eof141; -case 141: - switch( (*p) ) { - case 68: goto st142; - case 100: goto st142; - } - goto st0; -st142: - if ( ++p == pe ) - goto _test_eof142; -case 142: - if ( (*p) == 32 ) - goto tr209; - goto st0; -st143: - if ( ++p == pe ) - goto _test_eof143; -case 143: - switch( (*p) ) { - case 85: goto st144; - case 117: goto st144; - } - goto st0; -st144: - if ( ++p == pe ) - goto _test_eof144; -case 144: - switch( (*p) ) { - case 73: goto st145; - case 105: goto st145; - } - goto st0; -st145: - if ( ++p == pe ) - goto _test_eof145; -case 145: - switch( (*p) ) { - case 84: goto st146; - case 116: goto st146; - } - goto st0; -st146: - if ( ++p == pe ) - goto _test_eof146; -case 146: - switch( (*p) ) { - case 10: goto tr213; - case 13: goto st147; - } - goto st0; -st147: - if ( ++p == pe ) - goto _test_eof147; -case 147: - if ( (*p) == 10 ) - goto tr213; - goto st0; -st148: - if ( ++p == pe ) - goto _test_eof148; -case 148: - switch( (*p) ) { - case 69: goto st149; - case 101: goto st149; - } - goto st0; -st149: - if ( ++p == pe ) - goto _test_eof149; -case 149: - switch( (*p) ) { - case 80: goto st150; - case 112: goto st150; - } - goto st0; -st150: - if ( ++p == pe ) - goto _test_eof150; -case 150: - switch( (*p) ) { - case 76: goto st151; - case 108: goto st151; - } - goto st0; -st151: - if ( ++p == pe ) - goto _test_eof151; -case 151: - switch( (*p) ) { - case 65: goto st152; - case 97: goto st152; - } - goto st0; -st152: - if ( ++p == pe ) - goto _test_eof152; -case 152: - switch( (*p) ) { - case 67: goto st153; - case 99: goto st153; - } - goto st0; -st153: - if ( ++p == pe ) - goto _test_eof153; -case 153: - switch( (*p) ) { - case 69: goto st154; - case 101: goto st154; - } - goto st0; -st154: - if ( ++p == pe ) - goto _test_eof154; -case 154: - if ( (*p) == 32 ) - goto st155; - goto st0; -st155: - if ( ++p == pe ) - goto _test_eof155; -case 155: - switch( (*p) ) { - case 13: goto st0; - case 32: goto st155; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st0; - goto tr222; -tr222: -#line 222 "src/memcached-grammar.rl" - { - fstart = p; - for (; p < pe && *p != ' ' && *p != '\r' && *p != '\n'; p++); - if ( *p == ' ' || *p == '\r' || *p == '\n') { - tbuf_store_field(keys, fstart, p - fstart); - keys_count++; - p--; - } else - p = fstart; - } - goto st156; -st156: - if ( ++p == pe ) - goto _test_eof156; -case 156: -#line 2972 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto st157; - goto st0; -st157: - if ( ++p == pe ) - goto _test_eof157; -case 157: - if ( (*p) == 32 ) - goto st157; - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr224; - goto st0; -tr224: -#line 221 "src/memcached-grammar.rl" - { fstart = p; } - goto st158; -st158: - if ( ++p == pe ) - goto _test_eof158; -case 158: -#line 2993 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto tr225; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st158; - goto st0; -tr225: -#line 244 "src/memcached-grammar.rl" - {flags = memcached_natoq(fstart, p);} - goto st159; -st159: - if ( ++p == pe ) - goto _test_eof159; -case 159: -#line 3007 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto st159; - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr228; - goto st0; -tr228: -#line 221 "src/memcached-grammar.rl" - { fstart = p; } - goto st160; -st160: - if ( ++p == pe ) - goto _test_eof160; -case 160: -#line 3021 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto tr229; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st160; - goto st0; -tr229: -#line 237 "src/memcached-grammar.rl" - { - exptime = memcached_natoq(fstart, p); - if (exptime > 0 && exptime <= 60*60*24*30) - exptime = exptime + ev_now(); - } - goto st161; -st161: - if ( ++p == pe ) - goto _test_eof161; -case 161: -#line 3039 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto st161; - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr232; - goto st0; -tr232: -#line 221 "src/memcached-grammar.rl" - { fstart = p; } - goto st162; -st162: - if ( ++p == pe ) - goto _test_eof162; -case 162: -#line 3053 "src/memcached-grammar.cc" - switch( (*p) ) { - case 10: goto tr233; - case 13: goto tr234; - case 32: goto tr235; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st162; - goto st0; -tr234: -#line 245 "src/memcached-grammar.rl" - {bytes = memcached_natoq(fstart, p);} - goto st163; -tr247: -#line 281 "src/memcached-grammar.rl" - { noreply = true; } - goto st163; -st163: - if ( ++p == pe ) - goto _test_eof163; -case 163: -#line 3074 "src/memcached-grammar.cc" - if ( (*p) == 10 ) - goto tr237; - goto st0; -tr235: -#line 245 "src/memcached-grammar.rl" - {bytes = memcached_natoq(fstart, p);} - goto st164; -st164: - if ( ++p == pe ) - goto _test_eof164; -case 164: -#line 3086 "src/memcached-grammar.cc" - switch( (*p) ) { - case 32: goto st164; - case 78: goto st165; - case 110: goto st165; - } - goto st0; -st165: - if ( ++p == pe ) - goto _test_eof165; -case 165: - switch( (*p) ) { - case 79: goto st166; - case 111: goto st166; - } - goto st0; -st166: - if ( ++p == pe ) - goto _test_eof166; -case 166: - switch( (*p) ) { - case 82: goto st167; - case 114: goto st167; - } - goto st0; -st167: - if ( ++p == pe ) - goto _test_eof167; -case 167: - switch( (*p) ) { - case 69: goto st168; - case 101: goto st168; - } - goto st0; -st168: - if ( ++p == pe ) - goto _test_eof168; -case 168: - switch( (*p) ) { - case 80: goto st169; - case 112: goto st169; - } - goto st0; -st169: - if ( ++p == pe ) - goto _test_eof169; -case 169: - switch( (*p) ) { - case 76: goto st170; - case 108: goto st170; - } - goto st0; -st170: - if ( ++p == pe ) - goto _test_eof170; -case 170: - switch( (*p) ) { - case 89: goto st171; - case 121: goto st171; - } - goto st0; -st171: - if ( ++p == pe ) - goto _test_eof171; -case 171: - switch( (*p) ) { - case 10: goto tr246; - case 13: goto tr247; - } - goto st0; -st172: - if ( ++p == pe ) - goto _test_eof172; -case 172: - switch( (*p) ) { - case 69: goto st173; - case 84: goto st192; - case 101: goto st173; - case 116: goto st192; - } - goto st0; -st173: - if ( ++p == pe ) - goto _test_eof173; -case 173: - switch( (*p) ) { - case 84: goto st174; - case 116: goto st174; - } - goto st0; -st174: - if ( ++p == pe ) - goto _test_eof174; -case 174: - if ( (*p) == 32 ) - goto st175; - goto st0; -st175: - if ( ++p == pe ) - goto _test_eof175; -case 175: - switch( (*p) ) { - case 13: goto st0; - case 32: goto st175; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st0; - goto tr252; -tr252: -#line 222 "src/memcached-grammar.rl" - { - fstart = p; - for (; p < pe && *p != ' ' && *p != '\r' && *p != '\n'; p++); - if ( *p == ' ' || *p == '\r' || *p == '\n') { - tbuf_store_field(keys, fstart, p - fstart); - keys_count++; - p--; - } else - p = fstart; - } - goto st176; -st176: - if ( ++p == pe ) - goto _test_eof176; -case 176: -#line 3211 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto st177; - goto st0; -st177: - if ( ++p == pe ) - goto _test_eof177; -case 177: - if ( (*p) == 32 ) - goto st177; - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr254; - goto st0; -tr254: -#line 221 "src/memcached-grammar.rl" - { fstart = p; } - goto st178; -st178: - if ( ++p == pe ) - goto _test_eof178; -case 178: -#line 3232 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto tr255; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st178; - goto st0; -tr255: -#line 244 "src/memcached-grammar.rl" - {flags = memcached_natoq(fstart, p);} - goto st179; -st179: - if ( ++p == pe ) - goto _test_eof179; -case 179: -#line 3246 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto st179; - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr258; - goto st0; -tr258: -#line 221 "src/memcached-grammar.rl" - { fstart = p; } - goto st180; -st180: - if ( ++p == pe ) - goto _test_eof180; -case 180: -#line 3260 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto tr259; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st180; - goto st0; -tr259: -#line 237 "src/memcached-grammar.rl" - { - exptime = memcached_natoq(fstart, p); - if (exptime > 0 && exptime <= 60*60*24*30) - exptime = exptime + ev_now(); - } - goto st181; -st181: - if ( ++p == pe ) - goto _test_eof181; -case 181: -#line 3278 "src/memcached-grammar.cc" - if ( (*p) == 32 ) - goto st181; - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr262; - goto st0; -tr262: -#line 221 "src/memcached-grammar.rl" - { fstart = p; } - goto st182; -st182: - if ( ++p == pe ) - goto _test_eof182; -case 182: -#line 3292 "src/memcached-grammar.cc" - switch( (*p) ) { - case 10: goto tr263; - case 13: goto tr264; - case 32: goto tr265; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st182; - goto st0; -tr264: -#line 245 "src/memcached-grammar.rl" - {bytes = memcached_natoq(fstart, p);} - goto st183; -tr277: -#line 281 "src/memcached-grammar.rl" - { noreply = true; } - goto st183; -st183: - if ( ++p == pe ) - goto _test_eof183; -case 183: -#line 3313 "src/memcached-grammar.cc" - if ( (*p) == 10 ) - goto tr267; - goto st0; -tr265: -#line 245 "src/memcached-grammar.rl" - {bytes = memcached_natoq(fstart, p);} - goto st184; -st184: - if ( ++p == pe ) - goto _test_eof184; -case 184: -#line 3325 "src/memcached-grammar.cc" - switch( (*p) ) { - case 32: goto st184; - case 78: goto st185; - case 110: goto st185; - } - goto st0; -st185: - if ( ++p == pe ) - goto _test_eof185; -case 185: - switch( (*p) ) { - case 79: goto st186; - case 111: goto st186; - } - goto st0; -st186: - if ( ++p == pe ) - goto _test_eof186; -case 186: - switch( (*p) ) { - case 82: goto st187; - case 114: goto st187; - } - goto st0; -st187: - if ( ++p == pe ) - goto _test_eof187; -case 187: - switch( (*p) ) { - case 69: goto st188; - case 101: goto st188; - } - goto st0; -st188: - if ( ++p == pe ) - goto _test_eof188; -case 188: - switch( (*p) ) { - case 80: goto st189; - case 112: goto st189; - } - goto st0; -st189: - if ( ++p == pe ) - goto _test_eof189; -case 189: - switch( (*p) ) { - case 76: goto st190; - case 108: goto st190; - } - goto st0; -st190: - if ( ++p == pe ) - goto _test_eof190; -case 190: - switch( (*p) ) { - case 89: goto st191; - case 121: goto st191; - } - goto st0; -st191: - if ( ++p == pe ) - goto _test_eof191; -case 191: - switch( (*p) ) { - case 10: goto tr276; - case 13: goto tr277; - } - goto st0; -st192: - if ( ++p == pe ) - goto _test_eof192; -case 192: - switch( (*p) ) { - case 65: goto st193; - case 97: goto st193; - } - goto st0; -st193: - if ( ++p == pe ) - goto _test_eof193; -case 193: - switch( (*p) ) { - case 84: goto st194; - case 116: goto st194; - } - goto st0; -st194: - if ( ++p == pe ) - goto _test_eof194; -case 194: - switch( (*p) ) { - case 83: goto st195; - case 115: goto st195; - } - goto st0; -st195: - if ( ++p == pe ) - goto _test_eof195; -case 195: - switch( (*p) ) { - case 10: goto tr281; - case 13: goto st196; - } - goto st0; -st196: - if ( ++p == pe ) - goto _test_eof196; -case 196: - if ( (*p) == 10 ) - goto tr281; - goto st0; - } - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof9: cs = 9; goto _test_eof; - _test_eof10: cs = 10; goto _test_eof; - _test_eof11: cs = 11; goto _test_eof; - _test_eof12: cs = 12; goto _test_eof; - _test_eof197: cs = 197; goto _test_eof; - _test_eof13: cs = 13; goto _test_eof; - _test_eof14: cs = 14; goto _test_eof; - _test_eof15: cs = 15; goto _test_eof; - _test_eof16: cs = 16; goto _test_eof; - _test_eof17: cs = 17; goto _test_eof; - _test_eof18: cs = 18; goto _test_eof; - _test_eof19: cs = 19; goto _test_eof; - _test_eof20: cs = 20; goto _test_eof; - _test_eof21: cs = 21; goto _test_eof; - _test_eof22: cs = 22; goto _test_eof; - _test_eof23: cs = 23; goto _test_eof; - _test_eof24: cs = 24; goto _test_eof; - _test_eof25: cs = 25; goto _test_eof; - _test_eof26: cs = 26; goto _test_eof; - _test_eof27: cs = 27; goto _test_eof; - _test_eof28: cs = 28; goto _test_eof; - _test_eof29: cs = 29; goto _test_eof; - _test_eof30: cs = 30; goto _test_eof; - _test_eof31: cs = 31; goto _test_eof; - _test_eof32: cs = 32; goto _test_eof; - _test_eof33: cs = 33; goto _test_eof; - _test_eof34: cs = 34; goto _test_eof; - _test_eof35: cs = 35; goto _test_eof; - _test_eof36: cs = 36; goto _test_eof; - _test_eof37: cs = 37; goto _test_eof; - _test_eof38: cs = 38; goto _test_eof; - _test_eof39: cs = 39; goto _test_eof; - _test_eof40: cs = 40; goto _test_eof; - _test_eof41: cs = 41; goto _test_eof; - _test_eof42: cs = 42; goto _test_eof; - _test_eof43: cs = 43; goto _test_eof; - _test_eof44: cs = 44; goto _test_eof; - _test_eof45: cs = 45; goto _test_eof; - _test_eof46: cs = 46; goto _test_eof; - _test_eof47: cs = 47; goto _test_eof; - _test_eof48: cs = 48; goto _test_eof; - _test_eof49: cs = 49; goto _test_eof; - _test_eof50: cs = 50; goto _test_eof; - _test_eof51: cs = 51; goto _test_eof; - _test_eof52: cs = 52; goto _test_eof; - _test_eof53: cs = 53; goto _test_eof; - _test_eof54: cs = 54; goto _test_eof; - _test_eof55: cs = 55; goto _test_eof; - _test_eof56: cs = 56; goto _test_eof; - _test_eof57: cs = 57; goto _test_eof; - _test_eof58: cs = 58; goto _test_eof; - _test_eof59: cs = 59; goto _test_eof; - _test_eof60: cs = 60; goto _test_eof; - _test_eof61: cs = 61; goto _test_eof; - _test_eof62: cs = 62; goto _test_eof; - _test_eof63: cs = 63; goto _test_eof; - _test_eof64: cs = 64; goto _test_eof; - _test_eof65: cs = 65; goto _test_eof; - _test_eof66: cs = 66; goto _test_eof; - _test_eof67: cs = 67; goto _test_eof; - _test_eof68: cs = 68; goto _test_eof; - _test_eof69: cs = 69; goto _test_eof; - _test_eof70: cs = 70; goto _test_eof; - _test_eof71: cs = 71; goto _test_eof; - _test_eof72: cs = 72; goto _test_eof; - _test_eof73: cs = 73; goto _test_eof; - _test_eof74: cs = 74; goto _test_eof; - _test_eof75: cs = 75; goto _test_eof; - _test_eof76: cs = 76; goto _test_eof; - _test_eof77: cs = 77; goto _test_eof; - _test_eof78: cs = 78; goto _test_eof; - _test_eof79: cs = 79; goto _test_eof; - _test_eof80: cs = 80; goto _test_eof; - _test_eof81: cs = 81; goto _test_eof; - _test_eof82: cs = 82; goto _test_eof; - _test_eof83: cs = 83; goto _test_eof; - _test_eof84: cs = 84; goto _test_eof; - _test_eof85: cs = 85; goto _test_eof; - _test_eof86: cs = 86; goto _test_eof; - _test_eof87: cs = 87; goto _test_eof; - _test_eof88: cs = 88; goto _test_eof; - _test_eof89: cs = 89; goto _test_eof; - _test_eof90: cs = 90; goto _test_eof; - _test_eof91: cs = 91; goto _test_eof; - _test_eof92: cs = 92; goto _test_eof; - _test_eof93: cs = 93; goto _test_eof; - _test_eof94: cs = 94; goto _test_eof; - _test_eof95: cs = 95; goto _test_eof; - _test_eof96: cs = 96; goto _test_eof; - _test_eof97: cs = 97; goto _test_eof; - _test_eof98: cs = 98; goto _test_eof; - _test_eof99: cs = 99; goto _test_eof; - _test_eof100: cs = 100; goto _test_eof; - _test_eof101: cs = 101; goto _test_eof; - _test_eof102: cs = 102; goto _test_eof; - _test_eof103: cs = 103; goto _test_eof; - _test_eof104: cs = 104; goto _test_eof; - _test_eof105: cs = 105; goto _test_eof; - _test_eof106: cs = 106; goto _test_eof; - _test_eof107: cs = 107; goto _test_eof; - _test_eof108: cs = 108; goto _test_eof; - _test_eof109: cs = 109; goto _test_eof; - _test_eof110: cs = 110; goto _test_eof; - _test_eof111: cs = 111; goto _test_eof; - _test_eof112: cs = 112; goto _test_eof; - _test_eof113: cs = 113; goto _test_eof; - _test_eof114: cs = 114; goto _test_eof; - _test_eof115: cs = 115; goto _test_eof; - _test_eof116: cs = 116; goto _test_eof; - _test_eof117: cs = 117; goto _test_eof; - _test_eof118: cs = 118; goto _test_eof; - _test_eof119: cs = 119; goto _test_eof; - _test_eof120: cs = 120; goto _test_eof; - _test_eof121: cs = 121; goto _test_eof; - _test_eof122: cs = 122; goto _test_eof; - _test_eof123: cs = 123; goto _test_eof; - _test_eof124: cs = 124; goto _test_eof; - _test_eof125: cs = 125; goto _test_eof; - _test_eof126: cs = 126; goto _test_eof; - _test_eof127: cs = 127; goto _test_eof; - _test_eof128: cs = 128; goto _test_eof; - _test_eof129: cs = 129; goto _test_eof; - _test_eof130: cs = 130; goto _test_eof; - _test_eof131: cs = 131; goto _test_eof; - _test_eof132: cs = 132; goto _test_eof; - _test_eof133: cs = 133; goto _test_eof; - _test_eof134: cs = 134; goto _test_eof; - _test_eof135: cs = 135; goto _test_eof; - _test_eof136: cs = 136; goto _test_eof; - _test_eof137: cs = 137; goto _test_eof; - _test_eof138: cs = 138; goto _test_eof; - _test_eof139: cs = 139; goto _test_eof; - _test_eof140: cs = 140; goto _test_eof; - _test_eof141: cs = 141; goto _test_eof; - _test_eof142: cs = 142; goto _test_eof; - _test_eof143: cs = 143; goto _test_eof; - _test_eof144: cs = 144; goto _test_eof; - _test_eof145: cs = 145; goto _test_eof; - _test_eof146: cs = 146; goto _test_eof; - _test_eof147: cs = 147; goto _test_eof; - _test_eof148: cs = 148; goto _test_eof; - _test_eof149: cs = 149; goto _test_eof; - _test_eof150: cs = 150; goto _test_eof; - _test_eof151: cs = 151; goto _test_eof; - _test_eof152: cs = 152; goto _test_eof; - _test_eof153: cs = 153; goto _test_eof; - _test_eof154: cs = 154; goto _test_eof; - _test_eof155: cs = 155; goto _test_eof; - _test_eof156: cs = 156; goto _test_eof; - _test_eof157: cs = 157; goto _test_eof; - _test_eof158: cs = 158; goto _test_eof; - _test_eof159: cs = 159; goto _test_eof; - _test_eof160: cs = 160; goto _test_eof; - _test_eof161: cs = 161; goto _test_eof; - _test_eof162: cs = 162; goto _test_eof; - _test_eof163: cs = 163; goto _test_eof; - _test_eof164: cs = 164; goto _test_eof; - _test_eof165: cs = 165; goto _test_eof; - _test_eof166: cs = 166; goto _test_eof; - _test_eof167: cs = 167; goto _test_eof; - _test_eof168: cs = 168; goto _test_eof; - _test_eof169: cs = 169; goto _test_eof; - _test_eof170: cs = 170; goto _test_eof; - _test_eof171: cs = 171; goto _test_eof; - _test_eof172: cs = 172; goto _test_eof; - _test_eof173: cs = 173; goto _test_eof; - _test_eof174: cs = 174; goto _test_eof; - _test_eof175: cs = 175; goto _test_eof; - _test_eof176: cs = 176; goto _test_eof; - _test_eof177: cs = 177; goto _test_eof; - _test_eof178: cs = 178; goto _test_eof; - _test_eof179: cs = 179; goto _test_eof; - _test_eof180: cs = 180; goto _test_eof; - _test_eof181: cs = 181; goto _test_eof; - _test_eof182: cs = 182; goto _test_eof; - _test_eof183: cs = 183; goto _test_eof; - _test_eof184: cs = 184; goto _test_eof; - _test_eof185: cs = 185; goto _test_eof; - _test_eof186: cs = 186; goto _test_eof; - _test_eof187: cs = 187; goto _test_eof; - _test_eof188: cs = 188; goto _test_eof; - _test_eof189: cs = 189; goto _test_eof; - _test_eof190: cs = 190; goto _test_eof; - _test_eof191: cs = 191; goto _test_eof; - _test_eof192: cs = 192; goto _test_eof; - _test_eof193: cs = 193; goto _test_eof; - _test_eof194: cs = 194; goto _test_eof; - _test_eof195: cs = 195; goto _test_eof; - _test_eof196: cs = 196; goto _test_eof; - - _test_eof: {} - _out: {} - } - -#line 306 "src/memcached-grammar.rl" - - - if (!done) { - say_debug("parse failed after: `%.*s'", (int)(pe - p), p); - if (pe - p > (1 << 20)) { - exit: - say_warn("memcached proto error"); - obuf_dup(out, "ERROR\r\n", 7); - stats.bytes_written += 7; - return -1; - } - char *r; - if ((r = (char *) memmem(p, pe - p, "\r\n", 2)) != NULL) { - in->pos = r + 2; - obuf_dup(out, "CLIENT_ERROR bad command line format\r\n", 38); - return 1; - } - return 0; - } - - if (noreply) { - obuf_rollback_to_svp(out, &obuf_svp); - } - return 1; -} - -/* - * Local Variables: - * mode: c - * End: - * vim: syntax=objc - */ diff --git a/src/recovery.cc b/src/recovery.cc index 9a35aa6f30f629c6fb60144284c46cad0e3d67ea..a48de3f5de1bd516dd9866a90f1cee08e2d91025 100644 --- a/src/recovery.cc +++ b/src/recovery.cc @@ -253,6 +253,8 @@ void recovery_update_io_rate_limit(struct recovery_state *r, double new_limit) { r->snap_io_rate_limit = new_limit * 1024 * 1024; + if (r->snap_io_rate_limit == 0) + r->snap_io_rate_limit = UINT64_MAX; } void @@ -526,7 +528,9 @@ recover_remaining_wals(struct recovery_state *r) } /* TODO: find a better way of finding the next xlog */ - current_lsn = r->confirmed_lsn + 1; + current_lsn = r->confirmed_lsn; +find_next_wal: + current_lsn++; /* * For the last WAL, first try to open .inprogress * file: if it doesn't exist, we can safely try an @@ -546,6 +550,13 @@ recover_remaining_wals(struct recovery_state *r) filename = format_filename(r->wal_dir, current_lsn, suffix); f = fopen(filename, "r"); + /* + * Try finding wal for the next lsn if there is a + * gap in LSNs. + */ + if (f == NULL && errno == ENOENT && + current_lsn < wal_greatest_lsn) + goto find_next_wal; } next_wal = log_io_open(r->wal_dir, LOG_READ, filename, suffix, f); /* @@ -1212,7 +1223,7 @@ wal_writer_thread(void *worker_args) * to be written to disk and wait until this task is completed. */ int -wal_write(struct recovery_state *r, int64_t lsn, +wal_write(struct recovery_state *r, int64_t lsn, uint64_t cookie, uint16_t op, const char *row, uint32_t row_len) { say_debug("wal_write lsn=%" PRIi64, lsn); @@ -1229,7 +1240,7 @@ wal_write(struct recovery_state *r, int64_t lsn, req->fiber = fiber; req->res = -1; - wal_row_fill(&req->row, lsn, (const char *) &op, + wal_row_fill(&req->row, lsn, cookie, (const char *) &op, sizeof(op), row, row_len); (void) tt_pthread_mutex_lock(&writer->mutex); @@ -1268,7 +1279,7 @@ snapshot_write_row(struct log_io *l, struct fio_batch *batch, const char *data, size_t data_len) { static int rows; - static int bytes; + static uint64_t bytes; ev_tstamp elapsed; static ev_tstamp last = 0; @@ -1276,30 +1287,50 @@ snapshot_write_row(struct log_io *l, struct fio_batch *batch, sizeof(struct wal_row) + data_len + metadata_len); - wal_row_fill(row, ++rows, metadata, metadata_len, data, data_len); + wal_row_fill(row, ++rows, snapshot_cookie, metadata, + metadata_len, data, data_len); row_header_sign(&row->header); fio_batch_add(batch, row, wal_row_size(row)); + bytes += wal_row_size(row); if (rows % 100000 == 0) say_crit("%.1fM rows written", rows / 1000000.); - if (fio_batch_is_full(batch)) { + if (fio_batch_is_full(batch) || + bytes > recovery_state->snap_io_rate_limit) { + snap_write_batch(batch, fileno(l->f)); fio_batch_start(batch, INT_MAX); prelease_after(fiber->gc_pool, 128 * 1024); - } - - if (recovery_state->snap_io_rate_limit > 0) { - if (last == 0) { - ev_now_update(); - last = ev_now(); + if (recovery_state->snap_io_rate_limit != UINT64_MAX) { + if (last == 0) { + /* + * Remember the time of first + * write to disk. + */ + ev_now_update(); + last = ev_now(); + } + /** + * If io rate limit is set, flush the + * filesystem cache, otherwise the limit is + * not really enforced. + */ + fdatasync(fileno(l->f)); } - bytes += wal_row_size(row); while (bytes >= recovery_state->snap_io_rate_limit) { - ev_now_update(); + /* + * How much time have passed since + * last write? + */ elapsed = ev_now() - last; + /* + * If last write was in less than + * a second, sleep until the + * second is reached. + */ if (elapsed < 1) usleep(((1 - elapsed) * 1000000)); diff --git a/src/salloc.cc b/src/salloc.cc index 12257843c6a84cbf39c715e682578dc5f4331e90..4a15de7392d72c27fe8b5a90de901e606c107122 100644 --- a/src/salloc.cc +++ b/src/salloc.cc @@ -61,14 +61,16 @@ static const size_t MAX_SLAB_ITEM = 1 << 20; size_t MAX_SLAB_ITEM_COUNT; struct slab_item { - struct slab_item *next; + SLIST_ENTRY(slab_item) next; }; +SLIST_HEAD(item_slist_head, slab_item); + struct slab { uint32_t magic; size_t used; size_t items; - struct slab_item *free; + struct item_slist_head free; struct slab_cache *cache; void *brk; SLIST_ENTRY(slab) link; @@ -88,7 +90,10 @@ struct slab_cache { struct arena { void *mmap_base; size_t mmap_size; - + /** How items tuples do we have stacked for delayed free. */ + int64_t delayed_free_count; + /** How many items in the delayed free list to free at once. */ + size_t delayed_free_batch; void *base; size_t size; size_t used; @@ -96,6 +101,11 @@ struct arena { }; static uint32_t slab_active_caches; +/** + * Delayed garbage collection for items which are used + * in a forked process. + */ +static struct item_slist_head free_delayed; static struct slab_cache slab_caches[256]; static struct arena arena; @@ -126,17 +136,22 @@ slab_caches_init(size_t minimal, double factor) MAX_SLAB_ITEM_COUNT = (size_t) (SLAB_SIZE - sizeof(struct slab)) / slab_caches[0].item_size; + + SLIST_INIT(&free_delayed); } static bool arena_init(struct arena *arena, size_t size) { + arena->delayed_free_batch = 100; + arena->delayed_free_count = 0; + arena->used = 0; arena->size = size - size % SLAB_SIZE; arena->mmap_size = size - size % SLAB_SIZE + SLAB_SIZE; /* spend SLAB_SIZE bytes on align :-( */ arena->mmap_base = mmap(NULL, arena->mmap_size, - PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); if (arena->mmap_base == MAP_FAILED) { say_syserror("mmap"); return false; @@ -149,6 +164,16 @@ arena_init(struct arena *arena, size_t size) return true; } +/** + * Protect slab arena from changes. A safeguard used in a forked + * process to prevent changes to the master process arena. + */ +void +salloc_protect(void) +{ + mprotect(arena.mmap_base, arena.mmap_size, PROT_READ); +} + static void * arena_alloc(struct arena *arena) { @@ -182,7 +207,6 @@ salloc_free(void) { if (arena.mmap_base != NULL) munmap(arena.mmap_base, arena.mmap_size); - memset(&arena, 0, sizeof(struct arena)); } @@ -192,7 +216,7 @@ format_slab(struct slab_cache *cache, struct slab *slab) assert(cache->item_size <= MAX_SLAB_ITEM); slab->magic = SLAB_MAGIC; - slab->free = NULL; + SLIST_INIT(&slab->free); slab->cache = cache; slab->items = 0; slab->used = 0; @@ -269,6 +293,58 @@ valid_item(struct slab *slab, void *item) } #endif +void +sfree(void *ptr) +{ + struct slab *slab = slab_header(ptr); + struct slab_cache *cache = slab->cache; + struct slab_item *item = (struct slab_item *) ptr; + + if (fully_formatted(slab) && SLIST_EMPTY(&slab->free)) + TAILQ_INSERT_TAIL(&cache->free_slabs, slab, cache_free_link); + + assert(valid_item(slab, item)); + assert(SLIST_EMPTY(&slab->free) || valid_item(slab, SLIST_FIRST(&slab->free))); + + SLIST_INSERT_HEAD(&slab->free, item, next); + slab->used -= cache->item_size + sizeof(red_zone); + slab->items -= 1; + + if (slab->items == 0) { + TAILQ_REMOVE(&cache->free_slabs, slab, cache_free_link); + TAILQ_REMOVE(&cache->slabs, slab, cache_link); + SLIST_INSERT_HEAD(&arena.free_slabs, slab, free_link); + } + + VALGRIND_FREELIKE_BLOCK(item, sizeof(red_zone)); +} + +static void +sfree_batch(void) +{ + ssize_t batch = arena.delayed_free_batch; + + while (--batch >= 0 && !SLIST_EMPTY(&free_delayed)) { + assert(arena.delayed_free_count > 0); + struct slab_item *item = SLIST_FIRST(&free_delayed); + SLIST_REMOVE_HEAD(&free_delayed, next); + arena.delayed_free_count--; + sfree(item); + } +} + +void +sfree_delayed(void *ptr) +{ + if (ptr == NULL) + return; + struct slab_item *item = (struct slab_item *)ptr; + struct slab *slab = slab_header(item); + assert(valid_item(slab, item)); + SLIST_INSERT_HEAD(&free_delayed, item, next); + arena.delayed_free_count++; +} + void * salloc(size_t size, const char *what) { @@ -276,6 +352,8 @@ salloc(size_t size, const char *what) struct slab *slab; struct slab_item *item; + sfree_batch(); + if ((cache = cache_for(size)) == NULL || (slab = slab_of(cache)) == NULL) { @@ -283,21 +361,20 @@ salloc(size_t size, const char *what) "slab allocator", what); } - if (slab->free == NULL) { + if (SLIST_EMPTY(&slab->free)) { assert(valid_item(slab, slab->brk)); item = (struct slab_item *) slab->brk; memcpy((char *)item + cache->item_size, red_zone, sizeof(red_zone)); slab->brk = (char *) slab->brk + cache->item_size + sizeof(red_zone); } else { - assert(valid_item(slab, slab->free)); - item = slab->free; - + item = SLIST_FIRST(&slab->free); + assert(valid_item(slab, item)); (void) VALGRIND_MAKE_MEM_DEFINED(item, sizeof(void *)); - slab->free = item->next; + SLIST_REMOVE_HEAD(&slab->free, next); (void) VALGRIND_MAKE_MEM_UNDEFINED(item, sizeof(void *)); } - if (fully_formatted(slab) && slab->free == NULL) + if (fully_formatted(slab) && SLIST_EMPTY(&slab->free)) TAILQ_REMOVE(&cache->free_slabs, slab, cache_free_link); slab->used += cache->item_size + sizeof(red_zone); @@ -307,36 +384,6 @@ salloc(size_t size, const char *what) return (void *)item; } -void -sfree(void *ptr) -{ - if (ptr == NULL) - return; - struct slab *slab = slab_header(ptr); - struct slab_cache *cache = slab->cache; - struct slab_item *item = (struct slab_item *) ptr; - - if (fully_formatted(slab) && slab->free == NULL) - TAILQ_INSERT_TAIL(&cache->free_slabs, slab, cache_free_link); - - assert(valid_item(slab, item)); - assert(slab->free == NULL || valid_item(slab, slab->free)); - - item->next = slab->free; - slab->free = item; - slab->used -= cache->item_size + sizeof(red_zone); - slab->items -= 1; - - if (slab->items == 0) { - TAILQ_REMOVE(&cache->free_slabs, slab, cache_free_link); - TAILQ_REMOVE(&cache->slabs, slab, cache_link); - SLIST_INSERT_HEAD(&arena.free_slabs, slab, free_link); - } - - VALGRIND_FREELIKE_BLOCK(item, sizeof(red_zone)); -} - - size_t salloc_ptr_to_index(void *ptr) { diff --git a/src/say.cc b/src/say.cc index 55585103bb012330b4f1b2995087fb6abc474e69..bfaea8f521ec53f6bd62e66b31f0b09e693adb19 100644 --- a/src/say.cc +++ b/src/say.cc @@ -123,6 +123,7 @@ say_logger_init(int nonblock) execve(argv[0], argv, envp); goto error; } +#ifndef TARGET_OS_DARWIN /* * A courtesy to a DBA who might have * misconfigured the logger option: check whether @@ -135,6 +136,7 @@ say_logger_init(int nonblock) timeout.tv_nsec = 1; /* Mostly to trigger preemption. */ if (sigtimedwait(&mask, NULL, &timeout) == SIGCHLD) goto error; +#endif /* OK, let's hope for the best. */ sigprocmask(SIG_UNBLOCK, &mask, NULL); diff --git a/src/session.cc b/src/session.cc index aff039821dea273a450127304ea08e445d5cb250..e320563a521d48f338572d5f4c5609656ca9863d 100644 --- a/src/session.cc +++ b/src/session.cc @@ -32,6 +32,7 @@ #include "assoc.h" #include "trigger.h" #include "exception.h" +#include <sys/socket.h> uint32_t sid_max; @@ -41,7 +42,7 @@ RLIST_HEAD(session_on_connect); RLIST_HEAD(session_on_disconnect); uint32_t -session_create(int fd) +session_create(int fd, uint64_t cookie) { /* Return the next sid rolling over the reserved value of 0. */ while (++sid_max == 0) @@ -62,11 +63,11 @@ session_create(int fd) * Run the trigger *after* setting the current * fiber sid. */ - fiber_set_sid(fiber, sid); + fiber_set_sid(fiber, sid, cookie); try { trigger_run(&session_on_connect, NULL); } catch (const Exception& e) { - fiber_set_sid(fiber, 0); + fiber_set_sid(fiber, 0, 0); mh_i32ptr_remove(session_registry, &node, NULL); throw; } diff --git a/src/tarantool.cc b/src/tarantool.cc index 7888233ed57f9e2affc58cdfa98dae6849fa8931..f39602946897de56da6ed480507036fd936fda29 100644 --- a/src/tarantool.cc +++ b/src/tarantool.cc @@ -84,6 +84,8 @@ struct tarantool_cfg cfg; static ev_signal *sigs = NULL; int snapshot_pid = 0; /* snapshot processes pid */ +uint32_t snapshot_version = 0; + extern const void *opt_def; static int @@ -127,7 +129,7 @@ load_cfg(struct tarantool_cfg *conf, int32_t check_rdonly) FILE *f; int32_t n_accepted, n_skipped, n_ignored; - tbuf_reset(cfg_out); + rewind(cfg_out); if (cfg_filename_fullpath != NULL) f = fopen(cfg_filename_fullpath, "r"); @@ -172,48 +174,48 @@ static int core_reload_config(const struct tarantool_cfg *old_conf, const struct tarantool_cfg *new_conf) { - if (strcasecmp(old_conf->wal_mode, new_conf->wal_mode) == 0 && - old_conf->wal_fsync_delay == new_conf->wal_fsync_delay) - return 0; + if (strcasecmp(old_conf->wal_mode, new_conf->wal_mode) != 0 || + old_conf->wal_fsync_delay != new_conf->wal_fsync_delay) { - double new_delay = new_conf->wal_fsync_delay; + double new_delay = new_conf->wal_fsync_delay; - /* Mode has changed: */ - if (strcasecmp(old_conf->wal_mode, new_conf->wal_mode)) { - if (strcasecmp(old_conf->wal_mode, "fsync") == 0 || - strcasecmp(new_conf->wal_mode, "fsync") == 0) { - out_warning(CNF_OK, "wal_mode cannot switch to/from fsync"); - return -1; + /* Mode has changed: */ + if (strcasecmp(old_conf->wal_mode, new_conf->wal_mode)) { + if (strcasecmp(old_conf->wal_mode, "fsync") == 0 || + strcasecmp(new_conf->wal_mode, "fsync") == 0) { + out_warning(CNF_OK, "wal_mode cannot switch to/from fsync"); + return -1; + } } - say_debug("%s: wal_mode [%s] -> [%s]", - __func__, old_conf->wal_mode, new_conf->wal_mode); - } - /* - * Unless wal_mode=fsync_delay, wal_fsync_delay is irrelevant and must be 0. - */ - if (strcasecmp(new_conf->wal_mode, "fsync_delay") != 0) - new_delay = 0.0; + /* + * Unless wal_mode=fsync_delay, wal_fsync_delay is + * irrelevant and must be 0. + */ + if (strcasecmp(new_conf->wal_mode, "fsync_delay") != 0) + new_delay = 0.0; - if (old_conf->wal_fsync_delay != new_delay) - say_debug("%s: wal_fsync_delay [%f] -> [%f]", - __func__, old_conf->wal_fsync_delay, new_delay); - recovery_update_mode(recovery_state, new_conf->wal_mode, new_delay); + recovery_update_mode(recovery_state, new_conf->wal_mode, new_delay); + } - recovery_update_io_rate_limit(recovery_state, new_conf->snap_io_rate_limit); + if (old_conf->snap_io_rate_limit != new_conf->snap_io_rate_limit) + recovery_update_io_rate_limit(recovery_state, new_conf->snap_io_rate_limit); - ev_set_io_collect_interval(new_conf->io_collect_interval); + if (old_conf->io_collect_interval != new_conf->io_collect_interval) + ev_set_io_collect_interval(new_conf->io_collect_interval); return 0; } int -reload_cfg(struct tbuf *out) +reload_cfg() { static struct mutex *mutex = NULL; struct tarantool_cfg new_cfg, aux_cfg; + rewind(cfg_out); + if (mutex == NULL) { mutex = (struct mutex *) palloc(eter_pool, sizeof(*mutex)); mutex_create(mutex); @@ -221,8 +223,6 @@ reload_cfg(struct tbuf *out) if (mutex_trylock(mutex) == true) { out_warning(CNF_OK, "Could not reload configuration: it is being reloaded right now"); - tbuf_append(out, cfg_out->data, cfg_out->size); - return -1; } @@ -231,9 +231,6 @@ reload_cfg(struct tbuf *out) destroy_tarantool_cfg(&aux_cfg); destroy_tarantool_cfg(&new_cfg); - if (cfg_out->size != 0) - tbuf_append(out, cfg_out->data, cfg_out->size); - mutex_unlock(mutex); }); @@ -316,12 +313,21 @@ tarantool_uptime(void) return ev_now() - start_time; } +void snapshot_exit(int code, void* arg) { + (void)arg; + fflush(NULL); + _exit(code); +} + int snapshot(void) { if (snapshot_pid) return EINPROGRESS; + /* increment snapshot version */ + snapshot_version++; + pid_t p = fork(); if (p < 0) { say_syserror("fork"); @@ -334,6 +340,8 @@ snapshot(void) return (WIFSIGNALED(status) ? EINTR : WEXITSTATUS(status)); } + salloc_protect(); + fiber_set_name(fiber, "dumper"); set_proc_title("dumper (%" PRIu32 ")", getppid()); @@ -342,6 +350,14 @@ snapshot(void) * parent stdio buffers at exit(). */ close_all_xcpt(1, sayfd); + /* + * We must avoid double destruction of tuples on exit. + * Since there is no way to remove existing handlers + * registered in the master process, and snapshot_save() + * may call exit(), push a top-level handler which will do + * _exit() for us. + */ + on_exit(snapshot_exit, NULL); snapshot_save(recovery_state, box_snapshot); exit(EXIT_SUCCESS); @@ -616,6 +632,10 @@ tarantool_free(void) #ifdef HAVE_BFD symbols_free(); #endif + if (cfg_out) { + fclose(cfg_out); + free(cfg_log); + } } int @@ -703,23 +723,22 @@ main(int argc, char **argv) strcat(cfg_filename_fullpath, cfg_filename); } - cfg_out = tbuf_new(eter_pool); - assert(cfg_out); + cfg_out = open_memstream(&cfg_log, &cfg_logsize); if (gopt(opt, 'k')) { - if (fill_default_tarantool_cfg(&cfg) != 0 || load_cfg(&cfg, 0) != 0) { - say_error("check_config FAILED" - "%.*s", cfg_out->size, (char *)cfg_out->data); + if (fill_default_tarantool_cfg(&cfg) != 0 || + load_cfg(&cfg, 0) != 0) { + say_error("check_config FAILED%.*s", + (int) cfg_logsize, cfg_log); return 1; } - return 0; } - if (fill_default_tarantool_cfg(&cfg) != 0 || load_cfg(&cfg, 0) != 0) - panic("can't load config:" - "%.*s", cfg_out->size, (char *)cfg_out->data); + if (fill_default_tarantool_cfg(&cfg) != 0 || load_cfg(&cfg, 0) != 0) { + panic("can't load config:%.*s", (int) cfg_logsize, cfg_log); + } if (gopt_arg(opt, 'g', &cfg_paramname)) { tarantool_cfg_iterator_t *i; @@ -827,8 +846,8 @@ main(int argc, char **argv) signal_init(); - try { + say_crit("version %s", tarantool_version()); tarantool_L = tarantool_lua_init(); box_init(); atexit(tarantool_lua_free); diff --git a/test/big/sql.result b/test/big/sql.result index cf826ca72a694c7f026ce3364bc49d50ea084059..1a29374414992a382bfcf28c38c78a7adee4afe3 100644 --- a/test/big/sql.result +++ b/test/big/sql.result @@ -16,29 +16,41 @@ box.insert(box.schema.INDEX_ID, 0, 1, 'secondary', 'tree', 0, 1, 1, 'str') # https://bugs.launchpad.net/tarantool/+bug/729758 # insert into t0 values ('Doe', 'Richard') -Insert OK, 1 row affected +--- +- ['Doe', 'Richard'] +... insert into t0 values ('Roe', 'Richard') -Insert OK, 1 row affected +--- +- ['Roe', 'Richard'] +... insert into t0 values ('Woe', 'Richard') -Insert OK, 1 row affected +--- +- ['Woe', 'Richard'] +... insert into t0 values ('Major', 'Tomas') -Insert OK, 1 row affected +--- +- ['Major', 'Tomas'] +... insert into t0 values ('Kytes', 'Tomas') -Insert OK, 1 row affected +--- +- ['Kytes', 'Tomas'] +... select * from t0 where k1='Richard' or k1='Tomas' or k1='Tomas' limit 5 -Found 5 tuples: -['Doe', 'Richard'] -['Kytes', 'Tomas'] -['Major', 'Tomas'] -['Roe', 'Richard'] -['Woe', 'Richard'] +--- +- ['Doe', 'Richard'] +- ['Kytes', 'Tomas'] +- ['Major', 'Tomas'] +- ['Roe', 'Richard'] +- ['Woe', 'Richard'] +... # # A test case for Bug#729879 # "Zero limit is treated the same as no limit" # https://bugs.launchpad.net/tarantool/+bug/729879 # select * from t0 where k1='Richard' or k1='Tomas' limit 0 -No match +--- +... box.space[0]:truncate() --- ... @@ -51,31 +63,50 @@ box.space[0]:truncate() # get away with it. # insert into t0 values ('Britney') -An error occurred: ER_ILLEGAL_PARAMS, 'Illegal parameters, tuple must have all indexed fields' +--- +- error: + errcode: ER_INDEX_ARITY + errmsg: Tuple field count 1 is less than required by a defined index (expected 2) +... select * from t0 where k1='Anything' -No match +--- +... insert into t0 values ('Stephanie') -An error occurred: ER_ILLEGAL_PARAMS, 'Illegal parameters, tuple must have all indexed fields' +--- +- error: + errcode: ER_INDEX_ARITY + errmsg: Tuple field count 1 is less than required by a defined index (expected 2) +... select * from t0 where k1='Anything' -No match +--- +... insert into t0 values ('Spears', 'Britney') -Insert OK, 1 row affected +--- +- ['Spears', 'Britney'] +... select * from t0 where k0='Spears' -Found 1 tuple: -['Spears', 'Britney'] +--- +- ['Spears', 'Britney'] +... select * from t0 where k1='Anything' -No match +--- +... select * from t0 where k1='Britney' -Found 1 tuple: -['Spears', 'Britney'] +--- +- ['Spears', 'Britney'] +... call box.select_range('0', '0', '100', 'Spears') -Found 1 tuple: -['Spears', 'Britney'] +--- +- ['Spears', 'Britney'] +... call box.select_range('0', '1', '100', 'Britney') -Found 1 tuple: -['Spears', 'Britney'] +--- +- ['Spears', 'Britney'] +... delete from t0 where k0='Spears' -Delete OK, 1 row affected +--- +- ['Spears', 'Britney'] +... box.space[0]:truncate() --- ... @@ -87,13 +118,21 @@ box.replace(box.schema.INDEX_ID, 0, 1, 'secondary', 'tree', 1, 2, 1, 'str', 2, ' - [0, 1, 'secondary', 1701147252, 1, 2, 1, 'str', 2, 'str'] ... insert into t0 values ('key1', 'part1', 'part2') -Insert OK, 1 row affected +--- +- ['key1', 'part1', 'part2'] +... replace into t0 values ('key1', 'part1', 'part2') -Replace OK, 1 row affected +--- +- ['key1', 'part1', 'part2'] +... insert into t0 values ('key2', 'part1', 'part2_a') -Insert OK, 1 row affected +--- +- ['key2', 'part1', 'part2_a'] +... insert into t0 values ('key3', 'part1', 'part2_b') -Insert OK, 1 row affected +--- +- ['key3', 'part1', 'part2_b'] +... box.space[0]:select(1) --- - [830039403, 'part1', 'part2'] @@ -101,53 +140,70 @@ box.space[0]:select(1) - [863593835, 'part1', 'part2_b'] ... select * from t0 where k0='key1' -Found 1 tuple: -[830039403, 'part1', 'part2'] +--- +- ['key1', 'part1', 'part2'] +... select * from t0 where k0='key2' -Found 1 tuple: -[846816619, 'part1', 'part2_a'] +--- +- ['key2', 'part1', 'part2_a'] +... select * from t0 where k0='key3' -Found 1 tuple: -[863593835, 'part1', 'part2_b'] +--- +- ['key3', 'part1', 'part2_b'] +... select * from t0 where k1='part1' -Found 3 tuples: -[830039403, 'part1', 'part2'] -[846816619, 'part1', 'part2_a'] -[863593835, 'part1', 'part2_b'] +--- +- ['key1', 'part1', 'part2'] +- ['key2', 'part1', 'part2_a'] +- ['key3', 'part1', 'part2_b'] +... call box.select_range('0', '1', '100', 'part1') -Found 3 tuples: -[830039403, 'part1', 'part2'] -[846816619, 'part1', 'part2_a'] -[863593835, 'part1', 'part2_b'] +--- +- ['key1', 'part1', 'part2'] +- ['key2', 'part1', 'part2_a'] +- ['key3', 'part1', 'part2_b'] +... call box.select_range('0', '0', '100', 'key2') -Found 3 tuples: -[830039403, 'part1', 'part2'] -[846816619, 'part1', 'part2_a'] -[863593835, 'part1', 'part2_b'] +--- +- ['key1', 'part1', 'part2'] +- ['key2', 'part1', 'part2_a'] +- ['key3', 'part1', 'part2_b'] +... call box.select_range('0', '1', '100', 'part1', 'part2_a') -Found 2 tuples: -[846816619, 'part1', 'part2_a'] -[863593835, 'part1', 'part2_b'] +--- +- ['key2', 'part1', 'part2_a'] +- ['key3', 'part1', 'part2_b'] +... select * from t0 where k0='key1' -Found 1 tuple: -[830039403, 'part1', 'part2'] +--- +- ['key1', 'part1', 'part2'] +... select * from t0 where k0='key2' -Found 1 tuple: -[846816619, 'part1', 'part2_a'] +--- +- ['key2', 'part1', 'part2_a'] +... select * from t0 where k0='key3' -Found 1 tuple: -[863593835, 'part1', 'part2_b'] +--- +- ['key3', 'part1', 'part2_b'] +... select * from t0 where k1='part1' -Found 3 tuples: -[830039403, 'part1', 'part2'] -[846816619, 'part1', 'part2_a'] -[863593835, 'part1', 'part2_b'] +--- +- ['key1', 'part1', 'part2'] +- ['key2', 'part1', 'part2_a'] +- ['key3', 'part1', 'part2_b'] +... delete from t0 where k0='key1' -Delete OK, 1 row affected +--- +- ['key1', 'part1', 'part2'] +... delete from t0 where k0='key2' -Delete OK, 1 row affected +--- +- ['key2', 'part1', 'part2_a'] +... delete from t0 where k0='key3' -Delete OK, 1 row affected +--- +- ['key3', 'part1', 'part2_b'] +... box.space[0]:truncate() --- ... @@ -160,15 +216,25 @@ box.replace(box.schema.INDEX_ID, 0, 1, 'secondary', 'tree', 0, 2, 1, 'str', 2, ' - [0, 1, 'secondary', 1701147252, 0, 2, 1, 'str', 2, 'str'] ... insert into t0 values ('01234567', 'part1', 'part2') -Insert OK, 1 row affected +--- +- ['01234567', 'part1', 'part2'] +... insert into t0 values ('11234567', 'part1', 'part2') -Insert OK, 1 row affected +--- +- ['11234567', 'part1', 'part2'] +... insert into t0 values ('21234567', 'part1', 'part2_a') -Insert OK, 1 row affected +--- +- ['21234567', 'part1', 'part2_a'] +... insert into t0 values ('31234567', 'part1_a', 'part2') -Insert OK, 1 row affected +--- +- ['31234567', 'part1_a', 'part2'] +... insert into t0 values ('41234567', 'part1_a', 'part2_a') -Insert OK, 1 row affected +--- +- ['41234567', 'part1_a', 'part2_a'] +... l = {} --- ... @@ -184,46 +250,65 @@ return l - [3978425819141910836, 'part1_a', 'part2_a'] ... select * from t0 where k0='01234567' -Found 1 tuple: -['01234567', 'part1', 'part2'] +--- +- ['01234567', 'part1', 'part2'] +... select * from t0 where k0='11234567' -Found 1 tuple: -['11234567', 'part1', 'part2'] +--- +- ['11234567', 'part1', 'part2'] +... select * from t0 where k0='21234567' -Found 1 tuple: -['21234567', 'part1', 'part2_a'] +--- +- ['21234567', 'part1', 'part2_a'] +... select * from t0 where k1='part1' -Found 3 tuples: -['01234567', 'part1', 'part2'] -['11234567', 'part1', 'part2'] -['21234567', 'part1', 'part2_a'] +--- +- ['01234567', 'part1', 'part2'] +- ['11234567', 'part1', 'part2'] +- ['21234567', 'part1', 'part2_a'] +... select * from t0 where k1='part1_a' -Found 2 tuples: -['31234567', 'part1_a', 'part2'] -['41234567', 'part1_a', 'part2_a'] +--- +- ['31234567', 'part1_a', 'part2'] +- ['41234567', 'part1_a', 'part2_a'] +... select * from t0 where k1='part_none' -No match +--- +... call box.select('0', '1', 'part1', 'part2') -Found 2 tuples: -['01234567', 'part1', 'part2'] -['11234567', 'part1', 'part2'] +--- +- ['01234567', 'part1', 'part2'] +- ['11234567', 'part1', 'part2'] +... select * from t0 where k1='part1' -Found 3 tuples: -['01234567', 'part1', 'part2'] -['11234567', 'part1', 'part2'] -['21234567', 'part1', 'part2_a'] +--- +- ['01234567', 'part1', 'part2'] +- ['11234567', 'part1', 'part2'] +- ['21234567', 'part1', 'part2_a'] +... select * from t0 where k1='part2' -No match +--- +... delete from t0 where k0='01234567' -Delete OK, 1 row affected +--- +- ['01234567', 'part1', 'part2'] +... delete from t0 where k0='11234567' -Delete OK, 1 row affected +--- +- ['11234567', 'part1', 'part2'] +... delete from t0 where k0='21234567' -Delete OK, 1 row affected +--- +- ['21234567', 'part1', 'part2_a'] +... delete from t0 where k0='31234567' -Delete OK, 1 row affected +--- +- ['31234567', 'part1_a', 'part2'] +... delete from t0 where k0='41234567' -Delete OK, 1 row affected +--- +- ['41234567', 'part1_a', 'part2_a'] +... box.space[0]:select(0) --- ... @@ -239,28 +324,40 @@ box.replace(box.schema.INDEX_ID, 0, 1, 'secondary', 'hash', 1, 1, 1, 'str') - [0, 1, 'secondary', 1752392040, 1, 1, 1, 'str'] ... insert into t0 values (1, 'hello') -Insert OK, 1 row affected +--- +- ['\x01\x00\x00\x00', 'hello'] +... insert into t0 values (2, 'brave') -Insert OK, 1 row affected +--- +- ['\x02\x00\x00\x00', 'brave'] +... insert into t0 values (3, 'new') -Insert OK, 1 row affected +--- +- ['\x03\x00\x00\x00', 'new'] +... insert into t0 values (4, 'world') -Insert OK, 1 row affected +--- +- ['\x04\x00\x00\x00', 'world'] +... # # Bug#929654 - secondary hash index is not built with build_indexes() # select * from t0 where k1='hello' -Found 1 tuple: -[1, 'hello'] +--- +- ['\x01\x00\x00\x00', 'hello'] +... select * from t0 where k1='brave' -Found 1 tuple: -[2, 'brave'] +--- +- ['\x02\x00\x00\x00', 'brave'] +... select * from t0 where k1='new' -Found 1 tuple: -[3, 'new'] +--- +- ['\x03\x00\x00\x00', 'new'] +... select * from t0 where k1='world' -Found 1 tuple: -[4, 'world'] +--- +- ['\x04\x00\x00\x00', 'world'] +... box.space[0]:truncate() --- ... @@ -279,107 +376,187 @@ box.replace(box.schema.INDEX_ID, 0, 1, 'secondary', 'tree', 0, 1, 1, 'str') - [0, 1, 'secondary', 1701147252, 0, 1, 1, 'str'] ... insert into t0 values ('Spears', 'Britney') -Insert OK, 1 row affected +--- +- ['Spears', 'Britney'] +... select * from t0 where k0='Spears' -Found 1 tuple: -['Spears', 'Britney'] +--- +- ['Spears', 'Britney'] +... select * from t0 where k1='Britney' -Found 1 tuple: -['Spears', 'Britney'] +--- +- ['Spears', 'Britney'] +... replace into t0 values ('Spears') -An error occurred: ER_ILLEGAL_PARAMS, 'Illegal parameters, tuple must have all indexed fields' +--- +- error: + errcode: ER_INDEX_ARITY + errmsg: Tuple field count 1 is less than required by a defined index (expected 2) +... select * from t0 where k0='Spears' -Found 1 tuple: -['Spears', 'Britney'] +--- +- ['Spears', 'Britney'] +... delete from t0 where k0='Spears' -Delete OK, 1 row affected +--- +- ['Spears', 'Britney'] +... insert into t0 values (1, 'duplicate one') -Insert OK, 1 row affected +--- +- ['\x01\x00\x00\x00', 'duplicate one'] +... insert into t0 values (2, 'duplicate one') -Insert OK, 1 row affected +--- +- ['\x02\x00\x00\x00', 'duplicate one'] +... insert into t0 values (3, 'duplicate one') -Insert OK, 1 row affected +--- +- ['\x03\x00\x00\x00', 'duplicate one'] +... insert into t0 values (4, 'duplicate one') -Insert OK, 1 row affected +--- +- ['\x04\x00\x00\x00', 'duplicate one'] +... insert into t0 values (5, 'duplicate one') -Insert OK, 1 row affected +--- +- ['\x05\x00\x00\x00', 'duplicate one'] +... insert into t0 values (6, 'duplicate two') -Insert OK, 1 row affected +--- +- ['\x06\x00\x00\x00', 'duplicate two'] +... insert into t0 values (7, 'duplicate two') -Insert OK, 1 row affected +--- +- ['\x07\x00\x00\x00', 'duplicate two'] +... insert into t0 values (8, 'duplicate two') -Insert OK, 1 row affected +--- +- ['\x08\x00\x00\x00', 'duplicate two'] +... insert into t0 values (9, 'duplicate two') -Insert OK, 1 row affected +--- +- ['\t\x00\x00\x00', 'duplicate two'] +... insert into t0 values (10, 'duplicate two') -Insert OK, 1 row affected +--- +- ['\n\x00\x00\x00', 'duplicate two'] +... insert into t0 values (11, 'duplicate three') -Insert OK, 1 row affected +--- +- ['\x0b\x00\x00\x00', 'duplicate three'] +... insert into t0 values (12, 'duplicate three') -Insert OK, 1 row affected +--- +- ['\x0c\x00\x00\x00', 'duplicate three'] +... insert into t0 values (13, 'duplicate three') -Insert OK, 1 row affected +--- +- ['\r\x00\x00\x00', 'duplicate three'] +... insert into t0 values (14, 'duplicate three') -Insert OK, 1 row affected +--- +- ['\x0e\x00\x00\x00', 'duplicate three'] +... insert into t0 values (15, 'duplicate three') -Insert OK, 1 row affected +--- +- ['\x0f\x00\x00\x00', 'duplicate three'] +... select * from t0 where k1='duplicate one' -Found 5 tuples: -[1, 'duplicate one'] -[2, 'duplicate one'] -[3, 'duplicate one'] -[4, 'duplicate one'] -[5, 'duplicate one'] +--- +- ['\x01\x00\x00\x00', 'duplicate one'] +- ['\x02\x00\x00\x00', 'duplicate one'] +- ['\x03\x00\x00\x00', 'duplicate one'] +- ['\x04\x00\x00\x00', 'duplicate one'] +- ['\x05\x00\x00\x00', 'duplicate one'] +... select * from t0 where k1='duplicate two' -Found 5 tuples: -[10, 'duplicate two'] -[6, 'duplicate two'] -[7, 'duplicate two'] -[8, 'duplicate two'] -[9, 'duplicate two'] +--- +- ['\x06\x00\x00\x00', 'duplicate two'] +- ['\x07\x00\x00\x00', 'duplicate two'] +- ['\x08\x00\x00\x00', 'duplicate two'] +- ['\t\x00\x00\x00', 'duplicate two'] +- ['\n\x00\x00\x00', 'duplicate two'] +... select * from t0 where k1='duplicate three' -Found 5 tuples: -[11, 'duplicate three'] -[12, 'duplicate three'] -[13, 'duplicate three'] -[14, 'duplicate three'] -[15, 'duplicate three'] +--- +- ['\x0b\x00\x00\x00', 'duplicate three'] +- ['\x0c\x00\x00\x00', 'duplicate three'] +- ['\r\x00\x00\x00', 'duplicate three'] +- ['\x0e\x00\x00\x00', 'duplicate three'] +- ['\x0f\x00\x00\x00', 'duplicate three'] +... delete from t0 where k0=1 -Delete OK, 1 row affected +--- +- ['\x01\x00\x00\x00', 'duplicate one'] +... delete from t0 where k0=2 -Delete OK, 1 row affected +--- +- ['\x02\x00\x00\x00', 'duplicate one'] +... delete from t0 where k0=3 -Delete OK, 1 row affected +--- +- ['\x03\x00\x00\x00', 'duplicate one'] +... delete from t0 where k0=4 -Delete OK, 1 row affected +--- +- ['\x04\x00\x00\x00', 'duplicate one'] +... delete from t0 where k0=5 -Delete OK, 1 row affected +--- +- ['\x05\x00\x00\x00', 'duplicate one'] +... delete from t0 where k0=6 -Delete OK, 1 row affected +--- +- ['\x06\x00\x00\x00', 'duplicate two'] +... delete from t0 where k0=7 -Delete OK, 1 row affected +--- +- ['\x07\x00\x00\x00', 'duplicate two'] +... delete from t0 where k0=8 -Delete OK, 1 row affected +--- +- ['\x08\x00\x00\x00', 'duplicate two'] +... delete from t0 where k0=9 -Delete OK, 1 row affected +--- +- ['\t\x00\x00\x00', 'duplicate two'] +... delete from t0 where k0=10 -Delete OK, 1 row affected +--- +- ['\n\x00\x00\x00', 'duplicate two'] +... delete from t0 where k0=11 -Delete OK, 1 row affected +--- +- ['\x0b\x00\x00\x00', 'duplicate three'] +... delete from t0 where k0=12 -Delete OK, 1 row affected +--- +- ['\x0c\x00\x00\x00', 'duplicate three'] +... delete from t0 where k0=13 -Delete OK, 1 row affected +--- +- ['\r\x00\x00\x00', 'duplicate three'] +... delete from t0 where k0=14 -Delete OK, 1 row affected +--- +- ['\x0e\x00\x00\x00', 'duplicate three'] +... delete from t0 where k0=15 -Delete OK, 1 row affected +--- +- ['\x0f\x00\x00\x00', 'duplicate three'] +... insert into t0 values(1, 'Aardvark ') -Insert OK, 1 row affected +--- +- ['\x01\x00\x00\x00', 'Aardvark '] +... insert into t0 values(2, 'Bilimbi') -Insert OK, 1 row affected +--- +- ['\x02\x00\x00\x00', 'Bilimbi'] +... insert into t0 values(3, 'Creature ') -Insert OK, 1 row affected +--- +- ['\x03\x00\x00\x00', 'Creature '] +... box.space[0]:select(1) --- - [1, 'Aardvark '] @@ -403,11 +580,17 @@ box.space[0].index[1].idx:max() - [3, 'Creature '] ... delete from t0 where k0=1 -Delete OK, 1 row affected +--- +- ['\x01\x00\x00\x00', 'Aardvark '] +... delete from t0 where k0=2 -Delete OK, 1 row affected +--- +- ['\x02\x00\x00\x00', 'Bilimbi'] +... delete from t0 where k0=3 -Delete OK, 1 row affected +--- +- ['\x03\x00\x00\x00', 'Creature '] +... box.space[0]:drop() --- ... diff --git a/test/big/sql.test.py b/test/big/sql.test.py index fbc91a1b264f43096cf0e7c047612567af011c31..54f2797d9c41bd12a93124398f9d3aac0fe9faa8 100644 --- a/test/big/sql.test.py +++ b/test/big/sql.test.py @@ -1,5 +1,3 @@ -# encoding: utf-8 -# sql.sort = True # @@ -203,4 +201,3 @@ sql("delete from t0 where k0=3") admin("box.space[0]:drop()") sql.sort = False -# vim: syntax=python diff --git a/test/big/tree_pk_multipart.result b/test/big/tree_pk_multipart.result index f20e075cbcd82a2f227f65751dca68c40d96f8c2..b0c884a9dcb0b26a8eb445d38b389865b7278970 100644 --- a/test/big/tree_pk_multipart.result +++ b/test/big/tree_pk_multipart.result @@ -439,11 +439,11 @@ space = box.space[0] ... space:insert(1, 1) --- -- error: Illegal parameters, tuple must have all indexed fields +- error: Tuple field count 2 is less than required by a defined index (expected 3) ... space:replace_if_exists(1, 1) --- -- error: Illegal parameters, tuple must have all indexed fields +- error: Tuple field count 2 is less than required by a defined index (expected 3) ... space:drop() --- diff --git a/test/big/tree_variants.result b/test/big/tree_variants.result index 8f1e70ef319edc0c9186d74cbf18029d459ab1c3..01f2af4627b0f03ded056cdf099a71e2b5a4c790 100644 --- a/test/big/tree_variants.result +++ b/test/big/tree_variants.result @@ -81,35 +81,27 @@ space:select(1,'00000002') --- - [2, 3616443484303536176, 3472330495250935856, 'Joe', 'Sixpack', 'Drinks', 'Carlsberg', 'bar', 2002] ... -{space:select(2,'00000300')} +space:select(2,'00000300') --- -- - [3, 3688501078341464112, 3472331594762563632, 'Joe', 'Sixpack', 'Drinks', 'Corona Extra', 'bar', 2003] - - [4, 3760558672379392048, 3472331594762563632, 'Joe', 'Sixpack', 'Drinks', 'Stella Artois', 'bar', 2004] - - [5, 3832616266417319984, 3472331594762563632, 'Joe', 'Sixpack', 'Drinks', 'Miller Genuine Draft', 'bar', 2005] +- [3, 3688501078341464112, 3472331594762563632, 'Joe', 'Sixpack', 'Drinks', 'Corona Extra', 'bar', 2003] +- [4, 3760558672379392048, 3472331594762563632, 'Joe', 'Sixpack', 'Drinks', 'Stella Artois', 'bar', 2004] +- [5, 3832616266417319984, 3472331594762563632, 'Joe', 'Sixpack', 'Drinks', 'Miller Genuine Draft', 'bar', 2005] ... -{space:select(3, 'Joe', 'Sixpack')} +#{space:select(3, 'Joe', 'Sixpack')} --- -- - [0, 3472328296227680304, 3472329395739308080, 'Joe', 'Sixpack', 'Drinks', 'Amstel', 'bar', 2000] - - [1, 3544385890265608240, 3472330495250935856, 'Joe', 'Sixpack', 'Drinks', 7954882400208119112, 'bar', 2001] - - [2, 3616443484303536176, 3472330495250935856, 'Joe', 'Sixpack', 'Drinks', 'Carlsberg', 'bar', 2002] - - [3, 3688501078341464112, 3472331594762563632, 'Joe', 'Sixpack', 'Drinks', 'Corona Extra', 'bar', 2003] - - [4, 3760558672379392048, 3472331594762563632, 'Joe', 'Sixpack', 'Drinks', 'Stella Artois', 'bar', 2004] - - [5, 3832616266417319984, 3472331594762563632, 'Joe', 'Sixpack', 'Drinks', 'Miller Genuine Draft', 'bar', 2005] +- 6 ... -{space:select(3, 'John')} +#{space:select(3, 'John')} --- -- - [6, 3904673860455247920, 3472332694274191408, 1852337994, 'Smoker', 1937008968, 'A Pipe', 'foo', 2006] - - [7, 3976731454493175856, 3472332694274191408, 1852337994, 'Smoker', 1937008968, 'A Bong', 'foo', 2007] - - [8, 4048789048531103792, 3472332694274191408, 1852337994, 'Smoker', 'Rolls', 'A Joint', 'foo', 2008] - - [9, 4120846642569031728, 3472332694274191408, 1852337994, 'Smoker', 'Rolls', 'A Blunt', 'foo', 2009] +- 4 ... -{space:select(4, 'A Pipe')} +#{space:select(4, 'A Pipe')} --- -- - [6, 3904673860455247920, 3472332694274191408, 1852337994, 'Smoker', 1937008968, 'A Pipe', 'foo', 2006] +- 1 ... -{space:select(4, 'Miller Genuine Draft', 'Drinks')} +space:select(4, 'Miller Genuine Draft', 'Drinks') --- -- - [5, 3832616266417319984, 3472331594762563632, 'Joe', 'Sixpack', 'Drinks', 'Miller Genuine Draft', 'bar', 2005] +- [5, 3832616266417319984, 3472331594762563632, 'Joe', 'Sixpack', 'Drinks', 'Miller Genuine Draft', 'bar', 2005] ... space:select(5, 2007) --- diff --git a/test/big/tree_variants.test.lua b/test/big/tree_variants.test.lua index 357dbcb8b11c0e8ef5da35180b50009a16db32cc..84d01cd9b7060649bc432732877e3045dde8ce94 100644 --- a/test/big/tree_variants.test.lua +++ b/test/big/tree_variants.test.lua @@ -22,11 +22,11 @@ space:insert(9, '00000009', '00000400', 'John', 'Smoker', 'Rolls', 'A Blunt', 'f space:select(0, 1) space:select(1,'00000002') -{space:select(2,'00000300')} -{space:select(3, 'Joe', 'Sixpack')} -{space:select(3, 'John')} -{space:select(4, 'A Pipe')} -{space:select(4, 'Miller Genuine Draft', 'Drinks')} +space:select(2,'00000300') +#{space:select(3, 'Joe', 'Sixpack')} +#{space:select(3, 'John')} +#{space:select(4, 'A Pipe')} +space:select(4, 'Miller Genuine Draft', 'Drinks') space:select(5, 2007) space:select(6, 'Miller Genuine Draft', 'Drinks') diff --git a/test/box/admin.result b/test/box/admin.result index 6e1976193f498a897c8cbb4d022ef8f5cf002586..09d7e3ce4510c7d77c99e728d97f855cd4194e07 100644 --- a/test/box/admin.result +++ b/test/box/admin.result @@ -1,3 +1,5 @@ +--# stop server default +--# start server default space = box.schema.create_space('tweedledum', { id = 0 }) --- ... @@ -91,32 +93,180 @@ box.stat() total: 0 rps: 0 ... -insert into t0 values (1, 'tuple') -Insert OK, 1 row affected +box.insert(0, 1, 'tuple') +--- +- [1, 'tuple'] +... box.snapshot() --- - ok ... -delete from t0 where k0 = 1 -Delete OK, 1 row affected -box.info() ---- -- version: 1.minor.patch-<rev>-<commit> - status: primary - pid: <pid> - lsn: 5 - snapshot_pid: <pid> - recovery_last_update: 0 - recovery_lag: 0 - uptime: <uptime> - build: - flags: <flags> - target: <target> - compiler: <compiler> - options: <options> - logger_pid: <pid> - config: tarantool.cfg -... -space:drop() +box.delete(0, 1) +--- +- [1, 'tuple'] +... +--# setopt delimiter ';' +function check_type(arg, typeof) + return type(arg) == typeof +end; +--- +... +function test_box_info() + local tmp = box.info() + local num = {'pid', 'snapshot_pid', 'recovery_last_update', 'recovery_lag', 'uptime', 'logger_pid'} + local buildstr = {'flags', 'target', 'compiler', 'options'} + local str = {'version', 'status', 'config'} + local failed = {} + if check_type(tmp.lsn, 'cdata') == false then + table.insert(failed1, 'box.info().lsn') + else + tmp.lsn = nil + end + for k, v in ipairs(num) do + if check_type(tmp[v], 'number') == false then + table.insert(failed, 'box.info().'..v) + else + tmp[v] = nil + end + end + for k, v in ipairs(str) do + if check_type(tmp[v], 'string') == false then + table.insert(failed, 'box.info().'..v) + else + tmp[v] = nil + end + end + if type(tmp.build) == 'table' then + for k, v in ipairs(buildstr) do + if check_type(tmp.build[v], 'string') == false then + table.insert(failed, 'box.info().build.'..v) + else + tmp.build[v] = nil + end + end + if #tmp.build == 0 then + tmp.build = nil + end + else + table.insert(failed, 'box.info().build failed') + end + if #tmp > 0 or #failed > 0 then + return 'box.info() is not ok.', 'failed: ', failed, tmp + else + return 'box.info() is ok.' + end +end; +--- +... +function test_slab(tbl) + local num = {'items', 'bytes_used', 'item_size', 'slabs', 'bytes_free'} + local failed = {} + for k, v in ipairs(num) do + if check_type(tmp[v], 'number') == false then + table.insert(failed, 'box.slab.info().<slab_size>.'..v) + else + tmp[v] = nil + end + end + if #tbl > 0 or #failed > 0 then + return false, failed + else + return true, {} + end +end; +--- +... +function test_box_slab_info() + local tmp = box.slab.info() + local cdata = {'arena_size', 'arena_used'} + local failed = {} + if type(tmp.slabs) == 'table' then + for name, tbl in ipairs(tmp.slabs) do + local bl, fld = test_slab(tbl) + if bl == true then + tmp[name] = nil + else + for k, v in ipairs(fld) do + table.append(failed, v) + end + end + end + else + table.append(failed, 'box.slab.info().slabs is not ok') + end + if #tmp.slabs == 0 then + tmp.slabs = nil + end + for k, v in ipairs(cdata) do + if check_type(tmp[v], 'cdata') == false then + table.insert(failed, 'box.slab.info().'..v) + else + tmp[v] = nil + end + end + if #tmp > 0 or #failed > 0 then + return "box.slab.info() is not ok", tmp, failed + else + return "box.slab.info() is ok" + end +end; +--- +... +function test_fiber(tbl) + local num = {'fid', 'csw'} + for k, v in ipairs(num) do + if check_type(tmp[v], 'number') == false then + table.insert(failed, 'box.fiber.info().<fiber_name>.'..v) + else + tmp[v] = nil + end + end + if type(tbl.backtrace) == 'table' and #tbl.backtrace > 0 then + tbl.backtrace = nil + else + table.append(failed, 'backtrace') + end + if #tbl > 0 or #failed > 0 then + return false, failed + else + return true, {} + end +end; +--- +... +function test_box_fiber_info() + local tmp = box.fiber.info() + local failed = {} + for name, tbl in ipairs(tmp) do + local bl, fld = test_fiber(tbl) + if bl == true then + tmp[name] = nil + else + for k, v in ipairs(fld) do + table.append(failed, v) + end + end + end + if #tmp > 0 or #failed > 0 then + return "box.fiber.info is not ok. failed: ", tmp, failed + else + return "box.fiber.info() is ok" + end +end; +--- +... +test_box_info(); +--- +- box.info() is ok. +... +test_box_slab_info(); +--- +- box.slab.info() is ok +... +test_box_fiber_info(); +--- +- box.fiber.info() is ok +... +box.space[0]:drop(); --- ... diff --git a/test/box/admin.test.lua b/test/box/admin.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..2ab841d1aca90874bb72c348160351083e4acd60 --- /dev/null +++ b/test/box/admin.test.lua @@ -0,0 +1,162 @@ +--# stop server default +--# start server default + +space = box.schema.create_space('tweedledum', { id = 0 }) +space:create_index('primary', 'hash', { parts = { 0, 'num' }}) + +box.stat() +help() +box.cfg() +box.stat() +box.insert(0, 1, 'tuple') +box.snapshot() +box.delete(0, 1) + +--# setopt delimiter ';' +function check_type(arg, typeof) + return type(arg) == typeof +end; + +function test_box_info() + local tmp = box.info() + local num = {'pid', 'snapshot_pid', 'recovery_last_update', 'recovery_lag', 'uptime', 'logger_pid'} + local buildstr = {'flags', 'target', 'compiler', 'options'} + local str = {'version', 'status', 'config'} + local failed = {} + if check_type(tmp.lsn, 'cdata') == false then + table.insert(failed1, 'box.info().lsn') + else + tmp.lsn = nil + end + for k, v in ipairs(num) do + if check_type(tmp[v], 'number') == false then + table.insert(failed, 'box.info().'..v) + else + tmp[v] = nil + end + end + for k, v in ipairs(str) do + if check_type(tmp[v], 'string') == false then + table.insert(failed, 'box.info().'..v) + else + tmp[v] = nil + end + end + if type(tmp.build) == 'table' then + for k, v in ipairs(buildstr) do + if check_type(tmp.build[v], 'string') == false then + table.insert(failed, 'box.info().build.'..v) + else + tmp.build[v] = nil + end + end + if #tmp.build == 0 then + tmp.build = nil + end + else + table.insert(failed, 'box.info().build failed') + end + if #tmp > 0 or #failed > 0 then + return 'box.info() is not ok.', 'failed: ', failed, tmp + else + return 'box.info() is ok.' + end +end; + +function test_slab(tbl) + local num = {'items', 'bytes_used', 'item_size', 'slabs', 'bytes_free'} + local failed = {} + for k, v in ipairs(num) do + if check_type(tmp[v], 'number') == false then + table.insert(failed, 'box.slab.info().<slab_size>.'..v) + else + tmp[v] = nil + end + end + if #tbl > 0 or #failed > 0 then + return false, failed + else + return true, {} + end +end; + +function test_box_slab_info() + local tmp = box.slab.info() + local cdata = {'arena_size', 'arena_used'} + local failed = {} + if type(tmp.slabs) == 'table' then + for name, tbl in ipairs(tmp.slabs) do + local bl, fld = test_slab(tbl) + if bl == true then + tmp[name] = nil + else + for k, v in ipairs(fld) do + table.append(failed, v) + end + end + end + else + table.append(failed, 'box.slab.info().slabs is not ok') + end + if #tmp.slabs == 0 then + tmp.slabs = nil + end + for k, v in ipairs(cdata) do + if check_type(tmp[v], 'cdata') == false then + table.insert(failed, 'box.slab.info().'..v) + else + tmp[v] = nil + end + end + if #tmp > 0 or #failed > 0 then + return "box.slab.info() is not ok", tmp, failed + else + return "box.slab.info() is ok" + end +end; + +function test_fiber(tbl) + local num = {'fid', 'csw'} + for k, v in ipairs(num) do + if check_type(tmp[v], 'number') == false then + table.insert(failed, 'box.fiber.info().<fiber_name>.'..v) + else + tmp[v] = nil + end + end + if type(tbl.backtrace) == 'table' and #tbl.backtrace > 0 then + tbl.backtrace = nil + else + table.append(failed, 'backtrace') + end + if #tbl > 0 or #failed > 0 then + return false, failed + else + return true, {} + end +end; + +function test_box_fiber_info() + local tmp = box.fiber.info() + local failed = {} + for name, tbl in ipairs(tmp) do + local bl, fld = test_fiber(tbl) + if bl == true then + tmp[name] = nil + else + for k, v in ipairs(fld) do + table.append(failed, v) + end + end + end + if #tmp > 0 or #failed > 0 then + return "box.fiber.info is not ok. failed: ", tmp, failed + else + return "box.fiber.info() is ok" + end +end; + +test_box_info(); +test_box_slab_info(); +test_box_fiber_info(); +box.space[0]:drop(); diff --git a/test/box/admin.test.py b/test/box/admin.test.py deleted file mode 100644 index f439a53dedb1bfc4de31343ddaad306d062e2b5e..0000000000000000000000000000000000000000 --- a/test/box/admin.test.py +++ /dev/null @@ -1,38 +0,0 @@ -import sys - -# clear statistics: -server.stop() -server.deploy() - -admin("space = box.schema.create_space('tweedledum', { id = 0 })") -admin("space:create_index('primary', 'hash', { parts = { 0, 'num' }})") - -admin("box.stat()") -admin("help()") -sys.stdout.push_filter("'function: .*", "function_ptr") -admin("box.cfg()") -sys.stdout.clear_all_filters() -admin("box.stat()") -sql("insert into t0 values (1, 'tuple')") -admin("box.snapshot()") -sql("delete from t0 where k0 = 1") -sys.stdout.push_filter("(\d)\.\d\.\d(-\d+-\w+)?", "\\1.minor.patch-<rev>-<commit>") -sys.stdout.push_filter("pid: \d+", "pid: <pid>") -sys.stdout.push_filter("logger_pid: \d+", "pid: <pid>") -sys.stdout.push_filter("uptime: \d+", "uptime: <uptime>") -sys.stdout.push_filter("flags: .*", "flags: <flags>") -sys.stdout.push_filter("build: .*", "build: <build>") -sys.stdout.push_filter("options: .*", "options: <options>") -sys.stdout.push_filter("target: .*", "target: <target>") -sys.stdout.push_filter("compiler: .*", "compiler: <compiler>") -sys.stdout.push_filter("^ [^:]+$", "") -sys.stdout.push_filter("(/\S+)+/tarantool", "tarantool") -admin("box.info()") -sys.stdout.clear_all_filters() -sys.stdout.push_filter(".*", "") -admin("box.fiber.info()") -admin("box.slab.info()") - -sys.stdout.clear_all_filters() - -admin("space:drop()") diff --git a/test/box/alter_limits.result b/test/box/alter_limits.result index 0d958152857e473625e986c6e107cfc23e9cae98..6dbc6c985477625730dbf5846e629d209b3fb008 100644 --- a/test/box/alter_limits.result +++ b/test/box/alter_limits.result @@ -133,7 +133,7 @@ s:select(0) ... s:select_range(0, 0, 0) --- -- error: '[string "-- schema.lua (internal file)..."]:174: attempt to index a nil +- error: '[string "-- schema.lua (internal file)..."]:208: attempt to index a nil value' ... s:delete(0) @@ -266,7 +266,7 @@ box.space['_space']:update(s.n, "=p", 1, 1) -- remove arity - ok box.space['_space']:update(s.n, "=p", 1, 0) --- -- [512, 0, 1953719668] +- [512, 0, 1953719668, ''] ... s:select(0) --- @@ -286,7 +286,7 @@ s:select(0) -- set arity of an empty space box.space['_space']:update(s.n, "=p", 1, 3) --- -- [512, 3, 1953719668] +- [512, 3, 1953719668, ''] ... s:select(0) --- @@ -504,67 +504,696 @@ s:drop() --- ... -- index name, name manipulation --- box.schema.create_space(string.rep('t', box.schema.NAME_MAX)..'_') --- s = box.schema.create_space(string.rep('t', box.schema.NAME_MAX - 1)..'_') --- s.name --- s:drop() --- s = box.schema.create_space(string.rep('t', box.schema.NAME_MAX - 2)..'_') +s = box.schema.create_space('test') +--- +... +s:create_index('primary', 'hash') +--- +... +-- space cache is updated correctly +s.index[0].name +--- +- primary +... +s.index[0].id +--- +- 0 +... +s.index[0].type +--- +- HASH +... +s.index['primary'].name +--- +- primary +... +s.index['primary'].id +--- +- 0 +... +s.index['primary'].type +--- +- HASH +... +s.index.primary.name +--- +- primary +... +s.index.primary.id +--- +- 0 +... +-- other properties are preserved +s.index.primary.type +--- +- HASH +... +s.index.primary.unique +--- +- true +... +s.index.primary:rename('new') +--- +... +s.index[0].name +--- +- new +... +s.index.primary +--- +- null +... +s.index.new.name +--- +- new +... +-- too long name +s.index[0]:rename(string.rep('t', box.schema.NAME_MAX)..'_') +--- +- error: 'Can''t create or modify index 0 in space 512: index name is too long' +... +s.index[0].name +--- +- new +... +s.index[0]:rename(string.rep('t', box.schema.NAME_MAX - 1)..'_') +--- +... +s.index[0].name +--- +- ttttttttttttttttttttttttttttttt_ +... +s.index[0]:rename(string.rep('t', box.schema.NAME_MAX - 2)..'_') +--- +... +s.index[0].name +--- +- tttttttttttttttttttttttttttttt_ +... +s.index[0]:rename('primary') +--- +... +s.index.primary.name +--- +- primary +... +-- cleanup +s:drop() +--- +... -- modify index --- ------------ --- - alter unique -> non unique --- - alter index type --- - add identical index - verify there is no rebuild --- - index access by name --- - alter add key part --- - rename index --- --- build index --- ----------- --- - index rebuild: --- - a duplicate in the new index --- - no field for the new index --- - wrong field type in the new index --- --- space cache --- ----------- --- - all the various kinds of reference to a dropped space --- - iterator to index --- index to space --- space to index --- variable --- key def --- all userdata given away to lua - think how --- --- --- -- inject error at various stages of commit and see that --- the alter has no effects --- - test that during commit phase --- -> inject error at commit, inject error at rollback +s = box.schema.create_space('test') +--- +... +s:create_index('primary', 'hash') +--- +... +s.index.primary:alter({unique=false}) +--- +- error: 'Can''t create or modify index 0 in space 512: primary key must be unique' +... +-- unique -> non-unique, index type +s.index.primary:alter({type='tree', unique=false, name='pk'}) +--- +- error: 'Can''t create or modify index 0 in space 512: primary key must be unique' +... +s.index.primary +--- +- unique: true + idx: index 0 + n: 512 + type: HASH + key_field: + 0: + type: NUM + fieldno: 0 + name: primary + id: 0 +... +s.index.pk.type +--- +- error: '[string "return s.index.pk.type"]:1: attempt to index field ''pk'' (a nil + value)' +... +s.index.pk.unique +--- +- error: '[string "return s.index.pk.unique"]:1: attempt to index field ''pk'' (a + nil value)' +... +s.index.pk:rename('primary') +--- +- error: '[string "return s.index.pk:rename(''primary'')"]:1: attempt to index field + ''pk'' (a nil value)' +... +s:create_index('second', 'tree', { parts = { 1, 'str' } }) +--- +... +s.index.second.id +--- +- 1 +... +s:create_index('third', 'hash', { parts = { 2, 'num64' } }) +--- +... +s.index.third:rename('second') +--- +- error: Duplicate key exists in unique index 1 +... +s.index.third.id +--- +- 2 +... +s.index.second:drop() +--- +... +s.index.third:alter({id = 1, name = 'second'}) +--- +... +s.index.third +--- +- null +... +s.index.second.name +--- +- second +... +s.index.second.id +--- +- 1 +... +s:drop() +--- +... +-- ---------------------------------------------------------------- +-- BUILD INDEX: changes of a non-empty index +-- ---------------------------------------------------------------- +s = box.schema.create_space('full') +--- +... +s:create_index('primary', 'tree', {parts = { 0, 'str' }}) +--- +... +s:insert('No such movie', 999) +--- +- ['No such movie', 999] +... +s:insert('Barbara', 2012) +--- +- ['Barbara', 2012] +... +s:insert('Cloud Atlas', 2012) +--- +- ['Cloud Atlas', 2012] +... +s:insert('Almanya - Willkommen in Deutschland', 2011) +--- +- ['Almanya - Willkommen in Deutschland', 2011] +... +s:insert('Halt auf freier Strecke', 2011) +--- +- ['Halt auf freier Strecke', 2011] +... +s:insert('Homevideo', 2011) +--- +- ['Homevideo', 2011] +... +s:insert('Die Fremde', 2010) +--- +- ['Die Fremde', 2010] +... +-- create index with data +s:create_index('year', 'tree', { unique=false, parts = { 1, 'num'} }) +--- +... +s.index.primary:select() +--- +- ['Almanya - Willkommen in Deutschland', 2011] +- ['Barbara', 2012] +- ['Cloud Atlas', 2012] +- ['Die Fremde', 2010] +- ['Halt auf freier Strecke', 2011] +- ['Homevideo', 2011] +- ['No such movie', 999] +... +-- a duplicate in the created index +s:create_index('nodups', 'tree', { unique=true, parts = { 1, 'num'} }) +--- +- error: Duplicate key exists in unique index 2 +... +-- change of non-unique index to unique: same effect +s.index.year:alter({unique=true}) +--- +- error: Duplicate key exists in unique index 1 +... +-- num -> str -> num transition +box.space['_index']:update({s.n, s.index.year.id}, "=p", 7, 'str') +--- +- [512, 1, 1918985593, 1701147252, 0, 1, 1, 'str'] +... +s.index.primary:select() +--- +- ['Almanya - Willkommen in Deutschland', 2011] +- ['Barbara', 2012] +- ['Cloud Atlas', 2012] +- ['Die Fremde', 2010] +- ['Halt auf freier Strecke', 2011] +- ['Homevideo', 2011] +- ['No such movie', 999] +... +box.space['_index']:update({s.n, s.index.year.id}, "=p", 7, 'num') +--- +- [512, 1, 1918985593, 1701147252, 0, 1, 1, 'num'] +... +-- ambiguous field type +s:create_index('str', 'tree', {unique = false, parts = { 1, 'str'}}) +--- +- error: Ambiguous field type in index 2, key part 0. Requested type is STR but the + field has previously been defined as NUM +... +-- create index on a non-existing field +s:create_index('nosuchfield', 'tree', {unique = true, parts = { 2, 'str'}}) +--- +- error: Tuple field count 2 is less than required by a defined index (expected 3) +... +s.index.year:drop() +--- +... +s:insert('Der Baader Meinhof Komplex', '2009 ') +--- +- ['Der Baader Meinhof Komplex', '2009 '] +... +-- create an index on a field with a wrong type +s:create_index('year', 'tree', {unique = false, parts = { 1, 'num'}}) +--- +- error: 'Tuple field 1 type does not match one required by operation: expected NUM' +... +-- a field is missing +s:replace('Der Baader Meinhof Komplex') +--- +- ['Der Baader Meinhof Komplex'] +... +s:create_index('year', 'tree', {unique = false, parts = { 1, 'num'}}) +--- +- error: Tuple field count 1 is less than required by a defined index (expected 2) +... +s:drop() +--- +... +-- unique -> non-unique transition +s = box.schema.create_space('test') +--- +... +-- primary key must be unique +s:create_index('primary', 'tree', { unique = false, parts = {0, 'num'}}) +--- +- error: 'Can''t create or modify index 0 in space 512: primary key must be unique' +... +-- create primary key +s:create_index('primary', 'hash', { unique = true, parts = {0, 'num'}}) +--- +... +s:insert(1, 1) +--- +- [1, 1] +... +s:create_index('secondary', 'tree', { unique = false, parts = {1, 'num'}}) +--- +... +s:insert(2, 1) +--- +- [2, 1] +... +s.index.secondary:alter({ unique = true }) +--- +- error: Duplicate key exists in unique index 1 +... +s:delete(2) +--- +- [2, 1] +... +s.index.secondary:alter({ unique = true }) +--- +... +s:insert(2, 1) +--- +- error: Duplicate key exists in unique index 1 +... +s:insert(2, 2) +--- +- [2, 2] +... +s.index.secondary:alter({ unique = false}) +--- +... +s:insert(3, 2) +--- +- [3, 2] +... +s:drop() +--- +... +-- ---------------------------------------------------------------- +-- SPACE CACHE: what happens to a space cache when an object is gone +-- ---------------------------------------------------------------- +s = box.schema.create_space('test') +--- +... +s1 = s +--- +... +s:create_index('primary', 'tree') +--- +... +s1.index.primary.id +--- +- 0 +... +primary = s1.index.primary +--- +... +s.index.primary:drop() +--- +... +primary.id +--- +- 0 +... +primary:select() +--- +- error: 'No index #0 is defined in space 512' +... +s:drop() +--- +... +-- @todo: add a test case for dangling iterator (currently no checks +-- for a dangling iterator in the code +-- ---------------------------------------------------------------- +-- ---------------------------------------------------------------- +-- RECOVERY: check that all indexes are correctly built +-- during recovery regardless of when they are created +-- ---------------------------------------------------------------- +-- primary, secondary keys in a snapshot +s_empty = box.schema.create_space('s_empty') +--- +... +s_empty:create_index('primary', 'tree', {unique = true, parts = {0, 'num'}}) +--- +... +s_empty:create_index('secondary', 'hash', {unique = true, parts = {1, 'num'}}) +--- +... +s_full = box.schema.create_space('s_full') +--- +... +s_full:create_index('primary', 'tree', {unique = true, parts = {0, 'num'}}) +--- +... +s_full:create_index('secondary', 'hash', {unique = true, parts = {1, 'num'}}) +--- +... +s_full:insert(1, 1, 'a') +--- +- [1, 1, 'a'] +... +s_full:insert(2, 2, 'b') +--- +- [2, 2, 'b'] +... +s_full:insert(3, 3, 'c') +--- +- [3, 3, 'c'] +... +s_full:insert(4, 4, 'd') +--- +- [4, 4, 'd'] +... +s_full:insert(5, 5, 'e') +--- +- [5, 5, 'e'] +... +s_nil = box.schema.create_space('s_nil') +--- +... +s_drop = box.schema.create_space('s_drop') +--- +... +box.snapshot() +--- +- ok +... +s_drop:drop() +--- +... +s_nil:create_index('primary', 'hash', {unique=true, parts = {0, 'num'}}) +--- +... +s_nil:insert(1,2,3,4,5,6); +--- +- [1, 2, 3, 4, 5, 6] +... +s_nil:insert(7, 8, 9, 10, 11,12) +--- +- [7, 8, 9, 10, 11, 12] +... +s_nil:create_index('secondary', 'tree', {unique=false, parts = {1, 'num', 2, 'num', 3, 'num'}}) +--- +... +s_nil:insert(13, 14, 15, 16, 17) +--- +- [13, 14, 15, 16, 17] +... +r_empty = box.schema.create_space('r_empty') +--- +... +r_empty:create_index('primary', 'tree', {unique = true, parts = {0, 'num'}}) +--- +... +r_empty:create_index('secondary', 'hash', {unique = true, parts = {1, 'num'}}) +--- +... +r_full = box.schema.create_space('r_full') +--- +... +r_full:create_index('primary', 'tree', {unique = true, parts = {0, 'num'}}) +--- +... +r_full:create_index('secondary', 'hash', {unique = true, parts = {1, 'num'}}) +--- +... +r_full:insert(1, 1, 'a') +--- +- [1, 1, 'a'] +... +r_full:insert(2, 2, 'b') +--- +- [2, 2, 'b'] +... +r_full:insert(3, 3, 'c') +--- +- [3, 3, 'c'] +... +r_full:insert(4, 4, 'd') +--- +- [4, 4, 'd'] +... +r_full:insert(5, 5, 'e') +--- +- [5, 5, 'e'] +... +s_full:create_index('multikey', 'tree', {unique = true, parts = { 1, 'num', 2, 'str'}}) +--- +... +s_full:insert(6, 6, 'f') +--- +- [6, 6, 'f'] +... +s_full:insert(7, 7, 'g') +--- +- [7, 7, 'g'] +... +s_full:insert(8, 8, 'h') +--- +- [8, 8, 'h'] +... +r_disabled = box.schema.create_space('r_disabled') +--- +... +--# stop server default +--# start server default +s_empty = box.space['s_empty'] +--- +... +s_full = box.space['s_full'] +--- +... +s_nil = box.space['s_nil'] +--- +... +s_drop = box.space['s_drop'] +--- +... +r_empty = box.space['r_empty'] +--- +... +r_full = box.space['r_full'] +--- +... +r_disabled = box.space['r_disabled'] +--- +... +s_drop +--- +- null +... +s_empty.index.primary.type +--- +- TREE +... +s_full.index.primary.type +--- +- TREE +... +r_empty.index.primary.type +--- +- TREE +... +r_full.index.primary.type +--- +- TREE +... +s_nil.index.primary.type +--- +- HASH +... +s_empty.index.primary.name +--- +- primary +... +s_full.index.primary.name +--- +- primary +... +r_empty.index.primary.name +--- +- primary +... +r_full.index.primary.name +--- +- primary +... +s_nil.index.primary.name +--- +- primary +... +s_empty.enabled +--- +- true +... +s_full.enabled +--- +- true +... +r_empty.enabled +--- +- true +... +r_full.enabled +--- +- true +... +s_nil.enabled +--- +- true +... +r_disabled.enabled +--- +- false +... +s_empty.index.secondary.name +--- +- secondary +... +s_full.index.secondary.name +--- +- secondary +... +r_empty.index.secondary.name +--- +- secondary +... +r_full.index.secondary.name +--- +- secondary +... +s_nil.index.secondary.name +--- +- secondary +... +s_empty.index.primary:count(1) +--- +- 0 +... +s_full.index.primary:count(1) +--- +- 1 +... +r_empty.index.primary:count(1) +--- +- 0 +... +r_full.index.primary:count(1) +--- +- 1 +... +s_nil.index.primary:count(1) +--- +- 1 +... +s_empty.index.secondary:count(1) +--- +- 0 +... +s_full.index.secondary:count(1) +--- +- 1 +... +r_empty.index.secondary:count(1) +--- +- 0 +... +r_full.index.secondary:count(1) +--- +- 1 +... +s_nil.index.secondary:count(1) +--- +- 0 +... +-- cleanup +s_empty:drop() +--- +... +s_full:drop() +--- +... +r_empty:drop() +--- +... +r_full:drop() +--- +... +s_nil:drop() +--- +... +r_disabled:drop() +--- +... -- --- usability +-- @todo usability -- --------- -- - space name in all error messages! -- error: Duplicate key exists in unique index 1 (ugly) -- --- triggers --- -------- --- - test that after disabling triggers we can --- create an empty snapshot --- - test for run_triggers on/off --- --- recovery --- -------- --- - add primary key in snapshot --- - add secondary key in snapshot --- - add primary key in xlog --- - add secondary key in xlog --- - the same for an empty space and a space with data --- - test start from a space entry added in xlog --- - test start from a space entry dropped in xlog --- - test enabled/disabled property for these --- spaces and space from a snapshot --- --- --- features +-- @todo features -------- -- - ffi function to enable/disable space diff --git a/test/box/alter_limits.test.lua b/test/box/alter_limits.test.lua index d57cfff7a54d914341e9c89447c803a226080fd6..9a3eb57bcd29dfaad659c860b54466d2136d1fae 100644 --- a/test/box/alter_limits.test.lua +++ b/test/box/alter_limits.test.lua @@ -191,68 +191,241 @@ s.index[0]:drop() -- cleanup s:drop() -- index name, name manipulation - --- box.schema.create_space(string.rep('t', box.schema.NAME_MAX)..'_') --- s = box.schema.create_space(string.rep('t', box.schema.NAME_MAX - 1)..'_') --- s.name --- s:drop() --- s = box.schema.create_space(string.rep('t', box.schema.NAME_MAX - 2)..'_') +s = box.schema.create_space('test') +s:create_index('primary', 'hash') +-- space cache is updated correctly +s.index[0].name +s.index[0].id +s.index[0].type +s.index['primary'].name +s.index['primary'].id +s.index['primary'].type +s.index.primary.name +s.index.primary.id +-- other properties are preserved +s.index.primary.type +s.index.primary.unique +s.index.primary:rename('new') +s.index[0].name +s.index.primary +s.index.new.name +-- too long name +s.index[0]:rename(string.rep('t', box.schema.NAME_MAX)..'_') +s.index[0].name +s.index[0]:rename(string.rep('t', box.schema.NAME_MAX - 1)..'_') +s.index[0].name +s.index[0]:rename(string.rep('t', box.schema.NAME_MAX - 2)..'_') +s.index[0].name +s.index[0]:rename('primary') +s.index.primary.name +-- cleanup +s:drop() -- modify index --- ------------ --- - alter unique -> non unique --- - alter index type --- - add identical index - verify there is no rebuild --- - index access by name --- - alter add key part --- - rename index --- --- build index --- ----------- --- - index rebuild: --- - a duplicate in the new index --- - no field for the new index --- - wrong field type in the new index --- --- space cache --- ----------- --- - all the various kinds of reference to a dropped space --- - iterator to index --- index to space --- space to index --- variable --- key def --- all userdata given away to lua - think how --- --- --- -- inject error at various stages of commit and see that --- the alter has no effects --- - test that during commit phase --- -> inject error at commit, inject error at rollback +s = box.schema.create_space('test') +s:create_index('primary', 'hash') +s.index.primary:alter({unique=false}) +-- unique -> non-unique, index type +s.index.primary:alter({type='tree', unique=false, name='pk'}) +s.index.primary +s.index.pk.type +s.index.pk.unique +s.index.pk:rename('primary') +s:create_index('second', 'tree', { parts = { 1, 'str' } }) +s.index.second.id +s:create_index('third', 'hash', { parts = { 2, 'num64' } }) +s.index.third:rename('second') +s.index.third.id +s.index.second:drop() +s.index.third:alter({id = 1, name = 'second'}) +s.index.third +s.index.second.name +s.index.second.id +s:drop() +-- ---------------------------------------------------------------- +-- BUILD INDEX: changes of a non-empty index +-- ---------------------------------------------------------------- +s = box.schema.create_space('full') +s:create_index('primary', 'tree', {parts = { 0, 'str' }}) +s:insert('No such movie', 999) +s:insert('Barbara', 2012) +s:insert('Cloud Atlas', 2012) +s:insert('Almanya - Willkommen in Deutschland', 2011) +s:insert('Halt auf freier Strecke', 2011) +s:insert('Homevideo', 2011) +s:insert('Die Fremde', 2010) +-- create index with data +s:create_index('year', 'tree', { unique=false, parts = { 1, 'num'} }) +s.index.primary:select() +-- a duplicate in the created index +s:create_index('nodups', 'tree', { unique=true, parts = { 1, 'num'} }) +-- change of non-unique index to unique: same effect +s.index.year:alter({unique=true}) +-- num -> str -> num transition +box.space['_index']:update({s.n, s.index.year.id}, "=p", 7, 'str') +s.index.primary:select() +box.space['_index']:update({s.n, s.index.year.id}, "=p", 7, 'num') +-- ambiguous field type +s:create_index('str', 'tree', {unique = false, parts = { 1, 'str'}}) +-- create index on a non-existing field +s:create_index('nosuchfield', 'tree', {unique = true, parts = { 2, 'str'}}) +s.index.year:drop() +s:insert('Der Baader Meinhof Komplex', '2009 ') +-- create an index on a field with a wrong type +s:create_index('year', 'tree', {unique = false, parts = { 1, 'num'}}) +-- a field is missing +s:replace('Der Baader Meinhof Komplex') +s:create_index('year', 'tree', {unique = false, parts = { 1, 'num'}}) +s:drop() +-- unique -> non-unique transition +s = box.schema.create_space('test') +-- primary key must be unique +s:create_index('primary', 'tree', { unique = false, parts = {0, 'num'}}) +-- create primary key +s:create_index('primary', 'hash', { unique = true, parts = {0, 'num'}}) +s:insert(1, 1) +s:create_index('secondary', 'tree', { unique = false, parts = {1, 'num'}}) +s:insert(2, 1) +s.index.secondary:alter({ unique = true }) +s:delete(2) +s.index.secondary:alter({ unique = true }) +s:insert(2, 1) +s:insert(2, 2) +s.index.secondary:alter({ unique = false}) +s:insert(3, 2) +s:drop() +-- ---------------------------------------------------------------- +-- SPACE CACHE: what happens to a space cache when an object is gone +-- ---------------------------------------------------------------- +s = box.schema.create_space('test') +s1 = s +s:create_index('primary', 'tree') +s1.index.primary.id +primary = s1.index.primary +s.index.primary:drop() +primary.id +primary:select() +s:drop() +-- @todo: add a test case for dangling iterator (currently no checks +-- for a dangling iterator in the code +-- ---------------------------------------------------------------- +-- ---------------------------------------------------------------- +-- RECOVERY: check that all indexes are correctly built +-- during recovery regardless of when they are created +-- ---------------------------------------------------------------- +-- primary, secondary keys in a snapshot +s_empty = box.schema.create_space('s_empty') +s_empty:create_index('primary', 'tree', {unique = true, parts = {0, 'num'}}) +s_empty:create_index('secondary', 'hash', {unique = true, parts = {1, 'num'}}) + +s_full = box.schema.create_space('s_full') +s_full:create_index('primary', 'tree', {unique = true, parts = {0, 'num'}}) +s_full:create_index('secondary', 'hash', {unique = true, parts = {1, 'num'}}) + +s_full:insert(1, 1, 'a') +s_full:insert(2, 2, 'b') +s_full:insert(3, 3, 'c') +s_full:insert(4, 4, 'd') +s_full:insert(5, 5, 'e') + +s_nil = box.schema.create_space('s_nil') + +s_drop = box.schema.create_space('s_drop') + +box.snapshot() + +s_drop:drop() + +s_nil:create_index('primary', 'hash', {unique=true, parts = {0, 'num'}}) +s_nil:insert(1,2,3,4,5,6); +s_nil:insert(7, 8, 9, 10, 11,12) +s_nil:create_index('secondary', 'tree', {unique=false, parts = {1, 'num', 2, 'num', 3, 'num'}}) +s_nil:insert(13, 14, 15, 16, 17) + +r_empty = box.schema.create_space('r_empty') +r_empty:create_index('primary', 'tree', {unique = true, parts = {0, 'num'}}) +r_empty:create_index('secondary', 'hash', {unique = true, parts = {1, 'num'}}) + +r_full = box.schema.create_space('r_full') +r_full:create_index('primary', 'tree', {unique = true, parts = {0, 'num'}}) +r_full:create_index('secondary', 'hash', {unique = true, parts = {1, 'num'}}) + +r_full:insert(1, 1, 'a') +r_full:insert(2, 2, 'b') +r_full:insert(3, 3, 'c') +r_full:insert(4, 4, 'd') +r_full:insert(5, 5, 'e') + +s_full:create_index('multikey', 'tree', {unique = true, parts = { 1, 'num', 2, 'str'}}) +s_full:insert(6, 6, 'f') +s_full:insert(7, 7, 'g') +s_full:insert(8, 8, 'h') + +r_disabled = box.schema.create_space('r_disabled') + +--# stop server default +--# start server default + +s_empty = box.space['s_empty'] +s_full = box.space['s_full'] +s_nil = box.space['s_nil'] +s_drop = box.space['s_drop'] +r_empty = box.space['r_empty'] +r_full = box.space['r_full'] +r_disabled = box.space['r_disabled'] + +s_drop + +s_empty.index.primary.type +s_full.index.primary.type +r_empty.index.primary.type +r_full.index.primary.type +s_nil.index.primary.type + +s_empty.index.primary.name +s_full.index.primary.name +r_empty.index.primary.name +r_full.index.primary.name +s_nil.index.primary.name + +s_empty.enabled +s_full.enabled +r_empty.enabled +r_full.enabled +s_nil.enabled +r_disabled.enabled + +s_empty.index.secondary.name +s_full.index.secondary.name +r_empty.index.secondary.name +r_full.index.secondary.name +s_nil.index.secondary.name + +s_empty.index.primary:count(1) +s_full.index.primary:count(1) +r_empty.index.primary:count(1) +r_full.index.primary:count(1) +s_nil.index.primary:count(1) + +s_empty.index.secondary:count(1) +s_full.index.secondary:count(1) +r_empty.index.secondary:count(1) +r_full.index.secondary:count(1) +s_nil.index.secondary:count(1) + +-- cleanup +s_empty:drop() +s_full:drop() +r_empty:drop() +r_full:drop() +s_nil:drop() +r_disabled:drop() + -- --- usability +-- @todo usability -- --------- -- - space name in all error messages! -- error: Duplicate key exists in unique index 1 (ugly) -- --- triggers --- -------- --- - test that after disabling triggers we can --- create an empty snapshot --- - test for run_triggers on/off --- --- recovery --- -------- --- - add primary key in snapshot --- - add secondary key in snapshot --- - add primary key in xlog --- - add secondary key in xlog --- - the same for an empty space and a space with data --- - test start from a space entry added in xlog --- - test start from a space entry dropped in xlog --- - test enabled/disabled property for these --- spaces and space from a snapshot --- --- --- features +-- @todo features -------- -- - ffi function to enable/disable space diff --git a/test/box/bad_trigger.result b/test/box/bad_trigger.result index 2cbea1b12f7dbce2dd4ffdee9918376813c49467..83c63de72c7b07b286edcd34721a9fa72eb11e21 100644 --- a/test/box/bad_trigger.result +++ b/test/box/bad_trigger.result @@ -7,7 +7,13 @@ type(box.session.on_connect(function() nosuchfunction() end)) --- - nil ... -Exception raised +select * from t0 where k0=0 +--- +- error: + errcode: ER_PROC_LUA + errmsg: Lua error: [string "return type(box.session.on_connect(function()..."]:1: attempt to call global 'nosuchfunction' (a nil value) +... +Connection is dead. type(box.session.on_connect(nil)) --- diff --git a/test/box/bad_trigger.test.py b/test/box/bad_trigger.test.py index 3e6f851caed34f9bd7dbb7ed84746b82609ba1c8..d41473330a3ed5ff41e612a9564e2486e13cdda3 100644 --- a/test/box/bad_trigger.test.py +++ b/test/box/bad_trigger.test.py @@ -7,11 +7,10 @@ print """ admin("type(box.session.on_connect(function() nosuchfunction() end))") con1 = BoxConnection('localhost', server.primary_port) -try: - con1.execute("select * from t0 where k0=0") - con1.execute("select * from t0 where k0=0") -except Exception as e: - print "Exception raised\n" - +con1("select * from t0 where k0=0") +if not con1.check_connection(): + print "Connection is dead.\n" +else: + print "Connection is alive.\n" # Clean-up admin("type(box.session.on_connect(nil))") diff --git a/test/box/errinj.result b/test/box/errinj.result index f07602205d87e3873ea381d12d3f93a596b7c54a..b36bbd2b0ef151053542a9d71ef693bfe0e87702 100644 --- a/test/box/errinj.result +++ b/test/box/errinj.result @@ -148,3 +148,138 @@ space:truncate() space:drop() --- ... +-- Check how well we handle a failed log write in DDL +s_disabled = box.schema.create_space('disabled') +--- +... +s_withindex = box.schema.create_space('withindex') +--- +... +s_withindex:create_index('primary', 'hash') +--- +... +s_withdata = box.schema.create_space('withdata') +--- +... +s_withdata:create_index('primary', 'tree') +--- +... +s_withdata:insert(1, 2, 3, 4, 5) +--- +- [1, 2, 3, 4, 5] +... +s_withdata:insert(4, 5, 6, 7, 8) +--- +- [4, 5, 6, 7, 8] +... +s_withdata:create_index('secondary', 'hash', {parts = {1, 'num', 2, 'num' }}) +--- +... +box.errinj.set("ERRINJ_WAL_IO", true) +--- +- ok +... +test = box.schema.create_space('test') +--- +- error: Failed to write to disk +... +s_disabled:create_index('primary', 'hash') +--- +- error: Failed to write to disk +... +s_disabled.enabled +--- +- false +... +s_disabled:insert(0) +--- +- error: 'No index #0 is defined in space 512' +... +s_withindex:create_index('secondary', 'tree', { parts = { 1, 'num'} }) +--- +- error: Failed to write to disk +... +s_withindex.index.secondary +--- +- null +... +s_withdata.index.secondary:drop() +--- +- error: Failed to write to disk +... +s_withdata.index.secondary.unique +--- +- true +... +s_withdata:drop() +--- +- error: Failed to write to disk +... +box.space['withdata'].enabled +--- +- true +... +s_withdata:create_index('another', 'tree', {parts = { 4, 'num' }, unique = false}) +--- +- error: Failed to write to disk +... +s_withdata.index.another +--- +- null +... +box.errinj.set("ERRINJ_WAL_IO", false) +--- +- ok +... +test = box.schema.create_space('test') +--- +... +s_disabled:create_index('primary', 'hash') +--- +... +s_disabled.enabled +--- +- true +... +s_disabled:insert(0) +--- +- [0] +... +s_withindex:create_index('secondary', 'tree', { parts = { 1, 'num'} }) +--- +... +s_withindex.index.secondary.unique +--- +- true +... +s_withdata.index.secondary:drop() +--- +... +s_withdata.index.secondary +--- +- null +... +s_withdata:drop() +--- +... +box.space['withdata'] +--- +- null +... +s_withdata:create_index('another', 'tree', {parts = { 4, 'num' }, unique = false}) +--- +- error: Space 514 does not exist +... +s_withdata.index.another +--- +- null +... +test:drop() +--- +... +s_disabled:drop() +--- +... +s_withindex:drop() +--- +... diff --git a/test/box/errinj.test.lua b/test/box/errinj.test.lua index ba5a1d4f99fdcd7df54a660af37d5e707c011530..dfbf63d33d03b3be360d1fe31dd2bd17705f4a5a 100644 --- a/test/box/errinj.test.lua +++ b/test/box/errinj.test.lua @@ -42,3 +42,42 @@ box.errinj.set("ERRINJ_WAL_ROTATE", false) space:truncate() space:drop() + +-- Check how well we handle a failed log write in DDL +s_disabled = box.schema.create_space('disabled') +s_withindex = box.schema.create_space('withindex') +s_withindex:create_index('primary', 'hash') +s_withdata = box.schema.create_space('withdata') +s_withdata:create_index('primary', 'tree') +s_withdata:insert(1, 2, 3, 4, 5) +s_withdata:insert(4, 5, 6, 7, 8) +s_withdata:create_index('secondary', 'hash', {parts = {1, 'num', 2, 'num' }}) +box.errinj.set("ERRINJ_WAL_IO", true) +test = box.schema.create_space('test') +s_disabled:create_index('primary', 'hash') +s_disabled.enabled +s_disabled:insert(0) +s_withindex:create_index('secondary', 'tree', { parts = { 1, 'num'} }) +s_withindex.index.secondary +s_withdata.index.secondary:drop() +s_withdata.index.secondary.unique +s_withdata:drop() +box.space['withdata'].enabled +s_withdata:create_index('another', 'tree', {parts = { 4, 'num' }, unique = false}) +s_withdata.index.another +box.errinj.set("ERRINJ_WAL_IO", false) +test = box.schema.create_space('test') +s_disabled:create_index('primary', 'hash') +s_disabled.enabled +s_disabled:insert(0) +s_withindex:create_index('secondary', 'tree', { parts = { 1, 'num'} }) +s_withindex.index.secondary.unique +s_withdata.index.secondary:drop() +s_withdata.index.secondary +s_withdata:drop() +box.space['withdata'] +s_withdata:create_index('another', 'tree', {parts = { 4, 'num' }, unique = false}) +s_withdata.index.another +test:drop() +s_disabled:drop() +s_withindex:drop() diff --git a/test/box/fiber.result b/test/box/fiber.result index c50d6a0f6366ffbbfc92ca8bec63f562a0bafde9..5461d492fe5356512643348fddb934f37890e790 100644 --- a/test/box/fiber.result +++ b/test/box/fiber.result @@ -280,3 +280,11 @@ box.fiber.find(920) space:drop() --- ... +box.fiber.find() +--- +- error: 'fiber.find(id): bad arguments' +... +box.fiber.find('test') +--- +- null +... diff --git a/test/box/fiber.test.lua b/test/box/fiber.test.lua index 82d4b99e6f75c48793082aa91ec3a191f62a6b9d..17af822c8bb73e8a0e663f92f8f9e57d01e77219 100644 --- a/test/box/fiber.test.lua +++ b/test/box/fiber.test.lua @@ -97,3 +97,5 @@ box.fiber.find(900) box.fiber.find(910) box.fiber.find(920) space:drop() +box.fiber.find() +box.fiber.find('test') diff --git a/test/box/iproto.result b/test/box/iproto.result index 51f28f5624747a5cb5f8dfbbd2bf4f07d67cf118..a5fcc050ed134579c388c9a2a365ee2f88189ab1 100644 --- a/test/box/iproto.result +++ b/test/box/iproto.result @@ -10,5 +10,6 @@ 12 # check that is server alive ping -ok --- +- ok +... diff --git a/test/box/lua.result b/test/box/lua.result index fc98c621d4cfbe7455675b1fa361ac60435823c4..092c74829019cf4e2675085f0030c614c0c1b5e8 100644 --- a/test/box/lua.result +++ b/test/box/lua.result @@ -208,15 +208,25 @@ box.process(22, box.pack('iii', 0, 0, 0)) - error: box.process(CALL, ...) is not allowed ... call box.process('abc', 'def') -An error occurred: ER_ILLEGAL_PARAMS, 'Illegal parameters, unsupported command code, check the error log' +--- +- error: + errcode: ER_ILLEGAL_PARAMS + errmsg: Illegal parameters, unsupported command code, check the error log +... call box.pack('test') -An error occurred: ER_PROC_LUA, 'Lua error: box.pack: argument count does not match the format' +--- +- error: + errcode: ER_PROC_LUA + errmsg: Lua error: box.pack: argument count does not match the format +... call box.pack('p', 'this string is 45 characters long 1234567890 ') -Found 1 tuple: -['-this string is 45 characters long 1234567890 '] +--- +- ['-this string is 45 characters long 1234567890 '] +... call box.pack('p', 'ascii symbols are visible starting from code 20') -Found 1 tuple: -['/ascii symbols are visible starting from code 20'] +--- +- ['/ascii symbols are visible starting from code 20'] +... function f1() return 'testing', 1, false, -1, 1.123, 1e123, nil end --- ... @@ -231,33 +241,48 @@ f1() - null ... call f1() -Found 7 tuples: -['testing'] -[1] -['false'] -[4294967295] -[1] -['��������'] -['nil'] +--- +- ['testing'] +- ['\x01\x00\x00\x00'] +- ['false'] +- ['\xff\xff\xff\xff'] +- ['\x01\x00\x00\x00'] +- ['\x00\x00\x00\x00\x00\x00\x00\x00'] +- ['nil'] +... f1=nil --- ... call f1() -An error occurred: ER_NO_SUCH_PROC, 'Procedure 'f1' is not defined' +--- +- error: + errcode: ER_NO_SUCH_PROC + errmsg: Procedure 'f1' is not defined +... function f1() return f1 end --- ... call f1() -An error occurred: ER_PROC_RET, 'Return type 'function' is not supported in the binary protocol' +--- +- error: + errcode: ER_PROC_RET + errmsg: Return type 'function' is not supported in the binary protocol +... insert into t0 values (1, 'test box delete') -Insert OK, 1 row affected +--- +- ['\x01\x00\x00\x00', 'test box delete'] +... call box.delete('0', '���') -Found 1 tuple: -[1, 'test box delete'] +--- +- ['\x01\x00\x00\x00', 'test box delete'] +... call box.delete('0', '���') -No match +--- +... insert into t0 values (1, 'test box delete') -Insert OK, 1 row affected +--- +- ['\x01\x00\x00\x00', 'test box delete'] +... box.delete(0, 1) --- - [1, 'test box delete'] @@ -266,16 +291,23 @@ box.delete(0, 1) --- ... insert into t0 values ('abcd', 'test box delete') -Insert OK, 1 row affected +--- +- ['abcd', 'test box delete'] +... call box.delete('0', '���') -No match +--- +... call box.delete('0', 'abcd') -Found 1 tuple: -[1684234849, 'test box delete'] +--- +- ['abcd', 'test box delete'] +... call box.delete('0', 'abcd') -No match +--- +... insert into t0 values ('abcd', 'test box delete') -Insert OK, 1 row affected +--- +- ['abcd', 'test box delete'] +... box.delete(0, 'abcd') --- - [1684234849, 'test box delete'] @@ -284,12 +316,16 @@ box.delete(0, 'abcd') --- ... call box.select('0', '0', 'abcd') -No match +--- +... insert into t0 values ('abcd', 'test box.select()') -Insert OK, 1 row affected +--- +- ['abcd', 'test box.select()'] +... call box.select('0', '0', 'abcd') -Found 1 tuple: -[1684234849, 'test box.select()'] +--- +- ['abcd', 'test box.select()'] +... box.select(0, 0, 'abcd') --- - [1684234849, 'test box.select()'] @@ -307,73 +343,97 @@ box.select(0) - error: '[string "-- box.lua (internal file)..."]:11: box.pack: expected 32-bit int' ... call box.replace('0', 'abcd', 'hello', 'world') -Found 1 tuple: -[1684234849, 'hello', 'world'] +--- +- ['abcd', 'hello', 'world'] +... call box.replace('0', 'defc', 'goodbye', 'universe') -Found 1 tuple: -[1667655012, 'goodbye', 'universe'] +--- +- ['defc', 'goodbye', 'universe'] +... call box.select('0', '0', 'abcd') -Found 1 tuple: -[1684234849, 'hello', 'world'] +--- +- ['abcd', 'hello', 'world'] +... call box.select('0', '0', 'defc') -Found 1 tuple: -[1667655012, 'goodbye', 'universe'] +--- +- ['defc', 'goodbye', 'universe'] +... call box.replace('0', 'abcd') -Found 1 tuple: -[1684234849] +--- +- ['abcd'] +... call box.select('0', '0', 'abcd') -Found 1 tuple: -[1684234849] +--- +- ['abcd'] +... call box.delete('0', 'abcd') -Found 1 tuple: -[1684234849] +--- +- ['abcd'] +... call box.delete('0', 'defc') -Found 1 tuple: -[1667655012, 'goodbye', 'universe'] +--- +- ['defc', 'goodbye', 'universe'] +... call box.insert('0', 'test', 'old', 'abcd') -Found 1 tuple: -[1953719668, 'old', 1684234849] +--- +- ['test', 'old', 'abcd'] +... call box.insert('0', 'test', 'old', 'abcd') -An error occurred: ER_TUPLE_FOUND, 'Duplicate key exists in unique index 0' +--- +- error: + errcode: ER_TUPLE_FOUND + errmsg: Duplicate key exists in unique index 0 +... call box.update('0', 'test', '=p=p', '����', 'pass', 1, 'new') -Found 1 tuple: -[1936941424, 'new', 1684234849] +--- +- ['pass', 'new', 'abcd'] +... call box.select('0', '0', 'pass') -Found 1 tuple: -[1936941424, 'new', 1684234849] +--- +- ['pass', 'new', 'abcd'] +... call box.select_range(0, 0, 1, 'pass') -Found 1 tuple: -[1936941424, 'new', 1684234849] +--- +- ['pass', 'new', 'abcd'] +... call box.update('0', 'miss', '+p', 2, '���') -No match +--- +... call box.update('0', 'pass', '+p', 2, '���') -Found 1 tuple: -[1936941424, 'new', 1684234850] +--- +- ['pass', 'new', 'bbcd'] +... call box.update('0', 'pass', '-p', 2, '���') -Found 1 tuple: -[1936941424, 'new', 1684234849] +--- +- ['pass', 'new', 'abcd'] +... call box.update('0', 'pass', '-p', 2, '���') -Found 1 tuple: -[1936941424, 'new', 1684234848] +--- +- ['pass', 'new', '`bcd'] +... box.update(0, 'pass', '+p', 2, 1) --- - [1936941424, 'new', 1684234849] ... call box.select('0', '0', 'pass') -Found 1 tuple: -[1936941424, 'new', 1684234849] +--- +- ['pass', 'new', 'abcd'] +... function field_x(space, key, field_index) return (box.select(space, 0, key))[tonumber(field_index)] end --- ... call field_x('0', 'pass', '0') -Found 1 tuple: -[1936941424] +--- +- ['pass'] +... call field_x('0', 'pass', '1') -Found 1 tuple: -['new'] +--- +- ['new'] +... call box.delete('0', 'pass') -Found 1 tuple: -[1936941424, 'new', 1684234849] +--- +- ['pass', 'new', 'abcd'] +... dofile(...) --- ... @@ -469,10 +529,11 @@ t = {} for k,v in pairs(box.space[0]) do if type(v) ~= 'table' then table.insert ... t --- -- - 'arity: 0' +- - 'temporary: false' - 'n: 0' - 'enabled: true' - 'name: tweedledum' + - 'arity: 0' ... box.cfg.reload() --- @@ -518,10 +579,11 @@ t = {} for k,v in pairs(box.space[0]) do if type(v) ~= 'table' then table.insert ... t --- -- - 'arity: 0' +- - 'temporary: false' - 'n: 0' - 'enabled: true' - 'name: tweedledum' + - 'arity: 0' ... box.cfg.nosuchoption = 1 --- @@ -545,7 +607,7 @@ box.index.bind(0, 1) ... box.index.bind(0, 0) --- --index 0 +- index 0 ... #box.index.bind(0,0) --- @@ -844,7 +906,8 @@ f = function() box.fiber.wrap(f) end --- ... call f() -No match +--- +... f = function(a, b) box.fiber.wrap(function(arg) result = arg end, a..b) end --- ... @@ -940,64 +1003,89 @@ function f2(...) return f1({...}) end --- ... call f1('test_', 'test_') -Found 1 tuple: -['test_', 'test_'] +--- +- ['test_', 'test_'] +... call f2('test_', 'test_') -Found 1 tuple: -['test_', 'test_'] +--- +- ['test_', 'test_'] +... call f1() -Found 1 tuple: -[] +--- +- [] +... call f2() -Found 1 tuple: -[] +--- +- [] +... function f3() return {{'hello'}, {'world'}} end --- ... call f3() -Found 2 tuples: -['hello'] -['world'] +--- +- ['hello'] +- ['world'] +... function f3() return {'hello', {'world'}} end --- ... call f3() -An error occurred: ER_PROC_RET, 'Return type 'table' is not supported in the binary protocol' +--- +- error: + errcode: ER_PROC_RET + errmsg: Return type 'table' is not supported in the binary protocol +... function f3() return 'hello', {{'world'}, {'canada'}} end --- ... call f3() -An error occurred: ER_PROC_RET, 'Return type 'table' is not supported in the binary protocol' +--- +- error: + errcode: ER_PROC_RET + errmsg: Return type 'table' is not supported in the binary protocol +... function f3() return {}, '123', {{}, {}} end --- ... call f3() -An error occurred: ER_PROC_RET, 'Return type 'table' is not supported in the binary protocol' +--- +- error: + errcode: ER_PROC_RET + errmsg: Return type 'table' is not supported in the binary protocol +... function f3() return { {{'hello'}} } end --- ... call f3() -An error occurred: ER_PROC_RET, 'Return type 'table' is not supported in the binary protocol' +--- +- error: + errcode: ER_PROC_RET + errmsg: Return type 'table' is not supported in the binary protocol +... function f3() return { box.tuple.new('hello'), {'world'} } end --- ... call f3() -Found 2 tuples: -['hello'] -['world'] +--- +- ['hello'] +- ['world'] +... function f3() return { {'world'}, box.tuple.new('hello') } end --- ... call f3() -Found 2 tuples: -['world'] -['hello'] +--- +- ['world'] +- ['hello'] +... call f1('jason') -Found 1 tuple: -['jason'] +--- +- ['jason'] +... call f1('jason', 1, 'test', 2, 'stewart') -Found 1 tuple: -['jason', '1', 1953719668, '2', 'stewart'] +--- +- ['jason', '1', 'test', '2', 'stewart'] +... function box.crossjoin(space0, space1, limit) space0 = tonumber(space0) space1 = tonumber(space1) limit = tonumber(limit) local result = {} for k0, v0 in box.space[space0]:pairs() do for k1, v1 in box.space[space1]:pairs() do if limit <= 0 then return unpack(result) end newtuple = {v0:unpack()} for _, v in v1:pairs() do table.insert(newtuple, v) end table.insert(result, newtuple) limit = limit - 1 end end return unpack(result) end --- ... @@ -1012,33 +1100,36 @@ box.space[0]:insert(1) - [1] ... call box.crossjoin('0', '0', '10000') -Found 1 tuple: -[1, 1] +--- +- ['\x01\x00\x00\x00', '\x01\x00\x00\x00'] +... box.space[0]:insert(2) --- - [2] ... call box.crossjoin('0', '0', '10000') -Found 4 tuples: -[1, 1] -[1, 2] -[2, 1] -[2, 2] +--- +- ['\x01\x00\x00\x00', '\x01\x00\x00\x00'] +- ['\x01\x00\x00\x00', '\x02\x00\x00\x00'] +- ['\x02\x00\x00\x00', '\x01\x00\x00\x00'] +- ['\x02\x00\x00\x00', '\x02\x00\x00\x00'] +... box.space[0]:insert(3, 'hello') --- - [3, 'hello'] ... call box.crossjoin('0', '0', '10000') -Found 9 tuples: -[1, 1] -[1, 2] -[1, 3, 'hello'] -[2, 1] -[2, 2] -[2, 3, 'hello'] -[3, 'hello', 1] -[3, 'hello', 2] -[3, 'hello', 3, 'hello'] +--- +- ['\x01\x00\x00\x00', '\x01\x00\x00\x00'] +- ['\x01\x00\x00\x00', '\x02\x00\x00\x00'] +- ['\x01\x00\x00\x00', '\x03\x00\x00\x00', 'hello'] +- ['\x02\x00\x00\x00', '\x01\x00\x00\x00'] +- ['\x02\x00\x00\x00', '\x02\x00\x00\x00'] +- ['\x02\x00\x00\x00', '\x03\x00\x00\x00', 'hello'] +- ['\x03\x00\x00\x00', 'hello', '\x01\x00\x00\x00'] +- ['\x03\x00\x00\x00', 'hello', '\x02\x00\x00\x00'] +- ['\x03\x00\x00\x00', 'hello', '\x03\x00\x00\x00', 'hello'] +... box.space[0]:insert(4, 'world') --- - [4, 'world'] @@ -1048,32 +1139,33 @@ box.space[0]:insert(5, 'hello world') - [5, 'hello world'] ... call box.crossjoin('0', '0', '10000') -Found 25 tuples: -[1, 1] -[1, 2] -[1, 3, 'hello'] -[1, 4, 'world'] -[1, 5, 'hello world'] -[2, 1] -[2, 2] -[2, 3, 'hello'] -[2, 4, 'world'] -[2, 5, 'hello world'] -[3, 'hello', 1] -[3, 'hello', 2] -[3, 'hello', 3, 'hello'] -[3, 'hello', 4, 'world'] -[3, 'hello', 5, 'hello world'] -[4, 'world', 1] -[4, 'world', 2] -[4, 'world', 3, 'hello'] -[4, 'world', 4, 'world'] -[4, 'world', 5, 'hello world'] -[5, 'hello world', 1] -[5, 'hello world', 2] -[5, 'hello world', 3, 'hello'] -[5, 'hello world', 4, 'world'] -[5, 'hello world', 5, 'hello world'] +--- +- ['\x01\x00\x00\x00', '\x01\x00\x00\x00'] +- ['\x01\x00\x00\x00', '\x02\x00\x00\x00'] +- ['\x01\x00\x00\x00', '\x03\x00\x00\x00', 'hello'] +- ['\x01\x00\x00\x00', '\x04\x00\x00\x00', 'world'] +- ['\x01\x00\x00\x00', '\x05\x00\x00\x00', 'hello world'] +- ['\x02\x00\x00\x00', '\x01\x00\x00\x00'] +- ['\x02\x00\x00\x00', '\x02\x00\x00\x00'] +- ['\x02\x00\x00\x00', '\x03\x00\x00\x00', 'hello'] +- ['\x02\x00\x00\x00', '\x04\x00\x00\x00', 'world'] +- ['\x02\x00\x00\x00', '\x05\x00\x00\x00', 'hello world'] +- ['\x03\x00\x00\x00', 'hello', '\x01\x00\x00\x00'] +- ['\x03\x00\x00\x00', 'hello', '\x02\x00\x00\x00'] +- ['\x03\x00\x00\x00', 'hello', '\x03\x00\x00\x00', 'hello'] +- ['\x03\x00\x00\x00', 'hello', '\x04\x00\x00\x00', 'world'] +- ['\x03\x00\x00\x00', 'hello', '\x05\x00\x00\x00', 'hello world'] +- ['\x04\x00\x00\x00', 'world', '\x01\x00\x00\x00'] +- ['\x04\x00\x00\x00', 'world', '\x02\x00\x00\x00'] +- ['\x04\x00\x00\x00', 'world', '\x03\x00\x00\x00', 'hello'] +- ['\x04\x00\x00\x00', 'world', '\x04\x00\x00\x00', 'world'] +- ['\x04\x00\x00\x00', 'world', '\x05\x00\x00\x00', 'hello world'] +- ['\x05\x00\x00\x00', 'hello world', '\x01\x00\x00\x00'] +- ['\x05\x00\x00\x00', 'hello world', '\x02\x00\x00\x00'] +- ['\x05\x00\x00\x00', 'hello world', '\x03\x00\x00\x00', 'hello'] +- ['\x05\x00\x00\x00', 'hello world', '\x04\x00\x00\x00', 'world'] +- ['\x05\x00\x00\x00', 'hello world', '\x05\x00\x00\x00', 'hello world'] +... box.space[0]:truncate() --- ... @@ -1207,23 +1299,28 @@ box.space[0]:truncate() --- ... call box.insert('0', 'tes1', 'tes2', 'tes3', 'tes4', 'tes5') -Found 1 tuple: -[829646196, 846423412, 863200628, 879977844, 896755060] +--- +- ['tes1', 'tes2', 'tes3', 'tes4', 'tes5'] +... call box.update('0', 'tes1', '#p', 0, '') -Found 1 tuple: -[846423412, 863200628, 879977844, 896755060] +--- +- ['tes2', 'tes3', 'tes4', 'tes5'] +... call box.update('0', 'tes2', '#p', 0, '') -Found 1 tuple: -[863200628, 879977844, 896755060] +--- +- ['tes3', 'tes4', 'tes5'] +... call box.update('0', 'tes3', '#p', 0, '') -Found 1 tuple: -[879977844, 896755060] +--- +- ['tes4', 'tes5'] +... call box.update('0', 'tes4', '#p', 0, '') -Found 1 tuple: -[896755060] +--- +- ['tes5'] +... box.update(0, 'tes5', '#p', 0, '') --- -- error: Illegal parameters, tuple must have all indexed fields +- error: Tuple field count 0 is less than required by a defined index (expected 1) ... box.space[0]:truncate() --- @@ -1321,11 +1418,12 @@ function foo() return 1, 2, '1', '2' end --- ... call foo() -Found 4 tuples: -[1] -[2] -['1'] -['2'] +--- +- ['\x01\x00\x00\x00'] +- ['\x02\x00\x00\x00'] +- ['1'] +- ['2'] +... # test update's assign opearations @@ -1812,14 +1910,17 @@ test.test.f = f --- ... call f() -Found 1 tuple: -['OK'] +--- +- ['OK'] +... call test.f() -Found 1 tuple: -['OK'] +--- +- ['OK'] +... call test.test.f() -Found 1 tuple: -['OK'] +--- +- ['OK'] +... # A test case for box.counter @@ -2083,8 +2184,9 @@ function bug1075677() local range = {} table.insert(range, 1>0) return range end --- ... call bug1075677() -Found 1 tuple: -[1702195828] +--- +- ['true'] +... bug1075677=nil --- ... @@ -2107,6 +2209,12 @@ t:bsize() --- - 4 ... +call box.dostring('box.raise(33333, "Hey!")') +--- +- error: + errcode: ER_UNKNOWN (33333) + errmsg: Hey! +... box.space[0]:drop() --- ... diff --git a/test/box/lua.test.py b/test/box/lua.test.py index 57c9ec6cfcbabc46bbb6ba40615027aaaf53690e..84770d32f6a6fbda6313cc06747d2d6e02066eaf 100644 --- a/test/box/lua.test.py +++ b/test/box/lua.test.py @@ -1,4 +1,3 @@ -# encoding: utf-8 import os import sys @@ -716,6 +715,10 @@ admin("t") admin("t:bsize()") admin("box.delete(0, 8989)", silent=True) +# A test case for https://github.com/tarantool/tarantool/issues/44 +# IPROTO required! +sql("call box.dostring('box.raise(33333, \"Hey!\")')") + admin("box.space[0]:drop()") sys.stdout.clear_all_filters() diff --git a/test/box/lua_misc.result b/test/box/lua_misc.result index 2fcff38cde65a8f4e99a55d3ea0bfea7969c424a..608879c0226ebccd53ea79985e895be30790901e 100644 --- a/test/box/lua_misc.result +++ b/test/box/lua_misc.result @@ -137,9 +137,10 @@ t; - 'box.error.ER_FIELD_TYPE : 10242' - 'box.error.ER_OK : 0' - 'box.error.ER_TUPLE_NOT_FOUND : 12546' + - 'box.error.ER_INDEX_ARITY : 8194' - 'box.error.ER_WAL_IO : 9986' - 'box.error.ER_INJECTION : 2306' - - 'box.error.ER_DROP_PRIMARY_KEY : 7682' + - 'box.error.ER_LAST_DROP : 7426' - 'box.error.ER_INDEX_TYPE : 1282' - 'box.error.ER_ARG_TYPE : 10498' - 'box.error.ER_KEY_PART_COUNT : 12034' @@ -153,7 +154,7 @@ t; - 'box.error.ER_SECONDARY : 770' - 'box.error.ER_UPDATE_FIELD : 14338' - 'box.error.ER_DROP_SPACE : 6146' - - 'box.error.ER_UNKNOWN_UPDATE_OP : 11266' + - 'box.error.ER_SPLICE : 10754' - 'box.error.ER_NO_SUCH_SPACE : 14594' - 'box.error.ER_UNSUPPORTED : 2562' - 'box.error.ER_TUPLE_FOUND : 14082' @@ -161,15 +162,27 @@ t; - 'box.error.ER_SPACE_DISABLED : 13314' - 'box.error.ER_PROC_LUA : 13058' - 'box.error.ER_ALTER_SPACE : 6402' - - 'box.error.ER_TUPLE_IS_RO : 1025' - 'box.error.ER_FIBER_STACK : 6658' + - 'box.error.ER_TUPLE_IS_RO : 1025' - 'box.error.ER_NO_SUCH_PROC : 12802' - - 'box.error.ER_LAST_DROP : 7426' - - 'box.error.ER_SPLICE : 10754' + - 'box.error.ER_DROP_PRIMARY_KEY : 7682' - 'box.error.ER_SPACE_ARITY : 7938' + - 'box.error.ER_UNKNOWN_UPDATE_OP : 11266' - 'box.error.ER_FIELD_TYPE_MISMATCH : 11778' - 'box.error.ER_SPACE_EXISTS : 1538' ... space:drop(); --- ... +--# setopt delimiter '' +-- A test case for gh-37: print of 64-bit number +1, 1 +--- +- 1 +- 1 +... +tonumber64(1), 1 +--- +- 1 +- 1 +... diff --git a/test/box/lua_misc.test.lua b/test/box/lua_misc.test.lua index 4b15c51d0ad22d95b0c3b327f584f34d67dbb415..37dc31d1b33dfd9694688fb80baaee049256ea7d 100644 --- a/test/box/lua_misc.test.lua +++ b/test/box/lua_misc.test.lua @@ -60,3 +60,7 @@ end; t; space:drop(); +--# setopt delimiter '' +-- A test case for gh-37: print of 64-bit number +1, 1 +tonumber64(1), 1 diff --git a/test/box/reconfigure.result b/test/box/reconfigure.result index 42d1bf47e9065314c2f85f75eb91cbfb09e887ef..408acceb04f1740207186f024f7ab50aef958fad 100644 --- a/test/box/reconfigure.result +++ b/test/box/reconfigure.result @@ -50,6 +50,18 @@ box.cfg.too_long_threshold --- - 2 ... +box.cfg.snap_io_rate_limit +--- +- 10 +... +box.cfg.reload() +--- +- ok +... +box.cfg.snap_io_rate_limit +--- +- 1 +... box.cfg.reload() --- - error: 'can''t open config `tarantool.cfg''. @@ -75,8 +87,10 @@ space = box.schema.create_space('tweedledum', { id = 0 }) space:create_index('primary', 'hash', { parts = { 0, 'num' }}) --- ... -insert into t0 values (1, 'tuple') -Insert OK, 1 row affected +box.insert(0, 1, 'tuple') +--- +- [1, 'tuple'] +... box.snapshot() --- - ok @@ -87,8 +101,10 @@ box.cfg.reload() ' ... -insert into t0 values (2, 'tuple 2') -Insert OK, 1 row affected +box.insert(0, 2, 'tuple2') +--- +- [2, 'tuple2'] +... box.snapshot() --- - ok @@ -97,8 +113,10 @@ box.cfg.reload() --- - ok ... -insert into t0 values (3, 'tuple 3') -Insert OK, 1 row affected +box.insert(0, 3, 'tuple3') +--- +- [3, 'tuple3'] +... box.snapshot() --- - ok diff --git a/test/box/reconfigure.test.py b/test/box/reconfigure.test.py index 71d65c84d47e1de8ff6b44aef70cfc060eba59c0..d05649be6de9b016543c27367d00178fcfd5bf5b 100644 --- a/test/box/reconfigure.test.py +++ b/test/box/reconfigure.test.py @@ -12,6 +12,9 @@ admin("box.cfg.io_collect_interval") # empty server.reconfigure("box/tarantool_empty.cfg") admin("box.cfg.too_long_threshold") +admin("box.cfg.snap_io_rate_limit") +server.reconfigure("box/snap_io_rate_limit.cfg") +admin("box.cfg.snap_io_rate_limit") # no config server.reconfigure(None) @@ -28,13 +31,14 @@ print """# #""" admin("space = box.schema.create_space('tweedledum', { id = 0 })") admin("space:create_index('primary', 'hash', { parts = { 0, 'num' }})") -sql("insert into t0 values (1, 'tuple')") +admin("box.insert(0, 1, 'tuple')") +admin("") admin("box.snapshot()") server.reconfigure(None) -sql("insert into t0 values (2, 'tuple 2')") +admin("box.insert(0, 2, 'tuple2')") admin("box.snapshot()") server.reconfigure("box/tarantool_good.cfg") -sql("insert into t0 values (3, 'tuple 3')") +admin("box.insert(0, 3, 'tuple3')") admin("box.snapshot()") # Cleanup server.reconfigure(self.suite_ini["config"]) diff --git a/test/box/snap_io_rate_limit.cfg b/test/box/snap_io_rate_limit.cfg new file mode 100644 index 0000000000000000000000000000000000000000..81d0d33ab6e07caa0e931b4da33d23c32eeed3de --- /dev/null +++ b/test/box/snap_io_rate_limit.cfg @@ -0,0 +1,18 @@ +# gh-45: snap_io_rate_limit was not taken into account if +# no other option has changed +slab_alloc_arena = 0.1 + +pid_file = "box.pid" + +logger="cat - >> tarantool.log" + +primary_port = 33013 +secondary_port = 33014 +admin_port = 33015 + +rows_per_wal = 50 +too_long_threshold=2 +# 1MBps +snap_io_rate_limit = 1 +io_collect_interval = 0.01 + diff --git a/test/box/snapshot.result b/test/box/snapshot.result index eb281c0ca65dad15e9c2a2759cb2f6d1c5983ea0..e83187a02d6d8fae637189b2cc9c8f6273c67e29 100644 --- a/test/box/snapshot.result +++ b/test/box/snapshot.result @@ -11,8 +11,10 @@ space:create_index('primary', 'hash', { parts = { 0, 'num' }}) # error that happens when saving snapshot is propagated # to the caller. -insert into t0 values (1, 'first tuple') -Insert OK, 1 row affected +box.insert(0, 1, 'first tuple') +--- +- [1, 'first tuple'] +... box.snapshot() --- - ok @@ -21,17 +23,23 @@ box.snapshot() --- - error: can't save snapshot, errno 17 (File exists) ... -insert into t0 values (2, 'second tuple') -Insert OK, 1 row affected +box.insert(0, 2, 'second tuple') +--- +- [2, 'second tuple'] +... # Make 'var' directory read-only. box.snapshot() --- - error: can't save snapshot, errno 13 (Permission denied) ... -delete from t0 where k0 = 1 -Delete OK, 1 row affected -delete from t0 where k0 = 2 -Delete OK, 1 row affected +box.delete(0, 1) +--- +- [1, 'first tuple'] +... +box.delete(0, 2) +--- +- [2, 'second tuple'] +... # # A test case for http://bugs.launchpad.net/bugs/727174 # "tarantool_box crashes when saving snapshot on SIGUSR1" @@ -39,8 +47,10 @@ Delete OK, 1 row affected # Increment the lsn number, to make sure there is no such snapshot yet # -insert into t0 values (1, 'Test tuple') -Insert OK, 1 row affected +box.insert(0, 1, 'Test tuple') +--- +- [1, 'Test tuple'] +... Snapshot exists. box.space[0]:drop() --- diff --git a/test/box/snapshot.test.py b/test/box/snapshot.test.py index 5efd1c2dee09ee3f77f2ca19c17833eda2af9e0b..9d7cfdcbc92692ba13d348c885b4fb976c6b92a8 100644 --- a/test/box/snapshot.test.py +++ b/test/box/snapshot.test.py @@ -13,7 +13,7 @@ print """# # error that happens when saving snapshot is propagated # to the caller. """ -sql("insert into t0 values (1, 'first tuple')") +admin("box.insert(0, 1, 'first tuple')") admin("box.snapshot()") # In absence of data modifications, two consecutive @@ -24,7 +24,7 @@ admin("box.snapshot()") admin("box.snapshot()") # # Increment LSN -sql("insert into t0 values (2, 'second tuple')") +admin("box.insert(0, 2, 'second tuple')") # # Check for other errors, e.g. "Permission denied". print "# Make 'var' directory read-only." @@ -33,8 +33,9 @@ admin("box.snapshot()") # cleanup os.chmod(vardir, 0755) -sql("delete from t0 where k0 = 1") -sql("delete from t0 where k0 = 2") + +admin("box.delete(0, 1)") +admin("box.delete(0, 2)") print """# # A test case for http://bugs.launchpad.net/bugs/727174 @@ -45,7 +46,7 @@ print """ # Increment the lsn number, to make sure there is no such snapshot yet #""" -sql("insert into t0 values (1, 'Test tuple')") +admin("box.insert(0, 1, 'Test tuple')") pid = int(yaml.load(admin("box.info.pid", silent=True))[0]) lsn = yaml.load(admin("box.info.lsn", silent=True))[0] @@ -69,5 +70,3 @@ else: print "Snapshot exists." admin("box.space[0]:drop()") - -# vim: syntax=python spell diff --git a/test/box/sql.result b/test/box/sql.result index 2ad2b7081d48464d5de1e98bba4512c9a6fe0649..dd5d9a7960181af76a19db91b29e8e1bc5c1a22d 100644 --- a/test/box/sql.result +++ b/test/box/sql.result @@ -5,91 +5,144 @@ space:create_index('primary', 'hash', { parts = { 0, 'num' }}) --- ... ping -ok --- +- ok +... select * from t0 -An error occurred: ER_KEY_FIELD_TYPE, 'Supplied key type of part 0 does not match index part type: expected NUM' +--- +- error: + errcode: ER_EXACT_MATCH + errmsg: Invalid key part count in an exact match (expected 1, got 0) +... insert into t0 values (1, 'I am a tuple') -Insert OK, 1 row affected +--- +- [1, u'I am a tuple'] +... select * from t0 where k0 = 1 -Found 1 tuple: -[1, 'I am a tuple'] +--- +- [1, u'I am a tuple'] +... select * from t0 where k0 = 0 -No match +--- +... select * from t0 where k0 = 2 -No match +--- +... select * from t0 where k0 = 1 -Found 1 tuple: -[1, 'I am a tuple'] +--- +- [1, u'I am a tuple'] +... box.snapshot() --- - ok ... select * from t0 where k0 = 1 -Found 1 tuple: -[1, 'I am a tuple'] +--- +- [1, u'I am a tuple'] +... select * from t0 where k0 = 1 -Found 1 tuple: -[1, 'I am a tuple'] +--- +- [1, u'I am a tuple'] +... delete from t0 where k0 = 1 -Delete OK, 1 row affected +--- +- [1, u'I am a tuple'] +... select * from t0 where k0 = 1 -No match +--- +... update t0 set k1 = 'I am a new tuple' where k0=1 -Update OK, 0 row affected +--- +... select * from t0 where k0=1 -No match +--- +... insert into t0 values (1, 'I am a new tuple') -Insert OK, 1 row affected +--- +- [1, u'I am a new tuple'] +... select * from t0 where k0 = 1 -Found 1 tuple: -[1, 'I am a new tuple'] +--- +- [1, u'I am a new tuple'] +... update t0 set k1 = 'I am the newest tuple' where k0=1 -Update OK, 1 row affected +--- +- [1, u'I am the newest tuple'] +... select * from t0 where k0 = 1 -Found 1 tuple: -[1, 'I am the newest tuple'] +--- +- [1, u'I am the newest tuple'] +... update t0 set k1 = 'Huh', k2 = 'I am a new field! I was added via append' where k0=1 -Update OK, 1 row affected +--- +- [1, u'Huh', u'I am a new field! I was added via append'] +... select * from t0 where k0 = 1 -Found 1 tuple: -[1, 'Huh', 'I am a new field! I was added via append'] +--- +- [1, u'Huh', u'I am a new field! I was added via append'] +... update t0 set k1 = 'Huh', k1000 = 'invalid field' where k0=1 -An error occurred: ER_NO_SUCH_FIELD, 'Field 1000 was not found in the tuple' +--- +- error: + errcode: ER_NO_SUCH_FIELD + errmsg: Field 1000 was not found in the tuple +... select * from t0 where k0 = 1 -Found 1 tuple: -[1, 'Huh', 'I am a new field! I was added via append'] +--- +- [1, u'Huh', u'I am a new field! I was added via append'] +... replace into t0 values (1, 'I am a new tuple', 'stub') -Replace OK, 1 row affected +--- +- [1, u'I am a new tuple', u'stub'] +... update t0 set k1 = 'Huh', k2 = 'Oh-ho-ho' where k0=1 -Update OK, 1 row affected +--- +- [1, u'Huh', u'Oh-ho-ho'] +... select * from t0 where k0 = 1 -Found 1 tuple: -[1, 'Huh', 'Oh-ho-ho'] +--- +- [1, u'Huh', u'Oh-ho-ho'] +... update t0 set k1 = '', k2 = '' where k0=1 -Update OK, 1 row affected +--- +- [1, u'', u''] +... select * from t0 where k0 = 1 -Found 1 tuple: -[1, '', ''] +--- +- [1, u'', u''] +... update t0 set k1 = 2, k2 = 3 where k0=1 -Update OK, 1 row affected +--- +- [1, u'\x02\x00\x00\x00', u'\x03\x00\x00\x00'] +... select * from t0 where k0 = 1 -Found 1 tuple: -[1, 2, 3] +--- +- [1, u'\x02\x00\x00\x00', u'\x03\x00\x00\x00'] +... insert into t0 values (0) -Insert OK, 1 row affected +--- +- [0] +... select * from t0 where k0=0 -Found 1 tuple: -[0] +--- +- [0] +... insert into t0 values (4294967295) -Insert OK, 1 row affected +--- +- [4294967295] +... select * from t0 where k0=4294967295 -Found 1 tuple: -[4294967295] +--- +- [4294967295] +... delete from t0 where k0=0 -Delete OK, 1 row affected +--- +- [0] +... delete from t0 where k0=4294967295 -Delete OK, 1 row affected +--- +- [4294967295] +... # # A test case for: http://bugs.launchpad.net/bugs/712456 # Verify that when trying to access a non-existing or @@ -97,11 +150,23 @@ Delete OK, 1 row affected # select * from t1 where k0 = 0 -An error occurred: ER_NO_SUCH_SPACE, 'Space 1 does not exist' +--- +- error: + errcode: ER_NO_SUCH_SPACE + errmsg: Space 1 does not exist +... select * from t65537 where k0 = 0 -An error occurred: ER_NO_SUCH_SPACE, 'Space 65537 does not exist' +--- +- error: + errcode: ER_NO_SUCH_SPACE + errmsg: Space 65537 does not exist +... select * from t4294967295 where k0 = 0 -An error occurred: ER_NO_SUCH_SPACE, 'Space 4294967295 does not exist' +--- +- error: + errcode: ER_NO_SUCH_SPACE + errmsg: Space 4294967295 does not exist +... box.space[0]:drop() --- ... diff --git a/test/box/sql.test.py b/test/box/sql.test.py index 707c766fc65892dc666f494a6ffbf307d6c14a86..2186a455b8cb49488e73db9a3a3a6c3f365628e1 100644 --- a/test/box/sql.test.py +++ b/test/box/sql.test.py @@ -1,4 +1,17 @@ -# encoding: utf-8 +import tarantool +sql.set_schema({ + 0 : { + 'default_type': tarantool.STR, + 'fields' : { + 0 : tarantool.NUM, + 1 : tarantool.STR + }, + 'indexes': { + 0 : [0] # HASH + } + } +}) + admin("space = box.schema.create_space('tweedledum', { id = 0 })") admin("space:create_index('primary', 'hash', { parts = { 0, 'num' }})") sql("ping") @@ -66,5 +79,3 @@ print """# # Admin console should not stall on unknown command. """ admin("show status", simple=True) - -# vim: syntax=python diff --git a/test/box/stat.result b/test/box/stat.result index 579b4726523da97fab766351ba41a4bf511f31a1..f234415b2656bd4e80137687f3dd332438c84167 100644 --- a/test/box/stat.result +++ b/test/box/stat.result @@ -1,34 +1,17 @@ +-- clear statistics +--# stop server default +--# start server default space = box.schema.create_space('tweedledum', { id = 0 }) --- ... space:create_index('primary', 'hash', { parts = { 0, 'num' }}) --- ... -# -# check stat_cleanup -# add several tuples -# - -insert into t0 values (0, 'tuple') -Insert OK, 1 row affected -insert into t0 values (1, 'tuple') -Insert OK, 1 row affected -insert into t0 values (2, 'tuple') -Insert OK, 1 row affected -insert into t0 values (3, 'tuple') -Insert OK, 1 row affected -insert into t0 values (4, 'tuple') -Insert OK, 1 row affected -insert into t0 values (5, 'tuple') -Insert OK, 1 row affected -insert into t0 values (6, 'tuple') -Insert OK, 1 row affected -insert into t0 values (7, 'tuple') -Insert OK, 1 row affected -insert into t0 values (8, 'tuple') -Insert OK, 1 row affected -insert into t0 values (9, 'tuple') -Insert OK, 1 row affected +-- check stat_cleanup +-- add several tuples +for i=1,10 do box.insert(0, i, 'tuple'..tostring(i)) end; +--- +... box.stat() --- - DELETE: @@ -50,14 +33,9 @@ box.stat() total: 0 rps: 0 ... -# -# restart server -# - -# -# statistics must be zero -# - +--# stop server default +--# start server default +-- statistics must be zero box.stat() --- - DELETE: @@ -79,6 +57,7 @@ box.stat() total: 0 rps: 0 ... +-- cleanup box.space[0]:drop() --- ... diff --git a/test/box/stat.test.lua b/test/box/stat.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..eb56d589466f6568abca1960d731a71379c72594 --- /dev/null +++ b/test/box/stat.test.lua @@ -0,0 +1,21 @@ +-- clear statistics +--# stop server default +--# start server default + +space = box.schema.create_space('tweedledum', { id = 0 }) +space:create_index('primary', 'hash', { parts = { 0, 'num' }}) + + +-- check stat_cleanup +-- add several tuples +for i=1,10 do box.insert(0, i, 'tuple'..tostring(i)) end; +box.stat() + +--# stop server default +--# start server default + +-- statistics must be zero +box.stat() + +-- cleanup +box.space[0]:drop() diff --git a/test/box/stat.test.py b/test/box/stat.test.py deleted file mode 100644 index ba5235cb336524b2d1e10e37e5ad46e97bd4fd58..0000000000000000000000000000000000000000 --- a/test/box/stat.test.py +++ /dev/null @@ -1,30 +0,0 @@ -# encoding: utf-8 -# -# clear statistics -server.restart() -admin("space = box.schema.create_space('tweedledum', { id = 0 })") -admin("space:create_index('primary', 'hash', { parts = { 0, 'num' }})") - -print """# -# check stat_cleanup -# add several tuples -# -""" -for i in range(10): - sql("insert into t0 values ({0}, 'tuple')".format(i)) -admin("box.stat()") -print """# -# restart server -# -""" -server.restart() -print """# -# statistics must be zero -# -""" -admin("box.stat()") - -# cleanup -admin("box.space[0]:drop()") - -# vim: syntax=python diff --git a/test/box/temp_spaces.result b/test/box/temp_spaces.result new file mode 100644 index 0000000000000000000000000000000000000000..eb11a93fb044a13e8d32d70e99ea5756aac0e08e --- /dev/null +++ b/test/box/temp_spaces.result @@ -0,0 +1,131 @@ +-- temporary spaces +-- not a temporary +s = box.schema.create_space('t', { temporary = true }) +--- +... +s.temporary +--- +- true +... +s:drop() +--- +... +-- not a temporary, too +s = box.schema.create_space('t', { temporary = false }) +--- +... +s.temporary +--- +- false +... +s:drop() +--- +... +-- not a temporary, too +s = box.schema.create_space('t', { temporary = nil }) +--- +... +s.temporary +--- +- false +... +s:drop() +--- +... +s = box.schema.create_space('t', { temporary = true }) +--- +... +s:create_index('primary', 'hash') +--- +... +s:insert(1, 2, 3) +--- +- [1, 2, 3] +... +s:select(0, 1) +--- +- [1, 2, 3] +... +s:len() +--- +- 1 +... +box.space[box.schema.SPACE_ID]:update(s.n, '=p', 3, 'temporary') +--- +- [512, 0, 't', 'temporary'] +... +box.space[box.schema.SPACE_ID]:update(s.n, '=p', 3, '') +--- +- error: 'Can''t modify space 512: can not switch temporary flag on a non-empty space' +... +--# stop server default +--# start server default +s = box.space.t +--- +... +s:len() +--- +- 0 +... +s.temporary +--- +- true +... +box.space[box.schema.SPACE_ID]:update(s.n, '=p', 3, 'no-temporary') +--- +- [512, 0, 't', 'no-temporary'] +... +s.temporary +--- +- false +... +box.space[box.schema.SPACE_ID]:update(s.n, '=p', 3, ',:asfda:temporary') +--- +- [512, 0, 't', ',:asfda:temporary'] +... +s.temporary +--- +- false +... +box.space[box.schema.SPACE_ID]:update(s.n, '=p', 3, 'a,b,c,d,e') +--- +- [512, 0, 't', 'a,b,c,d,e'] +... +s.temporary +--- +- false +... +box.space[box.schema.SPACE_ID]:update(s.n, '=p', 3, 'temporary') +--- +- [512, 0, 't', 'temporary'] +... +s.temporary +--- +- true +... +s:select(0, 1) +--- +... +s:insert(1, 2, 3) +--- +- [1, 2, 3] +... +box.space[box.schema.SPACE_ID]:update(s.n, '=p', 3, 'temporary') +--- +- [512, 0, 't', 'temporary'] +... +box.space[box.schema.SPACE_ID]:update(s.n, '=p', 3, 'no-temporary') +--- +- error: 'Can''t modify space 512: can not switch temporary flag on a non-empty space' +... +s:delete(1) +--- +- [1, 2, 3] +... +box.space[box.schema.SPACE_ID]:update(s.n, '=p', 3, 'no-temporary') +--- +- [512, 0, 't', 'no-temporary'] +... +s:drop() +--- +... diff --git a/test/box/temp_spaces.test.lua b/test/box/temp_spaces.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..a21ae36bdfd80800acdfa2725fdb71a4c41043e8 --- /dev/null +++ b/test/box/temp_spaces.test.lua @@ -0,0 +1,51 @@ +-- temporary spaces +-- not a temporary +s = box.schema.create_space('t', { temporary = true }) +s.temporary +s:drop() + +-- not a temporary, too +s = box.schema.create_space('t', { temporary = false }) +s.temporary +s:drop() + +-- not a temporary, too +s = box.schema.create_space('t', { temporary = nil }) +s.temporary +s:drop() + +s = box.schema.create_space('t', { temporary = true }) +s:create_index('primary', 'hash') + +s:insert(1, 2, 3) +s:select(0, 1) +s:len() + +box.space[box.schema.SPACE_ID]:update(s.n, '=p', 3, 'temporary') +box.space[box.schema.SPACE_ID]:update(s.n, '=p', 3, '') + +--# stop server default +--# start server default + +s = box.space.t +s:len() +s.temporary + +box.space[box.schema.SPACE_ID]:update(s.n, '=p', 3, 'no-temporary') +s.temporary +box.space[box.schema.SPACE_ID]:update(s.n, '=p', 3, ',:asfda:temporary') +s.temporary +box.space[box.schema.SPACE_ID]:update(s.n, '=p', 3, 'a,b,c,d,e') +s.temporary +box.space[box.schema.SPACE_ID]:update(s.n, '=p', 3, 'temporary') +s.temporary + +s:select(0, 1) +s:insert(1, 2, 3) + +box.space[box.schema.SPACE_ID]:update(s.n, '=p', 3, 'temporary') +box.space[box.schema.SPACE_ID]:update(s.n, '=p', 3, 'no-temporary') + +s:delete(1) +box.space[box.schema.SPACE_ID]:update(s.n, '=p', 3, 'no-temporary') +s:drop() diff --git a/test/lib/box_connection.py b/test/lib/box_connection.py index 2c160031f96abc6aac90873f4891afc7c83fd307..ae379b2fedb0d4ebcc17a539230bbc1cd1f3c54c 100644 --- a/test/lib/box_connection.py +++ b/test/lib/box_connection.py @@ -20,54 +20,66 @@ __author__ = "Konstantin Osipov <kostja.osipov@gmail.com>" # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. - -import socket +import os import sql +import sys +import errno +import ctypes +import socket import struct +import warnings + +from test_suite import check_tarantool_import from tarantool_connection import TarantoolConnection +check_tarantool_import() +from tarantool import Connection as tnt_connection +from tarantool import Schema + class BoxConnection(TarantoolConnection): def __init__(self, host, port): super(BoxConnection, self).__init__(host, port) + self.py_con = tnt_connection(host, port, connect_now=False) + self.py_con.error = False self.sort = False - def recvall(self, length): - res = "" - while len(res) < length: - buf = self.socket.recv(length - len(res)) - if not buf: - raise RuntimeError("Got EOF from socket, the server has " - "probably crashed") - res = res + buf - return res + def connect(self): + self.py_con.connect() - def execute_no_reconnect(self, command, silent=True): - statement = sql.parse("sql", command) - if statement == None: - return "You have an error in your SQL syntax\n" - statement.sort = self.sort - - payload = statement.pack() - header = struct.pack("<lll", statement.reqeust_type, len(payload), 0) + def disconnect(self): + self.py_con.close() - self.socket.sendall(header) - if len(payload): - self.socket.sendall(payload) + def reconnect(self): + self.disconnect() + self.connect() - IPROTO_HEADER_SIZE = 12 + def set_schema(self, schemadict): + self.py_con.schema = Schema(schemadict) - header = self.recvall(IPROTO_HEADER_SIZE) + def check_connection(self): + rc = self.py_con._recv(self.py_con._socket.fileno(), '', 0, socket.MSG_DONTWAIT) + if ctypes.get_errno() == errno.EAGAIN: + ctypes.set_errno(0) + return True + return False - response_len = struct.unpack("<lll", header)[1] + def execute(self, command, silent=True): + return self.execute_no_reconnect(command, silent) - if response_len: - response = self.recvall(response_len) - else: - response = None + def execute_no_reconnect(self, command, silent=True): + statement = sql.parse("sql", command) + if statement == None: + return "You have an error in your SQL syntax\n" + statement.sort = self.sort + + response = None + request = statement.pack(self.py_con) + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + response = self.py_con._send_request(request, False) if not silent: print command print statement.unpack(response) - return statement.unpack(response) + "\n" - + return statement.unpack(response) diff --git a/test/lib/sql_ast.py b/test/lib/sql_ast.py index 700811017ba07b6c09c36b7bd2625e6b7b1ecf39..c1c8dbd3ce9ef6248b06900c623a452a0218d255 100644 --- a/test/lib/sql_ast.py +++ b/test/lib/sql_ast.py @@ -1,28 +1,20 @@ -import struct +import os import re +import sys import ctypes +import struct -# IPROTO header is always 3 4-byte ints: -# command code, length, request id -INT_FIELD_LEN = 4 -INT_BER_MAX_LEN = 5 -IPROTO_HEADER_LEN = 3*INT_FIELD_LEN -INSERT_REQUEST_FIXED_LEN = 2*INT_FIELD_LEN -UPDATE_REQUEST_FIXED_LEN = 2*INT_FIELD_LEN -DELETE_REQUEST_FIXED_LEN = 2*INT_FIELD_LEN -SELECT_REQUEST_FIXED_LEN = 5*INT_FIELD_LEN -PACKET_BUF_LEN = 2048 - -UPDATE_SET_FIELD_OPCODE = 0 - -# command code in IPROTO header +from lib.test_suite import check_tarantool_import -INSERT_REQUEST_TYPE = 13 -SELECT_REQUEST_TYPE = 17 -UPDATE_REQUEST_TYPE = 19 -DELETE_REQUEST_TYPE = 21 -CALL_REQUEST_TYPE = 22 -PING_REQUEST_TYPE = 65280 +check_tarantool_import() +from tarantool.request import ( + RequestPing, + RequestInsert, + RequestSelect, + RequestCall, + RequestUpdate, + RequestDelete, +) ER = { 0: "ER_OK" , @@ -57,7 +49,7 @@ ER = { 29: "ER_LAST_DROP" , 30: "ER_DROP_PRIMARY_KEY" , 31: "ER_SPACE_ARITY" , - 32: "ER_UNUSED32" , + 32: "ER_INDEX_ARITY" , 33: "ER_UNUSED33" , 34: "ER_UNUSED34" , 35: "ER_UNUSED35" , @@ -85,286 +77,143 @@ ER = { 57: "ER_NO_SUCH_SPACE" } -def format_error(return_code, response): - return "An error occurred: {0}, '{1}'".format(ER[return_code >> 8], - response[4:-1]) - - -def save_varint32(value): - """Implement Perl pack's 'w' option, aka base 128 encoding.""" - res = '' - if value >= 1 << 7: - if value >= 1 << 14: - if value >= 1 << 21: - if value >= 1 << 28: - res += chr(value >> 28 & 0xff | 0x80) - res += chr(value >> 21 & 0xff | 0x80) - res += chr(value >> 14 & 0xff | 0x80) - res += chr(value >> 7 & 0xff | 0x80) - res += chr(value & 0x7F) - - return res - - -def read_varint32(varint, offset): - """Implement Perl unpack's 'w' option, aka base 128 decoding.""" - res = ord(varint[offset]) - if ord(varint[offset]) >= 0x80: - offset += 1 - res = ((res - 0x80) << 7) + ord(varint[offset]) - if ord(varint[offset]) >= 0x80: - offset += 1 - res = ((res - 0x80) << 7) + ord(varint[offset]) - if ord(varint[offset]) >= 0x80: - offset += 1 - res = ((res - 0x80) << 7) + ord(varint[offset]) - if ord(varint[offset]) >= 0x80: - offset += 1 - res = ((res - 0x80) << 7) + ord(varint[offset]) - return res, offset + 1 - - -def opt_resize_buf(buf, newsize): - if len(buf) < newsize: - return ctypes.create_string_buffer(buf.value, max(2*len, newsize)) - return buf - - -def pack_field(value, buf, offset): - if type(value) is int or type(value) is long: - if value > 0xffffffff: - raise RuntimeError("Integer value is too big") - buf = opt_resize_buf(buf, offset + INT_FIELD_LEN) - struct.pack_into("<cL", buf, offset, chr(INT_FIELD_LEN), value) - offset += INT_FIELD_LEN + 1 - elif type(value) is str: - opt_resize_buf(buf, offset + INT_BER_MAX_LEN + len(value)) - value_len_ber = save_varint32(len(value)) - struct.pack_into("{0}s{1}s".format(len(value_len_ber), len(value)), - buf, offset, value_len_ber, value) - offset += len(value_len_ber) + len(value) - else: - raise RuntimeError("Unsupported value type in value list") - return (buf, offset) - - -def pack_tuple(value_list, buf, offset): - """Represents <tuple> rule in tarantool protocol description. - Pack tuple into a binary representation. - buf and offset are in-out parameters, offset is advanced - to the amount of bytes that it took to pack the tuple""" - - # length of int field: 1 byte - field len (is always 4), 4 bytes - data - # max length of compressed integer - cardinality = len(value_list) - struct.pack_into("<L", buf, offset, cardinality) - offset += INT_FIELD_LEN - for value in value_list: - (buf, offset) = pack_field(value, buf, offset) - - return buf, offset - - -def pack_operation_list(update_list, buf, offset): - buf = opt_resize_buf(buf, offset + INT_FIELD_LEN) - struct.pack_into("<L", buf, offset, len(update_list)) - offset += INT_FIELD_LEN - for update in update_list: - opt_resize_buf(buf, offset + INT_FIELD_LEN + 1) - struct.pack_into("<Lc", buf, offset, - update[0], - chr(UPDATE_SET_FIELD_OPCODE)) - offset += INT_FIELD_LEN + 1 - (buf, offset) = pack_field(update[1], buf, offset) - - return (buf, offset) - - -def unpack_tuple(response, offset): - (size, cardinality) = struct.unpack("<LL", response[offset:offset + 8]) - offset += 8 - res = [] - while len(res) < cardinality: - (data_len, offset) = read_varint32(response, offset) - data = response[offset:offset+data_len] - offset += data_len - if data_len == 4: - (data,) = struct.unpack("<L", data) - res.append((str(data))) - else: - res.append("'" + data + "'") - - return '[' + ', '.join(res) + ']', offset - +errstr = """--- +- error: + errcode: {0} + errmsg: {1} +...""" + +def format_error(response): + return errstr.format( + ER.get(response.return_code, "ER_UNKNOWN (%d)" % response.return_code), + response.return_message) + +def format_yamllike(response): + table = ("\n"+"\n".join(["- "+str(list(k)) for k in response])) \ + if len(response) else "" + return "---{0}\n...".format(table) + +class Statement(object): + def __init__(self): + pass + def pack(self, connection): + pass + def unpack(self, response): + pass -class StatementPing: - reqeust_type = PING_REQUEST_TYPE - def pack(self): - return "" +class StatementPing(Statement): + def pack(self, connection): + return RequestPing(connection) def unpack(self, response): - return "ok\n---" - -class StatementInsert(StatementPing): - reqeust_type = INSERT_REQUEST_TYPE + if response._return_code: + return format_error(response) + return "---\n- ok\n..." +class StatementInsert(Statement): def __init__(self, table_name, value_list): self.space_no = table_name - self.flags = 0x02 # ADD + self.flags = 0x03 # ADD + RET self.value_list = value_list - def pack(self): - buf = ctypes.create_string_buffer(PACKET_BUF_LEN) - (buf, offset) = pack_tuple(self.value_list, buf, INSERT_REQUEST_FIXED_LEN) - struct.pack_into("<LL", buf, 0, self.space_no, self.flags) - return buf[:offset] + def pack(self, connection): + return RequestInsert(connection, self.space_no, self.value_list, + self.flags) def unpack(self, response): - (return_code,) = struct.unpack("<L", response[:4]) - if return_code: - return format_error(return_code, response) - (tuple_count,) = struct.unpack("<L", response[4:8]) - return "Insert OK, {0} row affected".format(tuple_count) - -class StatementReplace(StatementPing): - reqeust_type = INSERT_REQUEST_TYPE + if response.return_code: + return format_error(response) + return format_yamllike(response) +class StatementReplace(Statement): def __init__(self, table_name, value_list): self.space_no = table_name - self.flags = 0x04 # REPLACE + self.flags = 0x05 # REPLACE + RET self.value_list = value_list - def pack(self): - buf = ctypes.create_string_buffer(PACKET_BUF_LEN) - (buf, offset) = pack_tuple(self.value_list, buf, INSERT_REQUEST_FIXED_LEN) - struct.pack_into("<LL", buf, 0, self.space_no, self.flags) - return buf[:offset] + def pack(self, connection): + return RequestInsert(connection, self.space_no, self.value_list, + self.flags) def unpack(self, response): - (return_code,) = struct.unpack("<L", response[:4]) - if return_code: - return format_error(return_code, response) - (tuple_count,) = struct.unpack("<L", response[4:8]) - return "Replace OK, {0} row affected".format(tuple_count) - -class StatementUpdate(StatementPing): - reqeust_type = UPDATE_REQUEST_TYPE + if response.return_code: + return format_error(response) + return format_yamllike(response) +class StatementUpdate(Statement): def __init__(self, table_name, update_list, where): self.space_no = table_name self.flags = 0 - key_no = where[0] - if key_no != 0: - raise RuntimeError("UPDATE can only be made by the primary key (#0)") - self.value_list = where[1:] - self.update_list = update_list + self.key_no = where[0] + if self.key_no != 0: + raise RuntimeError("UPDATE can only be made by the" + " primary key (#0)") + self.value_list = where[1] + self.update_list = [(pair[0], '=', pair[1]) for pair in update_list] - def pack(self): - buf = ctypes.create_string_buffer(PACKET_BUF_LEN) - struct.pack_into("<LL", buf, 0, self.space_no, self.flags) - (buf, offset) = pack_tuple(self.value_list, buf, UPDATE_REQUEST_FIXED_LEN) - (buf, offset) = pack_operation_list(self.update_list, buf, offset) - return buf[:offset] + def pack(self, connection): + return RequestUpdate(connection, self.space_no, self.value_list, + self.update_list, True) def unpack(self, response): - (return_code,) = struct.unpack("<L", response[:4]) - if return_code: - return format_error(return_code, response) - (tuple_count,) = struct.unpack("<L", response[4:8]) - return "Update OK, {0} row affected".format(tuple_count) - -class StatementDelete(StatementPing): - reqeust_type = DELETE_REQUEST_TYPE + if response.return_code: + return format_error(response) + return format_yamllike(response) +class StatementDelete(Statement): def __init__(self, table_name, where): self.space_no = table_name self.flags = 0 key_no = where[0] if key_no != 0: - raise RuntimeError("DELETE can only be made by the primary key (#0)") - self.value_list = where[1:] + raise RuntimeError("DELETE can only be made by the " + "primary key (#0)") + self.value_list = where[1] - def pack(self): - buf = ctypes.create_string_buffer(PACKET_BUF_LEN) - (buf, offset) = pack_tuple(self.value_list, buf, DELETE_REQUEST_FIXED_LEN) - struct.pack_into("<LL", buf, 0, self.space_no, self.flags) - return buf[:offset] + def pack(self, connection): + return RequestDelete(connection, self.space_no, self.value_list, True) def unpack(self, response): - (return_code,) = struct.unpack("<L", response[:4]) - if return_code: - return format_error(return_code, response) - (tuple_count,) = struct.unpack("<L", response[4:8]) - return "Delete OK, {0} row affected".format(tuple_count) - -class StatementSelect(StatementPing): - reqeust_type = SELECT_REQUEST_TYPE + if response.return_code: + return format_error(response) + return format_yamllike(response) +class StatementSelect(Statement): def __init__(self, table_name, where, limit): self.space_no = table_name self.index_no = None self.key_list = [] if not where: self.index_no = 0 - self.key_list = ["",] + self.key_list = [[]] else: for (index_no, key) in where: - self.key_list.append(key) + self.key_list.append([key, ]) if self.index_no == None: self.index_no = index_no elif self.index_no != index_no: - raise RuntimeError("All key values in a disjunction must refer to the same index") + raise RuntimeError("All key values in a disjunction must " + "refer to the same index") self.offset = 0 self.limit = limit - def pack(self): - buf = ctypes.create_string_buffer(PACKET_BUF_LEN) - struct.pack_into("<LLLLL", buf, 0, - self.space_no, - self.index_no, - self.offset, - self.limit, - len(self.key_list)) - offset = SELECT_REQUEST_FIXED_LEN - - for key in self.key_list: - (buf, offset) = pack_tuple([key], buf, offset) - - return buf[:offset] + def pack(self, connection): + return RequestSelect(connection, self.space_no, self.index_no, + self.key_list , self.offset, self.limit) def unpack(self, response): - (return_code,) = struct.unpack("<L", response[:4]) - if return_code: - return format_error(return_code, response) - (tuple_count,) = struct.unpack("<L", response[4:8]) - tuples = [] - offset = 8 - while len(tuples) < tuple_count: - (next_tuple, offset) = unpack_tuple(response, offset) - tuples.append(next_tuple) + if response.return_code: + return format_error(response) if self.sort: - tuples.sort() - if tuple_count == 0: - return "No match" - elif tuple_count == 1: - return "Found 1 tuple:\n" + tuples[0] - else: - return "Found {0} tuples:\n".format(tuple_count) + "\n".join(tuples) + response = sorted(response[0:]) + return format_yamllike(response) class StatementCall(StatementSelect): - reqeust_type = CALL_REQUEST_TYPE - def __init__(self, proc_name, value_list): self.proc_name = proc_name # the binary protocol passes everything into procedure as strings # convert input to strings to avoid data mangling by the protocol self.value_list = map(lambda val: str(val), value_list) - def pack(self): - buf = ctypes.create_string_buffer(PACKET_BUF_LEN) - offset = 0 - struct.pack_into("<L", buf, offset, 0) # flags - offset += INT_FIELD_LEN - (buf, offset) = pack_field(self.proc_name, buf, offset) - (buf, offset) = pack_tuple(self.value_list, buf, offset) - return buf[:offset] + def pack(self, connection): + return RequestCall(connection, self.proc_name, self.value_list, True) diff --git a/test/lib/tarantool-python b/test/lib/tarantool-python new file mode 160000 index 0000000000000000000000000000000000000000..e3e3f6f28429900850ed7af7b9b481002e1b1894 --- /dev/null +++ b/test/lib/tarantool-python @@ -0,0 +1 @@ +Subproject commit e3e3f6f28429900850ed7af7b9b481002e1b1894 diff --git a/test/lib/tarantool_connection.py b/test/lib/tarantool_connection.py index e05ee6baba50ce489a326cda2f0e7a3be7aaede2..b8b9246f52c231ce1728886e035231e6910c8de1 100644 --- a/test/lib/tarantool_connection.py +++ b/test/lib/tarantool_connection.py @@ -23,7 +23,6 @@ __author__ = "Konstantin Osipov <kostja.osipov@gmail.com>" import socket import sys -import cStringIO import errno class TarantoolConnection(object): @@ -31,7 +30,6 @@ class TarantoolConnection(object): self.host = host self.port = port self.is_connected = False - self.stream = cStringIO.StringIO() self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1) diff --git a/test/lib/tarantool_server.py b/test/lib/tarantool_server.py index 1761ee7320967549ec60f5831d2241919ef6b5f4..bb446075bafc7aeec5eae549926a86287b50d1a1 100644 --- a/test/lib/tarantool_server.py +++ b/test/lib/tarantool_server.py @@ -4,6 +4,7 @@ import sys import glob import time import yaml +import errno import daemon import socket import signal @@ -16,7 +17,7 @@ import ConfigParser from lib.server import Server from lib.box_connection import BoxConnection -from lib.test_suite import FilteredStream, Test +from lib.test_suite import FilteredStream, Test, check_tarantool_import from lib.admin_connection import AdminConnection from lib.memcached_connection import MemcachedConnection @@ -25,6 +26,9 @@ try: except ImportError: import StringIO +check_tarantool_import() +import tarantool + def check_port(port): """Check if the port we're connecting to is available""" try: @@ -505,7 +509,7 @@ class TarantoolServer(Server): else: self.process.wait() - self.wait_until_stopped() + self.wait_until_stopped(pid) # clean-up processs flags self.is_started = False self.process = None @@ -601,17 +605,17 @@ class TarantoolServer(Server): except socket.error as e: time.sleep(0.001) - def wait_until_stopped(self): + def wait_until_stopped(self, pid): """Wait until the server is stoped and has closed sockets""" while True: try: - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.connect(("localhost", self.port)) - sock.close() time.sleep(0.001) + os.kill(pid, 0) continue - except socket.error as e: - break + except OSError as err: + if err.errno == errno.ESRCH: + break + raise def find_tests(self, test_suite, suite_path): def patterned(test, patterns): diff --git a/test/lib/test_suite.py b/test/lib/test_suite.py index a00d9d438a7840b43c061c008768f8b1ea4bd214..bc019b5c47c6b2799c45b5d868a06a9381374364 100644 --- a/test/lib/test_suite.py +++ b/test/lib/test_suite.py @@ -15,6 +15,17 @@ try: except ImportError: from StringIO import StringIO +def check_tarantool_import(): + try: + tnt_py = os.path.dirname(os.path.abspath(__file__)) + tnt_py = os.path.join(tnt_py, 'tarantool-python/src') + if tnt_py not in sys.path: + sys.path = [tnt_py] + sys.path + import tarantool + except ImportError: + sys.stderr.write("\n\nNo tarantool-python library found\n") + sys.exit(1) + class FilteredStream: """Helper class to filter .result file output""" def __init__(self, filename): diff --git a/test/replication/swap.result b/test/replication/swap.result index 6a38bc467a4a23973f027af506a34630bd71d624..14fa18be3c9b0d5351525953dfbca8ca633867bc 100644 --- a/test/replication/swap.result +++ b/test/replication/swap.result @@ -8,55 +8,85 @@ box.replace(box.schema.INDEX_ID, 0, 0, 'primary', 'hash', 1, 1, 0, 'num') ... test 0 iteration insert into t0 values (0, 'tuple 0') -Insert OK, 1 row affected +--- +- [0, u'tuple 0'] +... insert into t0 values (1, 'tuple 1') -Insert OK, 1 row affected +--- +- [1, u'tuple 1'] +... insert into t0 values (2, 'tuple 2') -Insert OK, 1 row affected +--- +- [2, u'tuple 2'] +... insert into t0 values (3, 'tuple 3') -Insert OK, 1 row affected +--- +- [3, u'tuple 3'] +... insert into t0 values (4, 'tuple 4') -Insert OK, 1 row affected +--- +- [4, u'tuple 4'] +... select * from t0 where k0 = 0 -Found 1 tuple: -[0, 'tuple 0'] +--- +- [0, u'tuple 0'] +... select * from t0 where k0 = 1 -Found 1 tuple: -[1, 'tuple 1'] +--- +- [1, u'tuple 1'] +... select * from t0 where k0 = 2 -Found 1 tuple: -[2, 'tuple 2'] +--- +- [2, u'tuple 2'] +... select * from t0 where k0 = 3 -Found 1 tuple: -[3, 'tuple 3'] +--- +- [3, u'tuple 3'] +... select * from t0 where k0 = 4 -Found 1 tuple: -[4, 'tuple 4'] +--- +- [4, u'tuple 4'] +... insert into t0 values (5, 'tuple 5') -Insert OK, 1 row affected +--- +- [5, u'tuple 5'] +... insert into t0 values (6, 'tuple 6') -Insert OK, 1 row affected +--- +- [6, u'tuple 6'] +... insert into t0 values (7, 'tuple 7') -Insert OK, 1 row affected +--- +- [7, u'tuple 7'] +... insert into t0 values (8, 'tuple 8') -Insert OK, 1 row affected +--- +- [8, u'tuple 8'] +... insert into t0 values (9, 'tuple 9') -Insert OK, 1 row affected +--- +- [9, u'tuple 9'] +... select * from t0 where k0 = 5 -Found 1 tuple: -[5, 'tuple 5'] +--- +- [5, u'tuple 5'] +... select * from t0 where k0 = 6 -Found 1 tuple: -[6, 'tuple 6'] +--- +- [6, u'tuple 6'] +... select * from t0 where k0 = 7 -Found 1 tuple: -[7, 'tuple 7'] +--- +- [7, u'tuple 7'] +... select * from t0 where k0 = 8 -Found 1 tuple: -[8, 'tuple 8'] +--- +- [8, u'tuple 8'] +... select * from t0 where k0 = 9 -Found 1 tuple: -[9, 'tuple 9'] +--- +- [9, u'tuple 9'] +... swap servers box.cfg.reload() --- @@ -67,55 +97,85 @@ box.cfg.reload() - ok ... insert into t0 values (10, 'tuple 10') -Insert OK, 1 row affected +--- +- [10, u'tuple 10'] +... insert into t0 values (11, 'tuple 11') -Insert OK, 1 row affected +--- +- [11, u'tuple 11'] +... insert into t0 values (12, 'tuple 12') -Insert OK, 1 row affected +--- +- [12, u'tuple 12'] +... insert into t0 values (13, 'tuple 13') -Insert OK, 1 row affected +--- +- [13, u'tuple 13'] +... insert into t0 values (14, 'tuple 14') -Insert OK, 1 row affected +--- +- [14, u'tuple 14'] +... select * from t0 where k0 = 10 -Found 1 tuple: -[10, 'tuple 10'] +--- +- [10, u'tuple 10'] +... select * from t0 where k0 = 11 -Found 1 tuple: -[11, 'tuple 11'] +--- +- [11, u'tuple 11'] +... select * from t0 where k0 = 12 -Found 1 tuple: -[12, 'tuple 12'] +--- +- [12, u'tuple 12'] +... select * from t0 where k0 = 13 -Found 1 tuple: -[13, 'tuple 13'] +--- +- [13, u'tuple 13'] +... select * from t0 where k0 = 14 -Found 1 tuple: -[14, 'tuple 14'] +--- +- [14, u'tuple 14'] +... insert into t0 values (15, 'tuple 15') -Insert OK, 1 row affected +--- +- [15, u'tuple 15'] +... insert into t0 values (16, 'tuple 16') -Insert OK, 1 row affected +--- +- [16, u'tuple 16'] +... insert into t0 values (17, 'tuple 17') -Insert OK, 1 row affected +--- +- [17, u'tuple 17'] +... insert into t0 values (18, 'tuple 18') -Insert OK, 1 row affected +--- +- [18, u'tuple 18'] +... insert into t0 values (19, 'tuple 19') -Insert OK, 1 row affected +--- +- [19, u'tuple 19'] +... select * from t0 where k0 = 15 -Found 1 tuple: -[15, 'tuple 15'] +--- +- [15, u'tuple 15'] +... select * from t0 where k0 = 16 -Found 1 tuple: -[16, 'tuple 16'] +--- +- [16, u'tuple 16'] +... select * from t0 where k0 = 17 -Found 1 tuple: -[17, 'tuple 17'] +--- +- [17, u'tuple 17'] +... select * from t0 where k0 = 18 -Found 1 tuple: -[18, 'tuple 18'] +--- +- [18, u'tuple 18'] +... select * from t0 where k0 = 19 -Found 1 tuple: -[19, 'tuple 19'] +--- +- [19, u'tuple 19'] +... rollback servers configuration box.cfg.reload() --- @@ -127,55 +187,85 @@ box.cfg.reload() ... test 1 iteration insert into t0 values (20, 'tuple 20') -Insert OK, 1 row affected +--- +- [20, u'tuple 20'] +... insert into t0 values (21, 'tuple 21') -Insert OK, 1 row affected +--- +- [21, u'tuple 21'] +... insert into t0 values (22, 'tuple 22') -Insert OK, 1 row affected +--- +- [22, u'tuple 22'] +... insert into t0 values (23, 'tuple 23') -Insert OK, 1 row affected +--- +- [23, u'tuple 23'] +... insert into t0 values (24, 'tuple 24') -Insert OK, 1 row affected +--- +- [24, u'tuple 24'] +... select * from t0 where k0 = 20 -Found 1 tuple: -[20, 'tuple 20'] +--- +- [20, u'tuple 20'] +... select * from t0 where k0 = 21 -Found 1 tuple: -[21, 'tuple 21'] +--- +- [21, u'tuple 21'] +... select * from t0 where k0 = 22 -Found 1 tuple: -[22, 'tuple 22'] +--- +- [22, u'tuple 22'] +... select * from t0 where k0 = 23 -Found 1 tuple: -[23, 'tuple 23'] +--- +- [23, u'tuple 23'] +... select * from t0 where k0 = 24 -Found 1 tuple: -[24, 'tuple 24'] +--- +- [24, u'tuple 24'] +... insert into t0 values (25, 'tuple 25') -Insert OK, 1 row affected +--- +- [25, u'tuple 25'] +... insert into t0 values (26, 'tuple 26') -Insert OK, 1 row affected +--- +- [26, u'tuple 26'] +... insert into t0 values (27, 'tuple 27') -Insert OK, 1 row affected +--- +- [27, u'tuple 27'] +... insert into t0 values (28, 'tuple 28') -Insert OK, 1 row affected +--- +- [28, u'tuple 28'] +... insert into t0 values (29, 'tuple 29') -Insert OK, 1 row affected +--- +- [29, u'tuple 29'] +... select * from t0 where k0 = 25 -Found 1 tuple: -[25, 'tuple 25'] +--- +- [25, u'tuple 25'] +... select * from t0 where k0 = 26 -Found 1 tuple: -[26, 'tuple 26'] +--- +- [26, u'tuple 26'] +... select * from t0 where k0 = 27 -Found 1 tuple: -[27, 'tuple 27'] +--- +- [27, u'tuple 27'] +... select * from t0 where k0 = 28 -Found 1 tuple: -[28, 'tuple 28'] +--- +- [28, u'tuple 28'] +... select * from t0 where k0 = 29 -Found 1 tuple: -[29, 'tuple 29'] +--- +- [29, u'tuple 29'] +... swap servers box.cfg.reload() --- @@ -186,55 +276,85 @@ box.cfg.reload() - ok ... insert into t0 values (30, 'tuple 30') -Insert OK, 1 row affected +--- +- [30, u'tuple 30'] +... insert into t0 values (31, 'tuple 31') -Insert OK, 1 row affected +--- +- [31, u'tuple 31'] +... insert into t0 values (32, 'tuple 32') -Insert OK, 1 row affected +--- +- [32, u'tuple 32'] +... insert into t0 values (33, 'tuple 33') -Insert OK, 1 row affected +--- +- [33, u'tuple 33'] +... insert into t0 values (34, 'tuple 34') -Insert OK, 1 row affected +--- +- [34, u'tuple 34'] +... select * from t0 where k0 = 30 -Found 1 tuple: -[30, 'tuple 30'] +--- +- [30, u'tuple 30'] +... select * from t0 where k0 = 31 -Found 1 tuple: -[31, 'tuple 31'] +--- +- [31, u'tuple 31'] +... select * from t0 where k0 = 32 -Found 1 tuple: -[32, 'tuple 32'] +--- +- [32, u'tuple 32'] +... select * from t0 where k0 = 33 -Found 1 tuple: -[33, 'tuple 33'] +--- +- [33, u'tuple 33'] +... select * from t0 where k0 = 34 -Found 1 tuple: -[34, 'tuple 34'] +--- +- [34, u'tuple 34'] +... insert into t0 values (35, 'tuple 35') -Insert OK, 1 row affected +--- +- [35, u'tuple 35'] +... insert into t0 values (36, 'tuple 36') -Insert OK, 1 row affected +--- +- [36, u'tuple 36'] +... insert into t0 values (37, 'tuple 37') -Insert OK, 1 row affected +--- +- [37, u'tuple 37'] +... insert into t0 values (38, 'tuple 38') -Insert OK, 1 row affected +--- +- [38, u'tuple 38'] +... insert into t0 values (39, 'tuple 39') -Insert OK, 1 row affected +--- +- [39, u'tuple 39'] +... select * from t0 where k0 = 35 -Found 1 tuple: -[35, 'tuple 35'] +--- +- [35, u'tuple 35'] +... select * from t0 where k0 = 36 -Found 1 tuple: -[36, 'tuple 36'] +--- +- [36, u'tuple 36'] +... select * from t0 where k0 = 37 -Found 1 tuple: -[37, 'tuple 37'] +--- +- [37, u'tuple 37'] +... select * from t0 where k0 = 38 -Found 1 tuple: -[38, 'tuple 38'] +--- +- [38, u'tuple 38'] +... select * from t0 where k0 = 39 -Found 1 tuple: -[39, 'tuple 39'] +--- +- [39, u'tuple 39'] +... rollback servers configuration box.cfg.reload() --- @@ -246,55 +366,85 @@ box.cfg.reload() ... test 2 iteration insert into t0 values (40, 'tuple 40') -Insert OK, 1 row affected +--- +- [40, u'tuple 40'] +... insert into t0 values (41, 'tuple 41') -Insert OK, 1 row affected +--- +- [41, u'tuple 41'] +... insert into t0 values (42, 'tuple 42') -Insert OK, 1 row affected +--- +- [42, u'tuple 42'] +... insert into t0 values (43, 'tuple 43') -Insert OK, 1 row affected +--- +- [43, u'tuple 43'] +... insert into t0 values (44, 'tuple 44') -Insert OK, 1 row affected +--- +- [44, u'tuple 44'] +... select * from t0 where k0 = 40 -Found 1 tuple: -[40, 'tuple 40'] +--- +- [40, u'tuple 40'] +... select * from t0 where k0 = 41 -Found 1 tuple: -[41, 'tuple 41'] +--- +- [41, u'tuple 41'] +... select * from t0 where k0 = 42 -Found 1 tuple: -[42, 'tuple 42'] +--- +- [42, u'tuple 42'] +... select * from t0 where k0 = 43 -Found 1 tuple: -[43, 'tuple 43'] +--- +- [43, u'tuple 43'] +... select * from t0 where k0 = 44 -Found 1 tuple: -[44, 'tuple 44'] +--- +- [44, u'tuple 44'] +... insert into t0 values (45, 'tuple 45') -Insert OK, 1 row affected +--- +- [45, u'tuple 45'] +... insert into t0 values (46, 'tuple 46') -Insert OK, 1 row affected +--- +- [46, u'tuple 46'] +... insert into t0 values (47, 'tuple 47') -Insert OK, 1 row affected +--- +- [47, u'tuple 47'] +... insert into t0 values (48, 'tuple 48') -Insert OK, 1 row affected +--- +- [48, u'tuple 48'] +... insert into t0 values (49, 'tuple 49') -Insert OK, 1 row affected +--- +- [49, u'tuple 49'] +... select * from t0 where k0 = 45 -Found 1 tuple: -[45, 'tuple 45'] +--- +- [45, u'tuple 45'] +... select * from t0 where k0 = 46 -Found 1 tuple: -[46, 'tuple 46'] +--- +- [46, u'tuple 46'] +... select * from t0 where k0 = 47 -Found 1 tuple: -[47, 'tuple 47'] +--- +- [47, u'tuple 47'] +... select * from t0 where k0 = 48 -Found 1 tuple: -[48, 'tuple 48'] +--- +- [48, u'tuple 48'] +... select * from t0 where k0 = 49 -Found 1 tuple: -[49, 'tuple 49'] +--- +- [49, u'tuple 49'] +... swap servers box.cfg.reload() --- @@ -305,55 +455,85 @@ box.cfg.reload() - ok ... insert into t0 values (50, 'tuple 50') -Insert OK, 1 row affected +--- +- [50, u'tuple 50'] +... insert into t0 values (51, 'tuple 51') -Insert OK, 1 row affected +--- +- [51, u'tuple 51'] +... insert into t0 values (52, 'tuple 52') -Insert OK, 1 row affected +--- +- [52, u'tuple 52'] +... insert into t0 values (53, 'tuple 53') -Insert OK, 1 row affected +--- +- [53, u'tuple 53'] +... insert into t0 values (54, 'tuple 54') -Insert OK, 1 row affected +--- +- [54, u'tuple 54'] +... select * from t0 where k0 = 50 -Found 1 tuple: -[50, 'tuple 50'] +--- +- [50, u'tuple 50'] +... select * from t0 where k0 = 51 -Found 1 tuple: -[51, 'tuple 51'] +--- +- [51, u'tuple 51'] +... select * from t0 where k0 = 52 -Found 1 tuple: -[52, 'tuple 52'] +--- +- [52, u'tuple 52'] +... select * from t0 where k0 = 53 -Found 1 tuple: -[53, 'tuple 53'] +--- +- [53, u'tuple 53'] +... select * from t0 where k0 = 54 -Found 1 tuple: -[54, 'tuple 54'] +--- +- [54, u'tuple 54'] +... insert into t0 values (55, 'tuple 55') -Insert OK, 1 row affected +--- +- [55, u'tuple 55'] +... insert into t0 values (56, 'tuple 56') -Insert OK, 1 row affected +--- +- [56, u'tuple 56'] +... insert into t0 values (57, 'tuple 57') -Insert OK, 1 row affected +--- +- [57, u'tuple 57'] +... insert into t0 values (58, 'tuple 58') -Insert OK, 1 row affected +--- +- [58, u'tuple 58'] +... insert into t0 values (59, 'tuple 59') -Insert OK, 1 row affected +--- +- [59, u'tuple 59'] +... select * from t0 where k0 = 55 -Found 1 tuple: -[55, 'tuple 55'] +--- +- [55, u'tuple 55'] +... select * from t0 where k0 = 56 -Found 1 tuple: -[56, 'tuple 56'] +--- +- [56, u'tuple 56'] +... select * from t0 where k0 = 57 -Found 1 tuple: -[57, 'tuple 57'] +--- +- [57, u'tuple 57'] +... select * from t0 where k0 = 58 -Found 1 tuple: -[58, 'tuple 58'] +--- +- [58, u'tuple 58'] +... select * from t0 where k0 = 59 -Found 1 tuple: -[59, 'tuple 59'] +--- +- [59, u'tuple 59'] +... rollback servers configuration box.cfg.reload() --- @@ -365,55 +545,85 @@ box.cfg.reload() ... test 3 iteration insert into t0 values (60, 'tuple 60') -Insert OK, 1 row affected +--- +- [60, u'tuple 60'] +... insert into t0 values (61, 'tuple 61') -Insert OK, 1 row affected +--- +- [61, u'tuple 61'] +... insert into t0 values (62, 'tuple 62') -Insert OK, 1 row affected +--- +- [62, u'tuple 62'] +... insert into t0 values (63, 'tuple 63') -Insert OK, 1 row affected +--- +- [63, u'tuple 63'] +... insert into t0 values (64, 'tuple 64') -Insert OK, 1 row affected +--- +- [64, u'tuple 64'] +... select * from t0 where k0 = 60 -Found 1 tuple: -[60, 'tuple 60'] +--- +- [60, u'tuple 60'] +... select * from t0 where k0 = 61 -Found 1 tuple: -[61, 'tuple 61'] +--- +- [61, u'tuple 61'] +... select * from t0 where k0 = 62 -Found 1 tuple: -[62, 'tuple 62'] +--- +- [62, u'tuple 62'] +... select * from t0 where k0 = 63 -Found 1 tuple: -[63, 'tuple 63'] +--- +- [63, u'tuple 63'] +... select * from t0 where k0 = 64 -Found 1 tuple: -[64, 'tuple 64'] +--- +- [64, u'tuple 64'] +... insert into t0 values (65, 'tuple 65') -Insert OK, 1 row affected +--- +- [65, u'tuple 65'] +... insert into t0 values (66, 'tuple 66') -Insert OK, 1 row affected +--- +- [66, u'tuple 66'] +... insert into t0 values (67, 'tuple 67') -Insert OK, 1 row affected +--- +- [67, u'tuple 67'] +... insert into t0 values (68, 'tuple 68') -Insert OK, 1 row affected +--- +- [68, u'tuple 68'] +... insert into t0 values (69, 'tuple 69') -Insert OK, 1 row affected +--- +- [69, u'tuple 69'] +... select * from t0 where k0 = 65 -Found 1 tuple: -[65, 'tuple 65'] +--- +- [65, u'tuple 65'] +... select * from t0 where k0 = 66 -Found 1 tuple: -[66, 'tuple 66'] +--- +- [66, u'tuple 66'] +... select * from t0 where k0 = 67 -Found 1 tuple: -[67, 'tuple 67'] +--- +- [67, u'tuple 67'] +... select * from t0 where k0 = 68 -Found 1 tuple: -[68, 'tuple 68'] +--- +- [68, u'tuple 68'] +... select * from t0 where k0 = 69 -Found 1 tuple: -[69, 'tuple 69'] +--- +- [69, u'tuple 69'] +... swap servers box.cfg.reload() --- @@ -424,55 +634,85 @@ box.cfg.reload() - ok ... insert into t0 values (70, 'tuple 70') -Insert OK, 1 row affected +--- +- [70, u'tuple 70'] +... insert into t0 values (71, 'tuple 71') -Insert OK, 1 row affected +--- +- [71, u'tuple 71'] +... insert into t0 values (72, 'tuple 72') -Insert OK, 1 row affected +--- +- [72, u'tuple 72'] +... insert into t0 values (73, 'tuple 73') -Insert OK, 1 row affected +--- +- [73, u'tuple 73'] +... insert into t0 values (74, 'tuple 74') -Insert OK, 1 row affected +--- +- [74, u'tuple 74'] +... select * from t0 where k0 = 70 -Found 1 tuple: -[70, 'tuple 70'] +--- +- [70, u'tuple 70'] +... select * from t0 where k0 = 71 -Found 1 tuple: -[71, 'tuple 71'] +--- +- [71, u'tuple 71'] +... select * from t0 where k0 = 72 -Found 1 tuple: -[72, 'tuple 72'] +--- +- [72, u'tuple 72'] +... select * from t0 where k0 = 73 -Found 1 tuple: -[73, 'tuple 73'] +--- +- [73, u'tuple 73'] +... select * from t0 where k0 = 74 -Found 1 tuple: -[74, 'tuple 74'] +--- +- [74, u'tuple 74'] +... insert into t0 values (75, 'tuple 75') -Insert OK, 1 row affected +--- +- [75, u'tuple 75'] +... insert into t0 values (76, 'tuple 76') -Insert OK, 1 row affected +--- +- [76, u'tuple 76'] +... insert into t0 values (77, 'tuple 77') -Insert OK, 1 row affected +--- +- [77, u'tuple 77'] +... insert into t0 values (78, 'tuple 78') -Insert OK, 1 row affected +--- +- [78, u'tuple 78'] +... insert into t0 values (79, 'tuple 79') -Insert OK, 1 row affected +--- +- [79, u'tuple 79'] +... select * from t0 where k0 = 75 -Found 1 tuple: -[75, 'tuple 75'] +--- +- [75, u'tuple 75'] +... select * from t0 where k0 = 76 -Found 1 tuple: -[76, 'tuple 76'] +--- +- [76, u'tuple 76'] +... select * from t0 where k0 = 77 -Found 1 tuple: -[77, 'tuple 77'] +--- +- [77, u'tuple 77'] +... select * from t0 where k0 = 78 -Found 1 tuple: -[78, 'tuple 78'] +--- +- [78, u'tuple 78'] +... select * from t0 where k0 = 79 -Found 1 tuple: -[79, 'tuple 79'] +--- +- [79, u'tuple 79'] +... rollback servers configuration box.cfg.reload() --- @@ -484,55 +724,85 @@ box.cfg.reload() ... test 4 iteration insert into t0 values (80, 'tuple 80') -Insert OK, 1 row affected +--- +- [80, u'tuple 80'] +... insert into t0 values (81, 'tuple 81') -Insert OK, 1 row affected +--- +- [81, u'tuple 81'] +... insert into t0 values (82, 'tuple 82') -Insert OK, 1 row affected +--- +- [82, u'tuple 82'] +... insert into t0 values (83, 'tuple 83') -Insert OK, 1 row affected +--- +- [83, u'tuple 83'] +... insert into t0 values (84, 'tuple 84') -Insert OK, 1 row affected +--- +- [84, u'tuple 84'] +... select * from t0 where k0 = 80 -Found 1 tuple: -[80, 'tuple 80'] +--- +- [80, u'tuple 80'] +... select * from t0 where k0 = 81 -Found 1 tuple: -[81, 'tuple 81'] +--- +- [81, u'tuple 81'] +... select * from t0 where k0 = 82 -Found 1 tuple: -[82, 'tuple 82'] +--- +- [82, u'tuple 82'] +... select * from t0 where k0 = 83 -Found 1 tuple: -[83, 'tuple 83'] +--- +- [83, u'tuple 83'] +... select * from t0 where k0 = 84 -Found 1 tuple: -[84, 'tuple 84'] +--- +- [84, u'tuple 84'] +... insert into t0 values (85, 'tuple 85') -Insert OK, 1 row affected +--- +- [85, u'tuple 85'] +... insert into t0 values (86, 'tuple 86') -Insert OK, 1 row affected +--- +- [86, u'tuple 86'] +... insert into t0 values (87, 'tuple 87') -Insert OK, 1 row affected +--- +- [87, u'tuple 87'] +... insert into t0 values (88, 'tuple 88') -Insert OK, 1 row affected +--- +- [88, u'tuple 88'] +... insert into t0 values (89, 'tuple 89') -Insert OK, 1 row affected +--- +- [89, u'tuple 89'] +... select * from t0 where k0 = 85 -Found 1 tuple: -[85, 'tuple 85'] +--- +- [85, u'tuple 85'] +... select * from t0 where k0 = 86 -Found 1 tuple: -[86, 'tuple 86'] +--- +- [86, u'tuple 86'] +... select * from t0 where k0 = 87 -Found 1 tuple: -[87, 'tuple 87'] +--- +- [87, u'tuple 87'] +... select * from t0 where k0 = 88 -Found 1 tuple: -[88, 'tuple 88'] +--- +- [88, u'tuple 88'] +... select * from t0 where k0 = 89 -Found 1 tuple: -[89, 'tuple 89'] +--- +- [89, u'tuple 89'] +... swap servers box.cfg.reload() --- @@ -543,55 +813,85 @@ box.cfg.reload() - ok ... insert into t0 values (90, 'tuple 90') -Insert OK, 1 row affected +--- +- [90, u'tuple 90'] +... insert into t0 values (91, 'tuple 91') -Insert OK, 1 row affected +--- +- [91, u'tuple 91'] +... insert into t0 values (92, 'tuple 92') -Insert OK, 1 row affected +--- +- [92, u'tuple 92'] +... insert into t0 values (93, 'tuple 93') -Insert OK, 1 row affected +--- +- [93, u'tuple 93'] +... insert into t0 values (94, 'tuple 94') -Insert OK, 1 row affected +--- +- [94, u'tuple 94'] +... select * from t0 where k0 = 90 -Found 1 tuple: -[90, 'tuple 90'] +--- +- [90, u'tuple 90'] +... select * from t0 where k0 = 91 -Found 1 tuple: -[91, 'tuple 91'] +--- +- [91, u'tuple 91'] +... select * from t0 where k0 = 92 -Found 1 tuple: -[92, 'tuple 92'] +--- +- [92, u'tuple 92'] +... select * from t0 where k0 = 93 -Found 1 tuple: -[93, 'tuple 93'] +--- +- [93, u'tuple 93'] +... select * from t0 where k0 = 94 -Found 1 tuple: -[94, 'tuple 94'] +--- +- [94, u'tuple 94'] +... insert into t0 values (95, 'tuple 95') -Insert OK, 1 row affected +--- +- [95, u'tuple 95'] +... insert into t0 values (96, 'tuple 96') -Insert OK, 1 row affected +--- +- [96, u'tuple 96'] +... insert into t0 values (97, 'tuple 97') -Insert OK, 1 row affected +--- +- [97, u'tuple 97'] +... insert into t0 values (98, 'tuple 98') -Insert OK, 1 row affected +--- +- [98, u'tuple 98'] +... insert into t0 values (99, 'tuple 99') -Insert OK, 1 row affected +--- +- [99, u'tuple 99'] +... select * from t0 where k0 = 95 -Found 1 tuple: -[95, 'tuple 95'] +--- +- [95, u'tuple 95'] +... select * from t0 where k0 = 96 -Found 1 tuple: -[96, 'tuple 96'] +--- +- [96, u'tuple 96'] +... select * from t0 where k0 = 97 -Found 1 tuple: -[97, 'tuple 97'] +--- +- [97, u'tuple 97'] +... select * from t0 where k0 = 98 -Found 1 tuple: -[98, 'tuple 98'] +--- +- [98, u'tuple 98'] +... select * from t0 where k0 = 99 -Found 1 tuple: -[99, 'tuple 99'] +--- +- [99, u'tuple 99'] +... rollback servers configuration box.cfg.reload() --- @@ -603,55 +903,85 @@ box.cfg.reload() ... test 5 iteration insert into t0 values (100, 'tuple 100') -Insert OK, 1 row affected +--- +- [100, u'tuple 100'] +... insert into t0 values (101, 'tuple 101') -Insert OK, 1 row affected +--- +- [101, u'tuple 101'] +... insert into t0 values (102, 'tuple 102') -Insert OK, 1 row affected +--- +- [102, u'tuple 102'] +... insert into t0 values (103, 'tuple 103') -Insert OK, 1 row affected +--- +- [103, u'tuple 103'] +... insert into t0 values (104, 'tuple 104') -Insert OK, 1 row affected +--- +- [104, u'tuple 104'] +... select * from t0 where k0 = 100 -Found 1 tuple: -[100, 'tuple 100'] +--- +- [100, u'tuple 100'] +... select * from t0 where k0 = 101 -Found 1 tuple: -[101, 'tuple 101'] +--- +- [101, u'tuple 101'] +... select * from t0 where k0 = 102 -Found 1 tuple: -[102, 'tuple 102'] +--- +- [102, u'tuple 102'] +... select * from t0 where k0 = 103 -Found 1 tuple: -[103, 'tuple 103'] +--- +- [103, u'tuple 103'] +... select * from t0 where k0 = 104 -Found 1 tuple: -[104, 'tuple 104'] +--- +- [104, u'tuple 104'] +... insert into t0 values (105, 'tuple 105') -Insert OK, 1 row affected +--- +- [105, u'tuple 105'] +... insert into t0 values (106, 'tuple 106') -Insert OK, 1 row affected +--- +- [106, u'tuple 106'] +... insert into t0 values (107, 'tuple 107') -Insert OK, 1 row affected +--- +- [107, u'tuple 107'] +... insert into t0 values (108, 'tuple 108') -Insert OK, 1 row affected +--- +- [108, u'tuple 108'] +... insert into t0 values (109, 'tuple 109') -Insert OK, 1 row affected +--- +- [109, u'tuple 109'] +... select * from t0 where k0 = 105 -Found 1 tuple: -[105, 'tuple 105'] +--- +- [105, u'tuple 105'] +... select * from t0 where k0 = 106 -Found 1 tuple: -[106, 'tuple 106'] +--- +- [106, u'tuple 106'] +... select * from t0 where k0 = 107 -Found 1 tuple: -[107, 'tuple 107'] +--- +- [107, u'tuple 107'] +... select * from t0 where k0 = 108 -Found 1 tuple: -[108, 'tuple 108'] +--- +- [108, u'tuple 108'] +... select * from t0 where k0 = 109 -Found 1 tuple: -[109, 'tuple 109'] +--- +- [109, u'tuple 109'] +... swap servers box.cfg.reload() --- @@ -662,55 +992,85 @@ box.cfg.reload() - ok ... insert into t0 values (110, 'tuple 110') -Insert OK, 1 row affected +--- +- [110, u'tuple 110'] +... insert into t0 values (111, 'tuple 111') -Insert OK, 1 row affected +--- +- [111, u'tuple 111'] +... insert into t0 values (112, 'tuple 112') -Insert OK, 1 row affected +--- +- [112, u'tuple 112'] +... insert into t0 values (113, 'tuple 113') -Insert OK, 1 row affected +--- +- [113, u'tuple 113'] +... insert into t0 values (114, 'tuple 114') -Insert OK, 1 row affected +--- +- [114, u'tuple 114'] +... select * from t0 where k0 = 110 -Found 1 tuple: -[110, 'tuple 110'] +--- +- [110, u'tuple 110'] +... select * from t0 where k0 = 111 -Found 1 tuple: -[111, 'tuple 111'] +--- +- [111, u'tuple 111'] +... select * from t0 where k0 = 112 -Found 1 tuple: -[112, 'tuple 112'] +--- +- [112, u'tuple 112'] +... select * from t0 where k0 = 113 -Found 1 tuple: -[113, 'tuple 113'] +--- +- [113, u'tuple 113'] +... select * from t0 where k0 = 114 -Found 1 tuple: -[114, 'tuple 114'] +--- +- [114, u'tuple 114'] +... insert into t0 values (115, 'tuple 115') -Insert OK, 1 row affected +--- +- [115, u'tuple 115'] +... insert into t0 values (116, 'tuple 116') -Insert OK, 1 row affected +--- +- [116, u'tuple 116'] +... insert into t0 values (117, 'tuple 117') -Insert OK, 1 row affected +--- +- [117, u'tuple 117'] +... insert into t0 values (118, 'tuple 118') -Insert OK, 1 row affected +--- +- [118, u'tuple 118'] +... insert into t0 values (119, 'tuple 119') -Insert OK, 1 row affected +--- +- [119, u'tuple 119'] +... select * from t0 where k0 = 115 -Found 1 tuple: -[115, 'tuple 115'] +--- +- [115, u'tuple 115'] +... select * from t0 where k0 = 116 -Found 1 tuple: -[116, 'tuple 116'] +--- +- [116, u'tuple 116'] +... select * from t0 where k0 = 117 -Found 1 tuple: -[117, 'tuple 117'] +--- +- [117, u'tuple 117'] +... select * from t0 where k0 = 118 -Found 1 tuple: -[118, 'tuple 118'] +--- +- [118, u'tuple 118'] +... select * from t0 where k0 = 119 -Found 1 tuple: -[119, 'tuple 119'] +--- +- [119, u'tuple 119'] +... rollback servers configuration box.cfg.reload() --- @@ -722,55 +1082,85 @@ box.cfg.reload() ... test 6 iteration insert into t0 values (120, 'tuple 120') -Insert OK, 1 row affected +--- +- [120, u'tuple 120'] +... insert into t0 values (121, 'tuple 121') -Insert OK, 1 row affected +--- +- [121, u'tuple 121'] +... insert into t0 values (122, 'tuple 122') -Insert OK, 1 row affected +--- +- [122, u'tuple 122'] +... insert into t0 values (123, 'tuple 123') -Insert OK, 1 row affected +--- +- [123, u'tuple 123'] +... insert into t0 values (124, 'tuple 124') -Insert OK, 1 row affected +--- +- [124, u'tuple 124'] +... select * from t0 where k0 = 120 -Found 1 tuple: -[120, 'tuple 120'] +--- +- [120, u'tuple 120'] +... select * from t0 where k0 = 121 -Found 1 tuple: -[121, 'tuple 121'] +--- +- [121, u'tuple 121'] +... select * from t0 where k0 = 122 -Found 1 tuple: -[122, 'tuple 122'] +--- +- [122, u'tuple 122'] +... select * from t0 where k0 = 123 -Found 1 tuple: -[123, 'tuple 123'] +--- +- [123, u'tuple 123'] +... select * from t0 where k0 = 124 -Found 1 tuple: -[124, 'tuple 124'] +--- +- [124, u'tuple 124'] +... insert into t0 values (125, 'tuple 125') -Insert OK, 1 row affected +--- +- [125, u'tuple 125'] +... insert into t0 values (126, 'tuple 126') -Insert OK, 1 row affected +--- +- [126, u'tuple 126'] +... insert into t0 values (127, 'tuple 127') -Insert OK, 1 row affected +--- +- [127, u'tuple 127'] +... insert into t0 values (128, 'tuple 128') -Insert OK, 1 row affected +--- +- [128, u'tuple 128'] +... insert into t0 values (129, 'tuple 129') -Insert OK, 1 row affected +--- +- [129, u'tuple 129'] +... select * from t0 where k0 = 125 -Found 1 tuple: -[125, 'tuple 125'] +--- +- [125, u'tuple 125'] +... select * from t0 where k0 = 126 -Found 1 tuple: -[126, 'tuple 126'] +--- +- [126, u'tuple 126'] +... select * from t0 where k0 = 127 -Found 1 tuple: -[127, 'tuple 127'] +--- +- [127, u'tuple 127'] +... select * from t0 where k0 = 128 -Found 1 tuple: -[128, 'tuple 128'] +--- +- [128, u'tuple 128'] +... select * from t0 where k0 = 129 -Found 1 tuple: -[129, 'tuple 129'] +--- +- [129, u'tuple 129'] +... swap servers box.cfg.reload() --- @@ -781,55 +1171,85 @@ box.cfg.reload() - ok ... insert into t0 values (130, 'tuple 130') -Insert OK, 1 row affected +--- +- [130, u'tuple 130'] +... insert into t0 values (131, 'tuple 131') -Insert OK, 1 row affected +--- +- [131, u'tuple 131'] +... insert into t0 values (132, 'tuple 132') -Insert OK, 1 row affected +--- +- [132, u'tuple 132'] +... insert into t0 values (133, 'tuple 133') -Insert OK, 1 row affected +--- +- [133, u'tuple 133'] +... insert into t0 values (134, 'tuple 134') -Insert OK, 1 row affected +--- +- [134, u'tuple 134'] +... select * from t0 where k0 = 130 -Found 1 tuple: -[130, 'tuple 130'] +--- +- [130, u'tuple 130'] +... select * from t0 where k0 = 131 -Found 1 tuple: -[131, 'tuple 131'] +--- +- [131, u'tuple 131'] +... select * from t0 where k0 = 132 -Found 1 tuple: -[132, 'tuple 132'] +--- +- [132, u'tuple 132'] +... select * from t0 where k0 = 133 -Found 1 tuple: -[133, 'tuple 133'] +--- +- [133, u'tuple 133'] +... select * from t0 where k0 = 134 -Found 1 tuple: -[134, 'tuple 134'] +--- +- [134, u'tuple 134'] +... insert into t0 values (135, 'tuple 135') -Insert OK, 1 row affected +--- +- [135, u'tuple 135'] +... insert into t0 values (136, 'tuple 136') -Insert OK, 1 row affected +--- +- [136, u'tuple 136'] +... insert into t0 values (137, 'tuple 137') -Insert OK, 1 row affected +--- +- [137, u'tuple 137'] +... insert into t0 values (138, 'tuple 138') -Insert OK, 1 row affected +--- +- [138, u'tuple 138'] +... insert into t0 values (139, 'tuple 139') -Insert OK, 1 row affected +--- +- [139, u'tuple 139'] +... select * from t0 where k0 = 135 -Found 1 tuple: -[135, 'tuple 135'] +--- +- [135, u'tuple 135'] +... select * from t0 where k0 = 136 -Found 1 tuple: -[136, 'tuple 136'] +--- +- [136, u'tuple 136'] +... select * from t0 where k0 = 137 -Found 1 tuple: -[137, 'tuple 137'] +--- +- [137, u'tuple 137'] +... select * from t0 where k0 = 138 -Found 1 tuple: -[138, 'tuple 138'] +--- +- [138, u'tuple 138'] +... select * from t0 where k0 = 139 -Found 1 tuple: -[139, 'tuple 139'] +--- +- [139, u'tuple 139'] +... rollback servers configuration box.cfg.reload() --- @@ -841,55 +1261,85 @@ box.cfg.reload() ... test 7 iteration insert into t0 values (140, 'tuple 140') -Insert OK, 1 row affected +--- +- [140, u'tuple 140'] +... insert into t0 values (141, 'tuple 141') -Insert OK, 1 row affected +--- +- [141, u'tuple 141'] +... insert into t0 values (142, 'tuple 142') -Insert OK, 1 row affected +--- +- [142, u'tuple 142'] +... insert into t0 values (143, 'tuple 143') -Insert OK, 1 row affected +--- +- [143, u'tuple 143'] +... insert into t0 values (144, 'tuple 144') -Insert OK, 1 row affected +--- +- [144, u'tuple 144'] +... select * from t0 where k0 = 140 -Found 1 tuple: -[140, 'tuple 140'] +--- +- [140, u'tuple 140'] +... select * from t0 where k0 = 141 -Found 1 tuple: -[141, 'tuple 141'] +--- +- [141, u'tuple 141'] +... select * from t0 where k0 = 142 -Found 1 tuple: -[142, 'tuple 142'] +--- +- [142, u'tuple 142'] +... select * from t0 where k0 = 143 -Found 1 tuple: -[143, 'tuple 143'] +--- +- [143, u'tuple 143'] +... select * from t0 where k0 = 144 -Found 1 tuple: -[144, 'tuple 144'] +--- +- [144, u'tuple 144'] +... insert into t0 values (145, 'tuple 145') -Insert OK, 1 row affected +--- +- [145, u'tuple 145'] +... insert into t0 values (146, 'tuple 146') -Insert OK, 1 row affected +--- +- [146, u'tuple 146'] +... insert into t0 values (147, 'tuple 147') -Insert OK, 1 row affected +--- +- [147, u'tuple 147'] +... insert into t0 values (148, 'tuple 148') -Insert OK, 1 row affected +--- +- [148, u'tuple 148'] +... insert into t0 values (149, 'tuple 149') -Insert OK, 1 row affected +--- +- [149, u'tuple 149'] +... select * from t0 where k0 = 145 -Found 1 tuple: -[145, 'tuple 145'] +--- +- [145, u'tuple 145'] +... select * from t0 where k0 = 146 -Found 1 tuple: -[146, 'tuple 146'] +--- +- [146, u'tuple 146'] +... select * from t0 where k0 = 147 -Found 1 tuple: -[147, 'tuple 147'] +--- +- [147, u'tuple 147'] +... select * from t0 where k0 = 148 -Found 1 tuple: -[148, 'tuple 148'] +--- +- [148, u'tuple 148'] +... select * from t0 where k0 = 149 -Found 1 tuple: -[149, 'tuple 149'] +--- +- [149, u'tuple 149'] +... swap servers box.cfg.reload() --- @@ -900,55 +1350,85 @@ box.cfg.reload() - ok ... insert into t0 values (150, 'tuple 150') -Insert OK, 1 row affected +--- +- [150, u'tuple 150'] +... insert into t0 values (151, 'tuple 151') -Insert OK, 1 row affected +--- +- [151, u'tuple 151'] +... insert into t0 values (152, 'tuple 152') -Insert OK, 1 row affected +--- +- [152, u'tuple 152'] +... insert into t0 values (153, 'tuple 153') -Insert OK, 1 row affected +--- +- [153, u'tuple 153'] +... insert into t0 values (154, 'tuple 154') -Insert OK, 1 row affected +--- +- [154, u'tuple 154'] +... select * from t0 where k0 = 150 -Found 1 tuple: -[150, 'tuple 150'] +--- +- [150, u'tuple 150'] +... select * from t0 where k0 = 151 -Found 1 tuple: -[151, 'tuple 151'] +--- +- [151, u'tuple 151'] +... select * from t0 where k0 = 152 -Found 1 tuple: -[152, 'tuple 152'] +--- +- [152, u'tuple 152'] +... select * from t0 where k0 = 153 -Found 1 tuple: -[153, 'tuple 153'] +--- +- [153, u'tuple 153'] +... select * from t0 where k0 = 154 -Found 1 tuple: -[154, 'tuple 154'] +--- +- [154, u'tuple 154'] +... insert into t0 values (155, 'tuple 155') -Insert OK, 1 row affected +--- +- [155, u'tuple 155'] +... insert into t0 values (156, 'tuple 156') -Insert OK, 1 row affected +--- +- [156, u'tuple 156'] +... insert into t0 values (157, 'tuple 157') -Insert OK, 1 row affected +--- +- [157, u'tuple 157'] +... insert into t0 values (158, 'tuple 158') -Insert OK, 1 row affected +--- +- [158, u'tuple 158'] +... insert into t0 values (159, 'tuple 159') -Insert OK, 1 row affected +--- +- [159, u'tuple 159'] +... select * from t0 where k0 = 155 -Found 1 tuple: -[155, 'tuple 155'] +--- +- [155, u'tuple 155'] +... select * from t0 where k0 = 156 -Found 1 tuple: -[156, 'tuple 156'] +--- +- [156, u'tuple 156'] +... select * from t0 where k0 = 157 -Found 1 tuple: -[157, 'tuple 157'] +--- +- [157, u'tuple 157'] +... select * from t0 where k0 = 158 -Found 1 tuple: -[158, 'tuple 158'] +--- +- [158, u'tuple 158'] +... select * from t0 where k0 = 159 -Found 1 tuple: -[159, 'tuple 159'] +--- +- [159, u'tuple 159'] +... rollback servers configuration box.cfg.reload() --- @@ -960,55 +1440,85 @@ box.cfg.reload() ... test 8 iteration insert into t0 values (160, 'tuple 160') -Insert OK, 1 row affected +--- +- [160, u'tuple 160'] +... insert into t0 values (161, 'tuple 161') -Insert OK, 1 row affected +--- +- [161, u'tuple 161'] +... insert into t0 values (162, 'tuple 162') -Insert OK, 1 row affected +--- +- [162, u'tuple 162'] +... insert into t0 values (163, 'tuple 163') -Insert OK, 1 row affected +--- +- [163, u'tuple 163'] +... insert into t0 values (164, 'tuple 164') -Insert OK, 1 row affected +--- +- [164, u'tuple 164'] +... select * from t0 where k0 = 160 -Found 1 tuple: -[160, 'tuple 160'] +--- +- [160, u'tuple 160'] +... select * from t0 where k0 = 161 -Found 1 tuple: -[161, 'tuple 161'] +--- +- [161, u'tuple 161'] +... select * from t0 where k0 = 162 -Found 1 tuple: -[162, 'tuple 162'] +--- +- [162, u'tuple 162'] +... select * from t0 where k0 = 163 -Found 1 tuple: -[163, 'tuple 163'] +--- +- [163, u'tuple 163'] +... select * from t0 where k0 = 164 -Found 1 tuple: -[164, 'tuple 164'] +--- +- [164, u'tuple 164'] +... insert into t0 values (165, 'tuple 165') -Insert OK, 1 row affected +--- +- [165, u'tuple 165'] +... insert into t0 values (166, 'tuple 166') -Insert OK, 1 row affected +--- +- [166, u'tuple 166'] +... insert into t0 values (167, 'tuple 167') -Insert OK, 1 row affected +--- +- [167, u'tuple 167'] +... insert into t0 values (168, 'tuple 168') -Insert OK, 1 row affected +--- +- [168, u'tuple 168'] +... insert into t0 values (169, 'tuple 169') -Insert OK, 1 row affected +--- +- [169, u'tuple 169'] +... select * from t0 where k0 = 165 -Found 1 tuple: -[165, 'tuple 165'] +--- +- [165, u'tuple 165'] +... select * from t0 where k0 = 166 -Found 1 tuple: -[166, 'tuple 166'] +--- +- [166, u'tuple 166'] +... select * from t0 where k0 = 167 -Found 1 tuple: -[167, 'tuple 167'] +--- +- [167, u'tuple 167'] +... select * from t0 where k0 = 168 -Found 1 tuple: -[168, 'tuple 168'] +--- +- [168, u'tuple 168'] +... select * from t0 where k0 = 169 -Found 1 tuple: -[169, 'tuple 169'] +--- +- [169, u'tuple 169'] +... swap servers box.cfg.reload() --- @@ -1019,55 +1529,85 @@ box.cfg.reload() - ok ... insert into t0 values (170, 'tuple 170') -Insert OK, 1 row affected +--- +- [170, u'tuple 170'] +... insert into t0 values (171, 'tuple 171') -Insert OK, 1 row affected +--- +- [171, u'tuple 171'] +... insert into t0 values (172, 'tuple 172') -Insert OK, 1 row affected +--- +- [172, u'tuple 172'] +... insert into t0 values (173, 'tuple 173') -Insert OK, 1 row affected +--- +- [173, u'tuple 173'] +... insert into t0 values (174, 'tuple 174') -Insert OK, 1 row affected +--- +- [174, u'tuple 174'] +... select * from t0 where k0 = 170 -Found 1 tuple: -[170, 'tuple 170'] +--- +- [170, u'tuple 170'] +... select * from t0 where k0 = 171 -Found 1 tuple: -[171, 'tuple 171'] +--- +- [171, u'tuple 171'] +... select * from t0 where k0 = 172 -Found 1 tuple: -[172, 'tuple 172'] +--- +- [172, u'tuple 172'] +... select * from t0 where k0 = 173 -Found 1 tuple: -[173, 'tuple 173'] +--- +- [173, u'tuple 173'] +... select * from t0 where k0 = 174 -Found 1 tuple: -[174, 'tuple 174'] +--- +- [174, u'tuple 174'] +... insert into t0 values (175, 'tuple 175') -Insert OK, 1 row affected +--- +- [175, u'tuple 175'] +... insert into t0 values (176, 'tuple 176') -Insert OK, 1 row affected +--- +- [176, u'tuple 176'] +... insert into t0 values (177, 'tuple 177') -Insert OK, 1 row affected +--- +- [177, u'tuple 177'] +... insert into t0 values (178, 'tuple 178') -Insert OK, 1 row affected +--- +- [178, u'tuple 178'] +... insert into t0 values (179, 'tuple 179') -Insert OK, 1 row affected +--- +- [179, u'tuple 179'] +... select * from t0 where k0 = 175 -Found 1 tuple: -[175, 'tuple 175'] +--- +- [175, u'tuple 175'] +... select * from t0 where k0 = 176 -Found 1 tuple: -[176, 'tuple 176'] +--- +- [176, u'tuple 176'] +... select * from t0 where k0 = 177 -Found 1 tuple: -[177, 'tuple 177'] +--- +- [177, u'tuple 177'] +... select * from t0 where k0 = 178 -Found 1 tuple: -[178, 'tuple 178'] +--- +- [178, u'tuple 178'] +... select * from t0 where k0 = 179 -Found 1 tuple: -[179, 'tuple 179'] +--- +- [179, u'tuple 179'] +... rollback servers configuration box.cfg.reload() --- @@ -1079,55 +1619,85 @@ box.cfg.reload() ... test 9 iteration insert into t0 values (180, 'tuple 180') -Insert OK, 1 row affected +--- +- [180, u'tuple 180'] +... insert into t0 values (181, 'tuple 181') -Insert OK, 1 row affected +--- +- [181, u'tuple 181'] +... insert into t0 values (182, 'tuple 182') -Insert OK, 1 row affected +--- +- [182, u'tuple 182'] +... insert into t0 values (183, 'tuple 183') -Insert OK, 1 row affected +--- +- [183, u'tuple 183'] +... insert into t0 values (184, 'tuple 184') -Insert OK, 1 row affected +--- +- [184, u'tuple 184'] +... select * from t0 where k0 = 180 -Found 1 tuple: -[180, 'tuple 180'] +--- +- [180, u'tuple 180'] +... select * from t0 where k0 = 181 -Found 1 tuple: -[181, 'tuple 181'] +--- +- [181, u'tuple 181'] +... select * from t0 where k0 = 182 -Found 1 tuple: -[182, 'tuple 182'] +--- +- [182, u'tuple 182'] +... select * from t0 where k0 = 183 -Found 1 tuple: -[183, 'tuple 183'] +--- +- [183, u'tuple 183'] +... select * from t0 where k0 = 184 -Found 1 tuple: -[184, 'tuple 184'] +--- +- [184, u'tuple 184'] +... insert into t0 values (185, 'tuple 185') -Insert OK, 1 row affected +--- +- [185, u'tuple 185'] +... insert into t0 values (186, 'tuple 186') -Insert OK, 1 row affected +--- +- [186, u'tuple 186'] +... insert into t0 values (187, 'tuple 187') -Insert OK, 1 row affected +--- +- [187, u'tuple 187'] +... insert into t0 values (188, 'tuple 188') -Insert OK, 1 row affected +--- +- [188, u'tuple 188'] +... insert into t0 values (189, 'tuple 189') -Insert OK, 1 row affected +--- +- [189, u'tuple 189'] +... select * from t0 where k0 = 185 -Found 1 tuple: -[185, 'tuple 185'] +--- +- [185, u'tuple 185'] +... select * from t0 where k0 = 186 -Found 1 tuple: -[186, 'tuple 186'] +--- +- [186, u'tuple 186'] +... select * from t0 where k0 = 187 -Found 1 tuple: -[187, 'tuple 187'] +--- +- [187, u'tuple 187'] +... select * from t0 where k0 = 188 -Found 1 tuple: -[188, 'tuple 188'] +--- +- [188, u'tuple 188'] +... select * from t0 where k0 = 189 -Found 1 tuple: -[189, 'tuple 189'] +--- +- [189, u'tuple 189'] +... swap servers box.cfg.reload() --- @@ -1138,55 +1708,85 @@ box.cfg.reload() - ok ... insert into t0 values (190, 'tuple 190') -Insert OK, 1 row affected +--- +- [190, u'tuple 190'] +... insert into t0 values (191, 'tuple 191') -Insert OK, 1 row affected +--- +- [191, u'tuple 191'] +... insert into t0 values (192, 'tuple 192') -Insert OK, 1 row affected +--- +- [192, u'tuple 192'] +... insert into t0 values (193, 'tuple 193') -Insert OK, 1 row affected +--- +- [193, u'tuple 193'] +... insert into t0 values (194, 'tuple 194') -Insert OK, 1 row affected +--- +- [194, u'tuple 194'] +... select * from t0 where k0 = 190 -Found 1 tuple: -[190, 'tuple 190'] +--- +- [190, u'tuple 190'] +... select * from t0 where k0 = 191 -Found 1 tuple: -[191, 'tuple 191'] +--- +- [191, u'tuple 191'] +... select * from t0 where k0 = 192 -Found 1 tuple: -[192, 'tuple 192'] +--- +- [192, u'tuple 192'] +... select * from t0 where k0 = 193 -Found 1 tuple: -[193, 'tuple 193'] +--- +- [193, u'tuple 193'] +... select * from t0 where k0 = 194 -Found 1 tuple: -[194, 'tuple 194'] +--- +- [194, u'tuple 194'] +... insert into t0 values (195, 'tuple 195') -Insert OK, 1 row affected +--- +- [195, u'tuple 195'] +... insert into t0 values (196, 'tuple 196') -Insert OK, 1 row affected +--- +- [196, u'tuple 196'] +... insert into t0 values (197, 'tuple 197') -Insert OK, 1 row affected +--- +- [197, u'tuple 197'] +... insert into t0 values (198, 'tuple 198') -Insert OK, 1 row affected +--- +- [198, u'tuple 198'] +... insert into t0 values (199, 'tuple 199') -Insert OK, 1 row affected +--- +- [199, u'tuple 199'] +... select * from t0 where k0 = 195 -Found 1 tuple: -[195, 'tuple 195'] +--- +- [195, u'tuple 195'] +... select * from t0 where k0 = 196 -Found 1 tuple: -[196, 'tuple 196'] +--- +- [196, u'tuple 196'] +... select * from t0 where k0 = 197 -Found 1 tuple: -[197, 'tuple 197'] +--- +- [197, u'tuple 197'] +... select * from t0 where k0 = 198 -Found 1 tuple: -[198, 'tuple 198'] +--- +- [198, u'tuple 198'] +... select * from t0 where k0 = 199 -Found 1 tuple: -[199, 'tuple 199'] +--- +- [199, u'tuple 199'] +... rollback servers configuration box.cfg.reload() --- @@ -1198,55 +1798,85 @@ box.cfg.reload() ... test 10 iteration insert into t0 values (200, 'tuple 200') -Insert OK, 1 row affected +--- +- [200, u'tuple 200'] +... insert into t0 values (201, 'tuple 201') -Insert OK, 1 row affected +--- +- [201, u'tuple 201'] +... insert into t0 values (202, 'tuple 202') -Insert OK, 1 row affected +--- +- [202, u'tuple 202'] +... insert into t0 values (203, 'tuple 203') -Insert OK, 1 row affected +--- +- [203, u'tuple 203'] +... insert into t0 values (204, 'tuple 204') -Insert OK, 1 row affected +--- +- [204, u'tuple 204'] +... select * from t0 where k0 = 200 -Found 1 tuple: -[200, 'tuple 200'] +--- +- [200, u'tuple 200'] +... select * from t0 where k0 = 201 -Found 1 tuple: -[201, 'tuple 201'] +--- +- [201, u'tuple 201'] +... select * from t0 where k0 = 202 -Found 1 tuple: -[202, 'tuple 202'] +--- +- [202, u'tuple 202'] +... select * from t0 where k0 = 203 -Found 1 tuple: -[203, 'tuple 203'] +--- +- [203, u'tuple 203'] +... select * from t0 where k0 = 204 -Found 1 tuple: -[204, 'tuple 204'] +--- +- [204, u'tuple 204'] +... insert into t0 values (205, 'tuple 205') -Insert OK, 1 row affected +--- +- [205, u'tuple 205'] +... insert into t0 values (206, 'tuple 206') -Insert OK, 1 row affected +--- +- [206, u'tuple 206'] +... insert into t0 values (207, 'tuple 207') -Insert OK, 1 row affected +--- +- [207, u'tuple 207'] +... insert into t0 values (208, 'tuple 208') -Insert OK, 1 row affected +--- +- [208, u'tuple 208'] +... insert into t0 values (209, 'tuple 209') -Insert OK, 1 row affected +--- +- [209, u'tuple 209'] +... select * from t0 where k0 = 205 -Found 1 tuple: -[205, 'tuple 205'] +--- +- [205, u'tuple 205'] +... select * from t0 where k0 = 206 -Found 1 tuple: -[206, 'tuple 206'] +--- +- [206, u'tuple 206'] +... select * from t0 where k0 = 207 -Found 1 tuple: -[207, 'tuple 207'] +--- +- [207, u'tuple 207'] +... select * from t0 where k0 = 208 -Found 1 tuple: -[208, 'tuple 208'] +--- +- [208, u'tuple 208'] +... select * from t0 where k0 = 209 -Found 1 tuple: -[209, 'tuple 209'] +--- +- [209, u'tuple 209'] +... swap servers box.cfg.reload() --- @@ -1257,55 +1887,85 @@ box.cfg.reload() - ok ... insert into t0 values (210, 'tuple 210') -Insert OK, 1 row affected +--- +- [210, u'tuple 210'] +... insert into t0 values (211, 'tuple 211') -Insert OK, 1 row affected +--- +- [211, u'tuple 211'] +... insert into t0 values (212, 'tuple 212') -Insert OK, 1 row affected +--- +- [212, u'tuple 212'] +... insert into t0 values (213, 'tuple 213') -Insert OK, 1 row affected +--- +- [213, u'tuple 213'] +... insert into t0 values (214, 'tuple 214') -Insert OK, 1 row affected +--- +- [214, u'tuple 214'] +... select * from t0 where k0 = 210 -Found 1 tuple: -[210, 'tuple 210'] +--- +- [210, u'tuple 210'] +... select * from t0 where k0 = 211 -Found 1 tuple: -[211, 'tuple 211'] +--- +- [211, u'tuple 211'] +... select * from t0 where k0 = 212 -Found 1 tuple: -[212, 'tuple 212'] +--- +- [212, u'tuple 212'] +... select * from t0 where k0 = 213 -Found 1 tuple: -[213, 'tuple 213'] +--- +- [213, u'tuple 213'] +... select * from t0 where k0 = 214 -Found 1 tuple: -[214, 'tuple 214'] +--- +- [214, u'tuple 214'] +... insert into t0 values (215, 'tuple 215') -Insert OK, 1 row affected +--- +- [215, u'tuple 215'] +... insert into t0 values (216, 'tuple 216') -Insert OK, 1 row affected +--- +- [216, u'tuple 216'] +... insert into t0 values (217, 'tuple 217') -Insert OK, 1 row affected +--- +- [217, u'tuple 217'] +... insert into t0 values (218, 'tuple 218') -Insert OK, 1 row affected +--- +- [218, u'tuple 218'] +... insert into t0 values (219, 'tuple 219') -Insert OK, 1 row affected +--- +- [219, u'tuple 219'] +... select * from t0 where k0 = 215 -Found 1 tuple: -[215, 'tuple 215'] +--- +- [215, u'tuple 215'] +... select * from t0 where k0 = 216 -Found 1 tuple: -[216, 'tuple 216'] +--- +- [216, u'tuple 216'] +... select * from t0 where k0 = 217 -Found 1 tuple: -[217, 'tuple 217'] +--- +- [217, u'tuple 217'] +... select * from t0 where k0 = 218 -Found 1 tuple: -[218, 'tuple 218'] +--- +- [218, u'tuple 218'] +... select * from t0 where k0 = 219 -Found 1 tuple: -[219, 'tuple 219'] +--- +- [219, u'tuple 219'] +... rollback servers configuration box.cfg.reload() --- @@ -1317,55 +1977,85 @@ box.cfg.reload() ... test 11 iteration insert into t0 values (220, 'tuple 220') -Insert OK, 1 row affected +--- +- [220, u'tuple 220'] +... insert into t0 values (221, 'tuple 221') -Insert OK, 1 row affected +--- +- [221, u'tuple 221'] +... insert into t0 values (222, 'tuple 222') -Insert OK, 1 row affected +--- +- [222, u'tuple 222'] +... insert into t0 values (223, 'tuple 223') -Insert OK, 1 row affected +--- +- [223, u'tuple 223'] +... insert into t0 values (224, 'tuple 224') -Insert OK, 1 row affected +--- +- [224, u'tuple 224'] +... select * from t0 where k0 = 220 -Found 1 tuple: -[220, 'tuple 220'] +--- +- [220, u'tuple 220'] +... select * from t0 where k0 = 221 -Found 1 tuple: -[221, 'tuple 221'] +--- +- [221, u'tuple 221'] +... select * from t0 where k0 = 222 -Found 1 tuple: -[222, 'tuple 222'] +--- +- [222, u'tuple 222'] +... select * from t0 where k0 = 223 -Found 1 tuple: -[223, 'tuple 223'] +--- +- [223, u'tuple 223'] +... select * from t0 where k0 = 224 -Found 1 tuple: -[224, 'tuple 224'] +--- +- [224, u'tuple 224'] +... insert into t0 values (225, 'tuple 225') -Insert OK, 1 row affected +--- +- [225, u'tuple 225'] +... insert into t0 values (226, 'tuple 226') -Insert OK, 1 row affected +--- +- [226, u'tuple 226'] +... insert into t0 values (227, 'tuple 227') -Insert OK, 1 row affected +--- +- [227, u'tuple 227'] +... insert into t0 values (228, 'tuple 228') -Insert OK, 1 row affected +--- +- [228, u'tuple 228'] +... insert into t0 values (229, 'tuple 229') -Insert OK, 1 row affected +--- +- [229, u'tuple 229'] +... select * from t0 where k0 = 225 -Found 1 tuple: -[225, 'tuple 225'] +--- +- [225, u'tuple 225'] +... select * from t0 where k0 = 226 -Found 1 tuple: -[226, 'tuple 226'] +--- +- [226, u'tuple 226'] +... select * from t0 where k0 = 227 -Found 1 tuple: -[227, 'tuple 227'] +--- +- [227, u'tuple 227'] +... select * from t0 where k0 = 228 -Found 1 tuple: -[228, 'tuple 228'] +--- +- [228, u'tuple 228'] +... select * from t0 where k0 = 229 -Found 1 tuple: -[229, 'tuple 229'] +--- +- [229, u'tuple 229'] +... swap servers box.cfg.reload() --- @@ -1376,55 +2066,85 @@ box.cfg.reload() - ok ... insert into t0 values (230, 'tuple 230') -Insert OK, 1 row affected +--- +- [230, u'tuple 230'] +... insert into t0 values (231, 'tuple 231') -Insert OK, 1 row affected +--- +- [231, u'tuple 231'] +... insert into t0 values (232, 'tuple 232') -Insert OK, 1 row affected +--- +- [232, u'tuple 232'] +... insert into t0 values (233, 'tuple 233') -Insert OK, 1 row affected +--- +- [233, u'tuple 233'] +... insert into t0 values (234, 'tuple 234') -Insert OK, 1 row affected +--- +- [234, u'tuple 234'] +... select * from t0 where k0 = 230 -Found 1 tuple: -[230, 'tuple 230'] +--- +- [230, u'tuple 230'] +... select * from t0 where k0 = 231 -Found 1 tuple: -[231, 'tuple 231'] +--- +- [231, u'tuple 231'] +... select * from t0 where k0 = 232 -Found 1 tuple: -[232, 'tuple 232'] +--- +- [232, u'tuple 232'] +... select * from t0 where k0 = 233 -Found 1 tuple: -[233, 'tuple 233'] +--- +- [233, u'tuple 233'] +... select * from t0 where k0 = 234 -Found 1 tuple: -[234, 'tuple 234'] +--- +- [234, u'tuple 234'] +... insert into t0 values (235, 'tuple 235') -Insert OK, 1 row affected +--- +- [235, u'tuple 235'] +... insert into t0 values (236, 'tuple 236') -Insert OK, 1 row affected +--- +- [236, u'tuple 236'] +... insert into t0 values (237, 'tuple 237') -Insert OK, 1 row affected +--- +- [237, u'tuple 237'] +... insert into t0 values (238, 'tuple 238') -Insert OK, 1 row affected +--- +- [238, u'tuple 238'] +... insert into t0 values (239, 'tuple 239') -Insert OK, 1 row affected +--- +- [239, u'tuple 239'] +... select * from t0 where k0 = 235 -Found 1 tuple: -[235, 'tuple 235'] +--- +- [235, u'tuple 235'] +... select * from t0 where k0 = 236 -Found 1 tuple: -[236, 'tuple 236'] +--- +- [236, u'tuple 236'] +... select * from t0 where k0 = 237 -Found 1 tuple: -[237, 'tuple 237'] +--- +- [237, u'tuple 237'] +... select * from t0 where k0 = 238 -Found 1 tuple: -[238, 'tuple 238'] +--- +- [238, u'tuple 238'] +... select * from t0 where k0 = 239 -Found 1 tuple: -[239, 'tuple 239'] +--- +- [239, u'tuple 239'] +... rollback servers configuration box.cfg.reload() --- @@ -1436,55 +2156,85 @@ box.cfg.reload() ... test 12 iteration insert into t0 values (240, 'tuple 240') -Insert OK, 1 row affected +--- +- [240, u'tuple 240'] +... insert into t0 values (241, 'tuple 241') -Insert OK, 1 row affected +--- +- [241, u'tuple 241'] +... insert into t0 values (242, 'tuple 242') -Insert OK, 1 row affected +--- +- [242, u'tuple 242'] +... insert into t0 values (243, 'tuple 243') -Insert OK, 1 row affected +--- +- [243, u'tuple 243'] +... insert into t0 values (244, 'tuple 244') -Insert OK, 1 row affected +--- +- [244, u'tuple 244'] +... select * from t0 where k0 = 240 -Found 1 tuple: -[240, 'tuple 240'] +--- +- [240, u'tuple 240'] +... select * from t0 where k0 = 241 -Found 1 tuple: -[241, 'tuple 241'] +--- +- [241, u'tuple 241'] +... select * from t0 where k0 = 242 -Found 1 tuple: -[242, 'tuple 242'] +--- +- [242, u'tuple 242'] +... select * from t0 where k0 = 243 -Found 1 tuple: -[243, 'tuple 243'] +--- +- [243, u'tuple 243'] +... select * from t0 where k0 = 244 -Found 1 tuple: -[244, 'tuple 244'] +--- +- [244, u'tuple 244'] +... insert into t0 values (245, 'tuple 245') -Insert OK, 1 row affected +--- +- [245, u'tuple 245'] +... insert into t0 values (246, 'tuple 246') -Insert OK, 1 row affected +--- +- [246, u'tuple 246'] +... insert into t0 values (247, 'tuple 247') -Insert OK, 1 row affected +--- +- [247, u'tuple 247'] +... insert into t0 values (248, 'tuple 248') -Insert OK, 1 row affected +--- +- [248, u'tuple 248'] +... insert into t0 values (249, 'tuple 249') -Insert OK, 1 row affected +--- +- [249, u'tuple 249'] +... select * from t0 where k0 = 245 -Found 1 tuple: -[245, 'tuple 245'] +--- +- [245, u'tuple 245'] +... select * from t0 where k0 = 246 -Found 1 tuple: -[246, 'tuple 246'] +--- +- [246, u'tuple 246'] +... select * from t0 where k0 = 247 -Found 1 tuple: -[247, 'tuple 247'] +--- +- [247, u'tuple 247'] +... select * from t0 where k0 = 248 -Found 1 tuple: -[248, 'tuple 248'] +--- +- [248, u'tuple 248'] +... select * from t0 where k0 = 249 -Found 1 tuple: -[249, 'tuple 249'] +--- +- [249, u'tuple 249'] +... swap servers box.cfg.reload() --- @@ -1495,55 +2245,85 @@ box.cfg.reload() - ok ... insert into t0 values (250, 'tuple 250') -Insert OK, 1 row affected +--- +- [250, u'tuple 250'] +... insert into t0 values (251, 'tuple 251') -Insert OK, 1 row affected +--- +- [251, u'tuple 251'] +... insert into t0 values (252, 'tuple 252') -Insert OK, 1 row affected +--- +- [252, u'tuple 252'] +... insert into t0 values (253, 'tuple 253') -Insert OK, 1 row affected +--- +- [253, u'tuple 253'] +... insert into t0 values (254, 'tuple 254') -Insert OK, 1 row affected +--- +- [254, u'tuple 254'] +... select * from t0 where k0 = 250 -Found 1 tuple: -[250, 'tuple 250'] +--- +- [250, u'tuple 250'] +... select * from t0 where k0 = 251 -Found 1 tuple: -[251, 'tuple 251'] +--- +- [251, u'tuple 251'] +... select * from t0 where k0 = 252 -Found 1 tuple: -[252, 'tuple 252'] +--- +- [252, u'tuple 252'] +... select * from t0 where k0 = 253 -Found 1 tuple: -[253, 'tuple 253'] +--- +- [253, u'tuple 253'] +... select * from t0 where k0 = 254 -Found 1 tuple: -[254, 'tuple 254'] +--- +- [254, u'tuple 254'] +... insert into t0 values (255, 'tuple 255') -Insert OK, 1 row affected +--- +- [255, u'tuple 255'] +... insert into t0 values (256, 'tuple 256') -Insert OK, 1 row affected +--- +- [256, u'tuple 256'] +... insert into t0 values (257, 'tuple 257') -Insert OK, 1 row affected +--- +- [257, u'tuple 257'] +... insert into t0 values (258, 'tuple 258') -Insert OK, 1 row affected +--- +- [258, u'tuple 258'] +... insert into t0 values (259, 'tuple 259') -Insert OK, 1 row affected +--- +- [259, u'tuple 259'] +... select * from t0 where k0 = 255 -Found 1 tuple: -[255, 'tuple 255'] +--- +- [255, u'tuple 255'] +... select * from t0 where k0 = 256 -Found 1 tuple: -[256, 'tuple 256'] +--- +- [256, u'tuple 256'] +... select * from t0 where k0 = 257 -Found 1 tuple: -[257, 'tuple 257'] +--- +- [257, u'tuple 257'] +... select * from t0 where k0 = 258 -Found 1 tuple: -[258, 'tuple 258'] +--- +- [258, u'tuple 258'] +... select * from t0 where k0 = 259 -Found 1 tuple: -[259, 'tuple 259'] +--- +- [259, u'tuple 259'] +... rollback servers configuration box.cfg.reload() --- @@ -1555,55 +2335,85 @@ box.cfg.reload() ... test 13 iteration insert into t0 values (260, 'tuple 260') -Insert OK, 1 row affected +--- +- [260, u'tuple 260'] +... insert into t0 values (261, 'tuple 261') -Insert OK, 1 row affected +--- +- [261, u'tuple 261'] +... insert into t0 values (262, 'tuple 262') -Insert OK, 1 row affected +--- +- [262, u'tuple 262'] +... insert into t0 values (263, 'tuple 263') -Insert OK, 1 row affected +--- +- [263, u'tuple 263'] +... insert into t0 values (264, 'tuple 264') -Insert OK, 1 row affected +--- +- [264, u'tuple 264'] +... select * from t0 where k0 = 260 -Found 1 tuple: -[260, 'tuple 260'] +--- +- [260, u'tuple 260'] +... select * from t0 where k0 = 261 -Found 1 tuple: -[261, 'tuple 261'] +--- +- [261, u'tuple 261'] +... select * from t0 where k0 = 262 -Found 1 tuple: -[262, 'tuple 262'] +--- +- [262, u'tuple 262'] +... select * from t0 where k0 = 263 -Found 1 tuple: -[263, 'tuple 263'] +--- +- [263, u'tuple 263'] +... select * from t0 where k0 = 264 -Found 1 tuple: -[264, 'tuple 264'] +--- +- [264, u'tuple 264'] +... insert into t0 values (265, 'tuple 265') -Insert OK, 1 row affected +--- +- [265, u'tuple 265'] +... insert into t0 values (266, 'tuple 266') -Insert OK, 1 row affected +--- +- [266, u'tuple 266'] +... insert into t0 values (267, 'tuple 267') -Insert OK, 1 row affected +--- +- [267, u'tuple 267'] +... insert into t0 values (268, 'tuple 268') -Insert OK, 1 row affected +--- +- [268, u'tuple 268'] +... insert into t0 values (269, 'tuple 269') -Insert OK, 1 row affected +--- +- [269, u'tuple 269'] +... select * from t0 where k0 = 265 -Found 1 tuple: -[265, 'tuple 265'] +--- +- [265, u'tuple 265'] +... select * from t0 where k0 = 266 -Found 1 tuple: -[266, 'tuple 266'] +--- +- [266, u'tuple 266'] +... select * from t0 where k0 = 267 -Found 1 tuple: -[267, 'tuple 267'] +--- +- [267, u'tuple 267'] +... select * from t0 where k0 = 268 -Found 1 tuple: -[268, 'tuple 268'] +--- +- [268, u'tuple 268'] +... select * from t0 where k0 = 269 -Found 1 tuple: -[269, 'tuple 269'] +--- +- [269, u'tuple 269'] +... swap servers box.cfg.reload() --- @@ -1614,55 +2424,85 @@ box.cfg.reload() - ok ... insert into t0 values (270, 'tuple 270') -Insert OK, 1 row affected +--- +- [270, u'tuple 270'] +... insert into t0 values (271, 'tuple 271') -Insert OK, 1 row affected +--- +- [271, u'tuple 271'] +... insert into t0 values (272, 'tuple 272') -Insert OK, 1 row affected +--- +- [272, u'tuple 272'] +... insert into t0 values (273, 'tuple 273') -Insert OK, 1 row affected +--- +- [273, u'tuple 273'] +... insert into t0 values (274, 'tuple 274') -Insert OK, 1 row affected +--- +- [274, u'tuple 274'] +... select * from t0 where k0 = 270 -Found 1 tuple: -[270, 'tuple 270'] +--- +- [270, u'tuple 270'] +... select * from t0 where k0 = 271 -Found 1 tuple: -[271, 'tuple 271'] +--- +- [271, u'tuple 271'] +... select * from t0 where k0 = 272 -Found 1 tuple: -[272, 'tuple 272'] +--- +- [272, u'tuple 272'] +... select * from t0 where k0 = 273 -Found 1 tuple: -[273, 'tuple 273'] +--- +- [273, u'tuple 273'] +... select * from t0 where k0 = 274 -Found 1 tuple: -[274, 'tuple 274'] +--- +- [274, u'tuple 274'] +... insert into t0 values (275, 'tuple 275') -Insert OK, 1 row affected +--- +- [275, u'tuple 275'] +... insert into t0 values (276, 'tuple 276') -Insert OK, 1 row affected +--- +- [276, u'tuple 276'] +... insert into t0 values (277, 'tuple 277') -Insert OK, 1 row affected +--- +- [277, u'tuple 277'] +... insert into t0 values (278, 'tuple 278') -Insert OK, 1 row affected +--- +- [278, u'tuple 278'] +... insert into t0 values (279, 'tuple 279') -Insert OK, 1 row affected +--- +- [279, u'tuple 279'] +... select * from t0 where k0 = 275 -Found 1 tuple: -[275, 'tuple 275'] +--- +- [275, u'tuple 275'] +... select * from t0 where k0 = 276 -Found 1 tuple: -[276, 'tuple 276'] +--- +- [276, u'tuple 276'] +... select * from t0 where k0 = 277 -Found 1 tuple: -[277, 'tuple 277'] +--- +- [277, u'tuple 277'] +... select * from t0 where k0 = 278 -Found 1 tuple: -[278, 'tuple 278'] +--- +- [278, u'tuple 278'] +... select * from t0 where k0 = 279 -Found 1 tuple: -[279, 'tuple 279'] +--- +- [279, u'tuple 279'] +... rollback servers configuration box.cfg.reload() --- @@ -1674,55 +2514,85 @@ box.cfg.reload() ... test 14 iteration insert into t0 values (280, 'tuple 280') -Insert OK, 1 row affected +--- +- [280, u'tuple 280'] +... insert into t0 values (281, 'tuple 281') -Insert OK, 1 row affected +--- +- [281, u'tuple 281'] +... insert into t0 values (282, 'tuple 282') -Insert OK, 1 row affected +--- +- [282, u'tuple 282'] +... insert into t0 values (283, 'tuple 283') -Insert OK, 1 row affected +--- +- [283, u'tuple 283'] +... insert into t0 values (284, 'tuple 284') -Insert OK, 1 row affected +--- +- [284, u'tuple 284'] +... select * from t0 where k0 = 280 -Found 1 tuple: -[280, 'tuple 280'] +--- +- [280, u'tuple 280'] +... select * from t0 where k0 = 281 -Found 1 tuple: -[281, 'tuple 281'] +--- +- [281, u'tuple 281'] +... select * from t0 where k0 = 282 -Found 1 tuple: -[282, 'tuple 282'] +--- +- [282, u'tuple 282'] +... select * from t0 where k0 = 283 -Found 1 tuple: -[283, 'tuple 283'] +--- +- [283, u'tuple 283'] +... select * from t0 where k0 = 284 -Found 1 tuple: -[284, 'tuple 284'] +--- +- [284, u'tuple 284'] +... insert into t0 values (285, 'tuple 285') -Insert OK, 1 row affected +--- +- [285, u'tuple 285'] +... insert into t0 values (286, 'tuple 286') -Insert OK, 1 row affected +--- +- [286, u'tuple 286'] +... insert into t0 values (287, 'tuple 287') -Insert OK, 1 row affected +--- +- [287, u'tuple 287'] +... insert into t0 values (288, 'tuple 288') -Insert OK, 1 row affected +--- +- [288, u'tuple 288'] +... insert into t0 values (289, 'tuple 289') -Insert OK, 1 row affected +--- +- [289, u'tuple 289'] +... select * from t0 where k0 = 285 -Found 1 tuple: -[285, 'tuple 285'] +--- +- [285, u'tuple 285'] +... select * from t0 where k0 = 286 -Found 1 tuple: -[286, 'tuple 286'] +--- +- [286, u'tuple 286'] +... select * from t0 where k0 = 287 -Found 1 tuple: -[287, 'tuple 287'] +--- +- [287, u'tuple 287'] +... select * from t0 where k0 = 288 -Found 1 tuple: -[288, 'tuple 288'] +--- +- [288, u'tuple 288'] +... select * from t0 where k0 = 289 -Found 1 tuple: -[289, 'tuple 289'] +--- +- [289, u'tuple 289'] +... swap servers box.cfg.reload() --- @@ -1733,55 +2603,85 @@ box.cfg.reload() - ok ... insert into t0 values (290, 'tuple 290') -Insert OK, 1 row affected +--- +- [290, u'tuple 290'] +... insert into t0 values (291, 'tuple 291') -Insert OK, 1 row affected +--- +- [291, u'tuple 291'] +... insert into t0 values (292, 'tuple 292') -Insert OK, 1 row affected +--- +- [292, u'tuple 292'] +... insert into t0 values (293, 'tuple 293') -Insert OK, 1 row affected +--- +- [293, u'tuple 293'] +... insert into t0 values (294, 'tuple 294') -Insert OK, 1 row affected +--- +- [294, u'tuple 294'] +... select * from t0 where k0 = 290 -Found 1 tuple: -[290, 'tuple 290'] +--- +- [290, u'tuple 290'] +... select * from t0 where k0 = 291 -Found 1 tuple: -[291, 'tuple 291'] +--- +- [291, u'tuple 291'] +... select * from t0 where k0 = 292 -Found 1 tuple: -[292, 'tuple 292'] +--- +- [292, u'tuple 292'] +... select * from t0 where k0 = 293 -Found 1 tuple: -[293, 'tuple 293'] +--- +- [293, u'tuple 293'] +... select * from t0 where k0 = 294 -Found 1 tuple: -[294, 'tuple 294'] +--- +- [294, u'tuple 294'] +... insert into t0 values (295, 'tuple 295') -Insert OK, 1 row affected +--- +- [295, u'tuple 295'] +... insert into t0 values (296, 'tuple 296') -Insert OK, 1 row affected +--- +- [296, u'tuple 296'] +... insert into t0 values (297, 'tuple 297') -Insert OK, 1 row affected +--- +- [297, u'tuple 297'] +... insert into t0 values (298, 'tuple 298') -Insert OK, 1 row affected +--- +- [298, u'tuple 298'] +... insert into t0 values (299, 'tuple 299') -Insert OK, 1 row affected +--- +- [299, u'tuple 299'] +... select * from t0 where k0 = 295 -Found 1 tuple: -[295, 'tuple 295'] +--- +- [295, u'tuple 295'] +... select * from t0 where k0 = 296 -Found 1 tuple: -[296, 'tuple 296'] +--- +- [296, u'tuple 296'] +... select * from t0 where k0 = 297 -Found 1 tuple: -[297, 'tuple 297'] +--- +- [297, u'tuple 297'] +... select * from t0 where k0 = 298 -Found 1 tuple: -[298, 'tuple 298'] +--- +- [298, u'tuple 298'] +... select * from t0 where k0 = 299 -Found 1 tuple: -[299, 'tuple 299'] +--- +- [299, u'tuple 299'] +... rollback servers configuration box.cfg.reload() --- @@ -1793,55 +2693,85 @@ box.cfg.reload() ... test 15 iteration insert into t0 values (300, 'tuple 300') -Insert OK, 1 row affected +--- +- [300, u'tuple 300'] +... insert into t0 values (301, 'tuple 301') -Insert OK, 1 row affected +--- +- [301, u'tuple 301'] +... insert into t0 values (302, 'tuple 302') -Insert OK, 1 row affected +--- +- [302, u'tuple 302'] +... insert into t0 values (303, 'tuple 303') -Insert OK, 1 row affected +--- +- [303, u'tuple 303'] +... insert into t0 values (304, 'tuple 304') -Insert OK, 1 row affected +--- +- [304, u'tuple 304'] +... select * from t0 where k0 = 300 -Found 1 tuple: -[300, 'tuple 300'] +--- +- [300, u'tuple 300'] +... select * from t0 where k0 = 301 -Found 1 tuple: -[301, 'tuple 301'] +--- +- [301, u'tuple 301'] +... select * from t0 where k0 = 302 -Found 1 tuple: -[302, 'tuple 302'] +--- +- [302, u'tuple 302'] +... select * from t0 where k0 = 303 -Found 1 tuple: -[303, 'tuple 303'] +--- +- [303, u'tuple 303'] +... select * from t0 where k0 = 304 -Found 1 tuple: -[304, 'tuple 304'] +--- +- [304, u'tuple 304'] +... insert into t0 values (305, 'tuple 305') -Insert OK, 1 row affected +--- +- [305, u'tuple 305'] +... insert into t0 values (306, 'tuple 306') -Insert OK, 1 row affected +--- +- [306, u'tuple 306'] +... insert into t0 values (307, 'tuple 307') -Insert OK, 1 row affected +--- +- [307, u'tuple 307'] +... insert into t0 values (308, 'tuple 308') -Insert OK, 1 row affected +--- +- [308, u'tuple 308'] +... insert into t0 values (309, 'tuple 309') -Insert OK, 1 row affected +--- +- [309, u'tuple 309'] +... select * from t0 where k0 = 305 -Found 1 tuple: -[305, 'tuple 305'] +--- +- [305, u'tuple 305'] +... select * from t0 where k0 = 306 -Found 1 tuple: -[306, 'tuple 306'] +--- +- [306, u'tuple 306'] +... select * from t0 where k0 = 307 -Found 1 tuple: -[307, 'tuple 307'] +--- +- [307, u'tuple 307'] +... select * from t0 where k0 = 308 -Found 1 tuple: -[308, 'tuple 308'] +--- +- [308, u'tuple 308'] +... select * from t0 where k0 = 309 -Found 1 tuple: -[309, 'tuple 309'] +--- +- [309, u'tuple 309'] +... swap servers box.cfg.reload() --- @@ -1852,55 +2782,85 @@ box.cfg.reload() - ok ... insert into t0 values (310, 'tuple 310') -Insert OK, 1 row affected +--- +- [310, u'tuple 310'] +... insert into t0 values (311, 'tuple 311') -Insert OK, 1 row affected +--- +- [311, u'tuple 311'] +... insert into t0 values (312, 'tuple 312') -Insert OK, 1 row affected +--- +- [312, u'tuple 312'] +... insert into t0 values (313, 'tuple 313') -Insert OK, 1 row affected +--- +- [313, u'tuple 313'] +... insert into t0 values (314, 'tuple 314') -Insert OK, 1 row affected +--- +- [314, u'tuple 314'] +... select * from t0 where k0 = 310 -Found 1 tuple: -[310, 'tuple 310'] +--- +- [310, u'tuple 310'] +... select * from t0 where k0 = 311 -Found 1 tuple: -[311, 'tuple 311'] +--- +- [311, u'tuple 311'] +... select * from t0 where k0 = 312 -Found 1 tuple: -[312, 'tuple 312'] +--- +- [312, u'tuple 312'] +... select * from t0 where k0 = 313 -Found 1 tuple: -[313, 'tuple 313'] +--- +- [313, u'tuple 313'] +... select * from t0 where k0 = 314 -Found 1 tuple: -[314, 'tuple 314'] +--- +- [314, u'tuple 314'] +... insert into t0 values (315, 'tuple 315') -Insert OK, 1 row affected +--- +- [315, u'tuple 315'] +... insert into t0 values (316, 'tuple 316') -Insert OK, 1 row affected +--- +- [316, u'tuple 316'] +... insert into t0 values (317, 'tuple 317') -Insert OK, 1 row affected +--- +- [317, u'tuple 317'] +... insert into t0 values (318, 'tuple 318') -Insert OK, 1 row affected +--- +- [318, u'tuple 318'] +... insert into t0 values (319, 'tuple 319') -Insert OK, 1 row affected +--- +- [319, u'tuple 319'] +... select * from t0 where k0 = 315 -Found 1 tuple: -[315, 'tuple 315'] +--- +- [315, u'tuple 315'] +... select * from t0 where k0 = 316 -Found 1 tuple: -[316, 'tuple 316'] +--- +- [316, u'tuple 316'] +... select * from t0 where k0 = 317 -Found 1 tuple: -[317, 'tuple 317'] +--- +- [317, u'tuple 317'] +... select * from t0 where k0 = 318 -Found 1 tuple: -[318, 'tuple 318'] +--- +- [318, u'tuple 318'] +... select * from t0 where k0 = 319 -Found 1 tuple: -[319, 'tuple 319'] +--- +- [319, u'tuple 319'] +... rollback servers configuration box.cfg.reload() --- @@ -1912,55 +2872,85 @@ box.cfg.reload() ... test 16 iteration insert into t0 values (320, 'tuple 320') -Insert OK, 1 row affected +--- +- [320, u'tuple 320'] +... insert into t0 values (321, 'tuple 321') -Insert OK, 1 row affected +--- +- [321, u'tuple 321'] +... insert into t0 values (322, 'tuple 322') -Insert OK, 1 row affected +--- +- [322, u'tuple 322'] +... insert into t0 values (323, 'tuple 323') -Insert OK, 1 row affected +--- +- [323, u'tuple 323'] +... insert into t0 values (324, 'tuple 324') -Insert OK, 1 row affected +--- +- [324, u'tuple 324'] +... select * from t0 where k0 = 320 -Found 1 tuple: -[320, 'tuple 320'] +--- +- [320, u'tuple 320'] +... select * from t0 where k0 = 321 -Found 1 tuple: -[321, 'tuple 321'] +--- +- [321, u'tuple 321'] +... select * from t0 where k0 = 322 -Found 1 tuple: -[322, 'tuple 322'] +--- +- [322, u'tuple 322'] +... select * from t0 where k0 = 323 -Found 1 tuple: -[323, 'tuple 323'] +--- +- [323, u'tuple 323'] +... select * from t0 where k0 = 324 -Found 1 tuple: -[324, 'tuple 324'] +--- +- [324, u'tuple 324'] +... insert into t0 values (325, 'tuple 325') -Insert OK, 1 row affected +--- +- [325, u'tuple 325'] +... insert into t0 values (326, 'tuple 326') -Insert OK, 1 row affected +--- +- [326, u'tuple 326'] +... insert into t0 values (327, 'tuple 327') -Insert OK, 1 row affected +--- +- [327, u'tuple 327'] +... insert into t0 values (328, 'tuple 328') -Insert OK, 1 row affected +--- +- [328, u'tuple 328'] +... insert into t0 values (329, 'tuple 329') -Insert OK, 1 row affected +--- +- [329, u'tuple 329'] +... select * from t0 where k0 = 325 -Found 1 tuple: -[325, 'tuple 325'] +--- +- [325, u'tuple 325'] +... select * from t0 where k0 = 326 -Found 1 tuple: -[326, 'tuple 326'] +--- +- [326, u'tuple 326'] +... select * from t0 where k0 = 327 -Found 1 tuple: -[327, 'tuple 327'] +--- +- [327, u'tuple 327'] +... select * from t0 where k0 = 328 -Found 1 tuple: -[328, 'tuple 328'] +--- +- [328, u'tuple 328'] +... select * from t0 where k0 = 329 -Found 1 tuple: -[329, 'tuple 329'] +--- +- [329, u'tuple 329'] +... swap servers box.cfg.reload() --- @@ -1971,55 +2961,85 @@ box.cfg.reload() - ok ... insert into t0 values (330, 'tuple 330') -Insert OK, 1 row affected +--- +- [330, u'tuple 330'] +... insert into t0 values (331, 'tuple 331') -Insert OK, 1 row affected +--- +- [331, u'tuple 331'] +... insert into t0 values (332, 'tuple 332') -Insert OK, 1 row affected +--- +- [332, u'tuple 332'] +... insert into t0 values (333, 'tuple 333') -Insert OK, 1 row affected +--- +- [333, u'tuple 333'] +... insert into t0 values (334, 'tuple 334') -Insert OK, 1 row affected +--- +- [334, u'tuple 334'] +... select * from t0 where k0 = 330 -Found 1 tuple: -[330, 'tuple 330'] +--- +- [330, u'tuple 330'] +... select * from t0 where k0 = 331 -Found 1 tuple: -[331, 'tuple 331'] +--- +- [331, u'tuple 331'] +... select * from t0 where k0 = 332 -Found 1 tuple: -[332, 'tuple 332'] +--- +- [332, u'tuple 332'] +... select * from t0 where k0 = 333 -Found 1 tuple: -[333, 'tuple 333'] +--- +- [333, u'tuple 333'] +... select * from t0 where k0 = 334 -Found 1 tuple: -[334, 'tuple 334'] +--- +- [334, u'tuple 334'] +... insert into t0 values (335, 'tuple 335') -Insert OK, 1 row affected +--- +- [335, u'tuple 335'] +... insert into t0 values (336, 'tuple 336') -Insert OK, 1 row affected +--- +- [336, u'tuple 336'] +... insert into t0 values (337, 'tuple 337') -Insert OK, 1 row affected +--- +- [337, u'tuple 337'] +... insert into t0 values (338, 'tuple 338') -Insert OK, 1 row affected +--- +- [338, u'tuple 338'] +... insert into t0 values (339, 'tuple 339') -Insert OK, 1 row affected +--- +- [339, u'tuple 339'] +... select * from t0 where k0 = 335 -Found 1 tuple: -[335, 'tuple 335'] +--- +- [335, u'tuple 335'] +... select * from t0 where k0 = 336 -Found 1 tuple: -[336, 'tuple 336'] +--- +- [336, u'tuple 336'] +... select * from t0 where k0 = 337 -Found 1 tuple: -[337, 'tuple 337'] +--- +- [337, u'tuple 337'] +... select * from t0 where k0 = 338 -Found 1 tuple: -[338, 'tuple 338'] +--- +- [338, u'tuple 338'] +... select * from t0 where k0 = 339 -Found 1 tuple: -[339, 'tuple 339'] +--- +- [339, u'tuple 339'] +... rollback servers configuration box.cfg.reload() --- @@ -2031,55 +3051,85 @@ box.cfg.reload() ... test 17 iteration insert into t0 values (340, 'tuple 340') -Insert OK, 1 row affected +--- +- [340, u'tuple 340'] +... insert into t0 values (341, 'tuple 341') -Insert OK, 1 row affected +--- +- [341, u'tuple 341'] +... insert into t0 values (342, 'tuple 342') -Insert OK, 1 row affected +--- +- [342, u'tuple 342'] +... insert into t0 values (343, 'tuple 343') -Insert OK, 1 row affected +--- +- [343, u'tuple 343'] +... insert into t0 values (344, 'tuple 344') -Insert OK, 1 row affected +--- +- [344, u'tuple 344'] +... select * from t0 where k0 = 340 -Found 1 tuple: -[340, 'tuple 340'] +--- +- [340, u'tuple 340'] +... select * from t0 where k0 = 341 -Found 1 tuple: -[341, 'tuple 341'] +--- +- [341, u'tuple 341'] +... select * from t0 where k0 = 342 -Found 1 tuple: -[342, 'tuple 342'] +--- +- [342, u'tuple 342'] +... select * from t0 where k0 = 343 -Found 1 tuple: -[343, 'tuple 343'] +--- +- [343, u'tuple 343'] +... select * from t0 where k0 = 344 -Found 1 tuple: -[344, 'tuple 344'] +--- +- [344, u'tuple 344'] +... insert into t0 values (345, 'tuple 345') -Insert OK, 1 row affected +--- +- [345, u'tuple 345'] +... insert into t0 values (346, 'tuple 346') -Insert OK, 1 row affected +--- +- [346, u'tuple 346'] +... insert into t0 values (347, 'tuple 347') -Insert OK, 1 row affected +--- +- [347, u'tuple 347'] +... insert into t0 values (348, 'tuple 348') -Insert OK, 1 row affected +--- +- [348, u'tuple 348'] +... insert into t0 values (349, 'tuple 349') -Insert OK, 1 row affected +--- +- [349, u'tuple 349'] +... select * from t0 where k0 = 345 -Found 1 tuple: -[345, 'tuple 345'] +--- +- [345, u'tuple 345'] +... select * from t0 where k0 = 346 -Found 1 tuple: -[346, 'tuple 346'] +--- +- [346, u'tuple 346'] +... select * from t0 where k0 = 347 -Found 1 tuple: -[347, 'tuple 347'] +--- +- [347, u'tuple 347'] +... select * from t0 where k0 = 348 -Found 1 tuple: -[348, 'tuple 348'] +--- +- [348, u'tuple 348'] +... select * from t0 where k0 = 349 -Found 1 tuple: -[349, 'tuple 349'] +--- +- [349, u'tuple 349'] +... swap servers box.cfg.reload() --- @@ -2090,55 +3140,85 @@ box.cfg.reload() - ok ... insert into t0 values (350, 'tuple 350') -Insert OK, 1 row affected +--- +- [350, u'tuple 350'] +... insert into t0 values (351, 'tuple 351') -Insert OK, 1 row affected +--- +- [351, u'tuple 351'] +... insert into t0 values (352, 'tuple 352') -Insert OK, 1 row affected +--- +- [352, u'tuple 352'] +... insert into t0 values (353, 'tuple 353') -Insert OK, 1 row affected +--- +- [353, u'tuple 353'] +... insert into t0 values (354, 'tuple 354') -Insert OK, 1 row affected +--- +- [354, u'tuple 354'] +... select * from t0 where k0 = 350 -Found 1 tuple: -[350, 'tuple 350'] +--- +- [350, u'tuple 350'] +... select * from t0 where k0 = 351 -Found 1 tuple: -[351, 'tuple 351'] +--- +- [351, u'tuple 351'] +... select * from t0 where k0 = 352 -Found 1 tuple: -[352, 'tuple 352'] +--- +- [352, u'tuple 352'] +... select * from t0 where k0 = 353 -Found 1 tuple: -[353, 'tuple 353'] +--- +- [353, u'tuple 353'] +... select * from t0 where k0 = 354 -Found 1 tuple: -[354, 'tuple 354'] +--- +- [354, u'tuple 354'] +... insert into t0 values (355, 'tuple 355') -Insert OK, 1 row affected +--- +- [355, u'tuple 355'] +... insert into t0 values (356, 'tuple 356') -Insert OK, 1 row affected +--- +- [356, u'tuple 356'] +... insert into t0 values (357, 'tuple 357') -Insert OK, 1 row affected +--- +- [357, u'tuple 357'] +... insert into t0 values (358, 'tuple 358') -Insert OK, 1 row affected +--- +- [358, u'tuple 358'] +... insert into t0 values (359, 'tuple 359') -Insert OK, 1 row affected +--- +- [359, u'tuple 359'] +... select * from t0 where k0 = 355 -Found 1 tuple: -[355, 'tuple 355'] +--- +- [355, u'tuple 355'] +... select * from t0 where k0 = 356 -Found 1 tuple: -[356, 'tuple 356'] +--- +- [356, u'tuple 356'] +... select * from t0 where k0 = 357 -Found 1 tuple: -[357, 'tuple 357'] +--- +- [357, u'tuple 357'] +... select * from t0 where k0 = 358 -Found 1 tuple: -[358, 'tuple 358'] +--- +- [358, u'tuple 358'] +... select * from t0 where k0 = 359 -Found 1 tuple: -[359, 'tuple 359'] +--- +- [359, u'tuple 359'] +... rollback servers configuration box.cfg.reload() --- @@ -2150,55 +3230,85 @@ box.cfg.reload() ... test 18 iteration insert into t0 values (360, 'tuple 360') -Insert OK, 1 row affected +--- +- [360, u'tuple 360'] +... insert into t0 values (361, 'tuple 361') -Insert OK, 1 row affected +--- +- [361, u'tuple 361'] +... insert into t0 values (362, 'tuple 362') -Insert OK, 1 row affected +--- +- [362, u'tuple 362'] +... insert into t0 values (363, 'tuple 363') -Insert OK, 1 row affected +--- +- [363, u'tuple 363'] +... insert into t0 values (364, 'tuple 364') -Insert OK, 1 row affected +--- +- [364, u'tuple 364'] +... select * from t0 where k0 = 360 -Found 1 tuple: -[360, 'tuple 360'] +--- +- [360, u'tuple 360'] +... select * from t0 where k0 = 361 -Found 1 tuple: -[361, 'tuple 361'] +--- +- [361, u'tuple 361'] +... select * from t0 where k0 = 362 -Found 1 tuple: -[362, 'tuple 362'] +--- +- [362, u'tuple 362'] +... select * from t0 where k0 = 363 -Found 1 tuple: -[363, 'tuple 363'] +--- +- [363, u'tuple 363'] +... select * from t0 where k0 = 364 -Found 1 tuple: -[364, 'tuple 364'] +--- +- [364, u'tuple 364'] +... insert into t0 values (365, 'tuple 365') -Insert OK, 1 row affected +--- +- [365, u'tuple 365'] +... insert into t0 values (366, 'tuple 366') -Insert OK, 1 row affected +--- +- [366, u'tuple 366'] +... insert into t0 values (367, 'tuple 367') -Insert OK, 1 row affected +--- +- [367, u'tuple 367'] +... insert into t0 values (368, 'tuple 368') -Insert OK, 1 row affected +--- +- [368, u'tuple 368'] +... insert into t0 values (369, 'tuple 369') -Insert OK, 1 row affected +--- +- [369, u'tuple 369'] +... select * from t0 where k0 = 365 -Found 1 tuple: -[365, 'tuple 365'] +--- +- [365, u'tuple 365'] +... select * from t0 where k0 = 366 -Found 1 tuple: -[366, 'tuple 366'] +--- +- [366, u'tuple 366'] +... select * from t0 where k0 = 367 -Found 1 tuple: -[367, 'tuple 367'] +--- +- [367, u'tuple 367'] +... select * from t0 where k0 = 368 -Found 1 tuple: -[368, 'tuple 368'] +--- +- [368, u'tuple 368'] +... select * from t0 where k0 = 369 -Found 1 tuple: -[369, 'tuple 369'] +--- +- [369, u'tuple 369'] +... swap servers box.cfg.reload() --- @@ -2209,55 +3319,85 @@ box.cfg.reload() - ok ... insert into t0 values (370, 'tuple 370') -Insert OK, 1 row affected +--- +- [370, u'tuple 370'] +... insert into t0 values (371, 'tuple 371') -Insert OK, 1 row affected +--- +- [371, u'tuple 371'] +... insert into t0 values (372, 'tuple 372') -Insert OK, 1 row affected +--- +- [372, u'tuple 372'] +... insert into t0 values (373, 'tuple 373') -Insert OK, 1 row affected +--- +- [373, u'tuple 373'] +... insert into t0 values (374, 'tuple 374') -Insert OK, 1 row affected +--- +- [374, u'tuple 374'] +... select * from t0 where k0 = 370 -Found 1 tuple: -[370, 'tuple 370'] +--- +- [370, u'tuple 370'] +... select * from t0 where k0 = 371 -Found 1 tuple: -[371, 'tuple 371'] +--- +- [371, u'tuple 371'] +... select * from t0 where k0 = 372 -Found 1 tuple: -[372, 'tuple 372'] +--- +- [372, u'tuple 372'] +... select * from t0 where k0 = 373 -Found 1 tuple: -[373, 'tuple 373'] +--- +- [373, u'tuple 373'] +... select * from t0 where k0 = 374 -Found 1 tuple: -[374, 'tuple 374'] +--- +- [374, u'tuple 374'] +... insert into t0 values (375, 'tuple 375') -Insert OK, 1 row affected +--- +- [375, u'tuple 375'] +... insert into t0 values (376, 'tuple 376') -Insert OK, 1 row affected +--- +- [376, u'tuple 376'] +... insert into t0 values (377, 'tuple 377') -Insert OK, 1 row affected +--- +- [377, u'tuple 377'] +... insert into t0 values (378, 'tuple 378') -Insert OK, 1 row affected +--- +- [378, u'tuple 378'] +... insert into t0 values (379, 'tuple 379') -Insert OK, 1 row affected +--- +- [379, u'tuple 379'] +... select * from t0 where k0 = 375 -Found 1 tuple: -[375, 'tuple 375'] +--- +- [375, u'tuple 375'] +... select * from t0 where k0 = 376 -Found 1 tuple: -[376, 'tuple 376'] +--- +- [376, u'tuple 376'] +... select * from t0 where k0 = 377 -Found 1 tuple: -[377, 'tuple 377'] +--- +- [377, u'tuple 377'] +... select * from t0 where k0 = 378 -Found 1 tuple: -[378, 'tuple 378'] +--- +- [378, u'tuple 378'] +... select * from t0 where k0 = 379 -Found 1 tuple: -[379, 'tuple 379'] +--- +- [379, u'tuple 379'] +... rollback servers configuration box.cfg.reload() --- @@ -2269,55 +3409,85 @@ box.cfg.reload() ... test 19 iteration insert into t0 values (380, 'tuple 380') -Insert OK, 1 row affected +--- +- [380, u'tuple 380'] +... insert into t0 values (381, 'tuple 381') -Insert OK, 1 row affected +--- +- [381, u'tuple 381'] +... insert into t0 values (382, 'tuple 382') -Insert OK, 1 row affected +--- +- [382, u'tuple 382'] +... insert into t0 values (383, 'tuple 383') -Insert OK, 1 row affected +--- +- [383, u'tuple 383'] +... insert into t0 values (384, 'tuple 384') -Insert OK, 1 row affected +--- +- [384, u'tuple 384'] +... select * from t0 where k0 = 380 -Found 1 tuple: -[380, 'tuple 380'] +--- +- [380, u'tuple 380'] +... select * from t0 where k0 = 381 -Found 1 tuple: -[381, 'tuple 381'] +--- +- [381, u'tuple 381'] +... select * from t0 where k0 = 382 -Found 1 tuple: -[382, 'tuple 382'] +--- +- [382, u'tuple 382'] +... select * from t0 where k0 = 383 -Found 1 tuple: -[383, 'tuple 383'] +--- +- [383, u'tuple 383'] +... select * from t0 where k0 = 384 -Found 1 tuple: -[384, 'tuple 384'] +--- +- [384, u'tuple 384'] +... insert into t0 values (385, 'tuple 385') -Insert OK, 1 row affected +--- +- [385, u'tuple 385'] +... insert into t0 values (386, 'tuple 386') -Insert OK, 1 row affected +--- +- [386, u'tuple 386'] +... insert into t0 values (387, 'tuple 387') -Insert OK, 1 row affected +--- +- [387, u'tuple 387'] +... insert into t0 values (388, 'tuple 388') -Insert OK, 1 row affected +--- +- [388, u'tuple 388'] +... insert into t0 values (389, 'tuple 389') -Insert OK, 1 row affected +--- +- [389, u'tuple 389'] +... select * from t0 where k0 = 385 -Found 1 tuple: -[385, 'tuple 385'] +--- +- [385, u'tuple 385'] +... select * from t0 where k0 = 386 -Found 1 tuple: -[386, 'tuple 386'] +--- +- [386, u'tuple 386'] +... select * from t0 where k0 = 387 -Found 1 tuple: -[387, 'tuple 387'] +--- +- [387, u'tuple 387'] +... select * from t0 where k0 = 388 -Found 1 tuple: -[388, 'tuple 388'] +--- +- [388, u'tuple 388'] +... select * from t0 where k0 = 389 -Found 1 tuple: -[389, 'tuple 389'] +--- +- [389, u'tuple 389'] +... swap servers box.cfg.reload() --- @@ -2328,55 +3498,85 @@ box.cfg.reload() - ok ... insert into t0 values (390, 'tuple 390') -Insert OK, 1 row affected +--- +- [390, u'tuple 390'] +... insert into t0 values (391, 'tuple 391') -Insert OK, 1 row affected +--- +- [391, u'tuple 391'] +... insert into t0 values (392, 'tuple 392') -Insert OK, 1 row affected +--- +- [392, u'tuple 392'] +... insert into t0 values (393, 'tuple 393') -Insert OK, 1 row affected +--- +- [393, u'tuple 393'] +... insert into t0 values (394, 'tuple 394') -Insert OK, 1 row affected +--- +- [394, u'tuple 394'] +... select * from t0 where k0 = 390 -Found 1 tuple: -[390, 'tuple 390'] +--- +- [390, u'tuple 390'] +... select * from t0 where k0 = 391 -Found 1 tuple: -[391, 'tuple 391'] +--- +- [391, u'tuple 391'] +... select * from t0 where k0 = 392 -Found 1 tuple: -[392, 'tuple 392'] +--- +- [392, u'tuple 392'] +... select * from t0 where k0 = 393 -Found 1 tuple: -[393, 'tuple 393'] +--- +- [393, u'tuple 393'] +... select * from t0 where k0 = 394 -Found 1 tuple: -[394, 'tuple 394'] +--- +- [394, u'tuple 394'] +... insert into t0 values (395, 'tuple 395') -Insert OK, 1 row affected +--- +- [395, u'tuple 395'] +... insert into t0 values (396, 'tuple 396') -Insert OK, 1 row affected +--- +- [396, u'tuple 396'] +... insert into t0 values (397, 'tuple 397') -Insert OK, 1 row affected +--- +- [397, u'tuple 397'] +... insert into t0 values (398, 'tuple 398') -Insert OK, 1 row affected +--- +- [398, u'tuple 398'] +... insert into t0 values (399, 'tuple 399') -Insert OK, 1 row affected +--- +- [399, u'tuple 399'] +... select * from t0 where k0 = 395 -Found 1 tuple: -[395, 'tuple 395'] +--- +- [395, u'tuple 395'] +... select * from t0 where k0 = 396 -Found 1 tuple: -[396, 'tuple 396'] +--- +- [396, u'tuple 396'] +... select * from t0 where k0 = 397 -Found 1 tuple: -[397, 'tuple 397'] +--- +- [397, u'tuple 397'] +... select * from t0 where k0 = 398 -Found 1 tuple: -[398, 'tuple 398'] +--- +- [398, u'tuple 398'] +... select * from t0 where k0 = 399 -Found 1 tuple: -[399, 'tuple 399'] +--- +- [399, u'tuple 399'] +... rollback servers configuration box.cfg.reload() --- diff --git a/test/replication/swap.test.py b/test/replication/swap.test.py index c1a1ef5ed0f223861bba8bf41aed4af3889aac43..19fe91c0093303c3257c4c6e10ea6abb7c40df7d 100644 --- a/test/replication/swap.test.py +++ b/test/replication/swap.test.py @@ -1,4 +1,5 @@ import os +import tarantool from lib.tarantool_server import TarantoolServer REPEAT = 20 @@ -24,6 +25,22 @@ replica.deploy("replication/cfg/replica.cfg", replica.find_exe(self.args.builddir), os.path.join(self.args.vardir, "replica")) +schema = { + 0 : { + 'default_type': tarantool.STR, + 'fields' : { + 0 : tarantool.NUM, + 1 : tarantool.STR + }, + 'indexes': { + 0 : [0] # HASH + } + } +} + +master.sql.set_schema(schema) +replica.sql.set_schema(schema) + master.admin("box.replace(box.schema.SPACE_ID, 0, 0, 'tweedledum')") master.admin("box.replace(box.schema.INDEX_ID, 0, 0, 'primary', 'hash', 1, 1, 0, 'num')") id = ID_BEGIN diff --git a/test/wal/oom.result b/test/wal/oom.result index 3314ecc906eea5f2e0864c5de51fa8fbd95b1c5c..1375f39690b8df8eb41b37b66d563ca47e8e47ef 100644 --- a/test/wal/oom.result +++ b/test/wal/oom.result @@ -24,7 +24,7 @@ end; ... space:len(); --- -- 4853 +- 4852 ... i = 1; --- @@ -38,7 +38,7 @@ end; ... space:len(); --- -- 5871 +- 5869 ... i = 1; --- @@ -53,7 +53,7 @@ end; --# setopt delimiter '' space:len() --- -- 6378 +- 6375 ... space:select(0, 0) --- diff --git a/third_party/open_memstream.c b/third_party/open_memstream.c new file mode 100644 index 0000000000000000000000000000000000000000..559378f62733d9a07f0f19ae9de35955c770f7e9 --- /dev/null +++ b/third_party/open_memstream.c @@ -0,0 +1,185 @@ +/*- + * Copyright (c) 2013 Advanced Computing Technologies LLC + * Written by: John H. Baldwin <jhb@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> + +#include <assert.h> +#include <errno.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <wchar.h> + +/* XXX: There is no FPOS_MAX. This assumes fpos_t is an off_t. */ +#define FPOS_MAX OFF_MAX + +struct memstream { + char **bufp; + size_t *sizep; + ssize_t len; + fpos_t offset; +}; + +static int +memstream_grow(struct memstream *ms, fpos_t newoff) +{ + char *buf; + ssize_t newsize; + + if (newoff < 0 || newoff >= SSIZE_MAX) + newsize = SSIZE_MAX - 1; + else + newsize = newoff; + if (newsize > ms->len) { + buf = realloc(*ms->bufp, newsize + 1); + if (buf != NULL) { + memset(buf + ms->len + 1, 0, newsize - ms->len); + *ms->bufp = buf; + ms->len = newsize; + return (1); + } + return (0); + } + return (1); +} + +static void +memstream_update(struct memstream *ms) +{ + + assert(ms->len >= 0 && ms->offset >= 0); + *ms->sizep = ms->len < ms->offset ? ms->len : ms->offset; +} + +static int +memstream_write(void *cookie, const char *buf, int len) +{ + struct memstream *ms; + ssize_t tocopy; + + ms = cookie; + if (!memstream_grow(ms, ms->offset + len)) + return (-1); + tocopy = ms->len - ms->offset; + if (len < tocopy) + tocopy = len; + memcpy(*ms->bufp + ms->offset, buf, tocopy); + ms->offset += tocopy; + memstream_update(ms); + return (tocopy); +} + +static fpos_t +memstream_seek(void *cookie, fpos_t pos, int whence) +{ + struct memstream *ms; +#ifdef DEBUG + fpos_t old; +#endif + + ms = cookie; +#ifdef DEBUG + old = ms->offset; +#endif + switch (whence) { + case SEEK_SET: + /* _fseeko() checks for negative offsets. */ + assert(pos >= 0); + ms->offset = pos; + break; + case SEEK_CUR: + /* This is only called by _ftello(). */ + assert(pos == 0); + break; + case SEEK_END: + if (pos < 0) { + if (pos + ms->len < 0) { + errno = EINVAL; + return (-1); + } + } else { + if (FPOS_MAX - ms->len < pos) { + errno = EOVERFLOW; + return (-1); + } + } + ms->offset = ms->len + pos; + break; + } + memstream_update(ms); + return (ms->offset); +} + +static int +memstream_close(void *cookie) +{ + + free(cookie); + return (0); +} + +FILE * +open_memstream(char **bufp, size_t *sizep) +{ + struct memstream *ms; + int save_errno; + FILE *fp; + + if (bufp == NULL || sizep == NULL) { + errno = EINVAL; + return (NULL); + } + *bufp = calloc(1, 1); + if (*bufp == NULL) + return (NULL); + ms = malloc(sizeof(*ms)); + if (ms == NULL) { + save_errno = errno; + free(*bufp); + *bufp = NULL; + errno = save_errno; + return (NULL); + } + ms->bufp = bufp; + ms->sizep = sizep; + ms->len = 0; + ms->offset = 0; + memstream_update(ms); + fp = funopen(ms, NULL, memstream_write, memstream_seek, + memstream_close); + if (fp == NULL) { + save_errno = errno; + free(ms); + free(*bufp); + *bufp = NULL; + errno = save_errno; + return (NULL); + } + fwide(fp, -1); + return (fp); +}