Sometimes I break the Data.fs of my ZODB in a way that the Zope instance cannot start any more or I want to try again a migration. In such situations it is handy that writing to a Data.fs means extending the file at the end. So the unwanted transaction can be truncated. Normally I use the following steps to do so:
ZODB in a virtualenv
This is needed to get the script named
fstail. If you are already using Python 3, call:
python3.7 -m venv v_zodb
If you are still on Python 2, call:
Caution: The Python major version (2 or 3) must match the version you are using for the Zope instance.
Install the script into the virtual environment using:
bin/pip install ZODB
2. Stop Zope and ZEO
Stop both Zope and (if used) the ZEO server. This is necessary for your cut to get noticed by client and server.
3. Find the position where to cut
-n you are able to specify the number of transactions to be shown:
bin/fstail -n 20 path/to/Data.fs
fstail returns something like the following. Newer transaction are at the top: (These lines here are only some extracted from a longer output.)
2019-04-24 08:38:44.622984: hash=0b59c10e6eaa947b2ec0538e26d9b4f9128c03cb user=' admin' description='/storage/58bdea07-666c-11e9-8a63-34363bceb816/edit' length=19180 offset=12296784 (+97) 2019-04-24 08:38:06.823673: hash=3a595fb50b913bad819f0d5bd8d152e06bc695d7 user=' admin' description='/portal/site/add-page-form' length=132830 offset=12121677 (+58) 2019-02-26 10:28:10.856626: hash=5b2b0fbc33b53875b7110f82b2fe1793245c590b user=' admin' description='/index_html/pt_editAction' length=444 offset=11409587 (+54)
Using the provided information in
description you should be able to find the transaction from which on newer transactions should be removed. You need the provided value after
offset= to do the cut.
In my example above, if
/portal/site/add-page-form is the faulty transaction, my cut point is
4. 3, 2, 1 … cut
Caution: Every transaction after the cut point (including the one you took the
offset from) will get removed by cutting.
Get a truncate tool of your choice. I am using here one of Folkert van Heusden which comes with MacPorts and claims to be command-line compatible with the (Free-)BSD version.
In my example I would call it using:
truncate -s 12121677 path/to/Data.fs
That’s all. Start ZEO and Zope again to be back in transaction history where you have cut.
- This blog post is based on a post of David Beitey, see Plone/Zope: Truncating a Data.fs back to a certain date/time
- See also Zope – undo transactions via debug console for another way to truncate a ZODB via undo.