[Zope-Checkins] CVS: ZODB3/ZODB - fspack.py:1.8.8.5
Tim Peters
tim.one at comcast.net
Fri Jan 16 14:18:21 EST 2004
Update of /cvs-repository/ZODB3/ZODB
In directory cvs.zope.org:/tmp/cvs-serv25285/ZODB
Modified Files:
Tag: Zope-2_7-branch
fspack.py
Log Message:
Backport "redundant pack" fix from the HEAD: if you try to pack to a time
earlier than a .fs was previously packed to, the attempt shouldn't do
anything (except raise an exception). It was trying to pack to the
earlier time anyway, but pack's reachability traversal can't work
correctly then due to the "missing" revisions in the gap between the
pack times, and the packed .fs could lose live data as a result.
=== ZODB3/ZODB/fspack.py 1.8.8.4 => 1.8.8.5 ===
--- ZODB3/ZODB/fspack.py:1.8.8.4 Mon Sep 15 17:26:56 2003
+++ ZODB3/ZODB/fspack.py Fri Jan 16 14:17:51 2004
@@ -24,17 +24,11 @@
a backpointer after that time.
"""
-# This module contains code backported from ZODB4 from the
-# zodb.storage.file package. It's been edited heavily to work with
-# ZODB3 code and storage layout.
-
import os
-import struct
from types import StringType
from ZODB.referencesf import referencesf
-from ZODB.utils import p64, u64, z64, oid_repr
-from zLOG import LOG, BLATHER, WARNING, ERROR, PANIC
+from ZODB.utils import p64, u64, z64
try:
from ZODB.fsIndex import fsIndex
@@ -69,6 +63,7 @@
TRANS_HDR_LEN = 23
DATA_HDR_LEN = 42
DATA_VERSION_HDR_LEN = 58
+import struct
assert struct.calcsize(TRANS_HDR) == TRANS_HDR_LEN
assert struct.calcsize(DATA_HDR) == DATA_HDR_LEN
@@ -465,11 +460,19 @@
def buildPackIndex(self):
pos = 4L
+ # We make the initial assumption that the database has been
+ # packed before and set unpacked to True only after seeing the
+ # first record with a status == " ". If we get to the packtime
+ # and unpacked is still False, we need to watch for a redundant
+ # pack.
+ unpacked = False
while pos < self.eof:
th = self._read_txn_header(pos)
if th.tid > self.packtime:
break
self.checkTxn(th, pos)
+ if th.status != "p":
+ unpacked = True
tpos = pos
end = pos + th.tlen
@@ -493,6 +496,24 @@
self.packpos = pos
+ if unpacked:
+ return
+ # check for a redundant pack. If the first record following
+ # the newly computed packpos has status 'p', then it was
+ # packed earlier and the current pack is redudant.
+ try:
+ th = self._read_txn_header(pos)
+ except CorruptedDataError, err:
+ if err.buf != "":
+ raise
+ if th.status == 'p':
+ # Delay import to code with circular imports.
+ # XXX put exceptions in a separate module
+ from ZODB.FileStorage import FileStorageError
+ raise FileStorageError(
+ "The database has already been packed to a later time"
+ " or no changes have been made since the last pack")
+
def findReachableAtPacktime(self, roots):
"""Mark all objects reachable from the oids in roots as reachable."""
todo = list(roots)
@@ -878,3 +899,4 @@
if self._lock_counter % 20 == 0:
self._commit_lock_acquire()
return ipos
+
More information about the Zope-Checkins
mailing list