Adjust replica count before pulling parts from failed devices
When your device count falls below your replica count you can either add devices or reduce the replica count. Trying to reduce your replica count fails about half the time because removing parts from from failed devices temporarily invalidates your _replica2part2dev table with NONE_DEV which can result in an IndexError in _adjust_replica2part2dev_size. If you adjust the replica count first you won't have to worry about tracking unassigned parts from failed devices. Closes-Bug: #1558751 Change-Id: I99dc776fd260a2ba68ca77d7b5ed5120d10b06de
This commit is contained in:
parent
3a20e9b246
commit
c70abba529
@ -443,10 +443,10 @@ class RingBuilder(object):
|
||||
self._set_parts_wanted(replica_plan)
|
||||
|
||||
assign_parts = defaultdict(list)
|
||||
# gather parts from failed devices
|
||||
removed_devs = self._gather_parts_from_failed_devices(assign_parts)
|
||||
# gather parts from replica count adjustment
|
||||
self._adjust_replica2part2dev_size(assign_parts)
|
||||
# gather parts from failed devices
|
||||
removed_devs = self._gather_parts_from_failed_devices(assign_parts)
|
||||
# gather parts for dispersion (N.B. this only picks up parts that
|
||||
# *must* disperse according to the replica plan)
|
||||
self._gather_parts_for_dispersion(assign_parts, replica_plan)
|
||||
|
@ -1385,6 +1385,21 @@ class TestRingBuilder(unittest.TestCase):
|
||||
rb.rebalance() # this would crash since parts_wanted was not set
|
||||
rb.validate()
|
||||
|
||||
def test_reduce_replicas_after_remove_device(self):
|
||||
rb = ring.RingBuilder(8, 3, 1)
|
||||
rb.add_dev({'id': 0, 'region': 0, 'zone': 0, 'weight': 3,
|
||||
'ip': '127.0.0.1', 'port': 10000, 'device': 'sda'})
|
||||
rb.add_dev({'id': 1, 'region': 0, 'zone': 0, 'weight': 3,
|
||||
'ip': '127.0.0.1', 'port': 10000, 'device': 'sda'})
|
||||
rb.add_dev({'id': 2, 'region': 0, 'zone': 0, 'weight': 3,
|
||||
'ip': '127.0.0.1', 'port': 10000, 'device': 'sda'})
|
||||
rb.rebalance()
|
||||
rb.remove_dev(0)
|
||||
self.assertRaises(exceptions.RingValidationError, rb.rebalance)
|
||||
rb.set_replicas(2)
|
||||
rb.rebalance()
|
||||
rb.validate()
|
||||
|
||||
def test_rebalance_post_upgrade(self):
|
||||
rb = ring.RingBuilder(8, 3, 1)
|
||||
# 5 devices: 5 is the smallest number that does not divide 3 * 2^8,
|
||||
|
Loading…
Reference in New Issue
Block a user