Skip to content

Scripts

Nikita Zheleztsov edited this page Aug 6, 2025 · 7 revisions

Disclaimer

This page is intended for developers only! Please, make sure you know, what you're doing before running these scripts on production cluster.

Storage

Full delete of the bucket with all its data (DANGEROUS!!!)
function find_sharded_spaces()
    local spaces = {}
    local idx = 'bucket_id'
    for k, space in pairs(box.space) do
        if type(k) == 'number' and space.index[idx] ~= nil then
            local parts = space.index[idx].parts
            local p = parts[1].type
            if p == 'unsigned' or p == 'integer' or p == 'number' then
	    	table.insert(spaces, space)
            end
        end
    end
    return spaces
end

function tuple_extract_key(tuple, parts)
    local key = {}
    for _, part in ipairs(parts) do
        table.insert(key, tuple[part.fieldno])
    end
    return key
end

function full_delete_bucket(bucket_id)
    local spaces = find_sharded_spaces()
    for _, space in pairs(spaces) do
    	local pk_parts = space.index[0].parts
    	local bucket_index = space.index['bucket_id']
    	for _, tuple in bucket_index:pairs({bucket_id}) do
    		space:delete(tuple_extract_key(tuple, pk_parts))
	end
    end

    vshard.storage.bucket_force_drop(bucket_id)
end
Find all buckets with RW refs
buckets = {};
for _, b in pairs(vshard.storage.buckets_info()) do
    if b.ref_rw then
        table.insert(buckets, b.id)
    end
end;
return buckets

Router

Find doubled buckets in the cluster
function find_doubled()
  local BUCKET_COUNT = vshard.router.bucket_count()
  local all_buckets = {}
  for id = 1, BUCKET_COUNT do
    all_buckets[id] = {
      count = 0,
      info = {},
      uuids = {},
    }
  end

  local routes = vshard.router.routeall()
  for _, replicaset in pairs(routes) do
    local buckets, err = replicaset:callro('vshard.storage.buckets_info',
                                           {}, {timeout = 5})
    if err then
      error(err)
    end

    for id, bucket in pairs(buckets) do
      all_buckets[id].count = all_buckets[id].count + 1
      table.insert(all_buckets[id].uuids, replicaset.uuid)
      table.insert(all_buckets[id].info, bucket)
    end
  end

  local intersection = {}
  for id = 1, BUCKET_COUNT do
    if all_buckets[id].count > 1 then
      intersection[id] = all_buckets[id]
    end
  end

  return intersection
end

find_doubled()
Find all rw refs on replicas in the cluster
all_rw_refs = {};
for rs_uuid, rs in pairs(vshard.router.internal.static_router.replicasets) do
    for r_uuid, r in pairs(rs.replicas) do
        if r_uuid ~= rs.master.uuid then
            all_rw_refs[rs_uuid] =
                r.conn:eval('refs = {}; for _, tuple in box.space._bucket:pairs() do if vshard.storage.internal.bucket_refs[tuple[1]] and vshard.storage.internal.bucket_refs[tuple[1]].rw > 0 then table.insert(refs, tuple[1]) end end; return refs')
        end
    end
end;
return all_rw_refs
Drop all rw refs on replicas in the cluster (DANGEROUS!)
for _, rs in pairs(vshard.router.internal.static_router.replicasets) do
    for r_uuid, r in pairs(rs.replicas) do
        if r_uuid ~= rs.master.uuid then
            r.conn:eval('for _, tuple in box.space._bucket:pairs() do if vshard.storage.internal.bucket_refs[tuple[1]] then vshard.storage.internal.bucket_refs[tuple[1]].rw = 0 end end')
        end
    end
end
Find all non-active buckets in the cluster
buckets_no_active = {};
for rs_uuid, rs in pairs(vshard.router.internal.static_router.replicasets) do
    for r_uuid, r in pairs(rs.replicas) do
        if r_uuid == rs.master.uuid then
            buckets_no_active[rs_uuid] =
                r.conn:eval('buckets = {}; for _, b in pairs(vshard.storage.buckets_info()) do if b.status ~= "active" then table.insert(buckets, b.id) end end; return buckets')
        end
    end
end;
return buckets_no_active
Find all buckets with RW locks in the cluster
buckets = {};
for _, rs in pairs(vshard.router.internal.static_router.replicasets) do
    buckets[rs.name or rs.uuid] =
        rs.master.conn:eval('ret = {}; for _, b in pairs(vshard.storage.buckets_info()) do if b.rw_lock then table.insert(ret, b) end end; return ret')
end;
return buckets
Find callrw requests, which take more than 10 seconds
-- Measure latency of callrw
old_vshard_router_callrw = vshard.router.callrw
vshard.router.callrw = function(bucket_id, func, args, opts)
    local fiber = require('fiber')
    local json = require('json')
    local log = require('log')

    local start_time = fiber.clock()
    local call_status, call_err =
        old_vshard_router_callrw(bucket_id, func, args, opts)
    local latency = fiber.clock() - start_time

    if call_err ~= nil then
        if latency > 10 then
            log.warn('LATENCY: %.3f, request for %d bucket on %s func failed ' ..
                     'with error %s', latency, bucket_id, func, call_err)
        end
        return call_status, call_err
    end
    if latency > 10 then
        log.warn('LATENCY: %.3f, request for %d bucket on %s func succeeded',
                  latency, bucket_id, func)
    end
    return call_status
end

-- Restore the function back.
vshard.router.callrw =  old_vshard_router_callrw

Any

Find the fiber, name of which starts with `a`
a = 'vshard.rebalancer_worker_';
for id, f in pairs(require('fiber').info()) do
    if string.sub(f.name, 1, #a) == a then
        return f
    end
end

Clone this wiki locally