Fix broken zodbpack on Zope with RelStorage#
For some (unknown) reason the pack table in the RelStorage database got into a broken state, which prevented the zodbpack script from running.
The whole failure after running docker exec plone-service.IDENTIFIER /plone/buildout/bin/zodbpack /plone/buildout/relstorage-pack.cfg
is:
Traceback (most recent call last):
File "./bin/zodbpack", line 272, in <module>
sys.exit(relstorage.zodbpack.main())
File "/home/plone/.buildout/shared-eggs/RelStorage-3.5.0-py3.8-linux-x86_64.egg/relstorage/zodbpack.py", line 106, in main
storage.pack(t, ZODB.serialize.referencesf)
File "/home/plone/.buildout/shared-eggs/RelStorage-3.5.0-py3.8-linux-x86_64.egg/relstorage/storage/__init__.py", line 924, in pack
result = pack.pack(t, referencesf, prepack_only, skip_prepack)
File "src/perfmetrics/metric.py", line 72, in perfmetrics._metric._AbstractMetricImpl.__call__
File "/home/plone/.buildout/shared-eggs/RelStorage-3.5.0-py3.8-linux-x86_64.egg/relstorage/storage/pack.py", line 208, in pack
tid_int = self.__pre_pack(t, referencesf)
File "/home/plone/.buildout/shared-eggs/RelStorage-3.5.0-py3.8-linux-x86_64.egg/relstorage/storage/pack.py", line 135, in __pre_pack
self.packundo.pre_pack(tid_int, get_references)
File "src/perfmetrics/metric.py", line 72, in perfmetrics._metric._AbstractMetricImpl.__call__
File "/home/plone/.buildout/shared-eggs/RelStorage-3.5.0-py3.8-linux-x86_64.egg/relstorage/adapters/packundo.py", line 1445, in pre_pack
self._pre_pack_main(load_connection, store_connection,
File "/home/plone/.buildout/shared-eggs/RelStorage-3.5.0-py3.8-linux-x86_64.egg/relstorage/adapters/packundo.py", line 1524, in _pre_pack_main
self.fill_object_refs(load_connection, store_connection, get_references)
File "/home/plone/.buildout/shared-eggs/RelStorage-3.5.0-py3.8-linux-x86_64.egg/relstorage/adapters/packundo.py", line 1325, in fill_object_refs
refs_found = self._add_refs_for_oids(load_batcher, store_batcher,
File "/home/plone/.buildout/shared-eggs/RelStorage-3.5.0-py3.8-linux-x86_64.egg/relstorage/adapters/packundo.py", line 1382, in _add_refs_for_oids
store_batcher.insert_into(
File "/home/plone/.buildout/shared-eggs/RelStorage-3.5.0-py3.8-linux-x86_64.egg/relstorage/adapters/batch.py", line 149, in insert_into
self._flush_if_needed()
File "/home/plone/.buildout/shared-eggs/RelStorage-3.5.0-py3.8-linux-x86_64.egg/relstorage/adapters/batch.py", line 100, in _flush_if_needed
return self.flush()
File "/home/plone/.buildout/shared-eggs/RelStorage-3.5.0-py3.8-linux-x86_64.egg/relstorage/adapters/batch.py", line 273, in flush
count += self._do_inserts()
File "/home/plone/.buildout/shared-eggs/RelStorage-3.5.0-py3.8-linux-x86_64.egg/relstorage/adapters/batch.py", line 364, in _do_inserts
self.cursor.execute(stmt, params)
psycopg2.errors.UniqueViolation: duplicate key value violates unique constraint "object_refs_added_pkey"
DETAIL: Key (zoid)=(738500) already exists.
This could be caused by an upgrade of RelStorage, but I can not say for sure.
The object_refs_added_pkey
is an primary key index on the column zoid
in the table object_refs_added
.
What it tells me: The object_refs_added
table is not consistent, because the zoid 738500 is already in the table, but should not be there.
Since the table is not used for anything else and will be rebuild on the next pack, I can truncate the whole table (remove all data) and start over.
docker exec plone-db.IDENTIFIER psql -U plone -d plone -c "TRUNCATE object_refs_added;"
Now, the zodbpack runs again and the database got rid of it’s old transactions.