Database and Instance Migration: OrientDB Sunset, H2/PostgreSQL Paths, and Migrator Workflows: Diagnostics, Failure Modes, Security, and Performance
Migration failures are rarely solved by retrying the same command with broader privileges. Diagnose from the compatibility boundary inward: source/target versions, tool version, Java, PostgreSQL ownership/extensions/schema, blob mappings, migration logs, rebuild tasks, and independent content evidence. Preserve the source until the cause is understood.
Learning objectives
- Diagnose source/target/tool/Java compatibility failures before touching data.
- Interpret PostgreSQL ownership, extension, schema, connectivity, and capacity failures without granting excessive privileges.
- Separate metadata-count success from blob/content/checksum integrity.
- Recognize incomplete post-migration rebuilds and target-specific Instance Migrator exclusions.
- Apply the least-destructive correction while maintaining a tested rollback path.
1. Diagnostic sequence for migration incidents
- Freeze the failed attempt; preserve logs and exact commands with secrets redacted.
- Confirm source Nexus version, database engine, edition, Java runtime, and source health.
- Confirm target Nexus/database version and the current Sonatype-supported source→target path.
- Confirm the migrator binary/version and the tool choice itself.
-
Inspect PostgreSQL ownership,
pg_trgm, schema/search path, connectivity, free space, and RAM. - Inspect blob-store names/locations and whether the chosen tool moves blob content.
- Inspect migration state/logs and post-migration task history.
- Compare repository/security counts and independently verify critical asset SHA-256.
- Apply the smallest supported correction.
- Re-run validation before considering cutover.
2. Failure: OrientDB source was upgraded past the migration line
Symptom: an operator tries to start a 3.90+/3.95 binary against legacy OrientDB data or has no supported running 3.70.x source.
Cause: Nexus 3.71.0 and later do not support OrientDB. A legacy source must remain on the final 3.70.5 line for current migration workflows.
Correction: stop. Restore/reconstruct the supported 3.70.5 source from a verified pre-upgrade recovery set, using the Java version appropriate to that legacy line, then execute the current migration path. Do not downgrade an already-upgraded modern data directory.
3. Failure: PostgreSQL user can connect but is not the database owner
Symptom: migration/startup may reach the database but schema changes or upgrades fail with permissions/ownership errors.
SELECT current_user,
pg_get_userbyid(datdba) AS database_owner
FROM pg_database
WHERE datname = current_database();
Correction: have the DBA provision ownership according to Sonatype requirements. Do not “fix” the incident by making the application user a PostgreSQL superuser.
4. Failure: pg_trgm is missing
Symptom: startup/upgrade/migration behavior reports missing trigram functions/extension or fails during schema work.
SELECT extname, extversion, extnamespace::regnamespace
FROM pg_extension
WHERE extname='pg_trgm';
Correction: install the required extension in the intended schema as the supported database owner before proceeding, then re-run the preflight. Do not ignore the failure and hope a later upgrade creates it.
5. Failure: schema exists but the Nexus user cannot create/use objects
Current migration guidance requires suitable
CREATE/USAGE permissions and correct
currentSchema/search-path behavior when using a
non-default schema. Verify both the JDBC URL and database grants. A
typo in currentSchema can resemble an empty or
incorrectly provisioned target.
6. Failure: migrator fills disk or exhausts memory
Symptom: JVM OOM, temp extraction failure, filesystem nearly full, or migration aborts during extraction/transformation.
Cause: preflight did not reserve the documented RAM and temporary disk headroom. Database migration can require backup + extracted/transformed copies simultaneously.
Correction: preserve the failed logs,
free/provision dedicated capacity, verify the source remains
healthy, and restart only after the resource gate passes. Do not
delete unknown files from $data-dir/db to “make space.”
7. Failure: counts match, downloads return 404 or missing blob
Symptom: repository/component counts look correct but clients cannot fetch some assets.
Cause: Database Migrator moved metadata, not blob content; or target repository→blob mapping points at the wrong location/name.
# Fixture diagnosis: metadata row exists, but target blob is absent.
from pathlib import Path
import json
root=Path('ch26-lab')
state=json.loads((root/'target/db/state.json').read_text())
for a in state['assets']:
p=root/'target/blobs'/a['path']
print(a['path'], 'OK' if p.exists() else 'MISSING')
Correction: fix the supported storage/mapping plan, restore/migrate the correct content, then validate hashes. Never create fake empty files or edit blob metadata to satisfy counts.
8. Failure: counts and paths match, checksum differs
This is a stronger integrity failure. Preserve both source and target bytes, expected hashes, migration logs, storage-system checksums/version IDs, and the recovery checkpoint. Reject cutover. Determine whether the copy was corrupt, the source evidence was stale, or a post-migration write changed the coordinate. Do not redefine the expected checksum to match the target.
9. Failure: content exists but browse/search appears incomplete
After database migration Nexus may run browse/search/index normalization tasks; some formats need additional metadata rebuilds. Check task history/log state before assuming data loss. A repository can serve bytes while derived browse/search state is still rebuilding. The correction is usually to let the documented task complete or run the format-specific supported rebuild—not to manipulate database tables.
10. Failure: Instance Migrator reports configuration/content gaps
Use nexus-migrator.log,
asset-transfers.log, and
failed-asset-transfers.log (names from current
documentation) plus per-repository migration state. Distinguish a
retryable asset transfer from a documented exclusion. For example,
current target-specific migration guidance notes that some external
identity configuration must be recreated manually and some generated
format metadata is rebuilt rather than copied.
11. Failure: migrated target cannot authenticate to upstream/object storage
If the source migrator cipher was not configured for a supported secret category, the target may intentionally lack the secret. Do not extract or print the old encrypted value. Reconfigure the target credential from the organization’s secret system, then perform a narrowly scoped connectivity test. Redact authentication headers and tokens from evidence.
12. Failure: operator cancels mid-migration and assumes atomic rollback
Database Migrator and Instance Migrator have different state models. An interrupted live transfer may have a partially populated target with resumable state; an interrupted offline database transformation may need a clean restart from the preserved source/backup according to current documentation. Do not improvise by mixing partially migrated database files with a different blob snapshot.
13. Intentionally broken fixture
from pathlib import Path
import json, hashlib
root=Path('ch26-broken')
(root/'target/db').mkdir(parents=True,exist_ok=True)
(root/'target/blobs/pkg').mkdir(parents=True,exist_ok=True)
expected=hashlib.sha256(b'GOOD\n').hexdigest()
(root/'target/db/state.json').write_text(json.dumps({'assets':[{'path':'pkg/a.bin','sha256':expected}]},indent=2))
(root/'target/blobs/pkg/a.bin').write_bytes(b'CORRUPT\n')
state=json.loads((root/'target/db/state.json').read_text())
for a in state['assets']:
p=root/'target/blobs'/a['path']
actual=hashlib.sha256(p.read_bytes()).hexdigest()
print(a['path'], 'PASS' if actual==a['sha256'] else 'CHECKSUM_MISMATCH')
The only acceptable outcome is CHECKSUM_MISMATCH. The
repair is to recover/retransfer the known-good byte sequence from
the trusted source/backup, not to update the database’s expected
hash to the corrupt target.
14. Performance diagnosis: measure the bottleneck before tuning
Migration time can be dominated by source DB read, temp-disk IO, PostgreSQL ingest/WAL/autovacuum, blob transfer throughput, object-store latency, network bandwidth, or post-migration index rebuilds. Capture phase timings and rates. Blindly raising JVM heap or transfer parallelism can increase contention or memory pressure.
| Phase | Evidence | Typical bottleneck |
|---|---|---|
| DB transform | migrator logs, disk throughput, CPU | temp IO / database size |
| PostgreSQL load | DB metrics, WAL, locks, disk | DB IO / configuration |
| Instance asset transfer | asset transfer logs, bytes/sec | network/blob IO |
| Post-migration rebuild | Nexus task history/logs | DB + blob IO / CPU |
15. Migration incident evidence packet
- source/target Nexus versions and Java runtimes;
- source/target database engines and PostgreSQL ownership/extension/schema evidence;
- migrator tool/version and redacted command/config;
- backup/recovery-point identifier;
- blob-store names/types/locations;
- migration logs and post-migration task history;
- repository/component/asset count comparison;
- critical asset SHA-256 comparison;
- authorization/client test results;
- decision: retry, correct precondition, rollback, or escalate.
16. Knowledge check
A PostgreSQL user can connect but is not database owner. Is that acceptable?
No. Current Sonatype requirements say the Nexus database user must own the database; upgrades/schema changes require ownership.
Why can browse/search failure after migration be different from content loss?
Browse/search and format metadata may be derived state rebuilt by post-migration tasks, while the underlying asset bytes can still be present and valid.
What should you do when asset counts match but one SHA-256 differs?
Reject target acceptance, preserve evidence, recover/retransfer the expected bytes from a trusted checkpoint, and diagnose the cause. Never change the expected hash to hide corruption.
Why should you not grant PostgreSQL superuser to fix a schema error?
It violates least privilege and hides the real ownership/schema prerequisite. Provision the supported ownership and schema permissions instead.
What is the first action after a migration failure?
Freeze the attempt and preserve evidence/source state before retrying or changing anything.
17. Summary and bridge
Migration diagnostics now follow evidence instead of folklore: verify the path and preconditions, then database, blobs, logs/tasks, hashes, and clients. Lesson 5 integrates the chapter into a full side-by-side migration drill with prediction, cutover, validation, and rollback evidence.
Official references and version notes
- Sonatype: What to Choose — Instance Migrator or Database Migrator — current division between live source→target migration and offline database transformation.
- Sonatype: Instance Migrator — supported OrientDB source/target versions, Java requirement, resumability, logging, and asset migration behavior.
- Sonatype: OrientDB to Self-Hosted PostgreSQL Migration — target preparation, migrator cipher, migrated/excluded state, and known limitations.
- Sonatype: Migrating to a New Database — Database Migrator scenarios, offline requirements, H2→PostgreSQL sequence, and post-migration tasks.
- Sonatype: Upgrading to Nexus Repository 3.71.0 and Beyond — OrientDB 3.70.x migration gate, H2/PostgreSQL paths, and Java transition.
- Sonatype: Nexus Repository Upgrade Paths — current version sequencing and breaking-version gates.
- Sonatype: Reverting Back to OrientDB — why the old database is a recovery point only when matching blob state is restored.
-
Sonatype: Install Nexus Repository with PostgreSQL
— database ownership, schema privileges, and
pg_trgmrequirement. - Sonatype: Nexus Repository Database — H2 production limitations, PostgreSQL recommendation, and OrientDB sunset state.
- Sonatype: Nexus Repository 3.70.x Downloads with OrientDB — final OrientDB line and matching migration downloads.
- Sonatype: Download — current Nexus/Database Migrator/Instance Migrator download references.
- Sonatype: System Requirements — current Java/PostgreSQL requirements and supported database expectations.
- Sonatype: Nexus Repository 3.95.x Release Notes — dated current release line used as the modern target reference.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.