[ZODB-Dev] POSKeyError in zodb-3.6.0

Chris Bainbridge chris.bainbridge at gmail.com
Mon Nov 6 11:23:53 EST 2006


Hi,

This looks like a bug to me, but maybe I'm just doing something stupid
(possibly it's not allowed to deepcopy a Persistent object and then
re-sync the connection?). Try running several instances of the
following code in parallel (3 is enough for me here). Seems to be some
race condition; I quickly get an error like:

2006-11-06T16:17:37 (11114/127.0.0.1:60772) Transaction blocked
waiting for storage. Clients waiting: 1.
2006-11-06T16:17:37 (11114/127.0.0.1:60753) Blocked transaction restarted.
2006-11-06T16:17:37 (11114/127.0.0.1:60772) Transaction blocked
waiting for storage. Clients waiting: 1.
2006-11-06T16:17:37 (11114/127.0.0.1:60753) Blocked transaction restarted.
2006-11-06T16:17:37 (11114/127.0.0.1:60753) Transaction blocked
waiting for storage. Clients waiting: 1.
2006-11-06T16:17:37 (11114/127.0.0.1:60772) Blocked transaction restarted.
2006-11-06T16:17:37 (127.0.0.1:60753) loadEx() raised exception: 0xc9
Traceback (most recent call last):
  File "/usr/lib/python2.4/site-packages/ZEO/zrpc/connection.py", line
421, in handle_request
    ret = meth(*args)
  File "/usr/lib/python2.4/site-packages/ZEO/StorageServer.py", line
248, in loadEx
    return self.storage.loadEx(oid, version)
  File "/usr/lib/python2.4/site-packages/ZODB/FileStorage/FileStorage.py",
line 523, in loadEx
    pos = self._lookup_pos(oid)
  File "/usr/lib/python2.4/site-packages/ZODB/FileStorage/FileStorage.py",
line 514, in _lookup_pos
    raise POSKeyError(oid)
POSKeyError: 0xc9

And one of the clients will die. From that point on, any attempt to
access the bad entry in the list generates a POSKeyError.

#!/usr/bin/python

import thread
import asyncore
import random
import copy
from ZEO.ClientStorage import ClientStorage
from ZODB import DB
from persistent import Persistent
from persistent.list import PersistentList
from ZODB.POSException import ConflictError
from ZEO.zrpc.error import DisconnectedError
import transaction

storage = ClientStorage(('localhost', 12345), cache_size=16*1024**2)
db = DB(storage)
conn = db.open()
root = conn.root()
conn.sync()
thread.start_new_thread(asyncore.loop,())

try:
    g = root['test']
except:
    root['test'] = PersistentList()
    g = root['test']
    for x in range(100):
        g.append(PersistentList([x]))
    try:
        transaction.commit()
    except ConflictError:
        pass


while 1:
    conn.sync()
    x = random.choice(g)
    y = copy.deepcopy(x)
    while 1:
        try:
            conn.sync()
            i = g.index(random.choice(g))
            g[i] = y
            transaction.commit()
        except ConflictError:
            pass


More information about the ZODB-Dev mailing list