diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index e3cff88a570820324fd0a2c654dbc58bb336914f..e92e5f60124a50d4d466bf9aeb477d5613f88c9f 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -203,23 +203,49 @@ local function keify(key)
     return {key}
 end
 
-local iterator_mt = {
-    __call = function(iterator)
-        local tuple = iterator.cdata.next(iterator.cdata)
-        if tuple ~= nil then
-            return box.tuple.bless(tuple)
-        else
-            return nil
-        end
-    end;
+local iterator_t = ffi.typeof('struct iterator')
+ffi.metatype(iterator_t, {
     __tostring = function(iterator)
-        return string.format("iterator on space %d index %d",
-            iterator.index.n, iterator.index.id)
+        return "<iterator state>"
     end;
-}
+})
+
+local iterator_gen = function(param, state)
+    --[[
+        index:pairs() mostly confirms to the Lua for-in loop conventions and
+        tries to follow the best practices of Lua community.
+
+        - this generating function is stateless.
+
+        - *param* should contain **immutable** data needed to fully define
+          an iterator. *param* is opaque for users. Currently it contains keybuf
+          string just to prevent GC from collecting it. In future some other
+          variables like space_id, index_id, sc_version will be stored here.
+
+        - *state* should contain **immutable** transient state of an iterator.
+          *state* is opaque for users. Currently it contains `struct iterator`
+          cdata that is modified during iteration. This is a sad limitation of
+          underlying C API. Moreover, the separation of *param* and *state* is
+          not properly implemented here. These drawbacks can be fixed in
+          future without changing this API.
+
+        Please checkout http://www.lua.org/pil/7.3.html for the further
+        information.
+    --]]
+    if not ffi.istype(iterator_t, state) then
+        error('usage gen(param, state)')
+    end
+    -- next() modifies state in-place
+    local tuple = state.next(state)
+    if tuple ~= nil then
+        return state, box.tuple.bless(tuple) -- new state, value
+    else
+        return nil
+    end
+end
 
-local iterator_cdata_gc = function(iterator_cdata)
-    return iterator_cdata.free(iterator_cdata)
+local iterator_cdata_gc = function(iterator)
+    return iterator.free(iterator)
 end
 
 -- global struct port instance to use by select()/get()
@@ -260,7 +286,7 @@ function box.schema.space.bless(space)
     end
     index_mt.random = function(index, rnd) return index.idx:random(rnd) end
     -- iteration
-    index_mt.iterator = function(index, key, opts)
+    index_mt.pairs = function(index, key, opts)
         local pkey, pkey_end = msgpackffi.encode_tuple(key)
         -- Use ALL for {} and nil keys and EQ for other keys
         local itype = pkey + 1 < pkey_end and box.index.EQ or box.index.ALL
@@ -281,12 +307,10 @@ function box.schema.space.bless(space)
             box.raise()
         end
 
-        return setmetatable({
-            cdata = ffi.gc(cdata, iterator_cdata_gc);
-            keybuf = keybuf;
-            index = index;
-        }, iterator_mt)
+        return iterator_gen, keybuf, ffi.gc(cdata, iterator_cdata_gc)
     end
+    index_mt.__pairs = index_mt.pairs -- Lua 5.2 compatibility
+    index_mt.__ipairs = index_mt.pairs -- Lua 5.2 compatibility
     -- index subtree size
     index_mt.count = function(index, key, opts)
         local count = 0
@@ -302,7 +326,8 @@ function box.schema.space.bless(space)
             return #index.idx
         end
 
-        for tuple in index:iterator(key, { iterator = iterator }) do
+        local state, tuple
+        for state, tuple in index:pairs(key, { iterator = iterator }) do
             count = count + 1
         end
         return count
@@ -352,7 +377,8 @@ function box.schema.space.bless(space)
             return result
         end
 
-        for tuple in index:iterator(key, { iterator = iterator }) do
+        local state, tuple
+        for state, tuple in index:pairs(key, { iterator = iterator }) do
             if grep == nil or grep(tuple) then
                 if skip < offset then
                     skip = skip + 1
@@ -494,15 +520,18 @@ function box.schema.space.bless(space)
         table.insert(tuple, 1, max + 1)
         return space:insert(tuple)
     end
-    space_mt.iterator = function(space, key)
+    space_mt.pairs = function(space, key)
         check_index(space, 0)
-        return space.index[0]:iterator(key)
+        return space.index[0]:pairs(key)
     end
