[Zodb-checkins] CVS: ZODB3/ZODB - FileStorage.py:1.105.2.6.2.2
Jeremy Hylton
jeremy@zope.com
Fri, 15 Nov 2002 11:20:05 -0500
Update of /cvs-repository/ZODB3/ZODB
In directory cvs.zope.org:/tmp/cvs-serv27733
Modified Files:
Tag: ZODB3-restore-debug-branch
FileStorage.py
Log Message:
Two important fixes for backpointer handling.
In restore():
- If the backpointer points to a record with another backpointer,
assume the backpointer is valid.
- If the backpointer points to a record with data and the length of
the data doesn't match the length of the data passed to restore, log
an error() and return 0.
In iterator(): When assigning data_txn for a data record, don't chase
backpointers all the way to the data.
=== ZODB3/ZODB/FileStorage.py 1.105.2.6.2.1 => 1.105.2.6.2.2 ===
--- ZODB3/ZODB/FileStorage.py:1.105.2.6.2.1 Fri Nov 15 10:44:13 2002
+++ ZODB3/ZODB/FileStorage.py Fri Nov 15 11:20:04 2002
@@ -766,9 +766,13 @@
if vl:
self._file.read(vl + 16)
# Make sure this looks like the right data record
+ if dl == 0:
+ # This is also a backpointer. Gotta trust it.
+ return pos
if dl != len(data):
- # XXX what if this data record also has a backpointer?
- # I don't think that's possible, but I'm not sure.
+ # The expected data doesn't match what's in the
+ # backpointer. Something is wrong.
+ error("Mismatch between data and backpointer at %d", pos)
return 0
_data = self._file.read(dl)
if data != _data:
@@ -2211,6 +2215,17 @@
tid = h[:8]
return data, serial, tid
+def getTxnFromData(file, oid, back):
+ """Return transaction id for data at back."""
+ file.seek(U64(back))
+ h = file.read(DATA_HDR_LEN)
+ doid, serial, prev, stloc, vlen, plen = unpack(DATA_HDR, h)
+ assert oid == doid
+ tloc = U64(stloc)
+ file.seek(tloc)
+ # seek to transaction header, where tid is first 8 bytes
+ return file.read(8)
+
def _truncate(file, name, pos):
seek=file.seek
seek(0,2)
@@ -2451,7 +2466,7 @@
break
self._pos = pos + dlen
- tid = None
+ prev_txn = None
if plen:
data = self._file.read(plen)
else:
@@ -2464,10 +2479,12 @@
# Return None instead of a pickle to indicate
# this.
data = None
+ prev_txn = z64
else:
data, _s, tid = _loadBackTxn(self._file, oid, bp)
+ prev_txn = getTxnFromData(self._file, oid, bp)
- r = Record(oid, serial, version, data, tid)
+ r = Record(oid, serial, version, data, prev_txn)
return r