Automating OraDump to MySQL for Large Databases

Troubleshooting Common OraDump to MySQL IssuesMigrating data from Oracle (exported via OraDump) to MySQL is common but can be tricky. This article walks through frequent problems you’ll encounter during migration, explains why they happen, and gives concrete steps and examples to fix them. It covers schema translation, data types, encoding, large objects, constraints and sequences, performance, and verification.


1. Understanding the core differences

Before troubleshooting, recognize key differences between Oracle and MySQL that often cause trouble:

  • Data types differ (e.g., Oracle’s NUMBER, VARCHAR2, CLOB; MySQL’s INT/DECIMAL, VARCHAR/TEXT).
  • No native sequences in MySQL — auto-increment behaves differently.
  • Oracle-specific features (synonyms, packages, PL/SQL, nested table types) aren’t supported in MySQL.
  • SQL dialect differences (date functions, joins, hint syntax).
  • Different handling of NULL vs empty strings (Oracle treats empty string as NULL).

Knowing these differences lets you anticipate and target issues rather than treating errors as random.


2. Pre-migration checks and preparation

  • Export metadata and sample data from Oracle:
    • Use expdp/exp to produce a schema dump and data dump.
    • Extract DDL (CREATE TABLE statements) and review data types and constraints.
  • Inventory:
    • List tables, columns, primary/foreign keys, indexes, triggers, sequences, views, stored procedures, and LOBs.
  • Choose a migration method:
    • SQL-based conversion (translate DDL, then load data via LOAD DATA INFILE or INSERTs).
    • ETL tools (Oracle GoldenGate, AWS DMS, Talend, Pentaho).
    • Third-party converters (Ora2Pg, Full Convert, MySQL Workbench migration wizard).
  • Backup both source and destination before changes.

3. Schema translation issues

Problem: DDL from Oracle doesn’t run in MySQL (syntax errors, unsupported types).

Fixes:

  • Translate data types:
    • NUMBER(p,s) → DECIMAL(p,s) or BIGINT/INT when appropriate.
    • VARCHAR2(n) → VARCHAR(n) (watch max lengths).
    • DATE → DATETIME or DATE depending on time component.
    • TIMESTAMP WITH TIME ZONE → DATETIME + separate timezone handling.
    • CLOB/BLOB → TEXT/LONGTEXT / BLOB / LONGBLOB.
  • Remove or convert Oracle-specific clauses:
    • STORAGE, TABLESPACE, COMPRESS, PCTFREE — remove or map to MySQL equivalents.
    • Sequences → convert to AUTO_INCREMENT columns or maintain sequence table + triggers if needed.
  • Adjust constraints and indexes:
    • Oracle supports function-based indexes; convert logic into indexed computed columns (if MySQL version supports generated columns) or application-side logic.
  • Example: Oracle DDL snippet and MySQL equivalent “`sql – Oracle CREATE TABLE employees ( emp_id NUMBER(10) PRIMARY KEY, name VARCHAR2(200), salary NUMBER(12,2), hire_date DATE );

– MySQL CREATE TABLE employees ( emp_id BIGINT PRIMARY KEY, name VARCHAR(200), salary DECIMAL(12,2), hire_date DATE ) ENGINE=InnoDB;


--- ### 4. Data type and precision mismatches Problem: Numeric overflows, truncated strings, or rounding issues after import. Fixes: - Pre-scan data to find max precision/length per column:   - Run queries in Oracle to detect maximum values/lengths.   - Increase target column sizes or change types to DECIMAL/BIGINT as necessary. - Handle implicit conversions explicitly:   - Convert Oracle’s NUMBER without precision to DECIMAL(38,0) or appropriate scale. - Watch date/time precision and timezone. If Oracle uses TIMESTAMP WITH TIME ZONE, store UTC and an offset column or normalize to UTC before import. Example query to find max lengths: ```sql SELECT COLUMN_NAME, MAX(LENGTH(column_name)) FROM schema.table GROUP BY COLUMN_NAME; 

5. Character encoding and Unicode problems

Problem: Garbled text, question marks, or replacement characters in MySQL.

Causes:

  • Mismatch of character sets between Oracle export, dump files, client, and MySQL database (e.g., Oracle AL32UTF8 vs MySQL latin1).

Fixes:

  • Ensure Oracle export uses UTF-8 (AL32UTF8) or an expected charset.
  • Set MySQL database, tables, and connection to utf8mb4:
    
    CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; 
  • Use client tools with proper charset flags (e.g., mysql –default-character-set=utf8mb4).
  • If data already corrupted, you may need to re-export from Oracle with correct charset settings.

6. Large objects (CLOB/BLOB) handling

Problem: LOB columns fail to import or get truncated.

Fixes:

  • Use tools that support streaming LOBs or chunked transfers (Oracle SQL*Loader, DMS tools, custom ETL).
  • For SQL-based dumps, ensure the dump format preserves LOBs (e.g., use XML or secure BLOB encoding).
  • In MySQL, choose appropriate column type (TEXT/LONGTEXT or BLOB/LONGBLOB) and ensure max_allowed_packet is large enough:
    
    SET GLOBAL max_allowed_packet = 1073741824; -- 1GB 
  • When using LOAD DATA INFILE, be aware LOB data might require special handling or separate import processes.