+    space_mt.__pairs = space_mt.pairs -- Lua 5.2 compatibility
+    space_mt.__ipairs = space_mt.pairs -- Lua 5.2 compatibility
     space_mt.truncate = function(space)
         check_index(space, 0)
         local pk = space.index[0]
         while #pk.idx > 0 do
-            for t in pk:iterator() do
+            local state, t
+            for state, t in pk:pairs() do
                 local key = {}
                 -- ipairs does not work because pk.key_field is zero-indexed
                 for _k2, key_field in pairs(pk.key_field) do
diff --git a/test/big/hash_multipart.result b/test/big/hash_multipart.result
index 4eaad79a45b96e6a8a84dee15b237b0f5fd67080..33d6d02dd92f7fefdee52c549c2110533069d9af 100644
--- a/test/big/hash_multipart.result
+++ b/test/big/hash_multipart.result
@@ -52,7 +52,8 @@ hash:insert{1, 'bar', 1, '', 5}
 --# setopt delimiter ';'
 function box.select_all()
     local result = {}
-    for v in hash:iterator() do
+    local tuple, v
+    for tuple, v in hash:pairs() do
         table.insert(result, v)
     end
     return result
diff --git a/test/big/hash_multipart.test.lua b/test/big/hash_multipart.test.lua
index 4e1e0d0cb3c9a2b2a128403927f363b1dff27a55..847326d7f2846608ad68066a4f74240a84153da7 100644
--- a/test/big/hash_multipart.test.lua
+++ b/test/big/hash_multipart.test.lua
@@ -22,7 +22,8 @@ hash:insert{1, 'bar', 1, '', 5}
 --# setopt delimiter ';'
 function box.select_all()
     local result = {}
-    for v in hash:iterator() do
+    local tuple, v
+    for tuple, v in hash:pairs() do
         table.insert(result, v)
     end
     return result
diff --git a/test/big/iterator.result b/test/big/iterator.result
index 86c43987a1cb5053eb04f4392db7bb612ad3b717..e1b76a87365a310ed08abf5d3b8ccd66c21d56d4 100644
--- a/test/big/iterator.result
+++ b/test/big/iterator.result
@@ -884,12 +884,12 @@ iterate('tweedledum', 'i5', 1, 3, box.index.EQ, 'sid_005', 'tid_995', 'a')
 -------------------------------------------------------------------------------
 -- Iterator: various
 -------------------------------------------------------------------------------
-space.index['primary']:iterator({}, {iterator = -666 })
+space.index['primary']:pairs({}, {iterator = -666 })
 ---
 - error: Tree index does not support requested iterator type
 ...
 -- Test cases for #123: box.index.count does not check arguments properly
