forked from tarantool/tarantool
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
box: allow to truncate temp and local spaces in ro mode
To achieve that, we bypass the read-only check for the _truncate system space in box_process1() and perform it in the on_replace system trigger instead, when we know which space is truncated. Note, we have to move the check for insertion of a new record into the _truncate system space before the read-only check in the on_replace trigger callback; this is needed for initial recovery with a non-empty _truncate space to work. While we are at it, let's use recovery_state to make the check explicit. Closes tarantool#5616 @TarantoolBot document Title: Mention that temp and local spaces can be truncated in ro mode DML operations on temporary and local spaces can be performed even if the instance is in the read-only mode, but DDL operations (such as `alter`) are forbidden in this case[^1]. Technically, `truncate` is a DDL operation so initially it was forbidden as well. However, it should be safe to perform this operation on a temporary or local space because logically it only modifies the data stored in the space (like DML) and it isn't replicated (see tarantool#4263). So starting from Tarantool 2.11.1 we allow users to truncate temporary spaces in the read-only mode. [^1]: https://www.tarantool.io/en/doc/latest/concepts/replication/repl_architecture/#replication-local
- Loading branch information
Showing
7 changed files
with
204 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
## feature/box | ||
|
||
* Allowed truncation of temporary and local spaces in the read-only mode | ||
(gh-5616). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
167 changes: 167 additions & 0 deletions
167
test/box-luatest/gh_5616_temp_space_truncate_ro_test.lua
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
local server = require('luatest.server') | ||
local t = require('luatest') | ||
|
||
local g_single = t.group('gh_5616_temp_space_truncate_ro.single') | ||
|
||
g_single.before_all(function(cg) | ||
cg.server = server:new() | ||
cg.server:start() | ||
end) | ||
|
||
g_single.after_all(function(cg) | ||
cg.server:drop() | ||
end) | ||
|
||
g_single.after_each(function(cg) | ||
cg.server:exec(function() | ||
box.cfg({read_only = false}) | ||
if box.space.test ~= nil then | ||
box.space.test:drop() | ||
end | ||
end) | ||
end) | ||
|
||
-- Checks that a temporary space can be truncated in the read-only mode. | ||
g_single.test_temp_space_truncate_ro = function(cg) | ||
cg.server:exec(function() | ||
local s = box.schema.create_space('test', {temporary = true}) | ||
s:create_index('primary') | ||
s:insert({1}) | ||
box.cfg({read_only = true}) | ||
local ok, err = pcall(s.truncate, s) | ||
t.assert(ok, err) | ||
t.assert_equals(s:select(), {}) | ||
end) | ||
end | ||
|
||
-- Checks that a local space can be truncated in the read-only mode. | ||
g_single.test_local_space_truncate_ro = function(cg) | ||
cg.server:exec(function() | ||
local s = box.schema.create_space('test', {is_local = true}) | ||
s:create_index('primary') | ||
s:insert({1}) | ||
box.cfg({read_only = true}) | ||
local ok, err = pcall(s.truncate, s) | ||
t.assert(ok, err) | ||
t.assert_equals(s:select(), {}) | ||
end) | ||
end | ||
|
||
-- Checks that a persistent space can't be truncated in the read-only mode. | ||
g_single.test_persistent_space_truncate_ro = function(cg) | ||
cg.server:exec(function() | ||
local s = box.schema.create_space('test') | ||
s:create_index('primary') | ||
s:insert({1}) | ||
box.cfg({read_only = true}) | ||
local ok, err = pcall(s.truncate, s) | ||
t.assert_not(ok, err) | ||
t.assert_equals(s:select(), {{1}}) | ||
end) | ||
end | ||
|
||
local g_replication = t.group('gh_5616_temp_space_truncate_ro.replication') | ||
|
||
g_replication.before_all(function(cg) | ||
cg.master = server:new({alias = 'master'}) | ||
cg.master:start() | ||
cg.replica = server:new({ | ||
alias = 'replica', | ||
box_cfg = { | ||
read_only = true, | ||
replication = cg.master.net_box_uri, | ||
}, | ||
}) | ||
cg.replica:start() | ||
end) | ||
|
||
g_replication.after_all(function(cg) | ||
cg.replica:drop() | ||
cg.master:drop() | ||
end) | ||
|
||
g_replication.after_each(function(cg) | ||
cg.master:exec(function() | ||
if box.space.test ~= nil then | ||
box.space.test:drop() | ||
end | ||
end) | ||
cg.replica:wait_for_vclock_of(cg.master) | ||
end) | ||
|
||
-- Checks that a truncate operation for a temporary space isn't replicated to | ||
-- a read-only replica. | ||
g_replication.test_temp_space_truncate_ro = function(cg) | ||
cg.master:exec(function() | ||
local s = box.schema.create_space('test', {temporary = true}) | ||
s:create_index('primary') | ||
s:insert({1}) | ||
end) | ||
cg.replica:wait_for_vclock_of(cg.master) | ||
cg.replica:exec(function() | ||
local s = box.space.test | ||
t.assert_equals(s:select(), {}) | ||
s:insert({2}) | ||
end) | ||
cg.master:exec(function() | ||
local s = box.space.test | ||
s:truncate() | ||
t.assert_equals(s:select(), {}) | ||
end) | ||
cg.replica:wait_for_vclock_of(cg.master) | ||
cg.replica:exec(function() | ||
local s = box.space.test | ||
t.assert_equals(s:select(), {{2}}) | ||
end) | ||
end | ||
|
||
-- Checks that a truncate operation for a local space isn't replicated to | ||
-- a read-only replica. | ||
g_replication.test_local_space_truncate_ro = function(cg) | ||
cg.master:exec(function() | ||
local s = box.schema.create_space('test', {is_local = true}) | ||
s:create_index('primary') | ||
s:insert({1}) | ||
end) | ||
cg.replica:wait_for_vclock_of(cg.master) | ||
cg.replica:exec(function() | ||
local s = box.space.test | ||
t.assert_equals(s:select(), {}) | ||
s:insert({2}) | ||
end) | ||
cg.master:exec(function() | ||
local s = box.space.test | ||
s:truncate() | ||
t.assert_equals(s:select(), {}) | ||
end) | ||
cg.replica:wait_for_vclock_of(cg.master) | ||
cg.replica:exec(function() | ||
local s = box.space.test | ||
t.assert_equals(s:select(), {{2}}) | ||
end) | ||
end | ||
|
||
-- Checks that a truncate operation for a persistent space is replicated to | ||
-- a read-only replica. | ||
g_replication.test_persistent_space_truncate_ro = function(cg) | ||
cg.master:exec(function() | ||
local s = box.schema.create_space('test') | ||
s:create_index('primary') | ||
s:insert({1}) | ||
end) | ||
cg.replica:wait_for_vclock_of(cg.master) | ||
cg.replica:exec(function() | ||
local s = box.space.test | ||
t.assert_equals(s:select(), {{1}}) | ||
end) | ||
cg.master:exec(function() | ||
local s = box.space.test | ||
s:truncate() | ||
t.assert_equals(s:select(), {}) | ||
end) | ||
cg.replica:wait_for_vclock_of(cg.master) | ||
cg.replica:exec(function() | ||
local s = box.space.test | ||
t.assert_equals(s:select(), {}) | ||
end) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters