Atom feed of this document
  
 

 Emergency recovery of ring builder files

You should always keep a backup of Swift ring builder files. However, if an emergency occurs, this procedure may assist in returning your cluster to an operational state.

Using existing Swift tools, there is no way to recover a builder file from a ring.gz file. However, if you have a knowledge of Python, it is possible to construct a builder file that is pretty close to the one you have lost. The following is what you will need to do.

[Warning]Warning

This procedure is a last-resort for emergency circumstances. It requires knowledge of the swift python code and may not succeed.

First, load the ring and a new ringbuilder object in a Python REPL:

>>> from swift.common.ring import RingData, RingBuilder
>>> ring = RingData.load('/path/to/account.ring.gz')

Now, start copying the data we have in the ring into the builder.

>>> import math
>>> partitions = len(ring._replica2part2dev_id[0])
>>> replicas = len(ring._replica2part2dev_id)

>>> builder = RingBuilder(int(Math.log(partitions, 2)), replicas, 1)
>>> builder.devs = ring.devs
>>> builder._replica2part2dev = ring.replica2part2dev_id
>>> builder._last_part_moves_epoch = 0
>>> builder._last_part_moves = array('B', (0 for _ in xrange(self.parts)))
>>> builder._set_parts_wanted()
>>> for d in builder._iter_devs():
            d['parts'] = 0
>>> for p2d in builder._replica2part2dev:
            for dev_id in p2d:
                builder.devs[dev_id]['parts'] += 1

This is the extent of the recoverable fields. For min_part_hours you'll either have to remember what the value you used was, or just make up a new one.

>>> builder.change_min_part_hours(24) # or whatever you want it to be

Try some validation: if this doesn't raise an exception, you may feel some hope. Not too much, though.

>>> builder.validate()

Save the builder.

>>> import pickle
>>> pickle.dump(builder.to_dict(), open('account.builder', 'wb'), protocol=2)

You should now have a file called 'account.builder' in the current working directory. Next, run swift-ring-builder account.builder write_ring and compare the new account.ring.gz to the account.ring.gz that you started from. They probably won't be byte-for-byte identical, but if you load them up in a REPL and their _replica2part2dev_id and devs attributes are the same (or nearly so), then you're in good shape.

Next, repeat the procedure for container.ring.gz and object.ring.gz, and you might get usable builder files.

Questions? Discuss on ask.openstack.org
Found an error? Report a bug against this page

loading table of contents...