-space.index['primary']:iterator(function() end, { iterator = box.index.EQ })
+space.index['primary']:pairs(function() end, { iterator = box.index.EQ })
 ---
 - error: '[string "-- msgpackffi.lua (internal file)..."]:261: can not encode Lua
     type: ''function'''
diff --git a/test/big/iterator.test.lua b/test/big/iterator.test.lua
index e0ca38eaa65d483f2507feb7252946b0b862251b..a6f6b6ecf31dfebb7e785a8037d9acbead6a35b7 100644
--- a/test/big/iterator.test.lua
+++ b/test/big/iterator.test.lua
@@ -158,7 +158,7 @@ iterate('tweedledum', 'i5', 1, 3, box.index.EQ, 'sid_005', 'tid_995', 'a')
 -- Iterator: various
 -------------------------------------------------------------------------------
 
-space.index['primary']:iterator({}, {iterator = -666 })
+space.index['primary']:pairs({}, {iterator = -666 })
 -- Test cases for #123: box.index.count does not check arguments properly
-space.index['primary']:iterator(function() end, { iterator = box.index.EQ })
+space.index['primary']:pairs(function() end, { iterator = box.index.EQ })
 space:drop()
diff --git a/test/big/lua.result b/test/big/lua.result
index 45e66a3caf69fe13d84579dda41108f62b762e80..524b6a6a3e201b520da9361934e0186d0a8ebcaf 100644
--- a/test/big/lua.result
+++ b/test/big/lua.result
@@ -61,14 +61,20 @@ space:insert{'item 4', 'georgia', 'on my mind'}
 ---
 - ['item 4', 'georgia', 'on my mind']
 ...
-iter, state = space.index['minmax']:iterator('california', { iterator =  box.index.GE })
+iter, param, state = space.index['minmax']:pairs('california', { iterator =  box.index.GE })
 ---
 ...
-iter()
+state, v = iter(param, state)
+---
+...
+v
 ---
 - ['item 2', 'california', 'dreaming ']
 ...
-iter()
+state, v = iter(param, state)
+---
+...
+v
 ---
 - ['item 3', 'california', 'uber alles']
 ...
@@ -386,7 +392,7 @@ index = space.index['i1']
 t = {}
 ---
 ...
-for v in index:iterator('sid_1', { iterator = 'GE' }) do table.insert(t, v) end
+for state, v in index:pairs('sid_1', { iterator = 'GE' }) do table.insert(t, v) end
 ---
 ...
 t
@@ -401,7 +407,7 @@ t
 t = {}
 ---
 ...
-for v in index:iterator('sid_2', { iterator = 'LE' }) do table.insert(t, v) end
+for state, v in index:pairs('sid_2', { iterator = 'LE' }) do table.insert(t, v) end
 ---
 ...
 t
@@ -416,7 +422,7 @@ t
 t = {}
 ---
 ...
-for v in index:iterator('sid_1', { iterator = 'EQ' }) do table.insert(t, v) end
+for state, v in index:pairs('sid_1', { iterator = 'EQ' }) do table.insert(t, v) end
 ---
 ...
 t
@@ -428,7 +434,7 @@ t
 t = {}
 ---
 ...
-for v in index:iterator('sid_1', { iterator = 'REQ' }) do table.insert(t, v) end
+for state, v in index:pairs('sid_1', { iterator = 'REQ' }) do table.insert(t, v) end
 ---
 ...
 t
@@ -440,7 +446,7 @@ t
 t = {}
 ---
 ...
-for v in index:iterator('sid_2', { iterator = 'EQ' }) do table.insert(t, v) end
+for state, v in index:pairs('sid_2', { iterator = 'EQ' }) do table.insert(t, v) end
 ---
 ...
 t
@@ -452,7 +458,7 @@ t
 t = {}
 ---
 ...
-for v in index:iterator('sid_2', { iterator = 'REQ' }) do table.insert(t, v) end
+for state, v in index:pairs('sid_2', { iterator = 'REQ' }) do table.insert(t, v) end
 ---
 ...
 t
@@ -464,9 +470,9 @@ t
 t = {}
 ---
 ...
-index:iterator('sid_t', { iterator = 'wrong_iterator_type' })
+index:pairs('sid_t', { iterator = 'wrong_iterator_type' })
 ---
-- error: '[string "-- schema.lua (internal file)..."]:273: Wrong iterator type: wrong_iterator_type'
+- error: '[string "-- schema.lua (internal file)..."]:299: Wrong iterator type: wrong_iterator_type'
 ...
 index = nil
 ---
diff --git a/test/big/lua.test.lua b/test/big/lua.test.lua
index 3c77c280567a5fe250cca9e73a87c9571266b7f1..b96493075571849fc8f96b50cff58e5c0abfaa90 100644
--- a/test/big/lua.test.lua
+++ b/test/big/lua.test.lua
@@ -24,9 +24,11 @@ space.index['minmax']:get{'alabama'}
 space:insert{'item 2', 'california', 'dreaming '}
 space:insert{'item 3', 'california', 'uber alles'}
 space:insert{'item 4', 'georgia', 'on my mind'}
-iter, state = space.index['minmax']:iterator('california', { iterator =  box.index.GE })
-iter()
-iter()
+iter, param, state = space.index['minmax']:pairs('california', { iterator =  box.index.GE })
+state, v = iter(param, state)
+v
+state, v = iter(param, state)
+v
 space:delete{'item 1'}
 space:delete{'item 2'}
 space:delete{'item 3'}
@@ -146,27 +148,27 @@ end;
 index = space.index['i1']
 
 t = {}
-for v in index:iterator('sid_1', { iterator = 'GE' }) do table.insert(t, v) end
+for state, v in index:pairs('sid_1', { iterator = 'GE' }) do table.insert(t, v) end
 t
 t = {}
-for v in index:iterator('sid_2', { iterator = 'LE' }) do table.insert(t, v) end
+for state, v in index:pairs('sid_2', { iterator = 'LE' }) do table.insert(t, v) end
 t
 t = {}
-for v in index:iterator('sid_1', { iterator = 'EQ' }) do table.insert(t, v) end
+for state, v in index:pairs('sid_1', { iterator = 'EQ' }) do table.insert(t, v) end
 t
 t = {}
-for v in index:iterator('sid_1', { iterator = 'REQ' }) do table.insert(t, v) end
+for state, v in index:pairs('sid_1', { iterator = 'REQ' }) do table.insert(t, v) end
 t
 t = {}
-for v in index:iterator('sid_2', { iterator = 'EQ' }) do table.insert(t, v) end
+for state, v in index:pairs('sid_2', { iterator = 'EQ' }) do table.insert(t, v) end
 t
 t = {}
-for v in index:iterator('sid_2', { iterator = 'REQ' }) do table.insert(t, v) end
+for state, v in index:pairs('sid_2', { iterator = 'REQ' }) do table.insert(t, v) end
 t
 t = {}
 
 
-index:iterator('sid_t', { iterator = 'wrong_iterator_type' })
+index:pairs('sid_t', { iterator = 'wrong_iterator_type' })
 
 index = nil
 space:drop()
diff --git a/test/big/lua/utils.lua b/test/big/lua/utils.lua
index 063bf5fa89cad8e2ae3ae88f90f56326e19d73b1..67adc0e6d9ea8239daaa23931e2b19e5c562ce1b 100644
--- a/test/big/lua/utils.lua
+++ b/test/big/lua/utils.lua
@@ -22,7 +22,8 @@ function iterate(space_no, index_no, f1, f2, iterator, ...)
 			return f
 		end
 	end
-	for v in box.space[space_no].index[index_no]:iterator({...}, { iterator = iterator }) do
+	local state, v
+	for state, v in box.space[space_no].index[index_no]:pairs({...}, { iterator = iterator }) do
 		local pk = get_field(v, 0);
 		local tk = '$';
 		for f = f1, f2-1, 1 do tk = (tk..(get_field(v, f))..'$'); end;
diff --git a/test/big/sql.result b/test/big/sql.result
index 05185e29cc45dc44c9a1ecd6d2f2c00878adf493..cfc2318c3830c2e180de7baa72704d45e44fe972 100644
--- a/test/big/sql.result
+++ b/test/big/sql.result
@@ -228,7 +228,7 @@ insert into t0 values (41234567, 'part1_a', 'part2_a')
 l = {}
 ---
 ...
-for v in s:iterator() do table.insert(l, v) end
+for state, v in s:pairs() do table.insert(l, v) end
 ---
 ...
 return l
diff --git a/test/big/sql.test.py b/test/big/sql.test.py
index 7c8b8c52a61381c053af4a79af76f91a68fd8df3..1d3854dbd55669c6b3b36dbe52ee511a2d538d5d 100644
--- a/test/big/sql.test.py
+++ b/test/big/sql.test.py
@@ -90,7 +90,7 @@ sql("insert into t0 values (21234567, 'part1', 'part2_a')")
 sql("insert into t0 values (31234567, 'part1_a', 'part2')")
 sql("insert into t0 values (41234567, 'part1_a', 'part2_a')")
 admin("l = {}")
-admin("for v in s:iterator() do table.insert(l, v) end")
+admin("for state, v in s:pairs() do table.insert(l, v) end")
 admin("return l")
 sql("select * from t0 where k0=01234567")
 sql("select * from t0 where k0=11234567")
diff --git a/test/big/tree_pk.result b/test/big/tree_pk.result
index 2a4bc433aefdb631b466fac78ab7075ce53f5942..0eeee0869a33fc62c1863689aad2996c03e05940 100644
--- a/test/big/tree_pk.result
+++ b/test/big/tree_pk.result
@@ -137,8 +137,8 @@ s1:delete{'third'}
 --# setopt delimiter ';'
 function crossjoin(space0, space1, limit)
     local result = {}
-    for v0 in space0:iterator() do
-        for v1 in space1:iterator() do
+    for state, v0 in space0:pairs() do
+        for state, v1 in space1:pairs() do
             if limit <= 0 then
                 return result
             end
@@ -590,7 +590,7 @@ s:insert{8}
 - [8]
 ...
 -- it seems that all elements will be deleted:
-for t in ind:iterator() do s:delete{t[0]} end
+for state, t in ind:pairs() do s:delete{t[0]} end
 ---
 ...
 -- but (oops) some elements are left in space:
@@ -635,25 +635,37 @@ s:insert{1}
 ---
 - [1]
 ...
-itr = ind:iterator()
+gen, param, state = ind:pairs()
 ---
 ...
-itr() -- 1
+state, val = gen(param, state)
+---
+...
+val -- 1
 ---
 - [1]
 ...
-itr() -- 2
+state, val = gen(param, state)
+---
+...
+val -- 2
 ---
 - [2]
 ...
 for i = 5,100 do s:insert{i} end
 ---
 ...
-itr() -- 3
+state, val = gen(param, state)
+---
+...
+val -- 3
 ---
 - [3]
 ...
-itr() -- now you don't
+state, val = gen(param, state)
+---
+...
+val -- now you don't
 ---
 - null
 ...
@@ -687,10 +699,13 @@ s:insert{3}
 ---
 - [3]
 ...
-itr = ind:iterator()
+gen, param, state = ind:pairs()
+---
+...
+state, val = gen(param, state)
 ---
 ...
-itr() -- 1
+val -- 1
 ---
 - [1]
 ...
@@ -702,11 +717,17 @@ s:insert{0}
 ---
 - [0]
 ...
-itr() -- 1 again
+state, val = gen(param, state)
+---
+...
+val -- 1 again
 ---
 - [1]
 ...
-itr() -- null
+state, val = gen(param, state)
+---
+...
+val -- null
 ---
 - null
 ...
diff --git a/test/big/tree_pk.test.lua b/test/big/tree_pk.test.lua
index 028ec47c6b9ea0a4d784d425abb933eae5b623bd..e950f3be2e9e24058c471e5511913585006e5670 100644
--- a/test/big/tree_pk.test.lua
+++ b/test/big/tree_pk.test.lua
@@ -52,8 +52,8 @@ s1:delete{'third'}
 --# setopt delimiter ';'
 function crossjoin(space0, space1, limit)
     local result = {}
-    for v0 in space0:iterator() do
-        for v1 in space1:iterator() do
+    for state, v0 in space0:pairs() do
+        for state, v1 in space1:pairs() do
             if limit <= 0 then
                 return result
             end
@@ -212,7 +212,7 @@ s:insert{7}
 s:insert{8}
 
 -- it seems that all elements will be deleted:
-for t in ind:iterator() do s:delete{t[0]} end
+for state, t in ind:pairs() do s:delete{t[0]} end
 
 -- but (oops) some elements are left in space:
 iterate('test', 'primary', 0, 1)
@@ -232,12 +232,16 @@ s:insert{2}
 s:insert{4} -- now you see me
 s:insert{1}
 
-itr = ind:iterator()
-itr() -- 1
-itr() -- 2
+gen, param, state = ind:pairs()
+state, val = gen(param, state)
+val -- 1
+state, val = gen(param, state)
+val -- 2
 for i = 5,100 do s:insert{i} end
-itr() -- 3
-itr() -- now you don't
+state, val = gen(param, state)
+val -- 3
+state, val = gen(param, state)
+val -- now you don't
 
 -- cleanup
 s:drop()
@@ -254,12 +258,15 @@ s:insert{2}
 s:insert{1}
 s:insert{3}
 
-itr = ind:iterator()
-itr() -- 1
+gen, param, state = ind:pairs()
+state, val = gen(param, state)
+val -- 1
 s:delete{2}
 s:insert{0}
-itr() -- 1 again
-itr() -- null
+state, val = gen(param, state)
+val -- 1 again
+state, val = gen(param, state)
+val -- null
 
 -- cleanup
 s:drop()
diff --git a/test/big/tree_pk_multipart.result b/test/big/tree_pk_multipart.result
index efce5b461f15b05513808263e410c4d0dce14b92..b54c2cffc5f645d405903f3e8ca1ea07797d3c5f 100644
--- a/test/big/tree_pk_multipart.result
+++ b/test/big/tree_pk_multipart.result
@@ -394,12 +394,12 @@ space:insert{'c', 'c', 'c'}
 t = {}
 ---
 ...
-iterator = space.index['second']:iterator(nil, { iterator = box.index.GE })
+gen, param, state = space.index['second']:pairs(nil, { iterator = box.index.GE })
 ---
 ...
 --# setopt delimiter ';'
 for i = 1, 2 do
-    v = iterator()
+    state, v = gen(param, state)
     table.insert(t, v)
 end;
 ---
@@ -425,7 +425,7 @@ v
 ---
 - ['b', 'b', 'b']
 ...
-v = iterator()
+param, v = gen(param, state)
 ---
 ...
 v
@@ -445,7 +445,7 @@ t = {}
 ...
 --# setopt delimiter ';'
 for i = 1, 3 do
-    v = iterator()
+    param, v = gen(param, state)
     table.insert(t, v)
 end;
 ---
diff --git a/test/big/tree_pk_multipart.test.lua b/test/big/tree_pk_multipart.test.lua
index 942f30c246abdf59a13ba9d03501f1a2117c8e4d..c84891411125555fa1bb3a9cf7841016961a15ca 100644
--- a/test/big/tree_pk_multipart.test.lua
+++ b/test/big/tree_pk_multipart.test.lua
@@ -127,10 +127,10 @@ space:insert{'b', 'b', 'b'}
 space:insert{'c', 'c', 'c'}
 
 t = {}
-iterator = space.index['second']:iterator(nil, { iterator = box.index.GE })
+gen, param, state = space.index['second']:pairs(nil, { iterator = box.index.GE })
 --# setopt delimiter ';'
 for i = 1, 2 do
-    v = iterator()
+    state, v = gen(param, state)
     table.insert(t, v)
 end;
 --# setopt delimiter ''
@@ -141,7 +141,7 @@ v
 collectgarbage('collect')
 v
 
-v = iterator()
+param, v = gen(param, state)
 v
 collectgarbage('collect')
 v
@@ -149,7 +149,7 @@ v
 t = {}
 --# setopt delimiter ';'
 for i = 1, 3 do
-    v = iterator()
+    param, v = gen(param, state)
     table.insert(t, v)
 end;
 --# setopt delimiter ''
diff --git a/test/box/crossjoin.result b/test/box/crossjoin.result
index b3c9739ae917ae5e74413c38c36a02bb28d89ba8..ef64f6e841fac440068f04846a6c61c2e8a82b03 100644
--- a/test/box/crossjoin.result
+++ b/test/box/crossjoin.result
@@ -7,8 +7,8 @@ space:create_index('primary', { type = 'tree' })
 --# setopt delimiter ';'
 function crossjoin(space0, space1, limit)
   local result = {}
-  for v0 in space0:iterator() do
-    for v1 in space1:iterator() do
+  for _,v0 in space0:pairs() do
+    for _,v1 in space1:pairs() do
       if limit <= 0 then
         return result
       end
diff --git a/test/box/crossjoin.test.lua b/test/box/crossjoin.test.lua
index b7839c1f4e56b6be551f4fd20f825f2a3341f01b..5919ae40b5cd6f10a6f4fa0006af4cebc643e388 100644
--- a/test/box/crossjoin.test.lua
+++ b/test/box/crossjoin.test.lua
@@ -3,8 +3,8 @@ space:create_index('primary', { type = 'tree' })
 --# setopt delimiter ';'
 function crossjoin(space0, space1, limit)
   local result = {}
-  for v0 in space0:iterator() do
-    for v1 in space1:iterator() do
+  for _,v0 in space0:pairs() do
+    for _,v1 in space1:pairs() do
       if limit <= 0 then
         return result
       end
diff --git a/test/box/errinj_index.result b/test/box/errinj_index.result
index 76b497c56fa2bc0e6659dff4d4fd97e24a59d09d..feb59b77a8af5e0abc5053141aab1e0b40363a65 100644
--- a/test/box/errinj_index.result
+++ b/test/box/errinj_index.result
@@ -30,7 +30,7 @@ res
 res = {}
 ---
 ...
-for t in s.index[0]:iterator() do table.insert(res, t) end
+for _, t in s.index[0]:pairs() do table.insert(res, t) end
 ---
 ...
 res
@@ -80,7 +80,7 @@ s:delete{1}
 res = {}
 ---
 ...
-for t in s.index[0]:iterator() do table.insert(res, t) end
+for _, t in s.index[0]:pairs() do table.insert(res, t) end
 ---
 - error: Failed to allocate 196 bytes in TreeIndex for init iterator
 ...
@@ -126,7 +126,7 @@ s:delete{2}
 ---
 - [2, 2, 'test2']
 ...
-s.index[0]:iterator()
+s.index[0]:pairs()
 ---
 - error: Failed to allocate 200 bytes in TreeIndex for init iterator
 ...
@@ -168,7 +168,7 @@ s:delete{3}
 ---
 - [3, 3, 'test3']
 ...
-s.index[0]:iterator()
+s.index[0]:pairs()
 ---
 - error: Failed to allocate 200 bytes in TreeIndex for init iterator
 ...
diff --git a/test/box/errinj_index.test.lua b/test/box/errinj_index.test.lua
index d6743cbe8d5578519e0f474a5494e1b61a4a7711..05e65e060af7eb5630fff5f381bbfea05def1f2b 100644
--- a/test/box/errinj_index.test.lua
+++ b/test/box/errinj_index.test.lua
@@ -8,7 +8,7 @@ res = {}
 for i = 1,10 do table.insert(res, s:get{i}) end
 res
 res = {}
-for t in s.index[0]:iterator() do table.insert(res, t) end
+for _, t in s.index[0]:pairs() do table.insert(res, t) end
 res
 
 box.errinj.set("ERRINJ_TREE_ALLOC", true)
@@ -19,7 +19,7 @@ res
 for i = 501,1000 do s:insert{i, i} end
 s:delete{1}
 res = {}
-for t in s.index[0]:iterator() do table.insert(res, t) end
+for _, t in s.index[0]:pairs() do table.insert(res, t) end
 res
 
 -- reserve memory for iterator in index. last insert may increase tree depth
@@ -33,7 +33,7 @@ res
 
 for i = 1001,1500 do s:insert{i, i} end
 s:delete{2}
-s.index[0]:iterator()
+s.index[0]:pairs()
 
 -- reserve memory for iterator in index. last insert may increase tree depth
 -- (if rebalance was not initiated)
@@ -46,7 +46,7 @@ for i = 1,10 do table.insert(res, (s:get{i})) end
 res
 for i = 1501,2000 do s:insert{i, i} end
 s:delete{3}
-s.index[0]:iterator()
+s.index[0]:pairs()
 
 box.errinj.set("ERRINJ_TREE_ALLOC", false)
 
diff --git a/test/wal/lua.result b/test/wal/lua.result
index 599b03be4b8dec46cfad4b09d7edad9ad98a8a13..ee9912e4e91c3790b71d96ffe3eb673e6b02d5b0 100644
--- a/test/wal/lua.result
+++ b/test/wal/lua.result
@@ -17,7 +17,7 @@ for i = 1, 1000 do
         space:insert{tostring(j), os.time(), 1}
     end
     count = 0
-    for v in space.index[1]:iterator() do
+    for state, v in space.index[1]:pairs() do
         count = count + 1
     end
     if count ~= 30 then
diff --git a/test/wal/lua.test.lua b/test/wal/lua.test.lua
index 6895ce5339cb00824696635b3ae1d9b844e7daae..91cfbd9b0d654e6f83e6e34ae9fc1fe6f34d34cf 100644
--- a/test/wal/lua.test.lua
+++ b/test/wal/lua.test.lua
@@ -12,7 +12,7 @@ for i = 1, 1000 do
         space:insert{tostring(j), os.time(), 1}
     end
     count = 0
-    for v in space.index[1]:iterator() do
+    for state, v in space.index[1]:pairs() do
         count = count + 1
     end
     if count ~= 30 then
diff --git a/test/wal/oom.result b/test/wal/oom.result
index 96862214575d921448a496d056f1d5f66066fd08..0a1c9e08fe99e5a9bd2c786919b463689e699bbf 100644
--- a/test/wal/oom.result
+++ b/test/wal/oom.result
@@ -78,7 +78,7 @@ t = {}
 ---
 ...
 --# setopt delimiter ';'
-for v in space:iterator() do
+for state, v in space:pairs() do
     table.insert(t, v)
     i = i + 1
     if i == 50 then
diff --git a/test/wal/oom.test.lua b/test/wal/oom.test.lua
index bb949f1917330d7ac38b9d787abc4876fcdf2a31..4cbac50b324a1e5bdc50f0cbb8ce3f0c3837d68f 100644
--- a/test/wal/oom.test.lua
+++ b/test/wal/oom.test.lua
@@ -31,7 +31,7 @@ space.index['primary']:get{15}
 i = 0
 t = {}
 --# setopt delimiter ';'
-for v in space:iterator() do
+for state, v in space:pairs() do
     table.insert(t, v)
     i = i + 1
     if i == 50 then