daily pastebin goal
71%
SHARE
TWEET

Untitled

a guest May 3rd, 2010 394 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Overview
  2. ========
  3.  
  4. This is the storage server for the XXX website.
  5.  
  6. Production
  7. ----------
  8.  
  9. This buildout sets up a ZEO storage server. Make sure to run this buildout
  10. with the same Python version, as you run the ZEO clients.
  11.  
  12. Currently this sets up a ZEO 3.9 server with one filestorage and a blobstorage.
  13.  
  14. To run this buildout you do::
  15.  
  16.   $ python2.4 bootstrap.py
  17.   $ bin/buildout
  18.  
  19. This sets up the ZEO server, supervisord, log rotation and configures cron
  20. entries to restart and do regular maintenance. The ZEO server is protected via
  21. an authentication database.
  22.  
  23.  
  24. Development
  25. -----------
  26.  
  27. If you want to test this locally and do some development, you can use the
  28. ``devel.cfg`` buildout file::
  29.  
  30.   $ python2.4 bootstrap.py
  31.   $ bin/buildout -c devel.cfg
  32.  
  33. This will avoid creating crontab entries or log rotation functionality.
  34.  
  35.  
  36. Garbage collection
  37. ------------------
  38.  
  39. We don't do garbage collection as part of a pack anymore. Instead we use
  40. explicit garbage collection via a different job::
  41.  
  42.   bin/multi-zodb-gc etc/zeo.conf
  43.  
  44. Garbage collection can take between one and two hours.
  45.  
  46.  
  47. Packing
  48. -------
  49.  
  50. We do regular packing every day, via::
  51.  
  52.   bin/zeopack
  53.  
  54. Packing without garbage collection only takes about half an hour.
  55.  
  56.  
  57. Analysis
  58. --------
  59.  
  60. If a database has any POSKeyErrors, we can find and repair those. Make sure the
  61. ZEO server isn't running, as this will access the storage as a simple file
  62. storage.
  63.  
  64. Installing those scripts is easy via a buildout section::
  65.  
  66.   [zodbdgc]
  67.   recipe = zc.recipe.egg
  68.   eggs = zc.zodbdgc
  69.  
  70. To check if any errors exist at all, we can run the following script::
  71.  
  72.   $ bin/multi-zodb-check-refs etc/zodb.conf
  73.  
  74. This can take about 15 to 30 minutes. Write down the reported errors, we'll
  75. need them later on to analyze them.
  76.  
  77. The ``etc/zodb.conf`` might look like this::
  78.  
  79.   <zodb main>
  80.     <filestorage 1>
  81.       path <path to current dir>/var/filestorage/Data.fs
  82.       blob-dir <path to current dir>/var/blobstorage
  83.     </filestorage>
  84.   </zodb>
  85.  
  86. If there are some errors, we can create a reference database to make it easier
  87. to debug and find those errors::
  88.  
  89.   $ bin/multi-zodb-check-refs -r var/refdb.fs etc/zodb.conf
  90.  
  91. This is significantly slower and can take several hours to complete. Once this
  92. is complete you can open the generated database. Get an interpreter with the
  93. ZODB available in it. For example::
  94.  
  95.   [zeopy]
  96.   recipe = zc.recipe.egg
  97.   eggs =
  98.       ZODB3
  99.       zc.zodbdgc
  100.   interpreter = zeopy
  101.   scripts = zeopy
  102.  
  103. Then we can run the interpreter::
  104.  
  105.   $ bin/zeopy
  106.  
  107.   >>> import ZODB.config
  108.   >>> db = ZODB.config.databaseFromFile(open('./etc/refdb.conf'))
  109.   >>> conn = db.open()
  110.   >>> refs = conn.root()['references']
  111.  
  112. The ``etc/refdb.conf`` might look like this::
  113.  
  114.   <zodb main>
  115.     <filestorage 1>
  116.       path <path to current dir>/var/refdb.fs
  117.     </filestorage>
  118.   </zodb>
  119.  
  120. If you've gotten this error report::
  121.  
  122.   !!! main 13184375 ?
  123.   POSKeyError: 0xc92d77
  124.  
  125. You can look up the poid it was referenced from via::
  126.  
  127.   >>> parent = list(refs['main'][13184375])
  128.   >>> parent
  129.   [13178389]
  130.  
  131. If you prefer the hex representation, that's easy as well::
  132.  
  133.   >>> from ZODB.utils import p64
  134.   >>> p64(parent[0])
  135.   '\x00\x00\x00\x00\x00\xc9\x16\x15'
  136.  
  137. Once you are finished you should be nice and close the database::
  138.  
  139.   >>> conn.close()
  140.   >>> db.close()
  141.  
  142. With this information, you should get back to your actual database and look
  143. up this object. Leave the ref db open, as you might need to recursively look
  144. up some more objects, until you get one you can identify and work on.
  145.  
  146. You could load the parent. In a debug prompt you could do something like::
  147.  
  148.   >>> app._p_jar.get('\x00\x00\x00\x00\x00\xc9\x16\x15')
  149.   2010-04-28 14:28:28 ERROR ZODB.Connection Couldn't load state for 0xc91615
  150.   Traceback (most recent call last):
  151.   ...
  152.   ZODB.POSException.POSKeyError: 0xc92d77
  153.  
  154. Gah, this gives us the POSKeyError of course. But we can load the actual data
  155. of the parent, to get an idea of what this is::
  156.  
  157.   >>> app._p_jar.db()._storage.load('\x00\x00\x00\x00\x00\xc9\x16\x15', '')
  158.   ('cBTrees.IOBTree
  159.   IOBucket
  160.   q\x01.((J$KT\x02ccopy_reg
  161.   _reconstructor
  162.   q\x02(cfive.intid.keyreference
  163.   KeyReferenceToPersistent
  164.   ...
  165.  
  166. Now we can be real evil and create a new fake object in place of the missing
  167. one::
  168.  
  169.   >>> import transaction
  170.   >>> transaction.begin()
  171.  
  172. The poid that was reported missing was ``13184375``::
  173.  
  174.   >>> from ZODB.utils import p64
  175.   >>> p64(13184375)
  176.   '\x00\x00\x00\x00\x00\xc9-w'
  177.  
  178.   >>> from persistent import Persistent
  179.   >>> a = Persistent()
  180.   >>> a._p_oid = '\x00\x00\x00\x00\x00\xc9-w'
  181.  
  182. We cannot use the ``add`` method of the connection, as this would assign the
  183. object a new poid. So we replicate its internals here::
  184.  
  185.   >>> a._p_jar = app._p_jar
  186.   >>> app._p_jar._register(a)
  187.   >>> app._p_jar._added[a._p_oid] = a
  188.  
  189.   >>> transaction.commit()
  190.  
  191. Both getting the object as well as its parent will work now::
  192.  
  193.   >>> app._p_jar.get('\x00\x00\x00\x00\x00\xc9-w')
  194.   <persistent.Persistent object at 0xa3e348c>
  195.  
  196.   >>> app._p_jar.get('\x00\x00\x00\x00\x00\xc9\x16\x15')
  197.   BTrees.IOBTree.IOBucket([(39078692, <five.intid.keyreference...
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top