# MigratorXpress Documentation > An efficient database migration tool for cross-platform schema and data transfer. Migrates Oracle, PostgreSQL, SQL Server and Netezza schemas to SQL Server or PostgreSQL, with parallel data transfer through FastTransfer. ## 0.6 An efficient database migration tool for cross-platform schema and data migration. - [MigratorXpress](/0.6.md): An efficient database migration tool for cross-platform schema and data migration. ### compatibility Supported databases and platforms for MigratorXpress. - [Compatibility](/0.6/compatibility.md): Supported databases and platforms for MigratorXpress. ### configuration - [Database Connections](/0.6/configuration/database-configuration.md): Configure database connections for MigratorXpress source, target, and migration tracking databases. - [Netezza](/0.6/configuration/databases/netezza.md): Configure Netezza connections for MigratorXpress source databases. - [Oracle](/0.6/configuration/databases/oracle.md): Configure Oracle connections for MigratorXpress source databases. - [PostgreSQL](/0.6/configuration/databases/postgresql.md): Configure PostgreSQL connections for MigratorXpress source and target databases. - [PostgreSQL as Target](/0.6/configuration/databases/postgresql-as-target.md): Configure PostgreSQL as a migration target database for MigratorXpress. - [PostgreSQL as Migration Tracking](/0.6/configuration/databases/postgresql-as-tracking.md): Configure PostgreSQL as the migration tracking database for MigratorXpress. - [SQL Server](/0.6/configuration/databases/sql-server.md): Configure SQL Server connections for MigratorXpress source, target, and migration tracking databases. - [SQL Server as Target](/0.6/configuration/databases/sql-server-as-target.md): Configure SQL Server as a migration target database for MigratorXpress. - [SQL Server as Migration Tracking](/0.6/configuration/databases/sql-server-as-tracking.md): Configure SQL Server as the migration tracking database for MigratorXpress. - [FastTransfer Configuration](/0.6/configuration/fasttransfer-configuration.md): Configure FastTransfer for high-performance data transfer in MigratorXpress. - [Migration Tasks](/0.6/configuration/migration-tasks.md): Understanding MigratorXpress migration tasks and their execution order. ### guides - [Examples and use cases](/0.6/guides/examples.md): Real-world migration scenarios with complete command examples. - [Quick start guide](/0.6/guides/quickstart.md): Get up and running with MigratorXpress in 5 minutes. ### reference - [CLI Reference](/0.6/reference/cli-reference.md): Complete reference for all MigratorXpress command-line arguments. - [Logging and Monitoring](/0.6/reference/logging.md): Database logging, file-based logging, and monitoring for MigratorXpress migrations. - [MigratorXpress SBOM Downloads](/0.6/reference/sbom.md): Software Bill of Materials downloads and verification for MigratorXpress. - [Troubleshooting](/0.6/reference/troubleshooting.md): Common issues and solutions when using MigratorXpress. ### wizard Build your MigratorXpress command interactively. - [Command Builder](/0.6/wizard.md): Build your MigratorXpress command interactively. ## latest An efficient database migration tool for cross-platform schema and data migration. - [MigratorXpress](/latest.md): An efficient database migration tool for cross-platform schema and data migration. ### ai - [MigratorXpress Agent Skill](/latest/ai/agent-skills.md): Install the official arpe.io agent skill that teaches Claude Code, Codex, Cursor, Copilot and other AI agents to build correct MigratorXpress command lines - [MigratorXpress MCP Server](/latest/ai/mcp-server.md): Connect Claude, ChatGPT, Cursor, VS Code and other AI assistants to the arpe.io MCP server to build, check and run MigratorXpress commands ### compatibility Supported databases and platforms for MigratorXpress. - [Compatibility](/latest/compatibility.md): Supported databases and platforms for MigratorXpress. ### configuration - [Database Connections](/latest/configuration/database-configuration.md): Configure database connections for MigratorXpress source, target, and migration tracking databases. - [Netezza](/latest/configuration/databases/netezza.md): Configure Netezza connections for MigratorXpress source databases. - [Oracle](/latest/configuration/databases/oracle.md): Configure Oracle connections for MigratorXpress source databases. - [PostgreSQL](/latest/configuration/databases/postgresql.md): Configure PostgreSQL connections for MigratorXpress source and target databases. - [PostgreSQL as Target](/latest/configuration/databases/postgresql-as-target.md): Configure PostgreSQL as a migration target database for MigratorXpress. - [PostgreSQL as Migration Tracking](/latest/configuration/databases/postgresql-as-tracking.md): Configure PostgreSQL as the migration tracking database for MigratorXpress. - [SQL Server](/latest/configuration/databases/sql-server.md): Configure SQL Server connections for MigratorXpress source, target, and migration tracking databases. - [SQL Server as Target](/latest/configuration/databases/sql-server-as-target.md): Configure SQL Server as a migration target database for MigratorXpress. - [SQL Server as Migration Tracking](/latest/configuration/databases/sql-server-as-tracking.md): Configure SQL Server as the migration tracking database for MigratorXpress. - [FastTransfer Configuration](/latest/configuration/fasttransfer-configuration.md): Configure FastTransfer for high-performance data transfer in MigratorXpress. - [Migration Tasks](/latest/configuration/migration-tasks.md): Understanding MigratorXpress migration tasks and their execution order. ### guides - [Examples and use cases](/latest/guides/examples.md): Real-world migration scenarios with complete command examples. - [Quick start guide](/latest/guides/quickstart.md): Get up and running with MigratorXpress in 5 minutes. ### installation Install MigratorXpress on Windows or Linux, save your license file, and check the bundled FastTransfer engine. - [Installation](/latest/installation.md): Install MigratorXpress on Windows or Linux, save your license file, and check the bundled FastTransfer engine. ### reference - [CLI Reference](/latest/reference/cli-reference.md): Complete reference for all MigratorXpress command-line arguments. - [Logging and Monitoring](/latest/reference/logging.md): Database logging, file-based logging, and monitoring for MigratorXpress migrations. - [MigratorXpress SBOM Downloads](/latest/reference/sbom.md): Software Bill of Materials downloads and verification for MigratorXpress. - [Troubleshooting](/latest/reference/troubleshooting.md): Common issues and solutions when using MigratorXpress. ### wizard Build your MigratorXpress command interactively. - [Command Builder](/latest/wizard.md): Build your MigratorXpress command interactively. --- # Full Documentation Content # MigratorXpress ## What is MigratorXpress?[​](#what-is-migratorxpress "Direct link to What is MigratorXpress?") MigratorXpress is a CLI tool for database migrations between platforms. It translates schemas, transfers data, copies constraints, and validates results -- all from a single command. Under the hood it uses [FastTransfer](https://www.arpe.io/fasttransfer/) for streaming data transfer, so datasets of any size move without saturating memory. ## Architecture[​](#architecture "Direct link to Architecture") MigratorXpress connects three databases during a migration: ### Source Database[​](#source-database "Direct link to Source Database") The database you are migrating from. MigratorXpress reads schema metadata, profiles column types, and streams table data from the source. Supported sources: Oracle, PostgreSQL, SQL Server, Netezza. ### Target Database[​](#target-database "Direct link to Target Database") The database that receives the translated schema and data. MigratorXpress creates tables, loads data via FastTransfer, and optionally copies constraints. Supported targets: PostgreSQL, SQL Server. ### Migration Tracking DB[​](#migration-tracking-db "Direct link to Migration Tracking DB") A SQL Server **or PostgreSQL** database where MigratorXpress logs every migration step -- table discovery, translation, transfer status, diff results, and constraint operations. This enables auditing, monitoring, and resuming failed migrations. The backend is auto-detected from the auth entry's `ds_type` (`mssql` or `postgres`); no CLI flag is required. ## Key features[​](#key-features "Direct link to Key features") * **Cross-platform** -- native binaries for Windows and Linux. * **Multi-database** -- Oracle, PostgreSQL, SQL Server, and Netezza as sources; PostgreSQL and SQL Server as targets. * **Dual-level parallelism** -- migrate multiple tables at once with `--n_jobs` and partition large tables internally with `--fasttransfer_p`. * **Schema translation** -- automatic DDL conversion between database dialects. * **Data validation** -- the `diff` task compares row counts and content between source and target. * **Flexible task management** -- run any combination of `translate`, `create`, `transfer`, `diff`, `copy_pk`, `copy_ak`, `copy_fk`, or use `--task_list all`. ## Supported migration paths[​](#supported-migration-paths "Direct link to Supported migration paths") | Database | As Source | As Target | Migration Tracking | | ---------- | --------- | --------- | ------------------ | | Oracle | ✅ | ❌ | ❌ | | PostgreSQL | ✅ | ✅ | ✅ | | SQL Server | ✅ | ✅ | ✅ | | Netezza | ✅ | ❌ | ❌ | ## Quick example[​](#quick-example "Direct link to Quick example") A full Oracle-to-PostgreSQL migration on Linux: ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id oracle_prod \ --source_db_name ORCL \ --source_schema_name SALES \ --target_db_auth_id postgres_dev \ --target_db_name analytics \ --target_schema_name sales_copy \ --migration_db_auth_id ms_mig_log \ --n_jobs 2 \ --fasttransfer_p 2 \ --drop_tables_if_exists true \ --task_list translate create transfer diff ``` This single command translates the Oracle `SALES` schema to PostgreSQL DDL, creates the tables, streams the data with two parallel workers per table, and validates the result with a diff. ## Data transfer with FastTransfer[​](#data-transfer-with-fasttransfer "Direct link to Data transfer with FastTransfer") MigratorXpress delegates all data movement to FastTransfer, which uses a streaming architecture. Rows flow directly from source to target without being buffered entirely in memory. This design handles tables with billions of rows on modest hardware and avoids the out-of-memory failures common with dump-and-load approaches. ## Next steps[​](#next-steps "Direct link to Next steps") Ready to migrate? [Get Started](/0.6/guides/quickstart.md)[Command Builder](/0.6/wizard.md)[Examples & Use Cases](/0.6/guides/examples.md) --- # Compatibility ## Supported Databases[​](#supported-databases "Direct link to Supported Databases") | Database | As Source | As Target | Migration Tracking | | ---------- | ------------ | ------------ | ------------------ | | Oracle | ✅ Supported | ❌ | ❌ | | PostgreSQL | ✅ Supported | ✅ Supported | ✅ Supported | | SQL Server | ✅ Supported | ✅ Supported | ✅ Supported | | Netezza | ✅ Supported | ❌ | ❌ | ### Source databases[​](#source-databases "Direct link to Source databases") Any of the four supported databases can serve as a migration source. MigratorXpress reads the schema metadata and data, translates the DDL to the target dialect, and streams rows via FastTransfer. * **[Oracle](/0.6/configuration/databases/oracle.md)** -- thin and thick client modes, Rowid-based parallel extraction * **[PostgreSQL](/0.6/configuration/databases/postgresql.md)** -- Ctid-based parallel extraction * **[SQL Server](/0.6/configuration/databases/sql-server.md)** -- PhysLoc-based parallel extraction * **Netezza** -- source-only support, default port 5480 ### Target databases[​](#target-databases "Direct link to Target databases") PostgreSQL and SQL Server are supported as migration targets. MigratorXpress creates the schema, transfers data, and optionally copies constraints (PK, AK, FK). * **[PostgreSQL](/0.6/configuration/databases/postgresql.md)** -- target schema is created automatically * **[SQL Server](/0.6/configuration/databases/sql-server.md)** -- supports Clustered Columnstore Indexes via `--cci_threshold` ### Migration tracking database[​](#migration-tracking-database "Direct link to Migration tracking database") The migration tracking database can be **SQL Server** or **PostgreSQL**. It stores per-table transfer status, row counts, constraint copy results, and event logs. This database enables the `--resume` capability and provides a full audit trail. The backend is selected by the `ds_type` of the entry referenced by `--migration_db_auth_id` (`mssql` or `postgres`) and is auto-detected; no extra flag is required. * **[SQL Server as Migration Tracking](/0.6/configuration/databases/sql-server-as-tracking.md)** -- default, mature path * **[PostgreSQL as Migration Tracking](/0.6/configuration/databases/postgresql-as-tracking.md)** -- added in v0.6.32, tracking tables live in the `public` schema ## Supported Platforms[​](#supported-platforms "Direct link to Supported Platforms") | Platform | Architecture | | -------- | ------------ | | Windows | x64 | | Linux | x64 | MigratorXpress ships as a native binary for each platform. No runtime installation (Python, Java, .NET) is required. ## See Also[​](#see-also "Direct link to See Also") * [Quick Start Guide](/0.6/guides/quickstart.md) -- get started in 5 minutes * [CLI Reference](/0.6/reference/cli-reference.md) -- all command-line options * [Database Configuration](/0.6/configuration/database-configuration.md) -- connection setup for each database type --- # Database Connections MigratorXpress requires three database connections for every migration: 1. **Source Database** -- the database you are migrating from. 2. **Target Database** -- the database that receives the translated schema and data. 3. **Migration Tracking Database** -- a SQL Server database that records every migration step for auditing and resumability. ## Supported Databases[​](#supported-databases "Direct link to Supported Databases") ### Source Databases[​](#source-databases "Direct link to Source Databases") | Database | Parallel Transfer Method | Notes | | ------------------------------------------------------------ | ------------------------ | ---------------------------------------------------------------------------------- | | **[PostgreSQL](/0.6/configuration/databases/postgresql.md)** | Ctid | No key column required | | **[Oracle](/0.6/configuration/databases/oracle.md)** | Rowid | Thin and thick client modes; requires `SELECT_CATALOG_ROLE` for parallel transfers | | **[SQL Server](/0.6/configuration/databases/sql-server.md)** | Standard | Also usable as target and migration tracking | | **[Netezza](/0.6/configuration/databases/netezza.md)** | NZDataSlice | Source-only; default port 5480 | ### Target Databases[​](#target-databases "Direct link to Target Databases") | Database | Notes | | ------------------------------------------------------------ | --------------------------------------------------------------------- | | **[PostgreSQL](/0.6/configuration/databases/postgresql.md)** | Default target for most migrations | | **[SQL Server](/0.6/configuration/databases/sql-server.md)** | Supports columnstore index options (`cci_threshold`, `aci_threshold`) | ### Migration Tracking Database[​](#migration-tracking-database "Direct link to Migration Tracking Database") | Database | Notes | | ------------------------------------------------------------ | ------------------------------------------------------------------------------ | | **[SQL Server](/0.6/configuration/databases/sql-server.md)** | Required for all migrations; stores run history, task status, and resume state | ## Authentication File Format[​](#authentication-file-format "Direct link to Authentication File Format") Create a JSON file containing one entry per database connection. Each entry has a unique identifier (the JSON key), a `ds_type`, an `auth_mode`, and an `info` object with connection details. ``` { "source_oracle": { "ds_type": "oracle", "auth_mode": "classic", "info": { "username": "$env{ORACLE_USER}", "password": "$env{ORACLE_PASSWORD}", "server": "oracle-prod.company.com", "port": 1521, "database": "PRODPDB" } }, "source_postgres": { "ds_type": "postgres", "auth_mode": "classic", "info": { "username": "$env{PG_USER}", "password": "$env{PG_PASSWORD}", "server": "pg-prod.company.com", "port": 5432, "database": "analytics" } }, "target_mssql": { "ds_type": "mssql", "auth_mode": "classic", "info": { "username": "$env{MSSQL_USER}", "password": "$env{MSSQL_PASSWORD}", "server": "sql-host.company.com", "port": 1433, "database": "target_db" } }, "source_netezza": { "ds_type": "netezza", "auth_mode": "classic", "info": { "username": "$env{NZ_USER}", "password": "$env{NZ_PASSWORD}", "server": "nz-host.company.com", "port": 5480, "database": "PROD_DB" } }, "migration_tracking": { "ds_type": "mssql", "auth_mode": "classic", "info": { "username": "$env{MIG_USER}", "password": "$env{MIG_PASSWORD}", "server": "sql-host.company.com", "port": 1433, "database": "migration_log" } } } ``` Environment variable substitution Use `$env{VAR_NAME}` in any string value to reference an environment variable at runtime. MigratorXpress raises an error if a referenced variable is not set. Plain-text values also work -- values without `$env{` are returned as-is. ``` # Linux export ORACLE_USER="migrator" export ORACLE_PASSWORD="SecureP@ssw0rd" # Windows (PowerShell) $env:ORACLE_USER = "migrator" $env:ORACLE_PASSWORD = "SecureP@ssw0rd" ``` ## Using the Auth File[​](#using-the-auth-file "Direct link to Using the Auth File") Reference the file with `--auth` and point to individual entries by their ID: ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id source_oracle \ --target_db_auth_id target_mssql \ --migration_db_auth_id migration_tracking \ --source_schema_name SALES \ --target_schema_name sales \ --task_list translate create transfer diff ``` ## Security Best Practices[​](#security-best-practices "Direct link to Security Best Practices") ### 1. Credential Storage[​](#1-credential-storage "Direct link to 1. Credential Storage") * Never commit credentials to version control. * Restrict `credentials.json` permissions: ``` chmod 600 credentials.json ``` * Use environment-specific auth files (dev, staging, prod). ### 2. Least Privilege[​](#2-least-privilege "Direct link to 2. Least Privilege") * Create dedicated database users for MigratorXpress. * Grant only SELECT on source databases. * Grant CREATE, INSERT, UPDATE, DELETE on target databases. * Use a dedicated SQL Server database for migration tracking. ### 3. Network Security[​](#3-network-security "Direct link to 3. Network Security") * Use SSL/TLS connections where supported. * Restrict database access by IP. * Use VPN or private networks for cross-environment migrations. ### 4. Password Management[​](#4-password-management "Direct link to 4. Password Management") * Use strong passwords (12+ characters, mixed case, numbers, symbols). * Rotate passwords regularly. * Consider secret managers (AWS Secrets Manager, HashiCorp Vault, Azure Key Vault). ## See Also[​](#see-also "Direct link to See Also") * [PostgreSQL](/0.6/configuration/databases/postgresql.md) -- Source and target configuration * [Oracle](/0.6/configuration/databases/oracle.md) -- Source configuration with thin/thick modes * [SQL Server](/0.6/configuration/databases/sql-server.md) -- Source, target, and migration tracking configuration * [Netezza](/0.6/configuration/databases/netezza.md) -- Source configuration * [Quick Start Guide](/0.6/guides/quickstart.md) -- Getting started with MigratorXpress * [CLI Reference](/0.6/reference/cli-reference.md) -- Command-line options --- # Netezza Netezza is supported as a source-only database in MigratorXpress. It uses NZDataSlice-based parallel transfers for efficient extraction of large tables. ## Connection Parameters[​](#connection-parameters "Direct link to Connection Parameters") | Parameter | Required | Description | | ----------- | -------- | --------------------------- | | `ds_type` | Yes | Must be `"netezza"` | | `auth_mode` | Yes | Must be `"classic"` | | `username` | Yes | Netezza username | | `password` | Yes | Netezza password | | `server` | Yes | Hostname or IP address | | `port` | Yes | Port number (default: 5480) | | `database` | Yes | Database name | ## NZDataSlice Parallel Transfer[​](#nzdataslice-parallel-transfer "Direct link to NZDataSlice Parallel Transfer") Netezza distributes data across internal data slices. MigratorXpress leverages this architecture by reading from individual data slices in parallel, which significantly improves throughput for large tables. No key column is required -- the parallelism is based on Netezza's internal data distribution. The number of parallel streams is controlled by the `--fasttransfer_p` parameter. For best results, set it to a value that aligns with the number of data slices on your Netezza appliance. ## Required Permissions[​](#required-permissions "Direct link to Required Permissions") ``` -- Grant read access to the migration user GRANT SELECT ON TABLE schema_name.table_name TO migratorxpress_user; -- Or grant list access for an entire schema GRANT LIST ON schema_name TO migratorxpress_user; GRANT SELECT ON schema_name TO migratorxpress_user; ``` ## Example[​](#example "Direct link to Example") ``` { "netezza_prod": { "ds_type": "netezza", "auth_mode": "classic", "info": { "username": "$env{NZ_USER}", "password": "$env{NZ_PASSWORD}", "server": "nz-prod.company.com", "port": 5480, "database": "PROD_DB" } } } ``` ## Troubleshooting[​](#troubleshooting "Direct link to Troubleshooting") **Connection refused:** Verify that the Netezza appliance is running and accessible. The default port is 5480, not the standard PostgreSQL port of 5432. Check firewall rules and network connectivity: ``` # Test connectivity telnet nz-prod.company.com 5480 ``` **Authentication failed:** Confirm the username and password are correct. Verify that the user has not been locked out and has the required permissions on the target database. ## See Also[​](#see-also "Direct link to See Also") * [Database Connections Overview](/0.6/configuration/database-configuration.md) -- Auth file format and security best practices --- # Oracle Oracle is supported as a source database in MigratorXpress. It supports both thin and thick client modes and uses Rowid-based parallel transfers for large tables. ## Connection Parameters[​](#connection-parameters "Direct link to Connection Parameters") | Parameter | Required | Description | | ----------- | -------- | ------------------------------------------------- | | `ds_type` | Yes | Must be `"oracle"` | | `auth_mode` | Yes | Must be `"classic"` | | `username` | Yes | Oracle username | | `password` | Yes | Oracle password | | `server` | Yes | Hostname or IP address | | `port` | Yes | Port number (default: 1521) | | `database` | Yes | Service name or SID | | `lib_dir` | No | Oracle Instant Client directory (thick mode only) | ## Thin vs Thick Mode[​](#thin-vs-thick-mode "Direct link to Thin vs Thick Mode") **Thin Mode (Recommended):** * No Oracle client libraries required on the machine running MigratorXpress. * Requires Oracle 12.1 or later. * Omit the `lib_dir` parameter. **Thick Mode:** * Required for Oracle 11.2 and earlier. * Requires Oracle Instant Client installed locally. * Set `lib_dir` to the Instant Client directory path. ## Required Permissions[​](#required-permissions "Direct link to Required Permissions") Grant `SELECT_CATALOG_ROLE` to enable parallel Rowid-based transfers and metadata discovery: ``` -- As Oracle DBA (e.g., sys as sysdba) GRANT SELECT_CATALOG_ROLE TO your_username; ``` This role provides access to data dictionary views needed for Rowid range partitioning and transfer method selection. ## Example: Thin Mode[​](#example-thin-mode "Direct link to Example: Thin Mode") ``` { "oracle_prod": { "ds_type": "oracle", "auth_mode": "classic", "info": { "username": "$env{ORACLE_USER}", "password": "$env{ORACLE_PASSWORD}", "server": "oracle-prod.company.com", "port": 1521, "database": "PRODPDB" } } } ``` ## Example: Thick Mode[​](#example-thick-mode "Direct link to Example: Thick Mode") ``` { "oracle_legacy": { "ds_type": "oracle", "auth_mode": "classic", "info": { "username": "$env{ORACLE_USER}", "password": "$env{ORACLE_PASSWORD}", "server": "oracle-11g.company.com", "port": 1521, "database": "LEGACY", "lib_dir": "/opt/oracle/instantclient_19_8" } } } ``` ## Troubleshooting[​](#troubleshooting "Direct link to Troubleshooting") **ORA-12154: TNS could not resolve connect identifier:** Verify the service name in the `database` field. Check `tnsnames.ora` if applicable. Try using the IP address instead of the hostname and confirm the Oracle listener is running (`lsnrctl status`). **ORA-28000: account is locked:** ``` ALTER USER your_username ACCOUNT UNLOCK; ``` **Thick mode library not found:** Verify that the `lib_dir` path exists and contains the Instant Client shared libraries. Confirm Oracle Instant Client is installed and check file permissions. On Linux, you may also need to set `LD_LIBRARY_PATH`: ``` export LD_LIBRARY_PATH=/opt/oracle/instantclient_19_8:$LD_LIBRARY_PATH ``` ## See Also[​](#see-also "Direct link to See Also") * [Database Connections Overview](/0.6/configuration/database-configuration.md) -- Auth file format and security best practices --- # PostgreSQL PostgreSQL can serve as both a source and a target database in MigratorXpress migrations. As a source, it supports Ctid-based parallel transfers for large tables. ## Connection Parameters[​](#connection-parameters "Direct link to Connection Parameters") | Parameter | Required | Description | | ----------- | -------- | --------------------------- | | `ds_type` | Yes | Must be `"postgres"` | | `auth_mode` | Yes | `"classic"` or `"odbc"` | | `username` | Yes | PostgreSQL username | | `password` | Yes | PostgreSQL password | | `server` | Yes | Hostname or IP address | | `port` | Yes | Port number (default: 5432) | | `database` | Yes | Database name | ## Required Permissions[​](#required-permissions "Direct link to Required Permissions") ### As Source[​](#as-source "Direct link to As Source") ``` -- Grant read access to the migration user GRANT USAGE ON SCHEMA public TO migratorxpress_user; GRANT SELECT ON ALL TABLES IN SCHEMA public TO migratorxpress_user; -- For multiple schemas, repeat for each schema: GRANT USAGE ON SCHEMA my_schema TO migratorxpress_user; GRANT SELECT ON ALL TABLES IN SCHEMA my_schema TO migratorxpress_user; ``` ### As Target[​](#as-target "Direct link to As Target") ``` -- Grant write access to the migration user GRANT CREATE ON DATABASE target_db TO migratorxpress_user; GRANT ALL PRIVILEGES ON SCHEMA public TO migratorxpress_user; -- If using a custom target schema: CREATE SCHEMA IF NOT EXISTS target_schema; GRANT ALL PRIVILEGES ON SCHEMA target_schema TO migratorxpress_user; ``` ## Example: Classic Authentication[​](#example-classic-authentication "Direct link to Example: Classic Authentication") ``` { "postgres_source": { "ds_type": "postgres", "auth_mode": "classic", "info": { "username": "$env{PG_USER}", "password": "$env{PG_PASSWORD}", "server": "pg-prod.company.com", "port": 5432, "database": "analytics" } } } ``` ## Example: ODBC Mode[​](#example-odbc-mode "Direct link to Example: ODBC Mode") When ODBC drivers are available, you can use ODBC mode for additional connection options: ``` { "postgres_odbc": { "ds_type": "postgres", "auth_mode": "odbc", "info": { "connection_string": "Driver={PostgreSQL};Server=pg-prod.company.com;Port=5432;Database=analytics;Uid=$env{PG_USER};Pwd=$env{PG_PASSWORD};" } } } ``` ## Troubleshooting[​](#troubleshooting "Direct link to Troubleshooting") **Connection refused:** Check that PostgreSQL is running (`systemctl status postgresql`), verify `pg_hba.conf` allows connections from your IP, and check firewall rules (`sudo ufw allow 5432/tcp`). **Authentication failed:** Verify credentials, check the password encryption method in `pg_hba.conf` (md5, scram-sha-256), and confirm the user exists: ``` SELECT * FROM pg_user WHERE usename = 'your_user'; ``` ## See Also[​](#see-also "Direct link to See Also") * [Database Connections Overview](/0.6/configuration/database-configuration.md) -- Auth file format and security best practices --- # PostgreSQL as Target PostgreSQL is a fully supported migration target. MigratorXpress creates the target schema automatically and streams data via FastTransfer. For the complete connection reference, authentication modes, and troubleshooting, see the canonical **[PostgreSQL](/0.6/configuration/databases/postgresql.md)** page. ## Target-specific Permissions[​](#target-specific-permissions "Direct link to Target-specific Permissions") ``` -- Grant write access to the migration user GRANT CREATE ON DATABASE target_db TO migratorxpress_user; GRANT ALL PRIVILEGES ON SCHEMA public TO migratorxpress_user; -- If using a custom target schema: CREATE SCHEMA IF NOT EXISTS target_schema; GRANT ALL PRIVILEGES ON SCHEMA target_schema TO migratorxpress_user; ``` ## Example Auth Entry[​](#example-auth-entry "Direct link to Example Auth Entry") ``` { "postgres_target": { "ds_type": "postgres", "auth_mode": "classic", "info": { "username": "$env{PG_USER}", "password": "$env{PG_PASSWORD}", "server": "pg-target.company.com", "port": 5432, "database": "target_db" } } } ``` Reference it on the command line with `--target_db_auth_id postgres_target`. ## See Also[​](#see-also "Direct link to See Also") * [PostgreSQL](/0.6/configuration/databases/postgresql.md) -- full connection reference * [Database Connections](/0.6/configuration/database-configuration.md) -- auth file format and security --- # PostgreSQL as Migration Tracking Since v0.6.32, the migration tracking database can be PostgreSQL in addition to SQL Server. The two backends share the same schema (table names, columns, foreign keys, the `v_sourcetargetdiff` view) and the same workflow (run history, per-table task status, row counts, constraint copy results, event logs, `--resume`). MigratorXpress auto-detects the backend from the `ds_type` of the auth entry referenced by `--migration_db_auth_id` -- no extra CLI flag is required. For the full PostgreSQL connection reference (authentication modes, ODBC, troubleshooting), see the canonical **[PostgreSQL](/0.6/configuration/databases/postgresql.md)** page. ## Schema and Object Naming[​](#schema-and-object-naming "Direct link to Schema and Object Naming") * Tracking tables and the `v_sourcetargetdiff` view live in the `public` schema. * Types map to PG natives: `timestamp`, `text`, `boolean`, `varchar(N)`, `numeric(32,6)`. * The internal sequence `seq_id_load` is a standard `CREATE SEQUENCE`. * Idempotent DDL uses `CREATE TABLE IF NOT EXISTS`, `ALTER TABLE ... ADD COLUMN IF NOT EXISTS`, `CREATE OR REPLACE VIEW`, and `INSERT ... ON CONFLICT DO UPDATE`. ## Tracking-specific Permissions[​](#tracking-specific-permissions "Direct link to Tracking-specific Permissions") The tracking role needs full DDL/DML rights on the database hosting the tracking tables, because MigratorXpress creates tables, evolves the schema on upgrade, and writes rows continuously during a migration. ``` -- Full access to the migration tracking database GRANT CREATE ON DATABASE migration_log TO migratorxpress_user; GRANT ALL PRIVILEGES ON SCHEMA public TO migratorxpress_user; ALTER SCHEMA public OWNER TO migratorxpress_user; ``` If the role is not the schema owner, future schema upgrades (added columns, new tables) can fail with `permission denied for schema public`. Owning the schema (or granting `ALL` on it) avoids that. ## Migration DB Modes[​](#migration-db-modes "Direct link to Migration DB Modes") The `--migration_db_mode` flag controls how MigratorXpress treats the tracking schema at startup. Behavior is identical on SQL Server and PostgreSQL. | Mode | Behavior | | -------------------- | ---------------------------------------------- | | `preserve` (default) | Keep tracking data; required to use `--resume` | | `truncate` | Clear data, keep schema | | `drop` | Drop and recreate the tracking schema | ## Example Auth Entry[​](#example-auth-entry "Direct link to Example Auth Entry") ``` { "migration_tracking": { "ds_type": "postgres", "auth_mode": "classic", "info": { "username": "$env{MIG_USER}", "password": "$env{MIG_PASSWORD}", "server": "pg-host.company.com", "port": 5432, "database": "migration_log" } } } ``` Reference it on the command line with `--migration_db_auth_id migration_tracking`. The rest of the CLI is unchanged. ## Querying the Tracking Tables[​](#querying-the-tracking-tables "Direct link to Querying the Tracking Tables") The schema is the same across both backends, so any dashboard query that uses portable SQL (no `DATEDIFF`, `GETDATE()`, `TOP`, `+` for string concat) works on either. Example: list tables with errors for a given run. ``` SELECT src_tablename, eventmessage, eventtimestamp FROM eventlog WHERE eventrunid = '20260511-...' AND eventstatus = 'failed' ORDER BY eventtimestamp DESC; ``` For PG-specific date arithmetic and other reporting patterns, see [Logging and Monitoring](/0.6/reference/logging.md). ## See Also[​](#see-also "Direct link to See Also") * [PostgreSQL](/0.6/configuration/databases/postgresql.md) -- full connection reference * [SQL Server as Migration Tracking](/0.6/configuration/databases/sql-server-as-tracking.md) -- equivalent doc for the SQL Server backend * [Database Connections](/0.6/configuration/database-configuration.md) -- auth file format and security * [Logging and Monitoring](/0.6/reference/logging.md) -- schema details and dashboard queries --- # SQL Server SQL Server is the most versatile database in MigratorXpress -- it can serve as a source, a target, and the migration tracking database. ## Connection Parameters[​](#connection-parameters "Direct link to Connection Parameters") | Parameter | Required | Description | | ----------- | -------- | -------------------------------------------------------------- | | `ds_type` | Yes | Must be `"mssql"` | | `auth_mode` | Yes | `"classic"`, `"odbc"`, or `"connection_string"` | | `username` | Yes\* | SQL Server username (\*not required for Windows auth via ODBC) | | `password` | Yes\* | SQL Server password (\*not required for Windows auth via ODBC) | | `server` | Yes | Hostname or IP address | | `port` | Yes | Port number (default: 1433) | | `database` | Yes | Database name | note SQL Server is the only database that can fill all three roles in a MigratorXpress migration. You can even use the same SQL Server instance for source, target, and migration tracking by creating separate database entries in your auth file. ## Required Permissions[​](#required-permissions "Direct link to Required Permissions") ### As Source[​](#as-source "Direct link to As Source") ``` -- Grant read access for data transfer and schema discovery GRANT SELECT ON SCHEMA::dbo TO migratorxpress_user; GRANT VIEW DEFINITION ON SCHEMA::dbo TO migratorxpress_user; ``` ### As Target[​](#as-target "Direct link to As Target") ``` -- Grant permissions for schema creation and data loading GRANT CREATE TABLE TO migratorxpress_user; GRANT ALTER ON SCHEMA::dbo TO migratorxpress_user; GRANT INSERT ON SCHEMA::dbo TO migratorxpress_user; GRANT UPDATE ON SCHEMA::dbo TO migratorxpress_user; GRANT DELETE ON SCHEMA::dbo TO migratorxpress_user; ``` ### As Migration Tracking[​](#as-migration-tracking "Direct link to As Migration Tracking") ``` -- Full access to the migration tracking database ALTER ROLE db_owner ADD MEMBER migratorxpress_user; ``` The migration tracking user needs full access to create and manage the internal tables that track migration runs, task statuses, and resume state. ## Example: Classic Authentication[​](#example-classic-authentication "Direct link to Example: Classic Authentication") ``` { "mssql_target": { "ds_type": "mssql", "auth_mode": "classic", "info": { "username": "$env{MSSQL_USER}", "password": "$env{MSSQL_PASSWORD}", "server": "sql-prod.company.com", "port": 1433, "database": "TargetDB" } } } ``` ## Example: Windows Trusted Authentication (ODBC)[​](#example-windows-trusted-authentication-odbc "Direct link to Example: Windows Trusted Authentication (ODBC)") Use ODBC mode with `Trusted_Connection=yes` for Windows integrated authentication: ``` { "mssql_trusted": { "ds_type": "mssql", "auth_mode": "odbc", "info": { "connection_string": "Driver={ODBC Driver 17 for SQL Server};Server=sql-prod.company.com;Database=TargetDB;Trusted_Connection=yes;" } } } ``` ## Example: Connection String Mode[​](#example-connection-string-mode "Direct link to Example: Connection String Mode") For full control over the connection string: ``` { "mssql_connstr": { "ds_type": "mssql", "auth_mode": "connection_string", "info": { "connection_string": "Driver={ODBC Driver 17 for SQL Server};Server=sql-prod.company.com,1433;Database=TargetDB;Uid=$env{MSSQL_USER};Pwd=$env{MSSQL_PASSWORD};Encrypt=yes;TrustServerCertificate=no;" } } } ``` ## Troubleshooting[​](#troubleshooting "Direct link to Troubleshooting") **Login failed for user:** Confirm that SQL Server authentication mode is set to "SQL Server and Windows Authentication" (mixed mode), not Windows-only. Verify the user exists with the correct permissions and check for IP restrictions. **Cannot open database requested by the login:** Verify the database name, check that the user has been granted access, and confirm the database is online: ``` SELECT name, state_desc FROM sys.databases WHERE name = 'YourDB'; ``` ## See Also[​](#see-also "Direct link to See Also") * [Database Connections Overview](/0.6/configuration/database-configuration.md) -- Auth file format and security best practices --- # SQL Server as Target SQL Server is a fully supported migration target. MigratorXpress creates the target schema, streams data via FastTransfer, and can apply Clustered Columnstore Index (CCI) or archive compression based on row-count thresholds. For the complete connection reference, authentication modes (classic / ODBC / connection string), and troubleshooting, see the canonical **[SQL Server](/0.6/configuration/databases/sql-server.md)** page. ## Target-specific Permissions[​](#target-specific-permissions "Direct link to Target-specific Permissions") ``` -- Grant permissions for schema creation and data loading GRANT CREATE TABLE TO migratorxpress_user; GRANT ALTER ON SCHEMA::dbo TO migratorxpress_user; GRANT INSERT ON SCHEMA::dbo TO migratorxpress_user; GRANT UPDATE ON SCHEMA::dbo TO migratorxpress_user; GRANT DELETE ON SCHEMA::dbo TO migratorxpress_user; ``` ## Target-specific CLI Options[​](#target-specific-cli-options "Direct link to Target-specific CLI Options") | Option | Purpose | | ---------------------------------------- | ---------------------------------------------------------------------- | | `--cci_threshold N` | Create a Clustered Columnstore Index when a table has more than N rows | | `--aci_threshold N` | Apply archive compression when a table has more than N rows | | `--fk_mode {disabled,untrusted,trusted}` | Foreign-key enforcement strategy after `copy_fk` | ## Example Auth Entry[​](#example-auth-entry "Direct link to Example Auth Entry") ``` { "mssql_target": { "ds_type": "mssql", "auth_mode": "classic", "info": { "username": "$env{MSSQL_USER}", "password": "$env{MSSQL_PASSWORD}", "server": "sql-target.company.com", "port": 1433, "database": "TargetDB" } } } ``` Reference it on the command line with `--target_db_auth_id mssql_target`. ## See Also[​](#see-also "Direct link to See Also") * [SQL Server](/0.6/configuration/databases/sql-server.md) -- full connection reference * [Database Connections](/0.6/configuration/database-configuration.md) -- auth file format and security --- # SQL Server as Migration Tracking The migration tracking database is required for every MigratorXpress migration and **must be SQL Server**. It records run history, per-table task status, row counts, constraint copy results, and event logs. This database also enables `--resume` for interrupted migrations. For the complete connection reference, authentication modes (classic / ODBC / connection string), and troubleshooting, see the canonical **[SQL Server](/0.6/configuration/databases/sql-server.md)** page. ## Tracking-specific Permissions[​](#tracking-specific-permissions "Direct link to Tracking-specific Permissions") ``` -- Full access to the migration tracking database ALTER ROLE db_owner ADD MEMBER migratorxpress_user; ``` The tracking user needs full access to create and manage the internal tables that record migration runs, task statuses, and resume state. ## Migration DB Modes[​](#migration-db-modes "Direct link to Migration DB Modes") The `--migration_db_mode` flag controls how MigratorXpress treats the tracking schema at startup. | Mode | Behavior | | -------------------- | ---------------------------------------------- | | `preserve` (default) | Keep tracking data; required to use `--resume` | | `truncate` | Clear data, keep schema | | `drop` | Drop and recreate the tracking schema | ## Example Auth Entry[​](#example-auth-entry "Direct link to Example Auth Entry") ``` { "migration_tracking": { "ds_type": "mssql", "auth_mode": "classic", "info": { "username": "$env{MIG_USER}", "password": "$env{MIG_PASSWORD}", "server": "sql-host.company.com", "port": 1433, "database": "migration_log" } } } ``` Reference it on the command line with `--migration_db_auth_id migration_tracking`. ## See Also[​](#see-also "Direct link to See Also") * [SQL Server](/0.6/configuration/databases/sql-server.md) -- full connection reference * [Database Connections](/0.6/configuration/database-configuration.md) -- auth file format and security --- # FastTransfer Configuration MigratorXpress delegates all data movement to [FastTransfer](https://www.arpe.io/fasttransfer/) (>= 0.15.0 required), which uses a streaming architecture. Rows flow directly from source to target without being buffered entirely in memory, so tables with billions of rows can be transferred on modest hardware. ## FastTransfer Location[​](#fasttransfer-location "Direct link to FastTransfer Location") Point `--fasttransfer_dir_path` to the directory containing the FastTransfer binary. Since v0.6.25, if this flag is omitted, MigratorXpress auto-detects a bundled FastTransfer in the `engine/` subdirectory next to the binary. Trial distributions ship with FastTransfer pre-bundled. ## Key Parameters[​](#key-parameters "Direct link to Key Parameters") | Parameter | Type | Default | Description | | ------------------------- | ------- | ------------- | --------------------------------------------------------------------------- | | `--fasttransfer_dir_path` | Path | Auto-detected | Directory containing the FastTransfer binary | | `--fasttransfer_p` | Integer | 1 | Number of parallel streams within FastTransfer for large table partitioning | | `--ft_large_table_th` | Integer | 250,000,000 | Row count threshold above which a table is eligible for parallel transfer | | `--n_jobs` | Integer | 1 | Number of tables to transfer simultaneously | ### Dual-Level Parallelism[​](#dual-level-parallelism "Direct link to Dual-Level Parallelism") MigratorXpress supports two levels of parallelism: * **`--n_jobs`** controls how many tables are transferred concurrently. * **`--fasttransfer_p`** controls how many parallel streams each large table uses internally. For example, `--n_jobs 4 --fasttransfer_p 2` transfers 4 tables simultaneously, and any table above the large table threshold is split into 2 parallel streams. ## Parallel Transfer Methods[​](#parallel-transfer-methods "Direct link to Parallel Transfer Methods") Each source database uses a different method to partition tables for parallel transfer: | Source Database | Method | Key Column Required | Description | | --------------- | ----------- | ------------------- | -------------------------------------------------------- | | PostgreSQL | Ctid | No | Splits by physical tuple ID | | Oracle | Rowid | No | Splits by physical ROWID; requires `SELECT_CATALOG_ROLE` | | Netezza | NZDataSlice | No | Splits by internal data slice distribution | | SQL Server | Standard | N/A | Standard transfer without physical partitioning | ### Method Selection Logic[​](#method-selection-logic "Direct link to Method Selection Logic") MigratorXpress selects the parallel transfer method automatically based on the source database type. No manual configuration is needed. If `--fasttransfer_p` is set to 1 or the table row count is below `--ft_large_table_th`, the table is transferred as a single stream regardless of the source type. ## Performance Tuning[​](#performance-tuning "Direct link to Performance Tuning") ### PostgreSQL Sources[​](#postgresql-sources "Direct link to PostgreSQL Sources") Ctid-based parallelism works well with minimal configuration. Increase `--fasttransfer_p` for tables with hundreds of millions of rows. Start with 2-4 parallel streams and scale up based on available CPU and I/O bandwidth. ### Oracle Sources[​](#oracle-sources "Direct link to Oracle Sources") Rowid-based parallelism requires `SELECT_CATALOG_ROLE` (see [Oracle configuration](/0.6/configuration/databases/oracle.md)). Oracle parallel transfers benefit from higher stream counts on large tables. Consider 4-8 streams for tables exceeding 100M rows. ### Netezza Sources[​](#netezza-sources "Direct link to Netezza Sources") NZDataSlice parallelism aligns with Netezza's internal data distribution. Set `--fasttransfer_p` to match or be a factor of the number of data slices on the appliance. ### SQL Server Sources[​](#sql-server-sources "Direct link to SQL Server Sources") SQL Server uses standard (non-partitioned) transfers. Parallelism is achieved at the table level via `--n_jobs`. For SQL Server sources, increase `--n_jobs` rather than `--fasttransfer_p`. ## SQL Server Target Options[​](#sql-server-target-options "Direct link to SQL Server Target Options") When SQL Server is the target database, MigratorXpress supports additional options for columnstore indexes and foreign key handling. ### Columnstore Indexes[​](#columnstore-indexes "Direct link to Columnstore Indexes") | Parameter | Type | Default | Description | | ----------------- | ------- | ----------- | ------------------------------------------------------------------- | | `--cci_threshold` | Integer | 1,000,000 | Create Clustered Columnstore Index for tables above this row count | | `--aci_threshold` | Integer | 100,000,000 | Use archive compression (COLUMNSTORE\_ARCHIVE) above this row count | Tables >= `cci_threshold` but < `aci_threshold` get a standard CCI. Tables >= `aci_threshold` get a CCI with `DATA_COMPRESSION = COLUMNSTORE_ARCHIVE`. Tables below `cci_threshold` remain as standard rowstore tables. ### Foreign Key Mode[​](#foreign-key-mode "Direct link to Foreign Key Mode") | Parameter | Type | Default | Description | | ----------- | ------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------- | | `--fk_mode` | String | `disabled` | FK enforcement: `disabled` (created with NOCHECK and disabled), `untrusted` (NOCHECK but enabled), `trusted` (full enforcement) | ## Row Count Options[​](#row-count-options "Direct link to Row Count Options") | Parameter | Type | Default | Description | | ------------------ | ------- | ------- | ----------------------------------------------------------------- | | `--compute_nbrows` | Boolean | false | Use `COUNT(*)` for exact row counts instead of database estimates | | `--without_xid` | Flag | false | Disable transaction ID usage in Netezza and Oracle | ## Configuration Examples[​](#configuration-examples "Direct link to Configuration Examples") ### Small Migration (< 10 tables, < 1M rows total)[​](#small-migration--10-tables--1m-rows-total "Direct link to Small Migration (< 10 tables, < 1M rows total)") ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id oracle_prod \ --source_schema_name HR \ --target_db_auth_id postgres_dev \ --target_schema_name hr \ --fasttransfer_dir_path ./FastTransfer_linux-x64_v0.12.4/ \ --migration_db_auth_id ms_mig_log \ --task_list translate create transfer diff ``` Default parallelism is sufficient. Single-stream transfer per table, one table at a time. ### Medium Migration (10-100 tables, up to 100M rows)[​](#medium-migration-10-100-tables-up-to-100m-rows "Direct link to Medium Migration (10-100 tables, up to 100M rows)") ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id oracle_prod \ --source_schema_name SALES \ --target_db_auth_id postgres_dev \ --target_schema_name sales \ --fasttransfer_dir_path ./FastTransfer_linux-x64_v0.12.4/ \ --migration_db_auth_id ms_mig_log \ --n_jobs 4 \ --fasttransfer_p 2 \ --task_list translate create transfer diff ``` Four tables in parallel, large tables split into 2 streams each. ### Large Migration (100+ tables, billions of rows)[​](#large-migration-100-tables-billions-of-rows "Direct link to Large Migration (100+ tables, billions of rows)") ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id oracle_prod \ --source_schema_name WAREHOUSE \ --target_db_auth_id postgres_dev \ --target_schema_name warehouse \ --fasttransfer_dir_path ./FastTransfer_linux-x64_v0.12.4/ \ --migration_db_auth_id ms_mig_log \ --n_jobs 8 \ --fasttransfer_p 4 \ --ft_large_table_th 500000 \ --task_list translate create transfer diff ``` Eight tables in parallel, large tables (> 500K rows) split into 4 streams. Adjust thresholds based on hardware capacity. ## Monitoring Performance[​](#monitoring-performance "Direct link to Monitoring Performance") During and after a migration, you can query the migration tracking database to check progress and identify slow tables. ### Check Overall Progress[​](#check-overall-progress "Direct link to Check Overall Progress") ``` SELECT task_name, COUNT(*) AS total_tables, SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) AS completed, SUM(CASE WHEN status = 'running' THEN 1 ELSE 0 END) AS running, SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) AS failed FROM migration_tasks WHERE run_id = 'YOUR_RUN_ID' GROUP BY task_name; ``` ### Identify Slow Tables[​](#identify-slow-tables "Direct link to Identify Slow Tables") ``` SELECT table_name, task_name, DATEDIFF(SECOND, start_time, ISNULL(end_time, GETDATE())) AS duration_seconds, row_count FROM migration_tasks WHERE run_id = 'YOUR_RUN_ID' AND task_name = 'transfer' ORDER BY duration_seconds DESC; ``` ## Troubleshooting[​](#troubleshooting "Direct link to Troubleshooting") **FastTransfer binary not found:** Verify the `--fasttransfer_dir_path` points to the correct directory containing the FastTransfer executable. Check file permissions and ensure the binary is executable (`chmod +x FastTransfer` on Linux). **Transfer stalls on large tables:** Reduce `--fasttransfer_p` if the source or target database is under heavy load. Check network bandwidth between the MigratorXpress host and the databases. **Out of memory errors:** FastTransfer's streaming architecture normally prevents memory issues. If they occur, reduce `--n_jobs` to lower the number of concurrent table transfers. **Slow transfer throughput:** * Increase `--fasttransfer_p` for large tables. * Increase `--n_jobs` if the bottleneck is small-table overhead rather than individual table speed. * Check that the network path between source and target is not saturated. * Verify that the source database is not under heavy concurrent load. ## See Also[​](#see-also "Direct link to See Also") * [Migration Tasks](/0.6/configuration/migration-tasks.md) -- Task execution order and combinations * [Database Connections](/0.6/configuration/database-configuration.md) -- Auth file configuration * [Quick Start Guide](/0.6/guides/quickstart.md) -- Getting started with MigratorXpress * [CLI Reference](/0.6/reference/cli-reference.md) -- Full command-line reference --- # Migration Tasks MigratorXpress organizes migrations into discrete tasks. You specify which tasks to run with the `--task_list` parameter, and MigratorXpress executes them in the order listed. Use `--task_list all` as a shortcut for the full sequence. ## Available Tasks[​](#available-tasks "Direct link to Available Tasks") | Task | Description | When to Use | | ----------- | ------------------------------------------------------------------------- | --------------------------- | | `translate` | Convert source DDL to the target platform's SQL dialect | First step of any migration | | `create` | Create tables in the target database using the translated DDL | After translation | | `transfer` | Copy data from source to target (requires FastTransfer) | After tables are created | | `diff` | Validate data integrity by comparing row counts between source and target | After transfer | | `copy_pk` | Copy primary key constraints to the target database | After transfer | | `copy_ak` | Copy alternate key (unique) constraints to the target database | After primary keys | | `copy_fk` | Copy foreign key constraints to the target database | After all other keys | ## Task Dependencies and Recommended Order[​](#task-dependencies-and-recommended-order "Direct link to Task Dependencies and Recommended Order") Tasks should follow a logical sequence. Running them out of order will cause failures -- for example, `transfer` fails if the target tables do not exist yet. **Recommended full migration order:** ``` translate → create → transfer → diff → copy_pk → copy_ak → copy_fk ``` The `diff` task is optional but recommended. It provides a quick sanity check before committing to constraint creation. Constraint copying limitations Constraint copying (`copy_pk`, `copy_ak`, `copy_fk`) is currently supported only for Oracle to SQL Server migrations. For other migration paths, create constraints manually on the target database after the data transfer. ## Common Task Combinations[​](#common-task-combinations "Direct link to Common Task Combinations") ### Full Migration[​](#full-migration "Direct link to Full Migration") Translate the schema, create tables, transfer data, and validate: ``` --task_list translate create transfer diff ``` ### Schema Only[​](#schema-only "Direct link to Schema Only") Translate and create tables without transferring data. Useful for validating the DDL translation before committing to a full migration: ``` --task_list translate create ``` ### Data Only[​](#data-only "Direct link to Data Only") Transfer data into existing tables. The schema must already exist in the target database: ``` --task_list transfer ``` ### Data Append (Load Mode)[​](#data-append-load-mode "Direct link to Data Append (Load Mode)") Transfer data without dropping or truncating existing tables. Use `--load_mode append` to insert rows into existing tables: ``` --task_list transfer --load_mode append ``` ### Constraints Only[​](#constraints-only "Direct link to Constraints Only") Copy constraints after a successful data transfer. Run this as a separate step to avoid constraint violations during the initial load: ``` --task_list copy_pk copy_ak copy_fk ``` ## Migration Database Modes[​](#migration-database-modes "Direct link to Migration Database Modes") The `--drop_tables_if_exists` parameter controls how MigratorXpress handles existing tables in the target database: | Value | Behavior | | ------- | ------------------------------------------------ | | `true` | Drop and recreate target tables before migration | | `false` | Fail if target tables already exist (default) | For iterative development and testing, `--drop_tables_if_exists true` is convenient. For production migrations, leave it as `false` and manage table lifecycle explicitly. ## Resume Functionality[​](#resume-functionality "Direct link to Resume Functionality") If a migration fails partway through, you can resume from the point of failure instead of starting over: ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id oracle_prod \ --source_db_name ORCL \ --target_db_auth_id postgres_dev \ --target_db_name tpch \ --migration_db_auth_id ms_mig_log \ --resume 20260203-cf5be0ac-159f-4dad-861e-8b2b6f3868d7 ``` MigratorXpress skips tasks and tables that already completed successfully and resumes from the first incomplete item. Since v0.6.22, you do not need to specify `--task_list` or `--source_schema_name` when resuming -- they are retrieved automatically from the migration database. tip The run ID is displayed in the console output when the migration starts (format: `YYYYMMDD-{uuid}`). You can also query the migration tracking database to find it. ## Full Example[​](#full-example "Direct link to Full Example") A complete Oracle-to-PostgreSQL migration in two steps -- first data, then constraints: ``` # Step 1: Schema, data, and validation ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id oracle_prod \ --source_schema_name SALES \ --target_db_auth_id postgres_dev \ --target_schema_name sales \ --migration_db_auth_id ms_mig_log \ --n_jobs 4 \ --fasttransfer_p 2 \ --drop_tables_if_exists true \ --task_list translate create transfer diff # Step 2: Constraints (after verifying diff results) ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id oracle_prod \ --source_schema_name SALES \ --target_db_auth_id postgres_dev \ --target_schema_name sales \ --migration_db_auth_id ms_mig_log \ --task_list copy_pk copy_ak copy_fk ``` ## See Also[​](#see-also "Direct link to See Also") * [FastTransfer Configuration](/0.6/configuration/fasttransfer-configuration.md) -- Parallel transfer tuning and performance * [Database Connections](/0.6/configuration/database-configuration.md) -- Auth file configuration * [Quick Start Guide](/0.6/guides/quickstart.md) -- Getting started with MigratorXpress * [CLI Reference](/0.6/reference/cli-reference.md) -- Full command-line reference --- # Examples and use cases Complete command examples for every supported migration path, plus advanced scenarios. Each example assumes you already have a `credentials.json` file configured (see the [Quick Start Guide](/0.6/guides/quickstart.md)). *** ## Oracle to PostgreSQL[​](#oracle-to-postgresql "Direct link to Oracle to PostgreSQL") Full schema and data migration with validation. ### Linux[​](#linux "Direct link to Linux") ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id oracle_prod \ --source_schema_name HR \ --target_db_auth_id postgres_dev \ --target_schema_name hr \ --migration_db_auth_id ms_mig_log \ --n_jobs 4 \ --fasttransfer_p 2 \ --drop_tables_if_exists true \ --task_list translate create transfer diff ``` ### Windows (PowerShell)[​](#windows-powershell "Direct link to Windows (PowerShell)") ``` .\MigratorXpress.exe --auth .\credentials.json ` --source_db_auth_id oracle_prod ` --source_schema_name HR ` --target_db_auth_id postgres_dev ` --target_schema_name hr ` --migration_db_auth_id ms_mig_log ` --n_jobs 4 ` --fasttransfer_p 2 ` --drop_tables_if_exists true ` --task_list translate create transfer diff ``` *** ## Oracle to SQL Server[​](#oracle-to-sql-server "Direct link to Oracle to SQL Server") Two-phase approach: transfer data first, then add constraints. ### Phase 1: Schema and data[​](#phase-1-schema-and-data "Direct link to Phase 1: Schema and data") #### Linux[​](#linux-1 "Direct link to Linux") ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id oracle_prod \ --source_schema_name FINANCE \ --target_db_auth_id mssql_target \ --target_schema_name finance \ --migration_db_auth_id ms_mig_log \ --n_jobs 4 \ --fasttransfer_p 2 \ --drop_tables_if_exists true \ --task_list translate create transfer diff ``` #### Windows (PowerShell)[​](#windows-powershell-1 "Direct link to Windows (PowerShell)") ``` .\MigratorXpress.exe --auth .\credentials.json ` --source_db_auth_id oracle_prod ` --source_schema_name FINANCE ` --target_db_auth_id mssql_target ` --target_schema_name finance ` --migration_db_auth_id ms_mig_log ` --n_jobs 4 ` --fasttransfer_p 2 ` --drop_tables_if_exists true ` --task_list translate create transfer diff ``` ### Phase 2: Constraints[​](#phase-2-constraints "Direct link to Phase 2: Constraints") #### Linux[​](#linux-2 "Direct link to Linux") ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id oracle_prod \ --source_schema_name FINANCE \ --target_db_auth_id mssql_target \ --target_schema_name finance \ --migration_db_auth_id ms_mig_log \ --task_list copy_pk copy_ak copy_fk ``` #### Windows (PowerShell)[​](#windows-powershell-2 "Direct link to Windows (PowerShell)") ``` .\MigratorXpress.exe --auth .\credentials.json ` --source_db_auth_id oracle_prod ` --source_schema_name FINANCE ` --target_db_auth_id mssql_target ` --target_schema_name finance ` --migration_db_auth_id ms_mig_log ` --task_list copy_pk copy_ak copy_fk ``` *** ## PostgreSQL to PostgreSQL[​](#postgresql-to-postgresql "Direct link to PostgreSQL to PostgreSQL") Clone a schema across servers or within the same server. ### Linux[​](#linux-3 "Direct link to Linux") ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id postgres_prod \ --source_schema_name public \ --target_db_auth_id postgres_staging \ --target_schema_name public_copy \ --migration_db_auth_id ms_mig_log \ --n_jobs 4 \ --fasttransfer_p 2 \ --drop_tables_if_exists true \ --task_list translate create transfer diff ``` ### Windows (PowerShell)[​](#windows-powershell-3 "Direct link to Windows (PowerShell)") ``` .\MigratorXpress.exe --auth .\credentials.json ` --source_db_auth_id postgres_prod ` --source_schema_name public ` --target_db_auth_id postgres_staging ` --target_schema_name public_copy ` --migration_db_auth_id ms_mig_log ` --n_jobs 4 ` --fasttransfer_p 2 ` --drop_tables_if_exists true ` --task_list translate create transfer diff ``` *** ## PostgreSQL to SQL Server[​](#postgresql-to-sql-server "Direct link to PostgreSQL to SQL Server") ### Linux[​](#linux-4 "Direct link to Linux") ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id postgres_prod \ --source_schema_name analytics \ --target_db_auth_id mssql_target \ --target_schema_name analytics \ --migration_db_auth_id ms_mig_log \ --n_jobs 4 \ --fasttransfer_p 2 \ --drop_tables_if_exists true \ --task_list translate create transfer diff ``` ### Windows (PowerShell)[​](#windows-powershell-4 "Direct link to Windows (PowerShell)") ``` .\MigratorXpress.exe --auth .\credentials.json ` --source_db_auth_id postgres_prod ` --source_schema_name analytics ` --target_db_auth_id mssql_target ` --target_schema_name analytics ` --migration_db_auth_id ms_mig_log ` --n_jobs 4 ` --fasttransfer_p 2 ` --drop_tables_if_exists true ` --task_list translate create transfer diff ``` *** ## SQL Server to PostgreSQL[​](#sql-server-to-postgresql "Direct link to SQL Server to PostgreSQL") ### Linux[​](#linux-5 "Direct link to Linux") ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id mssql_source \ --source_schema_name dbo \ --target_db_auth_id postgres_dev \ --target_schema_name dbo_migrated \ --migration_db_auth_id ms_mig_log \ --n_jobs 4 \ --fasttransfer_p 2 \ --drop_tables_if_exists true \ --task_list translate create transfer diff ``` ### Windows (PowerShell)[​](#windows-powershell-5 "Direct link to Windows (PowerShell)") ``` .\MigratorXpress.exe --auth .\credentials.json ` --source_db_auth_id mssql_source ` --source_schema_name dbo ` --target_db_auth_id postgres_dev ` --target_schema_name dbo_migrated ` --migration_db_auth_id ms_mig_log ` --n_jobs 4 ` --fasttransfer_p 2 ` --drop_tables_if_exists true ` --task_list translate create transfer diff ``` *** ## Netezza to PostgreSQL[​](#netezza-to-postgresql "Direct link to Netezza to PostgreSQL") ### Linux[​](#linux-6 "Direct link to Linux") ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id netezza_source \ --source_schema_name ADMIN \ --target_db_auth_id postgres_dev \ --target_schema_name admin \ --migration_db_auth_id ms_mig_log \ --n_jobs 4 \ --fasttransfer_p 2 \ --drop_tables_if_exists true \ --task_list translate create transfer diff ``` ### Windows (PowerShell)[​](#windows-powershell-6 "Direct link to Windows (PowerShell)") ``` .\MigratorXpress.exe --auth .\credentials.json ` --source_db_auth_id netezza_source ` --source_schema_name ADMIN ` --target_db_auth_id postgres_dev ` --target_schema_name admin ` --migration_db_auth_id ms_mig_log ` --n_jobs 4 ` --fasttransfer_p 2 ` --drop_tables_if_exists true ` --task_list translate create transfer diff ``` *** ## Netezza to SQL Server[​](#netezza-to-sql-server "Direct link to Netezza to SQL Server") ### Linux[​](#linux-7 "Direct link to Linux") ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id netezza_source \ --source_schema_name WAREHOUSE \ --target_db_auth_id mssql_target \ --target_schema_name warehouse \ --migration_db_auth_id ms_mig_log \ --n_jobs 4 \ --fasttransfer_p 2 \ --drop_tables_if_exists true \ --task_list translate create transfer diff ``` ### Windows (PowerShell)[​](#windows-powershell-7 "Direct link to Windows (PowerShell)") ``` .\MigratorXpress.exe --auth .\credentials.json ` --source_db_auth_id netezza_source ` --source_schema_name WAREHOUSE ` --target_db_auth_id mssql_target ` --target_schema_name warehouse ` --migration_db_auth_id ms_mig_log ` --n_jobs 4 ` --fasttransfer_p 2 ` --drop_tables_if_exists true ` --task_list translate create transfer diff ``` *** ## SQL Server to SQL Server[​](#sql-server-to-sql-server "Direct link to SQL Server to SQL Server") Clone or migrate schemas between SQL Server instances. ### Linux[​](#linux-8 "Direct link to Linux") ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id mssql_source \ --source_schema_name dbo \ --target_db_auth_id mssql_target \ --target_schema_name dbo \ --migration_db_auth_id ms_mig_log \ --n_jobs 4 \ --fasttransfer_p 2 \ --drop_tables_if_exists true \ --task_list translate create transfer diff ``` ### Windows (PowerShell)[​](#windows-powershell-8 "Direct link to Windows (PowerShell)") ``` .\MigratorXpress.exe --auth .\credentials.json ` --source_db_auth_id mssql_source ` --source_schema_name dbo ` --target_db_auth_id mssql_target ` --target_schema_name dbo ` --migration_db_auth_id ms_mig_log ` --n_jobs 4 ` --fasttransfer_p 2 ` --drop_tables_if_exists true ` --task_list translate create transfer diff ``` *** ## Advanced scenarios[​](#advanced-scenarios "Direct link to Advanced scenarios") ### Incremental data sync[​](#incremental-data-sync "Direct link to Incremental data sync") Re-run only the `transfer` and `diff` tasks to refresh data without recreating tables. Useful for periodic syncs during a phased migration. ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id oracle_prod \ --source_schema_name SALES \ --target_db_auth_id postgres_dev \ --target_schema_name sales \ --migration_db_auth_id ms_mig_log \ --n_jobs 4 \ --fasttransfer_p 2 \ --drop_tables_if_exists true \ --task_list transfer diff ``` tip Use `--drop_tables_if_exists true` with `transfer` to truncate and reload. Omit it if the target tables support upsert logic in your workflow. ### Schema-only migration[​](#schema-only-migration "Direct link to Schema-only migration") Translate and create the schema without transferring any data. Useful for reviewing the translated DDL before committing to a full migration. ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id oracle_prod \ --source_schema_name INVENTORY \ --target_db_auth_id postgres_dev \ --target_schema_name inventory \ --migration_db_auth_id ms_mig_log \ --drop_tables_if_exists true \ --task_list translate create ``` ### Parallel large tables[​](#parallel-large-tables "Direct link to Parallel large tables") For schemas with very large tables, increase both parallelism levels: ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id oracle_prod \ --source_schema_name EVENTS \ --target_db_auth_id postgres_dev \ --target_schema_name events \ --migration_db_auth_id ms_mig_log \ --n_jobs 8 \ --fasttransfer_p 4 \ --drop_tables_if_exists true \ --task_list translate create transfer diff ``` * `--n_jobs 8` migrates up to 8 tables concurrently. * `--fasttransfer_p 4` splits each table into 4 partitions for parallel transfer. warning Higher parallelism increases load on both the source and target databases. Monitor CPU and I/O during large migrations and adjust values as needed. ### Multi-schema patterns[​](#multi-schema-patterns "Direct link to Multi-schema patterns") Migrate multiple schemas in one run (v0.6.12+): ``` # All schemas starting with "app_" ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id oracle_prod \ --source_schema_name "app_%" \ --target_db_auth_id postgres_dev \ --target_schema_name "app_%" \ --migration_db_auth_id ms_mig_log \ --n_jobs 4 \ --drop_tables_if_exists true \ --task_list translate create transfer diff ``` ``` # Every schema in the database ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id oracle_prod \ --source_schema_name "%" \ --target_db_auth_id postgres_dev \ --target_schema_name "%" \ --migration_db_auth_id ms_mig_log \ --n_jobs 4 \ --drop_tables_if_exists true \ --task_list translate create transfer diff ``` *** ## Best practices[​](#best-practices "Direct link to Best practices") 1. **Migrate data before constraints.** Run `translate create transfer diff` first, then `copy_pk copy_ak copy_fk` in a separate step. This avoids constraint-violation errors during bulk loading. 2. **Start with a small schema.** Test the full workflow on a schema with a few tables before migrating a large production database. 3. **Use `diff` to validate.** Always include `diff` in your task list to verify row counts match between source and target. 4. **Tune parallelism gradually.** Begin with `--n_jobs 2 --fasttransfer_p 2` and increase based on observed throughput and system load. 5. **Secure your credentials file.** Use `$env{VAR_NAME}` references instead of plain-text passwords, and restrict file permissions to the migration user. 6. **Review translated DDL.** Run a `translate`-only step first to inspect the generated DDL before creating tables on the target. ## Next steps[​](#next-steps "Direct link to Next steps") * [Quick Start Guide](/0.6/guides/quickstart.md) -- step-by-step setup * [CLI Reference](/0.6/reference/cli-reference.md) -- all available options and flags * [Command Wizard](/0.6/wizard.md) -- build your command interactively --- # Quick start guide Three steps: create a credentials file, run a full migration, then add constraints. ## Prerequisites[​](#prerequisites "Direct link to Prerequisites") 1. **MigratorXpress binary** (Windows or Linux) downloaded from [arpe.io](https://www.arpe.io/migratorxpress/) 2. **Database access** -- read access on the source, write access on the target, and a SQL Server database for migration tracking 3. **FastTransfer binary** (>= 0.15.0) -- MigratorXpress calls FastTransfer for data movement. Trial distributions include FastTransfer in the `engine/` directory. Otherwise, place it in a known directory and pass `--fasttransfer_dir_path` ## Step 1: Create a credentials file[​](#step-1-create-a-credentials-file "Direct link to Step 1: Create a credentials file") Save the connection details for every database involved in the migration. Each entry has a unique ID that you reference on the command line. ``` { "oracle_prod": { "ds_type": "oracle", "auth_mode": "classic", "info": { "username": "$env{ORA_USER}", "password": "$env{ORA_PASSWORD}", "server": "oracle-host.example.com", "port": 1521, "database": "ORCL" } }, "postgres_dev": { "ds_type": "postgres", "auth_mode": "classic", "info": { "username": "$env{PG_USER}", "password": "$env{PG_PASSWORD}", "server": "pg-host.example.com", "port": 5432, "database": "analytics" } }, "mssql_target": { "ds_type": "mssql", "auth_mode": "classic", "info": { "username": "$env{MSSQL_USER}", "password": "$env{MSSQL_PASSWORD}", "server": "sql-host.example.com", "port": 1433, "database": "target_db" } }, "ms_mig_log": { "ds_type": "mssql", "auth_mode": "classic", "info": { "username": "$env{MIG_LOG_USER}", "password": "$env{MIG_LOG_PASSWORD}", "server": "sql-host.example.com", "port": 1433, "database": "migration_log" } }, "netezza_source": { "ds_type": "netezza", "auth_mode": "classic", "info": { "username": "$env{NZ_USER}", "password": "$env{NZ_PASSWORD}", "server": "nz-host.example.com", "port": 5480, "database": "PROD_DB" } } } ``` Save the file as `credentials.json` in a secure location. Environment variables Use `$env{VAR_NAME}` in any string value to reference an environment variable at runtime. MigratorXpress raises an error if the variable is not set. Plain-text values also work if you prefer. ``` # Linux export ORA_USER="system" export ORA_PASSWORD="your_password" # Windows (PowerShell) $env:ORA_USER = "system" $env:ORA_PASSWORD = "your_password" ``` ## Step 2: Run a full migration[​](#step-2-run-a-full-migration "Direct link to Step 2: Run a full migration") Migrate an Oracle schema to PostgreSQL -- translate the DDL, create tables, transfer data, and validate. ### Linux[​](#linux "Direct link to Linux") ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id oracle_prod \ --source_schema_name SALES \ --target_db_auth_id postgres_dev \ --target_schema_name sales \ --migration_db_auth_id ms_mig_log \ --n_jobs 4 \ --fasttransfer_p 2 \ --drop_tables_if_exists true \ --task_list translate create transfer diff ``` ### Windows (PowerShell)[​](#windows-powershell "Direct link to Windows (PowerShell)") ``` .\MigratorXpress.exe --auth .\credentials.json ` --source_db_auth_id oracle_prod ` --source_schema_name SALES ` --target_db_auth_id postgres_dev ` --target_schema_name sales ` --migration_db_auth_id ms_mig_log ` --n_jobs 4 ` --fasttransfer_p 2 ` --drop_tables_if_exists true ` --task_list translate create transfer diff ``` The `task_list` parameter controls which steps run. The four tasks above cover schema translation, table creation, data transfer, and row-count validation. ## Step 3: Add constraints[​](#step-3-add-constraints "Direct link to Step 3: Add constraints") Once data is transferred and validated, copy primary keys, alternate keys, and foreign keys in a separate step. This avoids constraint violations during the initial load. ### Linux[​](#linux-1 "Direct link to Linux") ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id oracle_prod \ --source_schema_name SALES \ --target_db_auth_id postgres_dev \ --target_schema_name sales \ --migration_db_auth_id ms_mig_log \ --task_list copy_pk copy_ak copy_fk ``` ### Windows (PowerShell)[​](#windows-powershell-1 "Direct link to Windows (PowerShell)") ``` .\MigratorXpress.exe --auth .\credentials.json ` --source_db_auth_id oracle_prod ` --source_schema_name SALES ` --target_db_auth_id postgres_dev ` --target_schema_name sales ` --migration_db_auth_id ms_mig_log ` --task_list copy_pk copy_ak copy_fk ``` ## Advanced: Multi-schema migration[​](#advanced-multi-schema-migration "Direct link to Advanced: Multi-schema migration") Starting with v0.6.12, you can migrate multiple schemas in one run using SQL `LIKE` patterns for `--source_schema_name`: ### Linux[​](#linux-2 "Direct link to Linux") ``` # Migrate all schemas starting with "app_" ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id oracle_prod \ --source_schema_name "app_%" \ --target_db_auth_id postgres_dev \ --target_schema_name "app_%" \ --migration_db_auth_id ms_mig_log \ --n_jobs 4 \ --drop_tables_if_exists true \ --task_list translate create transfer diff ``` ### Windows (PowerShell)[​](#windows-powershell-2 "Direct link to Windows (PowerShell)") ``` # Migrate all schemas starting with "app_" .\MigratorXpress.exe --auth .\credentials.json ` --source_db_auth_id oracle_prod ` --source_schema_name "app_%" ` --target_db_auth_id postgres_dev ` --target_schema_name "app_%" ` --migration_db_auth_id ms_mig_log ` --n_jobs 4 ` --drop_tables_if_exists true ` --task_list translate create transfer diff ``` Pattern examples: * `app_%` -- all schemas starting with `app_` * `%_prod` -- all schemas ending with `_prod` * `%` -- every schema in the database ## Next steps[​](#next-steps "Direct link to Next steps") * [CLI Reference](/0.6/reference/cli-reference.md) -- all available options and flags * [Examples & Use Cases](/0.6/guides/examples.md) -- real-world migration scenarios * [Command Wizard](/0.6/wizard.md) -- build your command interactively --- # CLI Reference Complete reference for every MigratorXpress command-line argument. ## Basic Usage[​](#basic-usage "Direct link to Basic Usage") ``` ./MigratorXpress [OPTIONS] ``` MigratorXpress runs as a single command. On Windows, use `.\MigratorXpress.exe`. ## Authentication[​](#authentication "Direct link to Authentication") | Option | Type | Required | Description | | ------------------- | ---- | -------- | --------------------------------- | | `-a`, `--auth PATH` | Path | Yes | Path to the JSON credentials file | The credentials file contains connection details for every database involved in the migration. Each entry has a unique ID that you reference with other flags. See [Credentials File Format](#credentials-file-format) below. ## Source Database[​](#source-database "Direct link to Source Database") | Option | Type | Required | Description | | ------------------------------ | ------ | -------- | ---------------------------------------------------------------------------- | | `--source_db_auth_id ID` | String | Yes | Source database identifier in the credentials file | | `--source_db_name NAME` | String | Yes | Source database name (e.g., `orclpdb1`, `tpch`) | | `--source_schema_name PATTERN` | String | No | Source schema name, pattern, or comma-separated list. All schemas if omitted | ### Schema selection[​](#schema-selection "Direct link to Schema selection") The `--source_schema_name` flag supports three modes: **Single schema:** ``` --source_schema_name SALES ``` **SQL LIKE patterns (v0.6.12+):** ``` # All schemas starting with "app_" --source_schema_name "app_%" # Multiple patterns --source_schema_name "APP_%, TENANT_%" ``` **Exact comma-separated list (v0.6.21+):** ``` # Multiple specific schemas without wildcards --source_schema_name "tpch_1, tpch_2, tpch_3" ``` When omitted, MigratorXpress discovers and migrates all visible schemas in the source database. When using patterns or lists, target schemas are created automatically with the same names as the source schemas. The `--target_schema_name` flag is only used for single-schema migrations. ## Target Database[​](#target-database "Direct link to Target Database") | Option | Type | Required | Description | | --------------------------- | ------ | -------- | -------------------------------------------------------------------------- | | `--target_db_auth_id ID` | String | Yes | Target database identifier in the credentials file | | `--target_db_name NAME` | String | Yes | Target database name | | `--target_schema_name NAME` | String | No | Target schema name. Defaults to source schema name. Not used with patterns | Supported targets: PostgreSQL and SQL Server. See the [compatibility matrix](/0.6/compatibility.md). ## Migration Database[​](#migration-database "Direct link to Migration Database") | Option | Type | Required | Description | | --------------------------- | ------ | -------- | ----------------------------------------------------- | | `--migration_db_auth_id ID` | String | Yes | SQL Server database identifier for migration tracking | The migration database must be a SQL Server instance. MigratorXpress creates its tracking tables automatically on first use. ## Task Control[​](#task-control "Direct link to Task Control") | Option | Type | Description | | ---------------------- | --------- | ---------------------------------------- | | `--task_list TASKS...` | String(s) | Space-separated list of tasks to execute | Tasks run in the order specified. Available tasks: `translate`, `create`, `transfer`, `diff`, `copy_pk`, `copy_ak`, `copy_fk`, or `all`. Use `all` as a shortcut for the full sequence: `translate create transfer diff copy_pk copy_ak copy_fk`. ``` # Full migration --task_list translate create transfer diff # Schema only --task_list translate create # Data only (tables already exist) --task_list transfer # Constraints only (after data is loaded) --task_list copy_pk copy_ak copy_fk # Everything --task_list all ``` Constraint copying limitations Constraint copying (`copy_pk`, `copy_ak`, `copy_fk`) is currently supported only for **Oracle to SQL Server** migrations. For other migration paths, create constraints manually on the target database. ## Resume Operations[​](#resume-operations "Direct link to Resume Operations") | Option | Type | Description | | ------------------------------ | ------ | ---------------------------------------------------------- | | `-r RUN_ID`, `--resume RUN_ID` | String | Resume a previously interrupted migration using its run ID | When a migration is interrupted, use `--resume` with the run ID to pick up from the last completed step. Only tables that did not finish successfully are re-processed. Since v0.6.22, resume automatically retrieves the original task list and schema names from the migration database. You do not need to specify `--task_list` or `--source_schema_name` when resuming. ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id ds_09_ms \ --source_db_name tpch \ --target_db_auth_id ds_04_pg \ --target_db_name tpch \ --migration_db_auth_id ds_02_ms \ --resume 20260203-cf5be0ac-159f-4dad-861e-8b2b6f3868d7 ``` The run ID is displayed in the console output when a migration starts (format: `YYYYMMDD-{uuid}`). You can also query the migration tracking database to find it. ## Run Tagging[​](#run-tagging "Direct link to Run Tagging") | Option | Type | Description | | ---------------- | ------ | --------------------------------------------------------------------------------------- | | `--project NAME` | String | Optional project tag attached to every row this run writes in the migration tracking DB | Since v0.6.30, a user-supplied `--project` tag groups runs that belong to the same engagement. The tag is stored alongside `run_id` on `sourcetargetloads`, `eventlog`, and `sourcetargetdiff`, making all runs for a given project retrievable with a single SQL filter weeks or months later. ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id ds_09_ms --source_db_name tpch \ --target_db_auth_id ds_04_pg --target_db_name tpch \ --migration_db_auth_id ds_02_ms \ --task_list all \ --project bob_bods_oracle ``` Then, to find every run tagged with that project: ``` SELECT DISTINCT eventrunid FROM eventlog WHERE project = 'bob_bods_oracle'; ``` **Validation:** 1–64 characters, letters, digits, underscore, or hyphen only (e.g. `bob_bods_oracle`, `cust-2026-q2`). Invalid values are rejected at CLI parse time, before any database write. **Optional and backward compatible:** Runs without `--project` store `NULL`. Existing tracking databases are auto-upgraded with the new columns on the next startup via idempotent `ALTER TABLE … ADD COLUMN` statements. **`mxp_init` also accepts `--project`** for the discovery phase. Immutable per run\_id On `--resume`, any `--project` value on the command line is ignored with a warning, and the original run's tag is inherited from the migration DB. This keeps every row for a given `run_id` tagged consistently, even across multiple resumes. ## FastTransfer[​](#fasttransfer "Direct link to FastTransfer") | Option | Type | Default | Description | | ------------------------------ | ------- | ------------- | --------------------------------------------------------- | | `--fasttransfer_dir_path PATH` | Path | Auto-detected | Directory containing the FastTransfer binary | | `-p`, `--fasttransfer_p INT` | Integer | 1 | Parallel streams per large table (Ctid/Rowid/NZDataSlice) | | `--ft_large_table_th INT` | Integer | 250,000,000 | Row count threshold for parallel transfer methods | MigratorXpress delegates all data movement to [FastTransfer](https://www.arpe.io/fasttransfer/). FastTransfer >= 0.15.0 is required; the version is validated at startup. Since v0.6.25, if `--fasttransfer_dir_path` is omitted, MigratorXpress auto-detects a bundled FastTransfer in the `engine/` subdirectory next to the binary. Trial distributions ship with FastTransfer pre-bundled. ``` # Explicit path --fasttransfer_dir_path ./FastTransfer_linux-x64_v0.15.0/ # Or omit to use the bundled engine/ directory ``` ### Parallel transfer methods[​](#parallel-transfer-methods "Direct link to Parallel transfer methods") Tables with row count >= `--ft_large_table_th` and `--fasttransfer_p` > 1 use database-specific parallel methods: | Source Database | Method | Description | | --------------- | ----------- | --------------------------------------------------------- | | PostgreSQL | Ctid | Splits by physical tuple ID | | Oracle | Rowid | Splits by physical ROWID (requires `SELECT_CATALOG_ROLE`) | | Netezza | NZDataSlice | Splits by internal data slice distribution | | SQL Server | Standard | No physical partitioning; parallelism via `--n_jobs` only | ## Performance[​](#performance "Direct link to Performance") | Option | Type | Default | Description | | ----------------------- | ------- | ------- | ----------------------------------------------------------------- | | `--n_jobs INT` | Integer | 1 | Number of tables to process in parallel | | `--compute_nbrows BOOL` | Boolean | false | Use `COUNT(*)` for exact row counts instead of database estimates | | `--without_xid` | Flag | false | Disable transaction ID usage for Netezza and Oracle | `--n_jobs` controls table-level parallelism (how many tables transfer simultaneously). Combined with `--fasttransfer_p`, this gives dual-level parallelism: ``` # 4 tables at once, each large table split into 2 parallel streams --n_jobs 4 --fasttransfer_p 2 ``` ## Table Filtering[​](#table-filtering "Direct link to Table Filtering") | Option | Type | Default | Description | | -------------------------------- | ------- | ------------- | ------------------------------------------------------------------ | | `-i`, `--include_tables PATTERN` | String | `%` (all) | Include only tables matching SQL `LIKE` patterns (comma-separated) | | `-e`, `--exclude_tables PATTERN` | String | None | Exclude tables matching SQL `LIKE` patterns (comma-separated) | | `-min`, `--min_rows NROWS` | Integer | -1 (disabled) | Exclude tables with fewer rows than this value | | `-max`, `--max_rows NROWS` | Integer | -1 (disabled) | Exclude tables with row count >= this value | Exclude patterns are applied after include patterns. Filters are pushed to SQL level for performance (v0.6.12+). ``` # Include only tables starting with "fact_" or "dim_" -i "fact_%,dim_%" # Spaces after commas are trimmed automatically -i "fact_%, dim_%" # Exclude temporary and test tables -e "tmp_%,test_%" # Combine filters -i "%" -e "tmp_%,log_%" -min 100 -max 10000000 ``` Shell quoting Quote the entire comma-separated string as one argument. Do not quote each pattern separately: ``` # CORRECT -i "fact_%,dim_%" # WRONG — shell interprets as multiple arguments -i 'fact_%','dim_%' ``` ## Migration Options[​](#migration-options "Direct link to Migration Options") | Option | Type | Default | Description | | ------------------------------ | ------- | ---------- | ------------------------------------------------------------------------------------------------------------- | | `--drop_tables_if_exists BOOL` | Boolean | false | Drop target tables before creating them | | `--load_mode MODE` | String | `truncate` | `truncate`: clear target before loading. `append`: add rows without clearing | | `--migration_db_mode MODE` | String | `preserve` | `preserve`: keep tracking data (enables resume). `truncate`: clear data, keep schema. `drop`: recreate schema | | `--basic_diff` | Flag | false | Row/column count comparison only (skip content-level diff) | | `-f`, `--force` | Flag | false | Force migration by cleaning existing tracking data for these schemas | ## SQL Server Target Options[​](#sql-server-target-options "Direct link to SQL Server Target Options") These options apply only when the target database is SQL Server. | Option | Type | Default | Description | | --------------------- | ------- | ----------- | ------------------------------------------------------------------- | | `--cci_threshold INT` | Integer | 1,000,000 | Create Clustered Columnstore Index for tables above this row count | | `--aci_threshold INT` | Integer | 100,000,000 | Use archive compression (COLUMNSTORE\_ARCHIVE) above this row count | | `--fk_mode MODE` | String | `disabled` | Foreign key enforcement: `disabled`, `untrusted`, or `trusted` | **Columnstore behavior:** * Tables >= `cci_threshold` but < `aci_threshold`: Standard Clustered Columnstore Index * Tables >= `aci_threshold`: CCI with `DATA_COMPRESSION = COLUMNSTORE_ARCHIVE` * Tables < `cci_threshold`: Standard rowstore **Foreign key modes:** * `disabled` (default): FK constraints created with `WITH NOCHECK` and disabled. Fastest for loading. * `untrusted`: FK constraints created with `WITH NOCHECK` but left enabled. Enforced for new data only. * `trusted`: Standard FK constraints with full enforcement. Slowest but provides complete referential integrity. ## Oracle Source Options[​](#oracle-source-options "Direct link to Oracle Source Options") These options apply only when the source database is Oracle. | Option | Type | Default | Description | | -------------------------------- | --------- | ------- | -------------------------------------------------------------------------------------- | | `--forced_int_id_prefixes S...` | String(s) | None | Space-separated column name prefixes to force as integer type | | `--forced_int_id_suffixes S...` | String(s) | None | Space-separated column name suffixes to force as integer type | | `--profiling_sample_pc NUMBER` | Integer | 10 | Percentage of rows to sample for Oracle DATE/NUMBER profiling | | `--min_sample_pc_profile NUMBER` | Integer | 100,000 | Row count threshold below which tables are profiled in full (no sampling) | | `--p_query NUMBER` | Integer | 6 | Inner level of query parallelism for Oracle profiling queries (`PARALLEL` hint degree) | Oracle stores many integer values in `NUMBER` columns without precision. MigratorXpress profiles DATE and NUMBER columns to select optimal target types. Use `--forced_int_id_prefixes` and `--forced_int_id_suffixes` to skip profiling for known ID columns: ``` # Space-separated, case-insensitive matching --forced_int_id_prefixes ID_ PK_ KEY_ \ --forced_int_id_suffixes _ID _KEY _PK ``` **Sampling behavior:** * Tables >= `min_sample_pc_profile` rows: sampled at `profiling_sample_pc`% using Oracle `SAMPLE(n)` * Tables < `min_sample_pc_profile` rows: profiled in full * Set `--profiling_sample_pc 100` to disable sampling ## Logging Options[​](#logging-options "Direct link to Logging Options") | Option | Type | Default | Description | | ------------------- | ------ | ----------------- | --------------------------------------------------------------------------- | | `--log_level LEVEL` | String | `INFO` | Log verbosity: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL` | | `--log_dir PATH` | Path | Current directory | Directory for log files | | `--no_banner` | Flag | false | Suppress the startup banner | | `--no_progress` | Flag | false | Disable the progress bar | | `--quiet_ft` | Flag | false | Suppress FastTransfer subprocess output from console (still logged to file) | See [Logging and Monitoring](/0.6/reference/logging.md) for details on log format and database logging. ## License Management[​](#license-management "Direct link to License Management") | Option | Type | Description | | --------------------- | ------ | --------------------------- | | `--license TEXT` | String | License text (ECDSA signed) | | `--license_file PATH` | Path | Path to license file | **License sources (in order of precedence):** 1. `--license` command-line argument 2. `--license_file` command-line argument 3. `MIGRATORXPRESS_LICENSE` environment variable 4. Default location: `~/.migratorxpress/license.key` (Linux) or `%APPDATA%/MigratorXpress/license.key` (Windows) 5. Trial mode (automatic fallback) Trial mode provides all features without restrictions and is suitable for evaluation. ## Utility[​](#utility "Direct link to Utility") | Option | Description | | -------------- | --------------------------------------- | | `--version` | Display MigratorXpress version and exit | | `-h`, `--help` | Show help message and exit | ## Database Parameters[​](#database-parameters "Direct link to Database Parameters") ### Connection parameters by database type[​](#connection-parameters-by-database-type "Direct link to Connection parameters by database type") | Parameter | Oracle | PostgreSQL | SQL Server | Netezza | | ----------- | ---------------- | ------------------- | ------------------- | ------------- | | `ds_type` | `oracle` | `postgres` | `mssql` | `netezza` | | `auth_mode` | `classic` | `classic` or `odbc` | `classic` or `odbc` | `classic` | | `username` | Required | Required | Required | Required | | `password` | Required | Required | Required | Required | | `server` | Required | Required | Required | Required | | `port` | 1521 | 5432 | 1433 | 5480 | | `database` | Service name/SID | Database name | Database name | Database name | | `lib_dir` | Thick mode only | -- | -- | -- | ## Credentials File Format[​](#credentials-file-format "Direct link to Credentials File Format") The credentials file is a JSON object where each key is an identifier you reference on the command line. ``` { "oracle_prod": { "ds_type": "oracle", "auth_mode": "classic", "info": { "username": "$env{ORA_USER}", "password": "$env{ORA_PASSWORD}", "server": "oracle-host.example.com", "port": 1521, "database": "ORCL" } }, "postgres_dev": { "ds_type": "postgres", "auth_mode": "classic", "info": { "username": "$env{PG_USER}", "password": "$env{PG_PASSWORD}", "server": "pg-host.example.com", "port": 5432, "database": "analytics" } }, "ms_mig_log": { "ds_type": "mssql", "auth_mode": "classic", "info": { "username": "$env{MIG_USER}", "password": "$env{MIG_PASSWORD}", "server": "sql-host.example.com", "port": 1433, "database": "migration_log" } }, "netezza_source": { "ds_type": "netezza", "auth_mode": "classic", "info": { "username": "$env{NZ_USER}", "password": "$env{NZ_PASSWORD}", "server": "nz-host.example.com", "port": 5480, "database": "PROD_DB" } } } ``` Use `$env{VAR_NAME}` to reference environment variables. An error is raised if the variable is not set. Plain-text values work as well. ## Authentication Modes[​](#authentication-modes "Direct link to Authentication Modes") ### Classic (all databases)[​](#classic-all-databases "Direct link to Classic (all databases)") Standard username/password authentication. Works with all supported database types. ``` { "my_db": { "ds_type": "postgres", "auth_mode": "classic", "info": { "username": "user", "password": "pass", "server": "host", "port": 5432, "database": "dbname" } } } ``` ### Oracle Thick Mode[​](#oracle-thick-mode "Direct link to Oracle Thick Mode") For Oracle 11.2 and earlier, set `lib_dir` to the Oracle Instant Client directory. Later versions use thin mode by default (omit `lib_dir`). ``` { "oracle_thick": { "ds_type": "oracle", "auth_mode": "classic", "info": { "username": "user", "password": "pass", "server": "host", "port": 1521, "database": "SID", "lib_dir": "/opt/oracle/instantclient_19_8" } } } ``` ### PostgreSQL ODBC[​](#postgresql-odbc "Direct link to PostgreSQL ODBC") ``` { "pg_odbc": { "ds_type": "postgres", "auth_mode": "odbc", "info": { "dsn": "PostgreSQL", "username": "user", "password": "pass" } } } ``` ### SQL Server Trusted Authentication[​](#sql-server-trusted-authentication "Direct link to SQL Server Trusted Authentication") Windows integrated authentication using ODBC: ``` { "mssql_trusted": { "ds_type": "mssql", "auth_mode": "odbc", "info": { "trusted": true, "instance": "server.domain.com\\INSTANCE", "database": "dbname" } } } ``` ### Connection String[​](#connection-string "Direct link to Connection String") For advanced scenarios, pass a raw connection string: ``` { "mssql_custom": { "ds_type": "mssql", "auth_mode": "classic", "info": { "connect_string": "mssql+pymssql://user:pass@host:port/database" } } } ``` ## Supported Database Types[​](#supported-database-types "Direct link to Supported Database Types") | Database | `ds_type` value | Default Port | As Source | As Target | As Migration DB | | ---------- | --------------- | ------------ | --------- | --------- | --------------- | | Oracle | `oracle` | 1521 | Yes | No | No | | PostgreSQL | `postgres` | 5432 | Yes | Yes | No | | SQL Server | `mssql` | 1433 | Yes | Yes | Yes | | Netezza | `netezza` | 5480 | Yes | No | No | ## See Also[​](#see-also "Direct link to See Also") * [Quick Start Guide](/0.6/guides/quickstart.md) -- get started in 5 minutes * [Migration Tasks](/0.6/configuration/migration-tasks.md) -- task types and execution order * [FastTransfer Configuration](/0.6/configuration/fasttransfer-configuration.md) -- parallel transfer tuning * [Logging and Monitoring](/0.6/reference/logging.md) -- log format and database tracking * [Troubleshooting](/0.6/reference/troubleshooting.md) -- common issues and solutions --- # Logging and Monitoring MigratorXpress uses two logging systems: a tracking database (SQL Server or PostgreSQL) for structured migration history and log files for operational details. ## Database Logging[​](#database-logging "Direct link to Database Logging") The migration tracking database records every step of a migration for auditing, resumability, and troubleshooting. Either **SQL Server** or **PostgreSQL** can host it -- the schema and behavior are identical across both backends. The dialect is auto-detected from the `ds_type` of the entry pointed to by `--migration_db_auth_id`. On PostgreSQL the tracking tables live in the `public` schema; on SQL Server they live in `dbo`. ### Database Schema Overview[​](#database-schema-overview "Direct link to Database Schema Overview") ![Migration Database Schema](/assets/images/migration_db_schema-1520c7e05cb5f53e7ca90bf75c7e471c.png) Primary keys are marked with key symbols and relationships show cardinality (1:N). ### Key Tables[​](#key-tables "Direct link to Key Tables") #### sources[​](#sources "Direct link to sources") Source database metadata: * Source identifier and database type * Connection details (server, port, database) * Schema name and discovery timestamp * Table count and total row count #### targets[​](#targets "Direct link to targets") Target database metadata: * Target identifier and database type * Connection details (server, port, database) * Schema name * Creation timestamp #### sourcecolumns[​](#sourcecolumns "Direct link to sourcecolumns") Column-level metadata from the source: * Table and column name (composite key) * Source data type, precision, scale * Ordinal position, length, nullability * Primary key flag #### targetcolumns[​](#targetcolumns "Direct link to targetcolumns") Column-level metadata for the target: * Table and column name (composite key) * Translated data type, precision, scale * Ordinal position, length, nullability * Mapping from source column #### sourcetargetloads[​](#sourcetargetloads "Direct link to sourcetargetloads") Per-table transfer tracking: * Source and target table identification * Transfer status (pending, running, completed, failed) * Row counts (source, transferred, validated) * Start and completion timestamps * Transfer method and parallel degree * Error messages on failure * Resume checkpoint data #### eventlog[​](#eventlog "Direct link to eventlog") Event log for migration activity: * Log ID and timestamp * Migration run identifier * Log level (INFO, WARNING, ERROR, DEBUG) * Event type and status * Table context (schema, table) * Event message and error details * Elapsed time in seconds #### sourceconstraints[​](#sourceconstraints "Direct link to sourceconstraints") Constraint metadata from the source: * Constraint name and type (PK, AK, FK) * Source table and columns * Referenced table and columns (for FKs) * Copy status and timestamp ## File-Based Logging[​](#file-based-logging "Direct link to File-Based Logging") Each migration run creates a log file for detailed operational tracing. ### Naming Pattern[​](#naming-pattern "Direct link to Naming Pattern") ``` migratorxpress_YYYYMMDD_HHMMSS_.log ``` ### Log Format[​](#log-format "Direct link to Log Format") Structured format with timestamp, log level, process ID, and context: ``` [YYYY-MM-DD HH:MM:SS.fff+TZ :: LEVEL :: PID :: Context] Message ``` ### Sample Output[​](#sample-output "Direct link to Sample Output") ``` [2026-01-15 09:30:12.145+01:00 :: INFO :: 8421 :: MainProcess] Log file path: /var/log/migratorxpress/migratorxpress_20260115_093012_a1b2c3d4.log [2026-01-15 09:30:12.146+01:00 :: INFO :: 8421 :: MainProcess] **** Starting migration run **** [2026-01-15 09:30:12.147+01:00 :: INFO :: 8421 :: MainProcess] Source: Oracle - ORCL.SALES [2026-01-15 09:30:12.148+01:00 :: INFO :: 8421 :: MainProcess] Target: PostgreSQL - analytics.sales [2026-01-15 09:30:12.250+01:00 :: INFO :: 8421 :: MainProcess] Discovered 42 tables for migration [2026-01-15 09:30:12.385+01:00 :: INFO :: 8421 :: MainProcess] Task list: translate create transfer diff [2026-01-15 09:30:13.102+01:00 :: INFO :: 8421 :: Worker-1] Translating DDL: ORDERS [2026-01-15 09:30:13.456+01:00 :: INFO :: 8421 :: Worker-1] Creating table: sales.orders [2026-01-15 09:30:14.210+01:00 :: INFO :: 8421 :: Worker-1] Transferring: ORDERS (estimated 1.2M rows) [2026-01-15 09:30:36.721+01:00 :: INFO :: 8421 :: Worker-1] Transfer completed: ORDERS - 1,234,567 rows in 22.511s [2026-01-15 09:30:37.102+01:00 :: INFO :: 8421 :: Worker-1] Diff: ORDERS - source=1,234,567 target=1,234,567 OK ``` ## Log Levels[​](#log-levels "Direct link to Log Levels") Set via `--log_level`: | Level | Description | | ---------- | --------------------------------------------------------------------------- | | `DEBUG` | SQL queries, FastTransfer commands, detailed diagnostics | | `INFO` | Progress, row counts, task completion (default) | | `WARNING` | Non-critical issues such as type conversion fallbacks or schema differences | | `ERROR` | Failures preventing a table from migrating | | `CRITICAL` | Fatal errors stopping the entire run | ## Log Location[​](#log-location "Direct link to Log Location") Defaults to the current working directory. Override with `--log_dir`: ``` ./MigratorXpress --log_dir /var/log/migratorxpress \ --auth ./credentials.json \ ... ``` ## Terminal Output[​](#terminal-output "Direct link to Terminal Output") Logs are mirrored to the terminal with color coding: * **Green** -- success messages (table created, transfer completed) * **Yellow** -- warnings (type conversion fallback, schema mismatch) * **Red** -- errors (transfer failed, connection lost) * **Cyan** -- informational messages (discovery, progress) ## Monitoring Best Practices[​](#monitoring-best-practices "Direct link to Monitoring Best Practices") ### During migration[​](#during-migration "Direct link to During migration") * Watch the terminal for real-time progress on each table. * Use `--n_jobs 1` for initial test runs so log output is sequential and easier to follow. * Set `--log_level DEBUG` to capture SQL statements when diagnosing issues. ### After migration[​](#after-migration "Direct link to After migration") * Query the `sourcetargetloads` table for per-table transfer status and row counts. * Query the `eventlog` table for errors and warnings. * Use the `diff` task to validate row counts and content between source and target. ### Resuming failed runs[​](#resuming-failed-runs "Direct link to Resuming failed runs") If a migration is interrupted, the tracking database preserves the state of each table. Use `--resume` to pick up from where it stopped -- only tables that did not complete successfully are reprocessed. ``` ./MigratorXpress --auth ./credentials.json \ --source_db_auth_id oracle_prod \ --source_schema_name SALES \ --target_db_auth_id postgres_dev \ --target_schema_name sales \ --migration_db_auth_id ms_mig_log \ --resume ``` ## Integration with Monitoring Tools[​](#integration-with-monitoring-tools "Direct link to Integration with Monitoring Tools") ### Log file ingestion[​](#log-file-ingestion "Direct link to Log file ingestion") MigratorXpress log files use a structured format that can be parsed by log aggregation tools: * **Filebeat / Logstash** -- configure a file input pointing to `migratorxpress_*.log` with a grok pattern for the bracket-delimited format. * **Fluentd** -- use a regexp parser matching `\[(?