7. Sequences, auto-increment and identity handling

Problem: Loss of sequence values or duplicate primary keys after migration.

Fixes:

  • Detect columns that used Oracle sequences. Convert to AUTO_INCREMENT in MySQL:
    • Create column as INT/BIGINT AUTO_INCREMENT PRIMARY KEY.
    • Set AUTO_INCREMENT initial value to max(existing_value)+1:
      
      ALTER TABLE employees AUTO_INCREMENT = 10001; 
  • If sequences were used separately from primary keys, recreate equivalent logic with a sequence table or use MySQL 8.0 sequence objects (if available) or implement stored procedures.

8. Constraints, triggers, and stored procedures

Problem: Procedures, packages, and triggers fail to migrate (PL/SQL incompatible with MySQL’s SQL/PSM).

Fixes:

  • Manually rewrite PL/SQL logic into MySQL stored procedures/functions or implement application-side logic.
  • Convert triggers carefully; MySQL triggers have limitations (e.g., one trigger per action per table prior to MySQL 5.7; different timing semantics).
  • Drop or defer constraints during data load for speed, then recreate and validate after import:
    
    SET foreign_key_checks = 0; -- load data SET foreign_key_checks = 1; 

9. Referential integrity and ordering of data loads

Problem: Foreign key violations during bulk insert.

Fixes:

  • Load parent tables before child tables.
  • Disable foreign key checks during bulk load and then validate:
    • After loading, run queries to detect orphaned child rows before re-enabling constraints.
  • Use transactional loads and batch commits to limit lock contention.

10. Performance and locking during large imports

Problem: Import runs slowly, causes locking, or crashes.

Fixes:

  • Use bulk loading (LOAD DATA INFILE) instead of many INSERTs.
  • Disable indexes and constraints before large imports, then rebuild indexes after.
  • Tune MySQL settings for import:
    • Increase innodb_buffer_pool_size, bulk_insert_buffer_size, and tmp_table_size.
    • Use innodb_flush_log_at_trx_commit=2 during import (then restore).
  • Batch imports in manageable transactions (e.g., 10k–100k rows per commit).
  • Monitor IO and CPU; consider importing on a replica and promoting it.

11. Handling NULL vs empty string differences

Problem: Empty strings from Oracle become NULL or vice versa, causing application logic issues.

Fixes:

  • Normalize data either during export or after import:
    • Use COALESCE or CASE expressions to map NULL <-> ” as needed.
    • Explicitly replace empty strings:
      
      UPDATE table SET col = '' WHERE col IS NULL AND <condition>; 
  • Adjust application logic to treat empty string/NULL consistently.

12. Verifying data integrity after migration

  • Row counts: Compare row counts per table between Oracle and MySQL.
  • Checksums: Compute checksums or hashes per row (e.g., MD5 of concatenated columns) to detect mismatches.
  • Spot checks: Compare sample queries and aggregates (SUM, COUNT, MIN, MAX) across both systems.
  • Referential integrity: Run queries to detect orphaned rows or missing referenced keys.
  • Example checksum approach:
    
    SELECT MD5(GROUP_CONCAT(col1, '|', col2 ORDER BY id SEPARATOR '#')) FROM table; 

    (Adapt to your DB size; GROUP_CONCAT has limits — use streaming or per-chunk checksums for large tables.)


13. Common error messages and quick fixes

  • “Invalid character set” — ensure consistent charset and re-export if necessary.
  • “Data truncated for column” — increase column size or change type.
  • “Duplicate entry” — check sequences/auto-increment settings and resolve duplicate keys before enabling constraints.
  • “Packet too large” — increase max_allowed_packet on MySQL server and client.
  • “Out of memory” or “lock wait timeout” — reduce batch size, increase memory settings, or import during low traffic.

14. Automation and repeatable migrations

  • Script the DDL translation and data validation steps.
  • Use idempotent scripts that can be re-run safely (DROP IF EXISTS, CREATE OR REPLACE).
  • Log each table’s row counts, checksums, and errors to a migration report for rapid triage.

15. Tools and resources

  • Ora2Pg — open-source migration tool that converts Oracle schema and data to PostgreSQL (can be adapted for MySQL with custom mappings).
  • MySQL Workbench Migration Wizard — GUI-assisted migration.
  • AWS DMS / Oracle GoldenGate — for continuous replication or minimal downtime migrations.
  • Custom ETL with Python (cx_Oracle + mysql-connector), Perl, or Java for complex transformations.

16. Example migration checklist (concise)

  1. Inventory schema, sequences, LOBs, procedures.
  2. Choose tool/approach.
  3. Translate DDL and create MySQL schema.
  4. Configure charset to utf8mb4.
  5. Export data (consider chunking).
  6. Import data (disable constraints/indexes if large).
  7. Recreate constraints, indexes, triggers, sequences.
  8. Verify row counts, checksums, and referential integrity.
  9. Test application functionality.
  10. Monitor performance and tune.

If you want, I can produce: a) a DDL translation script template for specific Oracle types you use, b) an example Python ETL script to stream data from Oracle to MySQL, or c) a checklist tailored to a real schema — tell me which and share a sample table DDL.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *