diff --git a/.luacheckrc b/.luacheckrc
index 7b08fc7eabb4cd3244abe6d6f5616ea9a05710b4..ce58dbb14046f4b91642b2a00344935369f81dc0 100644
--- a/.luacheckrc
+++ b/.luacheckrc
@@ -1,12 +1,24 @@
 std = "luajit"
-globals = {"box", "_TARANTOOL"}
+globals = {"box", "_TARANTOOL", "tonumber64"}
 ignore = {
+    -- Accessing an undefined field of a global variable <debug>.
+    "143/debug",
+    -- Accessing an undefined field of a global variable <string>.
+    "143/string",
+    -- Accessing an undefined field of a global variable <table>.
+    "143/table",
     -- Unused argument <self>.
     "212/self",
     -- Redefining a local variable.
     "411",
+    -- Redefining an argument.
+    "412",
+    -- Shadowing a local variable.
+    "421",
     -- Shadowing an upvalue.
     "431",
+    -- Shadowing an upvalue argument.
+    "432",
 }
 
 include_files = {
@@ -16,7 +28,7 @@ include_files = {
 
 exclude_files = {
     "build/**/*.lua",
-    "src/**/*.lua",
+    "src/box/**/*.lua",
     "test-run/**/*.lua",
     "test/**/*.lua",
     "third_party/**/*.lua",
@@ -30,3 +42,11 @@ files["extra/dist/tarantoolctl.in"] = {
         "122",
     },
 }
+files["src/lua/help.lua"] = {
+    -- Globals defined for interactive mode.
+    globals = {"help", "tutorial"},
+}
+files["src/lua/init.lua"] = {
+    -- Miscellaneous global function definition.
+    globals = {"dostring"},
+}
diff --git a/src/lua/buffer.lua b/src/lua/buffer.lua
index 9aac82b39855974543a329822b3d24aad6ce2a62..00846bb20a4049f21980cf900fe9b383874f090f 100644
--- a/src/lua/buffer.lua
+++ b/src/lua/buffer.lua
@@ -182,7 +182,7 @@ local ibuf_methods = {
     unused = ibuf_unused;
 }
 
-local function ibuf_tostring(ibuf)
+local function ibuf_tostring(self)
     return '<ibuf>'
 end
 local ibuf_mt = {
@@ -193,7 +193,7 @@ local ibuf_mt = {
 
 ffi.metatype(ibuf_t, ibuf_mt);
 
-local function ibuf_new(arg, arg2)
+local function ibuf_new(arg)
     local buf = ffi.new(ibuf_t)
     local slabc = builtin.tarantool_lua_slab_cache()
     builtin.ibuf_create(buf, slabc, READAHEAD)
diff --git a/src/lua/clock.lua b/src/lua/clock.lua
index 60c78663caca653f3391236034a65af52efa4ddb..fee43ccde767f8afa3c2a5252cc7bd33da8279d4 100644
--- a/src/lua/clock.lua
+++ b/src/lua/clock.lua
@@ -33,7 +33,7 @@ clock.bench = function(fun, ...)
     overhead = clock.proc() - overhead
     local start_time = clock.proc()
     local res = {0, fun(...)}
-    res[1] = clock.proc() - start_time - overhead, res
+    res[1] = clock.proc() - start_time - overhead
     return res
 end
 
diff --git a/src/lua/crypto.lua b/src/lua/crypto.lua
index bf3064c7069ada591fce7b16688bbe48135a3934..f31708e294f410f4bc4d0a49f77692620be5ff56 100644
--- a/src/lua/crypto.lua
+++ b/src/lua/crypto.lua
@@ -75,7 +75,7 @@ local function openssl_err_str()
 end
 
 local digests = {}
-for class, name in pairs({
+for class, _ in pairs({
     md2 = 'MD2', md4 = 'MD4', md5 = 'MD5',
     sha1 = 'SHA1', sha224 = 'SHA224',
     sha256 = 'SHA256', sha384 = 'SHA384', sha512 = 'SHA512',
@@ -428,7 +428,7 @@ local public_methods = {
 }
 
 local module_mt = {
-    __serialize = function(s)
+    __serialize = function(self)
         return public_methods
     end,
     __index = public_methods
diff --git a/src/lua/csv.lua b/src/lua/csv.lua
index 7dff2f2139b986690c6fed0a249044d37b9db81e..de6726bb7a3b059e325f788cac00480bc71a4f96 100644
--- a/src/lua/csv.lua
+++ b/src/lua/csv.lua
@@ -188,10 +188,10 @@ module.dump = function(t, opts, writable)
     if type(writable) == 'nil' then
         result_table = {}
     end
-    for k, line in pairs(t) do
+    for _, line in pairs(t) do
         local first = true
         local output_tuple = {}
-        for k2, field in pairs(line) do
+        for _, field in pairs(line) do
             local strf = tostring(field)
             local buf_new_size = (strf:len() + 1) * 2
             if buf_new_size > bufsz then
@@ -214,7 +214,6 @@ module.dump = function(t, opts, writable)
         else
             writable:write(table.concat(output_tuple))
         end
-        output_tuple = {}
     end
     ffi.C.csv_destroy(csv)
     csv.realloc(buf, 0)
diff --git a/src/lua/digest.lua b/src/lua/digest.lua
index 6beaf562a2eb21748303321d433dbbd6c5e3c2b0..464cc6525ee725b57f7a12d582d43dcd9e71b5c6 100644
--- a/src/lua/digest.lua
+++ b/src/lua/digest.lua
@@ -246,7 +246,7 @@ local m = {
     end
 }
 
-for digest, name in pairs(digest_shortcuts) do
+for digest, _ in pairs(digest_shortcuts) do
     m[digest] = function (str)
         return crypto.digest[digest](str)
     end
diff --git a/src/lua/env.lua b/src/lua/env.lua
index dd1616a84eb02c9b7f6b913ea27660c7df398694..a31b7098fa521a7b42179c232da388252e913bba 100644
--- a/src/lua/env.lua
+++ b/src/lua/env.lua
@@ -28,7 +28,7 @@ os.environ = function()
 end
 
 os.setenv = function(key, value)
-    local rv = nil
+    local rv
     if value ~= nil then
         rv = ffi.C.setenv(key, value, 1)
     else
diff --git a/src/lua/fiber.lua b/src/lua/fiber.lua
index 89c17f63deafba15df7b0784f5b09c31d8c565f1..b14117714989bd9fb284f3378f29b6204309fe0b 100644
--- a/src/lua/fiber.lua
+++ b/src/lua/fiber.lua
@@ -39,8 +39,8 @@ local stall = fiber.stall
 fiber.stall = nil
 
 local worker_next_task = nil
-local worker_last_task = nil
-local worker_fiber = nil
+local worker_last_task
+local worker_fiber
 
 --
 -- Worker is a singleton fiber for not urgent delayed execution of
diff --git a/src/lua/fio.lua b/src/lua/fio.lua
index 83fddaa0a1a4c5675b7da02728a4e0a8c534121b..954c44cdf73435ce9cc152d40ee2fb1be64a44a8 100644
--- a/src/lua/fio.lua
+++ b/src/lua/fio.lua
@@ -329,7 +329,7 @@ fio.abspath = function(path)
         error("Usage: fio.abspath(path)")
     end
     path = path
-    local joined_path = ''
+    local joined_path
     local path_tab = {}
     if string.sub(path, 1, 1) == '/' then
         joined_path = path
@@ -366,7 +366,7 @@ fio.listdir = function(path)
         return t
     end
     local names = string.split(str, "\n")
-    for i, name in ipairs(names) do
+    for _, name in ipairs(names) do
         table.insert(t, name)
     end
     return t
@@ -382,11 +382,11 @@ fio.mktree = function(path, mode)
     local dirs = string.split(path, "/")
 
     local current_dir = "/"
-    for i, dir in ipairs(dirs) do
+    for _, dir in ipairs(dirs) do
         current_dir = fio.pathjoin(current_dir, dir)
         local stat = fio.stat(current_dir)
         if stat == nil then
-            local st, err = fio.mkdir(current_dir, mode)
+            local _, err = fio.mkdir(current_dir, mode)
             -- fio.stat() and fio.mkdir() above are separate calls
             -- and a file system may be changed between them. So
             -- if the error here is due to an existing directory,
@@ -407,27 +407,26 @@ fio.rmtree = function(path)
     if type(path) ~= 'string' then
         error("Usage: fio.rmtree(path)")
     end
-    local status, err
     path = fio.abspath(path)
     local ls, err = fio.listdir(path)
     if err ~= nil then
         return nil, err
     end
-    for i, f in ipairs(ls) do
+    for _, f in ipairs(ls) do
         local tmppath = fio.pathjoin(path, f)
         local st = fio.lstat(tmppath)
         if st then
             if st:is_dir() then
-                st, err = fio.rmtree(tmppath)
+                _, err = fio.rmtree(tmppath)
             else
-                st, err = fio.unlink(tmppath)
+                _, err = fio.unlink(tmppath)
             end
             if err ~= nil  then
                 return nil, err
             end
         end
     end
-    status, err = fio.rmdir(path)
+    local _, err = fio.rmdir(path)
     if err ~= nil then
         return false, string.format("failed to remove %s: %s", path, err)
     end
@@ -453,7 +452,6 @@ fio.copytree = function(from, to)
     if type(from) ~= 'string' or type(to) ~= 'string' then
         error('Usage: fio.copytree(from, to)')
     end
-    local status, reason
     local st = fio.stat(from)
     if not st then
         return false, string.format("Directory %s does not exist", from)
@@ -467,22 +465,22 @@ fio.copytree = function(from, to)
     end
 
     -- create tree of destination
-    status, reason = fio.mktree(to)
+    local _, reason = fio.mktree(to)
     if reason ~= nil then
         return false, reason
     end
-    for i, f in ipairs(ls) do
+    for _, f in ipairs(ls) do
         local ffrom = fio.pathjoin(from, f)
         local fto = fio.pathjoin(to, f)
         local st = fio.lstat(ffrom)
         if st and st:is_dir() then
-            status, reason = fio.copytree(ffrom, fto)
+            _, reason = fio.copytree(ffrom, fto)
             if reason ~= nil then
                 return false, reason
             end
         end
         if st:is_reg() then
-            status, reason = fio.copyfile(ffrom, fto)
+            _, reason = fio.copyfile(ffrom, fto)
             if reason ~= nil then
                 return false, reason
             end
@@ -492,7 +490,7 @@ fio.copytree = function(from, to)
             if reason ~= nil then
                 return false, reason
             end
-            status, reason = fio.symlink(link_to, fto)
+            _, reason = fio.symlink(link_to, fto)
             if reason ~= nil then
                 return false, "can't create symlink in place of existing file "..fto
             end
diff --git a/src/lua/help.lua b/src/lua/help.lua
index 54ff1b5d09af7df4622665ab7cc110a8bc366d6f..4f024832d6ea19bd29d5c90a83d852de80238919 100644
--- a/src/lua/help.lua
+++ b/src/lua/help.lua
@@ -11,10 +11,7 @@ help = { doc.help }
 tutorial = {}
 tutorial[1] = help[1]
 
-local help_function_data = {};
-local help_object_data = {}
-
-local function help_call(table, param)
+local function help_call()
     return help
 end
 
@@ -22,7 +19,7 @@ setmetatable(help, { __call = help_call })
 
 local screen_id = 1;
 
-local function tutorial_call(table, action)
+local function tutorial_call(self, action)
     if action == 'start' then
         screen_id = 1;
     elseif action == 'next' or action == 'more' then
diff --git a/src/lua/httpc.lua b/src/lua/httpc.lua
index 6381c6a1a99d664994f0531c829e312e2823293c..9336dcee063a474a9223b346e6030d562b45203e 100644
--- a/src/lua/httpc.lua
+++ b/src/lua/httpc.lua
@@ -29,8 +29,6 @@
 --  SUCH DAMAGE.
 --
 
-local fiber = require('fiber')
-
 local driver = package.loaded.http.client
 package.loaded.http = nil
 
@@ -112,7 +110,6 @@ local special_characters = {
     [']'] = true,
     ['<'] = true,
     ['>'] = true,
-    ['>'] = true,
     ['@'] = true,
     [','] = true,
     [';'] = true,
diff --git a/src/lua/init.lua b/src/lua/init.lua
index ff3e74c3c366dea1d355c4ea4576aca8d496f2ad..9e3c813c3639360173731f48bb4cbbc6d6e61b4d 100644
--- a/src/lua/init.lua
+++ b/src/lua/init.lua
@@ -80,7 +80,7 @@ dostring = function(s, ...)
 end
 
 local fiber = require("fiber")
-os.exit = function(code)
+local function exit(code)
     code = (type(code) == 'number') and code or 0
     ffi.C.tarantool_exit(code)
     -- Make sure we yield even if the code after
@@ -88,6 +88,7 @@ os.exit = function(code)
     -- fiber completes, we will never wake up again.
     while true do fiber.yield() end
 end
+rawset(os, "exit", exit)
 
 local function uptime()
     return tonumber(ffi.C.tarantool_uptime());
@@ -221,9 +222,9 @@ table.insert(package.loaders, 5, gen_loader_func(search_rocks_lib, load_lib))
 -- package.cpath  7
 -- croot          8
 
-package.search = search
-package.searchroot = searchroot
-package.setsearchroot = setsearchroot
+rawset(package, "search", search)
+rawset(package, "searchroot", searchroot)
+rawset(package, "setsearchroot", setsearchroot)
 
 return {
     uptime = uptime;
diff --git a/src/lua/log.lua b/src/lua/log.lua
index d7cafa5e89faea73774ecf3bf751390eee4c23d9..cfd83f5926cae1564dfeeba497158ca65fb6d76c 100644
--- a/src/lua/log.lua
+++ b/src/lua/log.lua
@@ -332,7 +332,7 @@ local function set_log_level(level, update_box_cfg)
 end
 
 -- Tries to set a new level, or print an error.
-local function log_level(level, update_box_cfg)
+local function log_level(level)
     local ok, msg = verify_option('level', level)
     if not ok then
         error(msg)
@@ -459,7 +459,7 @@ local function reload_cfg(cfg)
 end
 
 -- Load or reload configuration via log.cfg({}) call.
-local function load_cfg(oldcfg, cfg)
+local function load_cfg(self, cfg)
     cfg = cfg or {}
 
     -- log option might be zero length string, which
diff --git a/src/lua/msgpackffi.lua b/src/lua/msgpackffi.lua
index f01ffaef006617381f09ac5e7ad90b4d820f1f29..2bc37474281243b06f9505ee52a15117e3fd8eaf 100644
--- a/src/lua/msgpackffi.lua
+++ b/src/lua/msgpackffi.lua
@@ -302,10 +302,6 @@ local function encode(obj)
     return r
 end
 
-local function encode_ibuf(obj, ibuf)
-    encode_r(ibuf, obj, 0)
-end
-
 on_encode(ffi.typeof('uint8_t'), encode_int)
 on_encode(ffi.typeof('uint16_t'), encode_int)
 on_encode(ffi.typeof('uint32_t'), encode_int)
@@ -332,7 +328,6 @@ local decode_r
 
 -- See similar constants in utils.cc
 local DBL_INT_MAX = 1e14 - 1
-local DBL_INT_MIN = -1e14 + 1
 
 local function decode_u8(data)
     local num = ffi.cast(uint8_ptr_t, data[0])[0]
@@ -477,8 +472,7 @@ end
 local function decode_array(data, size)
     assert (type(size) == "number")
     local arr = {}
-    local i
-    for i=1,size,1 do
+    for _ = 1, size do
         table.insert(arr, decode_r(data))
     end
     if not msgpack.cfg.decode_save_metatables then
@@ -490,8 +484,7 @@ end
 local function decode_map(data, size)
     assert (type(size) == "number")
     local map = {}
-    local i
-    for i=1,size,1 do
+    for _ = 1, size do
         local key = decode_r(data);
         local val = decode_r(data);
         map[key] = val
@@ -504,11 +497,15 @@ end
 
 local ext_decoder = {
     -- MP_UNKNOWN_EXTENSION
-    [0] = function(data, len) error("unsupported extension type") end,
+    [0] = function(data, len) error("unsupported extension type") end, -- luacheck: no unused args
     -- MP_DECIMAL
     [1] = function(data, len) local num = ffi.new("decimal_t") builtin.decimal_unpack(data, len, num) return num end,
     -- MP_UUID
-    [2] = function(data, len) local uuid = ffi.new("struct tt_uuid") builtin.uuid_unpack(data, len, uuid) return uuid end,
+    [2] = function(data, len)
+        local uuid = ffi.new("struct tt_uuid")
+        builtin.uuid_unpack(data, len, uuid)
+        return uuid
+    end,
 }
 
 local function decode_ext(data)
@@ -516,7 +513,6 @@ local function decode_ext(data)
     -- mp_decode_extl and mp_decode_decimal
     -- need type code
     data[0] = data[0] - 1
-    local old_data = data[0]
     local len = builtin.mp_decode_extl(data, t)
     local fun = ext_decoder[t[0]]
     if type(fun) == 'function' then
diff --git a/src/lua/socket.lua b/src/lua/socket.lua
index bbdef01e36c3dbe5dc1cb410704d280bfd04d9a3..f10461667ee48f404725de6df2a7425155bac409 100644
--- a/src/lua/socket.lua
+++ b/src/lua/socket.lua
@@ -177,7 +177,7 @@ local function get_iflags(table, flags)
     if type(flags) ~= 'table' then
         flags = { flags }
     end
-    for i, f in pairs(flags) do
+    for _, f in pairs(flags) do
         if table[f] == nil then
             return nil
         end
@@ -665,7 +665,7 @@ local function check_delimiter(self, limit, eols)
     end
 
     local shortest
-    for i, eol in ipairs(eols) do
+    for _, eol in ipairs(eols) do
         local data = ffi.C.memmem(rbuf.rpos, rbuf:size(), eol, #eol)
         if data ~= nil then
             local len = ffi.cast('char *', data) - rbuf.rpos + #eol
@@ -1052,7 +1052,7 @@ local function tcp_connect(host, port, timeout)
         boxerrno(boxerrno.EINVAL)
         return nil
     end
-    for i, remote in pairs(dns) do
+    for _, remote in pairs(dns) do
         timeout = stop - fiber.clock()
         if timeout <= 0 then
             boxerrno(boxerrno.ETIMEDOUT)
@@ -1319,7 +1319,7 @@ local function lsocket_tcp_getpeername(self)
     return peer.host, tostring(peer.port), peer.family:match("AF_(.*)"):lower()
 end
 
-local function lsocket_tcp_settimeout(self, value, mode)
+local function lsocket_tcp_settimeout(self, value)
     check_socket(self)
     self.timeout = value
     -- mode is effectively ignored
@@ -1543,7 +1543,7 @@ lsocket_tcp_mt.__index.send = lsocket_tcp_send;
 -- TCP Constructor and Shortcuts
 --
 
-local function lsocket_tcp()
+local function lsocket_tcp(self)
     local s = socket_new('AF_INET', 'SOCK_STREAM', 'tcp')
     if not s then
         return nil, socket_error(self)
@@ -1567,7 +1567,7 @@ local function lsocket_bind(host, port, backlog)
     if host == nil or port == nil then
         error("Usage: luasocket.bind(host, port [, backlog])")
     end
-    local function prepare(s) return backlog end
+    local function prepare(s) return backlog end -- luacheck: no unused args
     local s = tcp_server_bind(host, port, prepare)
     if not s then
         return nil, boxerrno.strerror()
diff --git a/src/lua/string.lua b/src/lua/string.lua
index 6e12c59ae782c635b76c148283c340898c10449c..d3a846645490c651062c49969d6a2392dc5b9dd7 100644
--- a/src/lua/string.lua
+++ b/src/lua/string.lua
@@ -233,7 +233,6 @@ local function string_startswith(inp, head, _start, _end)
         return false
     end
     _start = _start - 1
-    _end = _start + head_len - 1
     return memcmp(c_char_ptr(inp) + _start, c_char_ptr(head), head_len) == 0
 end
 
diff --git a/src/lua/swim.lua b/src/lua/swim.lua
index 0859915c9e3b97239e202bfc4573a91803c507cf..c1ab1c5c337cdf90e7734a366d47d5fc6c423d54 100644
--- a/src/lua/swim.lua
+++ b/src/lua/swim.lua
@@ -371,7 +371,7 @@ end
 --
 local function swim_member_payload_str(m)
     local ptr = swim_check_member(m, 'member:payload_str()')
-    local cdata, size = swim_member_payload_raw(ptr)
+    local _, size = swim_member_payload_raw(ptr)
     if size > 0 then
         return ffi.string(swim_member_payload_raw(ptr))
     end
@@ -462,7 +462,7 @@ local swim_member_mt = {
         is_dropped = swim_member_is_dropped,
     },
     __serialize = swim_member_serialize,
-    __newindex = function(m)
+    __newindex = function(self)
         return error('swim_member is a read-only object')
     end
 }
diff --git a/src/lua/tap.lua b/src/lua/tap.lua
index 94b080d5a9f67722114d9cad5db00634307a4e64..346724d847083e6edcde03c7b3c8f857fa7fe1e8 100644
--- a/src/lua/tap.lua
+++ b/src/lua/tap.lua
@@ -53,7 +53,6 @@ local function ok(test, cond, message, extra)
     io.write(string.format("not ok - %s\n", message))
     extra = extra or {}
     if test.trace then
-        local frame = debug.getinfo(3, "Sl")
         extra.trace = traceback()
         extra.filename = extra.trace[#extra.trace].filename
         extra.line = extra.trace[#extra.trace].line
@@ -76,9 +75,6 @@ local function skip(test, message, extra)
     ok(test, true, message.." # skip", extra)
 end
 
-
-local nan = 0/0
-
 local function cmpdeeply(got, expected, extra)
     if type(expected) == "number" or type(got) == "number" then
         extra.got = got
diff --git a/src/lua/trigger.lua b/src/lua/trigger.lua
index 76a582c47ca2165447b8b47550cb89c94b193d18..1330ecdd4d1e11f032b0b48169c9cf71d0a7e24c 100644
--- a/src/lua/trigger.lua
+++ b/src/lua/trigger.lua
@@ -1,7 +1,4 @@
 local fun = require('fun')
-local log = require('log')
-
-local table_clear = require('table.clear')
 
 --
 -- Checks that argument is a callable, i.e. a function or a table