diff --git a/src/recovery.m b/src/recovery.m index 1e5b69f11865475f6c07c8b2e8d058a473d9970f..0bace63c5ba4fa714006eb5cc9e9a21f6fedea02 100644 --- a/src/recovery.m +++ b/src/recovery.m @@ -300,7 +300,8 @@ recover_snap(struct recovery_state *r) while ((row = log_io_cursor_next(&i))) { if (r->row_handler(row) < 0) { say_error("can't apply row"); - break; + if (snap->dir->panic_if_error) + break; } } log_io_cursor_close(&i); @@ -348,7 +349,8 @@ recover_wal(struct recovery_state *r, struct log_io *l) */ if (r->row_handler(row) < 0) { say_error("can't apply row"); - goto end; + if (l->dir->panic_if_error) + goto end; } set_lsn(r, lsn); } @@ -463,7 +465,6 @@ recover_current_wal: r->current_wal->filename); break; } - if (result == LOG_EOF) { say_info("done `%s' confirmed_lsn: %" PRIi64, r->current_wal->filename, diff --git a/test/box/dup_key1.xlog b/test/box/dup_key1.xlog new file mode 100644 index 0000000000000000000000000000000000000000..096b48ccc5c9e81dc613a37ac0bef8cd3ea58d7b Binary files /dev/null and b/test/box/dup_key1.xlog differ diff --git a/test/box/dup_key2.xlog b/test/box/dup_key2.xlog new file mode 100644 index 0000000000000000000000000000000000000000..2651dd6f0f692394c6f03bd61c955e5d693cf307 Binary files /dev/null and b/test/box/dup_key2.xlog differ diff --git a/test/box/panic_on_wal_error.cfg b/test/box/panic_on_wal_error.cfg new file mode 100644 index 0000000000000000000000000000000000000000..2838d32b40007a4b8cfe54c287c16ec895c15bff --- /dev/null +++ b/test/box/panic_on_wal_error.cfg @@ -0,0 +1,46 @@ +# +# Limit of memory used to store tuples to 100MB +# (0.1 GB) +# This effectively limits the memory, used by +# Tarantool. However, index and connection memory +# is stored outside the slab allocator, hence +# the effective memory usage can be higher (sometimes +# twice as high). +# +slab_alloc_arena = 0.1 + +# +# Store the pid in this file. Relative to +# startup dir. +# +pid_file = "box.pid" + +# +# Pipe the logs into the following process. +# +logger="cat - >> tarantool.log" + +# +# Read only and read-write port. +primary_port = 33013 +# Read-only port. +secondary_port = 33014 +# +# The port for administrative commands. +# +admin_port = 33015 +# +# Each write ahead log contains this many rows. +# When the limit is reached, Tarantool closes +# the WAL and starts a new one. +rows_per_wal = 50 +panic_on_wal_error = false + +# Define a simple space with 1 HASH-based +# primary key. +space[0].enabled = 1 +space[0].index[0].type = "HASH" +space[0].index[0].unique = 1 +space[0].index[0].key_field[0].fieldno = 0 +space[0].index[0].key_field[0].type = "NUM" + diff --git a/test/box/xlog.result b/test/box/xlog.result index 8faf70ef7bf22a5ae04a09d3289844e222f3d3c3..78b89b6f88786caece5cda485c73a56afbe64965 100644 --- a/test/box/xlog.result +++ b/test/box/xlog.result @@ -32,3 +32,19 @@ Stopping the server... # Inprogress xlog with bad record must be deleted during recovery. 00000000000000000006.xlog.inprogress has been successfully deleted + +A test case for https://bugs.launchpad.net/tarantool/+bug/1052018 +panic_on_wal_error doens't work for duplicate key errors + +lua box.space[0]:select(0, 1) +--- + - 1: {} +... +lua box.space[0]:select(0, 2) +--- + - 2: {} +... +lua #box.space[0] +--- + - 0 +... diff --git a/test/box/xlog.test b/test/box/xlog.test index 170bbec31e1a76806a5833accc0be4b576d474db..8b803b4c10b9c1e39b8c6ede76080ea748f215d0 100644 --- a/test/box/xlog.test +++ b/test/box/xlog.test @@ -2,6 +2,7 @@ # import os from os.path import abspath +import shutil # cleanup vardir server.stop() @@ -105,9 +106,25 @@ server.start() if not os.access(wal_inprogress, os.F_OK) and not os.access(wal, os.F_OK): print "00000000000000000006.xlog.inprogress has been successfully deleted" + +print """ +A test case for https://bugs.launchpad.net/tarantool/+bug/1052018 +panic_on_wal_error doens't work for duplicate key errors +""" server.stop() +server.deploy("box/panic_on_wal_error.cfg") +server.stop() +shutil.copy(abspath("box/dup_key1.xlog"), + os.path.join(vardir, "00000000000000000002.xlog")) +shutil.copy(abspath("box/dup_key2.xlog"), + os.path.join(vardir, "00000000000000000004.xlog")) +server.start() +exec admin "lua box.space[0]:select(0, 1)" +exec admin "lua box.space[0]:select(0, 2)" +exec admin "lua #box.space[0]" # cleanup +server.stop() server.deploy() # vim: syntax=python