[ZODB-Dev] Recovering from a POSkeyerror

Paulo Eduardo Neves pauloneves at gmail.com
Fri Jan 14 00:57:34 EST 2005


No need to read this message. I've solved my problem. I'm just posting
to make it appear in Google. Thanks for the help.


On Thu, 13 Jan 2005 15:36:03 -0500, Tim Peters <tim at zope.com> wrote:
> [Paulo Eduardo Neves]
> > Hi, I'm somewhat desperade, maybe someone here can help me.
> 
> I hope so (but it probably won't be me).

Thanks for your answer. It looks like the problem is getting closer. 
I'm reordering some of your comments below.

> This is worth reading:
> 
>     http://zope.org/Wikis/ZODB/FileStorageBackup

I've already found this one, but everything is still misterious.

>The POSKeyError exception you got should have contained the oid (object id)
>of the missing object. 

Ops! I didn't notice it. There's really an id: 
Error Type: POSKeyError
Error Value: 000000000003250e

>  Download ZODB 3.2.4 (the current
> stable release) and use its fsrefs.py, 

After fighting with different python versions (Zope 2.6.4 runs in
python 2.13) and ZODB, it was easier to download Zope-2.7.4-RC2,
install it as an instance, and copy my Data.fs to the var directory.

Now running the fsrefs.py I get a more readable message:

>>python /home/install/source/Zope-2.7.4-RC2/utilities/ZODBTools/fsrefs.py
Data.fs
oid 0x0323e0 ExtensionClass.ExtensionClass
last updated: 2004-02-13 18:20:50.857404, tid=0x3530A2CD8FDD8DDL
refers to invalid object:
        oid 0x03250e object creation was undone: 'ZClasses.Method.MWp'

oid 0x0dfe OFS.DTMLMethod.DTMLMethod
last updated: 2003-04-28 03:05:00.457394, tid=0x34C8B3901F398A2L
refers to invalid object:
        oid 0x0330df object creation was undone: 'Persistence.PersistentMapping'

Good, the first oid is the same one that's in the exception message.
Googling for this strange ZClasses.Method.MWp shows some pages titled
" Very severe memory leak". I didn't like it <wink -0.7>

> There's a long comment at the bottom of the page you referenced, starting
> with "If you don't have a clue where to start looking for the broken
> object(s) ...".  Maybe that will help.

I still can't find the parent of the object to delete it. I've tried
the first suggestion in the cited comment.

In [13]: from ZODB.utils import  p64
In [14]: oid = 0x03250e
In [15]: o = root._p_jar[p64(oid)]
In [16]: o
Out[16]: <MWp instance at 40799050>

It's good till now the problem is that every time I try to get some
info about the object  I get the damm POSKeyError exception:

In [17]: o.getId()
---------------------------------------------------------------------------
ZODB.POSException.POSKeyError                               Traceback
(most recent call last)

/home/install/source/Zope-2.7.4-RC2/var/<console>

/home/install/source/Zope-2.7.4-RC2/lib/python/ZODB/Connection.py in
setstate(self, obj)
    608                 "Couldn't load state for %s" % oid_repr(oid),
    609                 error=sys.exc_info())
--> 610             raise
    611
    612     def _is_invalidated(self, obj):

/home/install/source/Zope-2.7.4-RC2/lib/python/ZODB/FileStorage.py in
load(self, oid, version)
    689             return self._load(oid, version, self._index, self._file)
    690         finally:
--> 691             self._lock_release()
    692
    693     def loadSerial(self, oid, serial):

/home/install/source/Zope-2.7.4-RC2/lib/python/ZODB/FileStorage.py in
_load(self, oid, version, _index, file)
    669                 (read(8) # skip past version link
    670                  and version != read(vlen))):
--> 671                 return _loadBack(file, oid, pnv)
    672         else:
    673             # The most recent record is for non-version data -- cache

/home/install/source/Zope-2.7.4-RC2/lib/python/ZODB/FileStorage.py in
_loadBack(file, oid, back)
   1978
   1979 def _loadBack(file, oid, back):
-> 1980     data, serial, old, tloc = _loadBack_impl(file, oid, back)
   1981     return data, serial
   1982

