Nota
En esta es una traducción del articulo llamado ZODB reparieren donde se ofrece la información de como reparar una ZODB.
En una base de datos Zope puede estar dañada, por ejemplo, por una caída del sistema o fallo del disco duro. Esto se vuelve más notable por un POSKeyError o CorruptedError y entonces ya no tenemos objetos editables.
Este error puede tener varias causas, por ejemplo, longitudes incorrectas o tiempos de las transacciones.
fsrecover.py es un script que verifica la integridad de las transacciones y la distancia con los datos corruptos. Por lo tanto, no es para POSKeyErrors adecuado sino más bien recomendado para CorruptedErrors. Además, también puede conducir a más POSKeyErrors cuando se retira una mala operación, dejando de ese modo la referencia a un objeto ya no existente:
$ ./bin/zopepy eggs/ZODB3-3.10.2-py2.6-linux-x86_64.egg/ZODB/fsrecover.py \
-P 0 var/filestorage/Data.fs var/filestorage/Data.fs.recovered &> logrecover.txt
A continuación en el archivo logrecover.txt, puede comprobar cuántos datos se han perdido, incluyendo:
Recovering var/filestorage/Data.fs into var/filestorage/Data.fs.recovered
. 1 . 2 . 3 . 4 . 5 . 6 . 7 . 8 . 9 . 0
0 bytes removed during recovery
Packing ...
Para entender este error, es importante saber que cada objeto de la base de datos tiene un identificador único (OID) que se le ha asignado. Este OID es un número binario, como 0x40A90L que hace referencia a un objeto serializado. En un POSKeyError ahora se puede encontrar por un OID no objeto adecuado. Así, por ejemplo, almacene una carpeta que se deriva de OFS.ObjectManager, los objetos como valores de atributos _objects. El listado resultante se compilará cuando se guarda en una lista de OID. Ahora se puede cargar el método objectValues() de un OID ya no puede asignar a un objeto serializado, entonces se emite un POSKeyError.
$ easy_install-2.6 virtualenv $ virtualenv --no-site-packages zeo_check
$ cd zeo_check $ ./bin/easy_install zc.zodbdgc
<zodb> <filestorage my> path var/filestorage/my.fs blob-dir var/blobstorage-my </filestorage> </zodb>
A continuación, el script multi-zodb-check-refs puede ser ejecutado con el siguiente comando:
$ ./bin/multi-zodb-check-refs storages.cfg
¿Son todas las referencias a su base de datos es válida?, recibirá ninguna salida. En POSKeyErrors la salida se ve como el siguiente ejemplo:
!!! main 26798 ? POSKeyError: 0x68ae
Este script debe ejecutarse regularmente como un tarea de cron:
# Check ZEO Storages
0 6 * * * cd /home/veit/zeo_check; ./bin/multi-zodb-check-refs \
| mailx -s "Check Storages" -c admin@veit-schiele.de
$ ./bin/multi-zodb-check-refs -r var/filestorage/refdb.fs storages.cfg !!! main 26798 main 16717 POSKeyError: 0x68ae
<zodb main> <filestorage 1> path /home/veit/zeo_check/var/filestorage/refdb.fs </filestorage> </zodb>
A continuación, puede abrir la base de datos:
$ ../myproject/bin/zopepy >>> import ZODB.config >>> db = ZODB.config.databaseFromFile(open('./refdb.cfg')) >>> conn = db.open() >>> refs = conn.root()['references']
Ahora debería obtener un mensaje de error como este:
!!! main 13184375 ? POSKeyError: 0xc92d77
Ahora usted puede averiguar el OID del objeto referenciado por el de:
>>> parent = list(refs['main'][13184375]) >>> parent [13178389]
>>> app._p_jar.get('13178389') 2010-07-16 15:30:18 ERROR ZODB.Connection Couldn't load state for 0xc91615 Traceback (most recent call last): … ZODB.POSException.POSKeyError: 0xc92d77
>>> app._p_jar.db()._storage.load('\x00\x00\x00\x00\x00\xc9\x16\x15', '') ('cBTrees.IOBTree IOBucket q\x01.((J$KT\x02ccopy_reg _reconstructor q\x02(cfive.intid.keyreference KeyReferenceToPersistent …
$ ./bin/instance-debug debug Starting debugger (the name "app" is bound to the top-level Zope object) … >>> import transaction >>> transaction.begin() >>> from ZODB.utils import p64 >>> p64(26798) '\x00\x00\x00\x00\x00\x00h\xae' >>> from persistent import Persistent >>> a = Persistent() >>> a._p_oid = '\x00\x00\x00\x00\x00\x00h\xae' >>> a._p_jar = app._p_jar >>> app._p_jar._register(a) >>> app._p_jar._added[a._p_oid] = a >>> transaction.commit()
>>> app._p_jar.get('\x00\x00\x00\x00\x00\x00h\xae') <persistent.Persistent object at 0xab7f9cc> >>> app._p_jar.get('\x00\x00\x00\x00\x00\xc9\x16\x15') BTrees.IOBTree.IOBucket([(39078692, <five.intid.keyreference…
>>> conn.close() >>> db.close()
Si recibe el mensaje de error POSKeyError: 'No blob file', Mikko Ohtamaa escribió un script fixblobs.py, con el puede eliminar el contenido de la ZODB, para el contenido que no está más disponible como BLOB.
Truco
Consulte el articulo Fixing POSKeyError: ‘No blob file’ content in Plone.
El código fuente de este archivo esta hospedado en GitHub. Todos pueden actualizar y corregir errores en este documento con unos clic - sin necesidad de descargar.
Para mas información básica acerca de como actualizar este manual y referencia a sintaxis Sphinx, por favor consulte la guía Escribiendo y actualizando el manual.