From 752fd27fbc02250a159e536045743ec8a8f5e69a Mon Sep 17 00:00:00 2001 From: Alexandr <a.lyapunov@corp.mail.ru> Date: Tue, 31 Dec 2013 15:10:56 +0400 Subject: [PATCH] fixes, follows from discussion https://github.com/tarantool/tarantool/issues/79#issuecomment-29309533 --- src/box/tree_index.cc | 21 ++-- test/big/tarantool.cfg | 8 ++ test/big/tree_alloc_fail.result | 176 ++++++++++++++++++++++++++++++++ test/big/tree_alloc_fail.test | 50 +++++++++ test/box/errinj.result | 35 ------- test/box/errinj.test | 14 --- 6 files changed, 243 insertions(+), 61 deletions(-) create mode 100644 test/big/tree_alloc_fail.result create mode 100644 test/big/tree_alloc_fail.test diff --git a/src/box/tree_index.cc b/src/box/tree_index.cc index 5feba50828..1333c7f4d8 100644 --- a/src/box/tree_index.cc +++ b/src/box/tree_index.cc @@ -281,8 +281,8 @@ TreeIndex::replace(struct tuple *old_tuple, struct tuple *new_tuple, sptree_index_fold(&new_node, new_tuple); /* Try to optimistically replace the new_tuple. */ - int tree_res = sptree_index_replace(&tree, &new_node, - (void **) &p_dup_node); + int tree_res = sptree_index_replace(&tree, &new_node, + (void **) &p_dup_node); if (tree_res) { tnt_raise(ClientError, ER_MEMORY_ISSUE, tree_res, @@ -393,8 +393,7 @@ TreeIndex::beginBuild() size_t sz = tree.max_size * sizeof(struct sptree_index_node); tree.members = malloc(sz); if (tree.members == NULL) { - tnt_raise(ClientError, ER_MEMORY_ISSUE, - sz, "TreeIndex", "begin build"); + panic("malloc(): failed to allocate %" PRI_SZ " bytes", sz); } } @@ -407,8 +406,8 @@ TreeIndex::buildNext(struct tuple *tuple) size_t sz = tree.max_size * sizeof(struct sptree_index_node); tree.members = realloc(tree.members, sz); if (tree.members == NULL) { - tnt_raise(ClientError, ER_MEMORY_ISSUE, - sz, "TreeIndex", "begin build"); + panic("malloc(): failed to allocate %" PRI_SZ " bytes", + sz); } } @@ -434,8 +433,7 @@ TreeIndex::endBuild() sptree_index_node_compare, this); if (tree_res) { - tnt_raise(ClientError, ER_MEMORY_ISSUE, - tree_res, "TreeIndex", "init tree"); + panic("tree_init: failed to allocate %d bytes", tree_res); } } @@ -455,8 +453,8 @@ TreeIndex::build(Index *pk) size_t sz = estimated_tuples * sizeof(struct sptree_index_node); nodes = malloc(sz); if (nodes == NULL) { - tnt_raise(ClientError, ER_MEMORY_ISSUE, - sz, "TreeIndex", "build"); + panic("malloc(): failed to allocate %" PRI_SZ " bytes", + sz); } } @@ -485,7 +483,6 @@ TreeIndex::build(Index *pk) : sptree_index_node_compare_dup, this); if (tree_res) { - tnt_raise(ClientError, ER_MEMORY_ISSUE, - tree_res, "TreeIndex", "init tree"); + panic("tree_init: failed to allocate %d bytes", tree_res); } } diff --git a/test/big/tarantool.cfg b/test/big/tarantool.cfg index 58def14511..619d1396e7 100644 --- a/test/big/tarantool.cfg +++ b/test/big/tarantool.cfg @@ -394,3 +394,11 @@ space[27].index[1].key_field[0].fieldno = 2 space[27].index[1].key_field[0].type = NUM space[27].index[1].key_field[1].fieldno = 4 space[27].index[1].key_field[1].type = NUM + +# Test alloc fail in tree +space[28].enabled = 1 + +space[28].index[0].type = TREE +space[28].index[0].unique = true +space[28].index[0].key_field[0].fieldno = 0 +space[28].index[0].key_field[0].type = NUM diff --git a/test/big/tree_alloc_fail.result b/test/big/tree_alloc_fail.result new file mode 100644 index 0000000000..843173a8b7 --- /dev/null +++ b/test/big/tree_alloc_fail.result @@ -0,0 +1,176 @@ +lua s = box.space[28] +--- +... +lua for i = 1,10 do s:insert(i, i, 'test' .. i) end +--- +... +lua for i = 1,10 do print(s:select(0, i)) end +--- +1: {1, 'test1'} +2: {2, 'test2'} +3: {3, 'test3'} +4: {4, 'test4'} +5: {5, 'test5'} +6: {6, 'test6'} +7: {7, 'test7'} +8: {8, 'test8'} +9: {9, 'test9'} +10: {10, 'test10'} +... +lua for t in s.index[0]:iterator(box.index.ALL) do print(t); end +--- +1: {1, 'test1'} +2: {2, 'test2'} +3: {3, 'test3'} +4: {4, 'test4'} +5: {5, 'test5'} +6: {6, 'test6'} +7: {7, 'test7'} +8: {8, 'test8'} +9: {9, 'test9'} +10: {10, 'test10'} +... +set injection ERRINJ_TREE_ALLOC on +--- +ok +... +lua for i = 1,10 do print(s:select(0, i)) end +--- +1: {1, 'test1'} +2: {2, 'test2'} +3: {3, 'test3'} +4: {4, 'test4'} +5: {5, 'test5'} +6: {6, 'test6'} +7: {7, 'test7'} +8: {8, 'test8'} +9: {9, 'test9'} +10: {10, 'test10'} +... +lua for i = 501,1000 do s:insert(i, i) end +--- +error: 'Failed to allocate 1024 bytes in TreeIndex for replace' +... +lua s:delete(1) +--- + - 1: {1, 'test1'} +... +lua for t in s.index[0]:iterator(box.index.ALL) do print(t) end +--- +error: 'Failed to allocate 196 bytes in TreeIndex for init iterator' +... +set injection ERRINJ_TREE_ALLOC off +--- +ok +... +lua s:select(0, 1) +--- +... +set injection ERRINJ_TREE_ALLOC on +--- +ok +... +lua for i = 1,10 do print(s:select(0, i)) end +--- +2: {2, 'test2'} +3: {3, 'test3'} +4: {4, 'test4'} +5: {5, 'test5'} +6: {6, 'test6'} +7: {7, 'test7'} +8: {8, 'test8'} +9: {9, 'test9'} +10: {10, 'test10'} +... +lua for i = 1001,1500 do s:insert(i, i) end +--- +error: 'Failed to allocate 1024 bytes in TreeIndex for replace' +... +lua s:delete(2) +--- + - 2: {2, 'test2'} +... +lua s.index[0]:iterator(box.index.ALL) +--- +error: 'Failed to allocate 200 bytes in TreeIndex for init iterator' +... +set injection ERRINJ_TREE_ALLOC off +--- +ok +... +lua s:select(0, 1) +--- +... +set injection ERRINJ_TREE_ALLOC on +--- +ok +... +lua for i = 1,10 do print(s:select(0, i)) end +--- +3: {3, 'test3'} +4: {4, 'test4'} +5: {5, 'test5'} +6: {6, 'test6'} +7: {7, 'test7'} +8: {8, 'test8'} +9: {9, 'test9'} +10: {10, 'test10'} +... +lua for i = 1501,2000 do s:insert(i, i) end +--- +error: 'Failed to allocate 1024 bytes in TreeIndex for replace' +... +lua s:delete(3) +--- + - 3: {3, 'test3'} +... +lua s.index[0]:iterator(box.index.ALL) +--- +error: 'Failed to allocate 200 bytes in TreeIndex for init iterator' +... +set injection ERRINJ_TREE_ALLOC off +--- +ok +... +lua for i = 2001,2500 do s:insert(i, i) end +--- +... +lua for i = 1,10 do print(s:select(0, i)) end +--- +4: {4, 'test4'} +5: {5, 'test5'} +6: {6, 'test6'} +7: {7, 'test7'} +8: {8, 'test8'} +9: {9, 'test9'} +10: {10, 'test10'} +... +lua s:delete(8) +--- + - 8: {8, 'test8'} +... +lua for i = 1,10 do print(s:select(0, i)) end +--- +4: {4, 'test4'} +5: {5, 'test5'} +6: {6, 'test6'} +7: {7, 'test7'} +9: {9, 'test9'} +10: {10, 'test10'} +... +lua for i = 2001,2010 do print(s:select(0, i)) end +--- +2001: {2001} +2002: {2002} +2003: {2003} +2004: {2004} +2005: {2005} +2006: {2006} +2007: {2007} +2008: {2008} +2009: {2009} +2010: {2010} +... +lua s:truncate() +--- +... diff --git a/test/big/tree_alloc_fail.test b/test/big/tree_alloc_fail.test new file mode 100644 index 0000000000..ef7de11a7d --- /dev/null +++ b/test/big/tree_alloc_fail.test @@ -0,0 +1,50 @@ +# encoding: tarantool +# +import sys + +# Check a failed realloc in tree. +exec admin "lua s = box.space[28]" + +exec admin "lua for i = 1,10 do s:insert(i, i, 'test' .. i) end" +exec admin "lua for i = 1,10 do print(s:select(0, i)) end" +exec admin "lua for t in s.index[0]:iterator(box.index.ALL) do print(t); end" + +exec admin "set injection ERRINJ_TREE_ALLOC on" + +exec admin "lua for i = 1,10 do print(s:select(0, i)) end" +exec admin "lua for i = 501,1000 do s:insert(i, i) end" +exec admin "lua s:delete(1)" +exec admin "lua for t in s.index[0]:iterator(box.index.ALL) do print(t) end" + +# reserve memory for iterator in index. last insert may increase tree depth +exec admin "set injection ERRINJ_TREE_ALLOC off" +exec admin "lua s:select(0, 1)" +exec admin "set injection ERRINJ_TREE_ALLOC on" + +exec admin "lua for i = 1,10 do print(s:select(0, i)) end" + +exec admin "lua for i = 1001,1500 do s:insert(i, i) end" +exec admin "lua s:delete(2)" +exec admin "lua s.index[0]:iterator(box.index.ALL)" + +# reserve memory for iterator in index. last insert may increase tree depth +# (if rebalance was not initiated) +exec admin "set injection ERRINJ_TREE_ALLOC off" +exec admin "lua s:select(0, 1)" +exec admin "set injection ERRINJ_TREE_ALLOC on" + +exec admin "lua for i = 1,10 do print(s:select(0, i)) end" +exec admin "lua for i = 1501,2000 do s:insert(i, i) end" +exec admin "lua s:delete(3)" +exec admin "lua s.index[0]:iterator(box.index.ALL)" + +exec admin "set injection ERRINJ_TREE_ALLOC off" + +exec admin "lua for i = 2001,2500 do s:insert(i, i) end" +exec admin "lua for i = 1,10 do print(s:select(0, i)) end" +exec admin "lua s:delete(8)" +exec admin "lua for i = 1,10 do print(s:select(0, i)) end" +exec admin "lua for i = 2001,2010 do print(s:select(0, i)) end" +exec admin "lua s:truncate()" + +# vim: syntax=python diff --git a/test/box/errinj.result b/test/box/errinj.result index eef7c12f29..e6bb917253 100644 --- a/test/box/errinj.result +++ b/test/box/errinj.result @@ -111,38 +111,3 @@ ok lua box.space[0]:truncate() --- ... -lua for i = 1,10 do box.space[0]:insert(i, i, 'testtesttest') end ---- -... -set injection ERRINJ_TREE_ALLOC on ---- -ok -... -lua for i = 11,1000 do box.space[0]:insert(i, i) end ---- -error: 'Failed to allocate 1024 bytes in TreeIndex for replace' -... -lua box.space[0].index[0]:iterator(box.index.ALL) ---- -error: 'Failed to allocate 196 bytes in TreeIndex for init iterator' -... -set injection ERRINJ_TREE_ALLOC off ---- -ok -... -lua for i = 1,10 do print(box.space[0]:select(0, i)) end ---- -1: {1, 'testtesttest'} -2: {2, 'testtesttest'} -3: {3, 'testtesttest'} -4: {4, 'testtesttest'} -5: {5, 'testtesttest'} -6: {6, 'testtesttest'} -7: {7, 'testtesttest'} -8: {8, 'testtesttest'} -9: {9, 'testtesttest'} -10: {10, 'testtesttest'} -... -lua box.space[0]:truncate() ---- -... diff --git a/test/box/errinj.test b/test/box/errinj.test index 7f692e2ebe..63d1a04ce6 100644 --- a/test/box/errinj.test +++ b/test/box/errinj.test @@ -43,18 +43,4 @@ exec admin "set injection ERRINJ_WAL_ROTATE on" exec admin "lua box.space[0]:truncate()" exec admin "set injection ERRINJ_WAL_ROTATE off" exec admin "lua box.space[0]:truncate()" - -# Check a failed realloc in tree. -server.stop() -server.deploy("box/tarantool_tree_alloc.cfg") -exec admin "lua for i = 1,10 do box.space[0]:insert(i, i, 'testtesttest') end" -exec admin "set injection ERRINJ_TREE_ALLOC on" -exec admin "lua for i = 11,1000 do box.space[0]:insert(i, i) end" -exec admin "lua box.space[0].index[0]:iterator(box.index.ALL)" -exec admin "set injection ERRINJ_TREE_ALLOC off" -exec admin "lua for i = 1,10 do print(box.space[0]:select(0, i)) end" -exec admin "lua box.space[0]:truncate()" -server.stop() -server.deploy(self.suite_ini["config"]) - # vim: syntax=python -- GitLab