/home/install/source/Zope-2.7.4-RC2/lib/python/ZODB/FileStorage.py in
_loadBack_impl(file, oid, back)
   1965         if not old:
   1966             # If the backpointer is 0, the object does not
currently exist.
-> 1967             raise POSKeyError(oid)
   1968         file.seek(old)
   1969         h = file.read(DATA_HDR_LEN)

POSKeyError: 0x03250e


#############
Now trying the second approach in the cited comment:

In [35]: edit
Editing... done. Executing edited code...
Out[35]: 'from ZODB.POSException import POSKeyError\ndef
error_finder(folder, exception=POSKeyError, stop_on_first=None):\n  
""" start at the given folderish object.\n    If stop_on_first is
true, quit after one exception;\n    otherwise, keep going through the
whole tree."""\n    for id, next_item in folder.objectItems():\n      
 try:\n            next_item.getId()\n        except exception:\n     
      print `exception`, "in folder",\n            print 
\'/\'.join(folder.getPhysicalpath()),     \n            print "at
id:", id\n            if stop_on_first:\n                raise "done" 
 # hack to break out of recursion\n        else:\n            # no
error, recurse if it\'s objectManagerish\n            if
hasattr(next_item.aq_base, \'objectItems\'):\n               
error_finder(next_item, exception, stop_on_first)\n'

In [36]: error_finder(root) 

####
Ops, no output. It visited all the object hierarchy and didin't find a
POSKeyError

> The POSKeyError exception you got should have contained the oid (object id)
> of the missing object.  You can use fsdump.py (see the link I gave above) to
> get a semi-readable text dump of your .fs file, and search for that oid in
> the dump for more clues.

Let's try it. Argh!!! There's a version here:
Trans #00957 tid=034b444f64449677 time=2003-03-01 00:15:23.500294
offset=65792859
	status='p' user= xxxxx
description=/Control_Panel/Products/Comentario/ComentarioClass/propertysheets/methods/manage_addPythonScript
  data #00000 oid=000000000003250e version=/Atualizacao
class=ZClasses.Method.MWp

There's really some ZClass magic. Finally there's the location of the object:
 Weird. The problem object is a manage_addPythonScript. Hope that's
killing it won't forbid me to add script methods to this object. Let's
do it anyway.

This recipe explains how to use lamba to get the id of the problematic object
http://www.zopelabs.com/cookbook/1095965033

In [15]: obj= root.unrestrictedTraverse('/Control_Panel/Products/Comentario/ComentarioClass/propertysheets/methods/')
In [22]: obj._objects
Out[22]:
({'meta_type': 'Script (Python)', 'id': 'nome '},
 {'meta_type': 'DTML Method', 'id': 'edita '},
 {'meta_type': 'DTML Method', 'id': 'mostra '},
 {'meta_type': 'DTML Document', 'id': 'index_html '},
 {'meta_type': 'Script (Python)', 'id': 'data '},
 {'meta_type': 'Script (Python)', 'id': 'numBlocoComentarios '},
 {'meta_type': 'DTML Method', 'id': 'vazio '})
#let's try each one to find the gangster
In [27]: n = obj['index_html']
In [27]: n = obj['data']
---------------------------------------------------------------------------
ZODB.POSException.POSKeyError 

There's also some help here
http://www.dzug.org/mailinglisten/zope-org-zope/archive/2004/2004-07/1090024676313

In [6]: id = 'data'
In [7]: obj._objects=tuple(filter(lambda i,n=id: i['id']!=n, obj._objects))
In [8]: delattr(obj,id)
---------------------------------------------------------------------------
exceptions.KeyError 
...

Argh! It refuses to die. Probably it's because the object is inside a version. 

(some time later)

It's 4am, and I finally solved just using the management interface.
Entered in the version. The POSKeyError desapeared. Leave the
problematic object open in one tab, delete the object, save and quit
the version, recreate the object with the same id, copy and paste from
the tab. Repeated it with the second POSKeyError.

Versions are bad, bad, bad. Deleted them all. Never more will touch
one of these.

good night,
-- 
Paulo Eduardo Neves
Agenda do Samba & Choro
http://www.samba-choro.com.br


More information about the ZODB-Dev mailing list