-
Notifications
You must be signed in to change notification settings - Fork 33
Closed
Description
Bucket GC procedure drops SENT
buckets as soon as it sees them. The problem is that bucket_send()
might still be in progress and expects the SENT
bucket to stay until the sending is fully finished.
GC should take into account rebalancer_transfering_buckets
.
Here is a patch which fixes it, but it lacks a test:
diff --git a/vshard/storage/init.lua b/vshard/storage/init.lua
index 5f34410..e6d3ec0 100644
--- a/vshard/storage/init.lua
+++ b/vshard/storage/init.lua
@@ -1766,6 +1766,7 @@ local function bucket_recv(bucket_id, from, data, opts)
M.rebalancer_transfering_buckets[bucket_id] = true
local status, ret, err = pcall(bucket_recv_xc, bucket_id, from, data, opts)
M.rebalancer_transfering_buckets[bucket_id] = nil
+ bucket_generation_increment()
if status then
if ret then
return ret
@@ -1790,6 +1791,9 @@ local function bucket_test_gc(bids)
local _bucket = box.space._bucket
local ref, bucket, status
for i, bid in ipairs(bids) do
+ if M.rebalancer_transfering_buckets[bid] then
+ goto not_ok_bid
+ end
bucket = _bucket:get(bid)
status = bucket ~= nil and bucket.status or consts.BUCKET.GARBAGE
if status ~= consts.BUCKET.GARBAGE and status ~= consts.BUCKET.SENT then
@@ -2163,6 +2167,7 @@ local function bucket_send(bucket_id, destination, opts)
exception_guard.ref.rw_lock = false
end
M.rebalancer_transfering_buckets[bucket_id] = nil
+ bucket_generation_increment()
if status then
if ret then
return ret
@@ -2393,10 +2398,15 @@ local function gc_bucket_process_sent_xc()
local batch = table.new(limit, 0)
local i = 0
local is_done = true
+ local ref
for _, b in _bucket.index.status:pairs(consts.BUCKET.SENT) do
i = i + 1
local bid = b.id
- local ref = M.bucket_refs[bid]
+ if M.rebalancer_transfering_buckets[bid] then
+ goto continue
+ end
+ ref = M.bucket_refs[bid]
if ref ~= nil then
assert(ref.rw == 0)
if ref.ro ~= 0 then
Note that is_done = false
is not needed in gc_bucket_process_sent_xc()
. Bucket GC won't freeze, because bucket generation is updated when a bucket transfer ends.