8.3 module migration: supported timing for deleting legacy PersistentRecord rows after NamedRecordMigrationStrategy?

Hi all,

We're developing a module that supports both Ignition 8.1 and 8.3, and I'm testing the supported 8.1 β†’ 8.3 configuration migration path.

On 8.1, the module stores configuration in a PersistentRecord. On 8.3, the equivalent configuration is a named resource using ResourceTypeMeta / NamedResourceHandler.

For migration we're using:

  • GatewayModuleHook.getRecordMigrationStrategies()
  • NamedRecordMigrationStrategy
  • DefaultRecordEncodingDelegate

The migration itself is working correctly on 8.3.6, including conversion of an 8.1 encoded credential into the 8.3 secret representation.

The part I'm trying to clarify is what the supported lifecycle is for cleaning up the old 8.1 row afterward.

I tested deleting the module-owned legacy row through the public persistence APIs:

GatewayContext.getPersistenceInterface().getSession()

followed by normal find, deleteRecord(), and explicit transaction/commit handling.

That works in testing. I also tested interruption around the cleanup transaction:

  • kill before migration
  • kill after the new resource exists but before cleanup
  • kill after the delete is flushed but before commit
  • kill after cleanup commit

The rollback/restart behavior looked safe in those cases.

However, I also found an important restore case: if an 8.3 .gwbk restore is still being processed and the Gateway is killed, the next startup may replay restoration and migration. Because of that, I don't want to assume that simply reaching Gateway RUNNING means it is safe for the module to automatically delete migrated legacy rows.

So I have three questions:

  1. After a NamedRecordMigrationStrategy has successfully created the new resource, is it supported for a module to transactionally delete its own migrated PersistentRecord row using the normal persistence/session APIs?

    Does Ignition's migration bookkeeping require the migrated rows or RecordMeta definitions to remain afterward?

  2. Is there a public lifecycle callback/event/state that guarantees Gateway restore and record-to-resource migration are fully and durably complete?

    In particular, is the Gateway reaching RUNNING sufficient, or is there another supported readiness point a module should wait for before performing post-migration cleanup/configuration writes?

  3. Is there a supported module API for removing an obsolete migrated table entirely?

    If not, is the recommended approach simply to delete the old rows and leave the empty table/schema in place?

I specifically want to avoid raw SQL or private/internal database APIs.

Target floor versions are 8.1.33 β†’ 8.3.6, so I'm especially interested in what is supported on 8.3.6 rather than behavior added in later 8.3 releases.

Thanks!

You don't need to do anything.
The internal database is inert and ignored after migration has been run.
Migration is expected to either succeed or fail (it's typically very quick), and if it's succeeded an entry will be written to the MIGRATED_TABLES table in the idb - at which point, on next startup your migrator will be skipped.

Just ignore it. In the next major version (2027) we're dropping all the migration and SQLite/IDB code entirely, because the only path to upgrade will be from 8.3. In some version beyond that, we may proactively remove .idb files from gateway backups.

But generally, the advice is "don't overthink it".
Write your migrator to do the simplest idb config -> file config. It should take a few milliseconds, and then you never have to think about migration again.