Nikita Pettik
authored
If recovery process fails during range restoration, range itself is
deleted and recovery is assumed to be finished as failed (in case of
casual i.e. not forced recovery). During recovery of particular range,
runs to be restored are refed twice: once when they are created at
vy_run_new() and once when they are attached to slice. This fact is
taken into consideration and after all ranges are recovered: all runs of
lsm tree are unrefed so that slices own run resources (as a result, when
slice is to be deleted its runs unrefed and deleted as well). However, if
range recovery fails, range is dropped alongside with already recovered
slices. This leads to unrefing runs - this is not accounted. To sum up
recovery process below is a brief schema:
foreach range in lsm.ranges {
vy_lsm_recover_range(range) {
foreach slice in range.slices {
// inside recover_slice() each run is refed twice
if vy_lsm_recover_slice() != 0 {
// here all already restored slices are deleted and
// corresponding runs are unrefed, so now they have 1 ref.
range_delete()
}
}
}
}
foreach run in lsm.runs {
assert(run->refs > 1)
vy_run_unref(run)
}
In this case, unrefing such runs one more time would lead to their
destruction. On the other hand, iteration over runs may turn out to
be unsafe, so we should use rlist_foreach_entry_safe(). Moreover, we
should explicitly clean-up these runs calling vy_lsm_remove_run().
Reviewed-by:
Vladislav Shpilevoy <vshpilevoi@mail.ru>
Closes #4805
Name | Last commit | Last update |
---|