Bug #13530
closedHashIndex: shall cancel merge if it is going to trigger another split on it's direct parent.
0%
Description
int HashIndex::_remove(const vector<string> &path, const ghobject_t &oid, const string &mangled_name) { int r; r = remove_object(path, oid); if (r < 0) return r; subdir_info_s info; r = get_info(path, &info); if (r < 0) return r; info.objs--; r = set_info(path, info); if (r < 0) return r; if (must_merge(info)) { ...
See above, if we delete an object from the current dirent, a check for whether this dirent's containing objects dropping below the merge_threshold is performed. And if it does, a merge of current dirent to it's parent dirent will be kicked off.
I think this code logic can be a little bit problematic for the following reason:
Suppose we have a dirent-A, say, which consists of:
1. subdir-0( which has 0 subdir and 9 objects)
2. subdir-1( which has 0 subdir and 100 objects)
3. 154 objects
Now we reset merge_threshold to 10 and split_multiplier to 1, and we know if we delete a object from subdir-0, a merge shall occur. As a result, subdir-0 is removed and all its containing objects goes into dirent-A which now has 1 subdir and 162(154 + 8) objects.
However, if we try to add another new object to dirent-A later, it will trigger a split immediately and the subdir-0 is recreated and all it's previous objects are re-claimed.
From the above scenario, we now see the cost of the merge may be very expensive and thus shall be avoided.