oracle
mariadb

Migrate Oracle to MariaDB

Beta — live-tested path

Migrating from Oracle (Oracle Database, the long-standing enterprise standard) to MariaDB (the community-driven MySQL fork) means every table, column type, key, index and row has to survive two engines' different opinions about data. DBShifts converts the schema with deterministic rules, transfers data in parallel batches, and validates the result with per-table row counts and type-aware checksums.

Start OracleMariaDB Migration

Free tier · no credit card

Oracle vs MariaDB

oracle

Oracle

Oracle Database, the long-standing enterprise standard.

mariadb

MariaDB

the community-driven MySQL fork.

How the migration works

01

Connect

Point DBShifts at your source and target. Credentials stay encrypted; SSH tunnels supported for private databases.

02

Analyze

Automatic schema introspection produces a migration plan: what converts automatically, what migrates with warnings, what needs human review.

03

Migrate

Schema is created on the target, data transfers in parallel batches with constraints deferred, indexes rebuilt after load.

04

Validate

Per-table row counts, type-aware checksums on both sides, FK integrity — plus a fidelity report listing anything lossy.

Oracle to MariaDB data type mapping

Pulled directly from DBShifts's own conversion rules — not a general reference table, this is what actually runs.

OracleMariaDB
NUMBER(10)bigint
NUMBER(19)decimal(19,0)
NUMBER(10,2)decimal(10,2)
VARCHAR2(255)varchar(255)
NVARCHAR2(255)varchar(255)
CHAR(10)char(10)
CLOBlongtext
NCLOBlongtext
BLOBlongblob
DATEdatetime
TIMESTAMPdatetime
BINARY_FLOATfloat
BINARY_DOUBLEdouble
RAWblob
LONGlongtext

Example: Oracle to MariaDB schema conversion

Oracle

CREATE TABLE orders (
  id            NUMBER(10) GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  customer_id   NUMBER(10) NOT NULL,
  total         NUMBER(10,2) NOT NULL,
  notes         CLOB,
  reference     VARCHAR2(255),
  placed_at     TIMESTAMP NOT NULL
);

MariaDB

CREATE TABLE IF NOT EXISTS `orders` (
    `id` bigint NOT NULL,
    `customer_id` bigint NOT NULL,
    `total` decimal(10,2) NOT NULL,
    `notes` longtext,
    `reference` varchar(255),
    `placed_at` datetime NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

NUMBER is the type that decides this migration

Oracle's NUMBER is a single decimal type covering everything from a boolean flag to a 38-digit value, and the conversion depends entirely on the declared precision and scale. NUMBER(10) with no scale becomes an integer type; NUMBER(10,2) becomes DECIMAL(10,2); NUMBER with no precision at all has no safe fixed mapping, because the column could hold anything within Oracle's 38 digits.

Unqualified NUMBER columns are worth auditing individually before the migration. Converting them to DOUBLE is the fast answer and the wrong one for money, because it introduces binary rounding into values that were exact in Oracle. DECIMAL(38,10) is the safe default at some cost in storage.

MariaDB's DECIMAL maximum is 65 digits total, comfortably above Oracle's 38, so precision itself is not the constraint. The constraint is knowing which precision each column actually needs.

Empty string is NULL in Oracle and is not in MariaDB

Oracle treats the empty string as NULL. Insert '' into a VARCHAR2 column and Oracle stores NULL, which means an Oracle NOT NULL column can never contain an empty string. MariaDB distinguishes the two, so after migration a column may contain both NULL and '' where the source could only express one.

This changes query results rather than breaking loads. Application code written against Oracle will use IS NULL to test for emptiness, and that test silently stops matching rows that arrived as empty strings from another source later. It is a correctness difference that no row count or checksum will flag, because both sides genuinely match at migration time.

Sequences, triggers and the identity pattern

Older Oracle schemas generate keys with a sequence plus a BEFORE INSERT trigger, because identity columns only arrived in Oracle 12c. That pattern converts to AUTO_INCREMENT, and the trigger should be dropped rather than translated, since keeping both produces a trigger fighting the auto-increment.

After the data loads, the AUTO_INCREMENT counter has to be set past the highest imported key or the first insert collides with existing rows. Sequences that are not tied to a single table, such as a shared sequence used across several tables, have no AUTO_INCREMENT equivalent and need a separate approach.

Oracle's PL/SQL packages have no MariaDB equivalent. Procedures and functions convert individually, but package-level state, package variables that persist for a session, has nowhere to go and needs redesign.

OracleMariaDB conversion notes

Engine-specific rules baked into the conversion and transfer pipeline — verified by live certification of this exact pair.

  • NUMBER columns are fetched as exact decimals (38 digits), not lossy floats.
  • Identifier case differences (Oracle uppercases unquoted names) are reconciled automatically during transfer.
  • Empty string = NULL semantics are accounted for in validation so comparisons stay honest.
  • Literal 'NULL' defaults reported by MariaDB's information schema are cleaned instead of becoming DEFAULT 'NULL' strings.
  • AUTO_INCREMENT reseed after bulk load, same as MySQL.

Frequently asked questions

Is Oracle to MariaDB migration production-ready in DBShifts?

Oracle to MariaDB is a live-verified beta pair: it passed the same certification suite as every other pair — a real migration with edge-case data validated by row counts and checksums — and ships with a post-migration fidelity report you can audit before cutover.

How does DBShifts verify the Oracle to MariaDB migration was correct?

Three layers: per-table row counts on both sides, an order-independent type-aware checksum of row data (canonicalized so engine representation differences don't false-alarm), and FK integrity checks on the target. Rows that fail to insert are quarantined with the exact error — never silently dropped — and can be fixed and retried from the UI.

What happens to Oracle types that MariaDB doesn't have?

They convert by deterministic rules with a recorded decision: a native equivalent where one exists, a portable fallback (TEXT/JSON/DECIMAL) where one doesn't. Every lossy conversion appears in the migration plan before you run and in the fidelity report after. You can override any mapping per column.

Can I keep Oracle and MariaDB in sync after the initial migration?

Yes. DBShifts supports incremental sync (UPSERT-based delta transfers on a sync key) and, for supported sources, real-time change data capture so the target stays current until you cut over.

Do I need to write any SQL or scripts for Oracle to MariaDB?

No. Connect both databases, review the generated migration plan (what's automatic, what migrates with warnings, what needs manual review — typically triggers and stored procedures), and run. Procedural code is transpiled best-effort and queued for human review rather than auto-applied.

What's the hardest part of moving Oracle to MariaDB?

Type-system mismatches that fail silently rather than loudly — Oracle's edge-case types (3 engine-specific rules apply) converting into MariaDB's nearest equivalent. DBShifts's deterministic mapping records every downgrade in the fidelity report, so a value that clips, rounds, or widens is visible before cutover, not after.

Which Oracle data types change when moving to MariaDB?

4 of the mapped types convert to something that cannot represent exactly the same range or constraint. The clearest cases are NUMBER(10) to bigint, CLOB to longtext, TIMESTAMP to datetime. The full table above lists every mapping the converter performs, and analysis flags each one on your actual schema before any data moves.

Go deeper

Related migration paths

Ready to move Oracle to MariaDB?

Set up in under two minutes. Validation and rollback included.

Start Free Migration