diff --git a/src/box/replication.cc b/src/box/replication.cc index d376f44b963ce266c5d1f7315d82ac7905d592e9..a54a1593b4c5d07a1f1baf40d38c4255cc6a96d3 100644 --- a/src/box/replication.cc +++ b/src/box/replication.cc @@ -43,6 +43,7 @@ #include "coio.h" #include "cfg.h" #include "trigger.h" +#include "errinj.h" void replication_send_row(struct recovery_state *r, void *param, @@ -227,6 +228,10 @@ relay_send(Relay *relay, struct xrow_header *packet) struct iovec iov[XROW_IOVMAX]; int iovcnt = xrow_to_iovec(packet, iov); coio_writev(&relay->io, iov, iovcnt, 0); + ERROR_INJECT(ERRINJ_RELAY, + { + sleep(1000); + }); } /** Send a single row to the client. */ diff --git a/src/errinj.h b/src/errinj.h index e0b2dec8ee9153a0273430877680d9ea4ce7415e..d35f64179e41f3c8505d92e9ea7f1deeb4a5e6f4 100644 --- a/src/errinj.h +++ b/src/errinj.h @@ -45,7 +45,8 @@ struct errinj { _(ERRINJ_WAL_ROTATE, false) \ _(ERRINJ_WAL_WRITE, false) \ _(ERRINJ_INDEX_ALLOC, false) \ - _(ERRINJ_TUPLE_ALLOC, false) + _(ERRINJ_TUPLE_ALLOC, false) \ + _(ERRINJ_RELAY, false) ENUM0(errinj_enum, ERRINJ_LIST); extern struct errinj errinjs[]; diff --git a/test/replication/catch.result b/test/replication/catch.result new file mode 100644 index 0000000000000000000000000000000000000000..76b5554dac3fc9f03a652ba2dd17f13d14693337 --- /dev/null +++ b/test/replication/catch.result @@ -0,0 +1,89 @@ +net_box = require('net.box') +--- +... +errinj = box.error.injection +--- +... +box.schema.user.grant('guest', 'replication') +--- +... +--# create server replica with rpl_master=default, script='replication/replica.lua' +--# start server replica +--# set connection replica +box.schema.user.grant('guest', 'read,write,execute', 'universe') +--- +... +--# set connection default +s = box.schema.space.create('test'); +--- +... +index = s:create_index('primary', {type = 'hash'}) +--- +... +--# set connection replica +fiber = require('fiber') +--- +... +while box.space.test == nil do fiber.sleep(0.01) end +--- +... +--# set connection default +--# stop server replica +-- insert values on the master while replica os stopped and can't fetch them +for i=1,100 do s:insert{i, 'this is test message12345'} end +--- +... +-- sleep after every tuple +errinj.set("ERRINJ_RELAY", true) +--- +- ok +... +--# start server replica +--# set connection replica +-- Check that replica doesn't enter read-write mode +-- before catching up with the master: to check that we inject +-- sleep into the master relay_send function and attempt a data +-- modifying statement in replica while it's still fetching +-- data from the master. +-- In next 2 cases we try to delete tuple +-- during fetching process(local delete, remote delete) +-- case #1: delete tuple in replica +box.space.test:len() +--- +- 1 +... +d = box.space.test:delete{1} +--- +... +box.space.test:get(1) ~= nil +--- +- false +... +-- case #2: delete tuple by net.box +--# set connection default +--# set variable r_uri to 'replica.listen' +c = net_box:new(r_uri) +--- +... +d = c.space.test:delete{1} +--- +... +c.space.test:get(1) ~= nil +--- +- false +... +-- check sync +errinj.set("ERRINJ_RELAY", false) +--- +- ok +... +-- cleanup +--# stop server replica +--# cleanup server replica +--# set connection default +box.space.test:drop() +--- +... +box.schema.user.revoke('guest', 'replication') +--- +... diff --git a/test/replication/catch.test.lua b/test/replication/catch.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..5ed3e89d712e96f14baf7ab6d57f20d14dd20273 --- /dev/null +++ b/test/replication/catch.test.lua @@ -0,0 +1,57 @@ +net_box = require('net.box') +errinj = box.error.injection + +box.schema.user.grant('guest', 'replication') +--# create server replica with rpl_master=default, script='replication/replica.lua' +--# start server replica +--# set connection replica +box.schema.user.grant('guest', 'read,write,execute', 'universe') + +--# set connection default +s = box.schema.space.create('test'); +index = s:create_index('primary', {type = 'hash'}) + +--# set connection replica +fiber = require('fiber') +while box.space.test == nil do fiber.sleep(0.01) end +--# set connection default +--# stop server replica + +-- insert values on the master while replica os stopped and can't fetch them +for i=1,100 do s:insert{i, 'this is test message12345'} end + +-- sleep after every tuple +errinj.set("ERRINJ_RELAY", true) + +--# start server replica +--# set connection replica + +-- Check that replica doesn't enter read-write mode +-- before catching up with the master: to check that we inject +-- sleep into the master relay_send function and attempt a data +-- modifying statement in replica while it's still fetching +-- data from the master. +-- In next 2 cases we try to delete tuple +-- during fetching process(local delete, remote delete) +-- case #1: delete tuple in replica +box.space.test:len() +d = box.space.test:delete{1} +box.space.test:get(1) ~= nil + +-- case #2: delete tuple by net.box +--# set connection default +--# set variable r_uri to 'replica.listen' +c = net_box:new(r_uri) +d = c.space.test:delete{1} +c.space.test:get(1) ~= nil + +-- check sync +errinj.set("ERRINJ_RELAY", false) + +-- cleanup +--# stop server replica +--# cleanup server replica +--# set connection default +box.space.test:drop() +box.schema.user.revoke('guest', 'replication') + diff --git a/test/replication/suite.ini b/test/replication/suite.ini index c0a179cce971a84ef394aa6bb06c3a4b3403a547..1841d9fb39fe062c9f022ce0e51252673293b256 100644 --- a/test/replication/suite.ini +++ b/test/replication/suite.ini @@ -3,3 +3,4 @@ core = tarantool script = master.lua description = tarantool/box, replication disabled = consistent.test.lua status.test.py +release_disabled = catch.test.lua