Trouble converting relstorage to python3

I'm trying to convert a PostgreSQL 11.12 database from python 2.7 to python 3 on Plone 5.2.

I'm running:
bin/zodbupdate --pack --convert-py3 --encoding utf8 --encoding-fallback latin1 -c migration.conf

And get the error psycopg2.ProgrammingError: named cursor isn't valid anymore. I'm not sure if the issue is relstorage, psycopg2, or somewhere else. I suspect it may be a relstorage bug, so I also created an issue here psycopg2.ProgrammingError: named cursor isn't valid anymore · Issue #486 · zodb/relstorage · GitHub. I really want to run this migration against the relstorage, as converting to filestorage has presented its own set of challenges.

Full Traceback:

Committing changes (#1).
Using store connection <StoreConnection at 0x7f70ae438f90 active=False description={'backend_pid': xxx} conn=<connection object at 0x7f70ae4b4440; dsn: '[...]', closed: 0> cur=<cursor object at 0x7f70ae422650; closed: 0>>
Function _flush_temps_to_db took 1.660s.
Function _lock_and_move took 3.991s.
Objects were locked by tpc_finish for 3.992s
Function tpc_finish took 4.475s.
Exception closing <cursor object at 0x7f70b38d5450; closed: 0>
Traceback (most recent call last):
  File "/srv/plone/cache/eggs/RelStorage-3.4.5-py3.7-linux-x86_64.egg/relstorage/adapters/connections.py", line 279, in server_side_cursor
    yield ss_cursor
  File "/srv/plone/cache/eggs/RelStorage-3.4.5-py3.7-linux-x86_64.egg/relstorage/storage/__init__.py", line 586, in __record_iternext_gen
    for record in self._adapter.dbiter.iter_current_records(ss_cursor, start_oid_int):
  File "/srv/plone/cache/eggs/RelStorage-3.4.5-py3.7-linux-x86_64.egg/relstorage/adapters/dbiter.py", line 96, in iter_current_records
    for oid_int, tid_int, state_bytes in cursor:
psycopg2.ProgrammingError: named cursor isn't valid anymore

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/srv/plone/cache/eggs/RelStorage-3.4.5-py3.7-linux-x86_64.egg/relstorage/adapters/connmanager.py", line 186, in close
    obj.close()
psycopg2.ProgrammingError: named cursor isn't valid anymore
An error occured
Traceback (most recent call last):
  File "/srv/plone/cache/eggs/zodbupdate-1.5-py3.7.egg/zodbupdate/main.py", line 223, in main
    updater()
  File "/srv/plone/cache/eggs/zodbupdate-1.5-py3.7.egg/zodbupdate/update.py", line 81, in __call__
    for oid, serial, current in self.records:
  File "/srv/plone/cache/eggs/zodbupdate-1.5-py3.7.egg/zodbupdate/update.py", line 147, in records
    oid, tid, data, next = storage.record_iternext(next)
  File "/srv/plone/cache/eggs/RelStorage-3.4.5-py3.7-linux-x86_64.egg/relstorage/storage/__init__.py", line 643, in record_iternext
    new_oid, new_tid, new_state = self.__next(cursor)
  File "/srv/plone/cache/eggs/RelStorage-3.4.5-py3.7-linux-x86_64.egg/relstorage/storage/__init__.py", line 586, in __record_iternext_gen
    for record in self._adapter.dbiter.iter_current_records(ss_cursor, start_oid_int):
  File "/srv/plone/cache/eggs/RelStorage-3.4.5-py3.7-linux-x86_64.egg/relstorage/adapters/dbiter.py", line 96, in iter_current_records
    for oid_int, tid_int, state_bytes in cursor:
psycopg2.ProgrammingError: named cursor isn't valid anymore
Stopped processing, due to: named cursor isn't valid anymore
Traceback (most recent call last):
  File "/srv/plone/cache/eggs/zodbupdate-1.5-py3.7.egg/zodbupdate/main.py", line 223, in main
    updater()
  File "/srv/plone/cache/eggs/zodbupdate-1.5-py3.7.egg/zodbupdate/update.py", line 81, in __call__
    for oid, serial, current in self.records:
  File "/srv/plone/cache/eggs/zodbupdate-1.5-py3.7.egg/zodbupdate/update.py", line 147, in records
    oid, tid, data, next = storage.record_iternext(next)
  File "/srv/plone/cache/eggs/RelStorage-3.4.5-py3.7-linux-x86_64.egg/relstorage/storage/__init__.py", line 643, in record_iternext
    new_oid, new_tid, new_state = self.__next(cursor)
  File "/srv/plone/cache/eggs/RelStorage-3.4.5-py3.7-linux-x86_64.egg/relstorage/storage/__init__.py", line 586, in __record_iternext_gen
    for record in self._adapter.dbiter.iter_current_records(ss_cursor, start_oid_int):
  File "/srv/plone/cache/eggs/RelStorage-3.4.5-py3.7-linux-x86_64.egg/relstorage/adapters/dbiter.py", line 96, in iter_current_records
    for oid_int, tid_int, state_bytes in cursor:
psycopg2.ProgrammingError: named cursor isn't valid anymore

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/srv/plone/bin/zodbupdate", line 294, in <module>
    sys.exit(zodbupdate.main.main())
  File "/srv/plone/cache/eggs/zodbupdate-1.5-py3.7.egg/zodbupdate/main.py", line 227, in main
    raise AssertionError()
AssertionError

Pinned Versions:

psycopg2 = 2.9.2
relstorage = 3.4.5

Any help or thoughts are greatly appreciated.

ok O In Place Migration Guru @pbauer ... surely you've upgraded RelStorage-powered sites before. You haven't run into this?

Is the source using the same RelStorage version and pgsql version as the target?

I think I get your question, but correct me if I've misunderstood.

We're migrating in several steps. Plone 5.1.7/py2 and Plone 5.2.5/py2 both use psycopg2 = 2.8.6 and relstorage = 3.4.5. Plone 5.2.5/py3 uses relstorage = 3.4.5 as well. I've tried psycopg2 2.8.6 up to 2.9.2 while troubleshooting this.

Process-wise, I have been using these steps as a guide: Flame alert: the Plone Python 3 upgrade story - #13 by jensens

I've never migrated relstorage sites directly. Before migration I would switch to filestorage and then back. Mostly because zodbverify does not work in RelStorage and is a invaluable tool to debug the DB after a migration.

Plone Foundation Code of Conduct