Oracle to HeliosDB Migration Guide
Oracle to HeliosDB Migration Guide
Version: 1.0 Last Updated: January 2026 Compatibility Target: Oracle 11g, 12c, 18c, 19c, 21c, 23ai
Table of Contents
- Introduction
- Compatibility Overview
- Pre-Migration Assessment
- Conceptual Mapping
- Step-by-Step Migration
- Feature Mapping
- PL/SQL Migration
- Application Connectivity
- Post-Migration Validation
- Performance Considerations
- Common Issues and Troubleshooting
- Rollback Procedures
1. Introduction
1.1 Why Migrate from Oracle to HeliosDB?
Organizations are increasingly migrating from Oracle Database to HeliosDB for several compelling reasons:
Cost Savings
| Cost Factor | Oracle | HeliosDB | Savings |
|---|---|---|---|
| Processor License (Enterprise) | $47,500/core | Open pricing | 60-80% |
| Annual Support | 22% of license | Included | 100% |
| RAC/Clustering | Additional license | Built-in | 100% |
| Partitioning | $11,500/core | Included | 100% |
| Advanced Security | $15,000/core | Included | 100% |
| In-Memory | $23,000/core | Included | 100% |
Typical 4-year TCO Reduction: 65-85%
Multi-Model Support
HeliosDB provides native support for multiple data models through a single platform:
- Relational SQL: Full Oracle SQL compatibility
- Document/JSON: MongoDB-compatible document storage
- Key-Value: Redis-compatible operations
- Time-Series: Native time-series optimizations
- Graph: Cypher query language support
- Vector: AI/ML embeddings with similarity search
Modern Architecture Advantages
| Capability | Oracle | HeliosDB |
|---|---|---|
| Cloud-Native | Partial | Full Kubernetes support |
| Multi-Protocol | No | 9+ protocols |
| Auto-Scaling | Manual/Licensed | Automatic |
| Self-Healing | Manual intervention | AI-driven autonomous |
| ML Integration | External tools | Native in-database ML |
| HTAP | Separate systems | Unified workload |
1.2 Migration Goals
This guide helps you achieve:
- Zero data loss during migration
- Minimal downtime through parallel operation strategies
- Application compatibility with existing Oracle clients
- Performance parity or improvement post-migration
- Reduced operational complexity through HeliosDB automation
2. Compatibility Overview
2.1 Oracle Protocol Support in HeliosDB
HeliosDB implements the Oracle TNS wire protocol and provides comprehensive Oracle 23ai compatibility:
| Category | Coverage | Notes |
|---|---|---|
| SQL Language | 95%+ | Full Oracle SQL dialect |
| PL/SQL | 95% | Complete execution engine |
| DBMS Packages | 85% | Core packages fully implemented |
| Hierarchical Queries | 93% | Full CONNECT BY support |
| JSON Functions | 94% | Oracle 21c+ JSON support |
| Pseudo-columns | 95% | ROWNUM, ROWID, LEVEL |
| Analytics | 92% | Window functions |
2.2 Supported Oracle Features
Fully Supported (Direct Migration)
- DDL: CREATE TABLE, INDEX, VIEW, MATERIALIZED VIEW, SEQUENCE, SYNONYM
- DML: SELECT, INSERT, UPDATE, DELETE, MERGE, INSERT ALL
- Transactions: COMMIT, ROLLBACK, SAVEPOINT, SET TRANSACTION
- PL/SQL: Procedures, Functions, Packages, Triggers
- Hierarchical: CONNECT BY, START WITH, LEVEL, SYS_CONNECT_BY_PATH
- Advanced: PIVOT/UNPIVOT, MERGE, Flashback queries
- JSON: JSON_VALUE, JSON_QUERY, JSON_TABLE, JSON_OBJECT
- Analytics: ROW_NUMBER, RANK, DENSE_RANK, LAG, LEAD, LISTAGG
Partially Supported (Requires Modification)
- MODEL clause (basic support)
- BFILE data type (read-only)
- ORA_ROWSCN (partial tracking)
- Some DBMS_STATS functions
Not Supported (Requires Redesign)
| Oracle Feature | HeliosDB Alternative |
|---|---|
| Oracle RAC | HeliosDB distributed clustering |
| Data Guard | HeliosDB multi-region replication |
| Advanced Queuing (AQ) | Native streaming + Kafka integration |
| Spatial (SDO_*) | HeliosDB geospatial indexing |
| Label Security | Row-level security policies |
| Oracle Text | HeliosDB full-text search |
2.3 Connection Compatibility
HeliosDB accepts Oracle client connections via TNS protocol:
Connection Port: 1521 (default)Protocol: Oracle TNSWire Protocol Version: 12.2 compatibleSupported drivers:
- Oracle JDBC (21c+)
- cx_Oracle / oracledb (Python)
- ODP.NET (21c+)
- oracledb (Node.js 6.x)
- godror (Go)
3. Pre-Migration Assessment
3.1 Database Inventory
Before migration, perform a comprehensive inventory of your Oracle environment.
Schema Analysis Script
-- Database size summarySELECT owner, segment_type, COUNT(*) as object_count, ROUND(SUM(bytes)/1024/1024/1024, 2) as size_gbFROM dba_segmentsWHERE owner NOT IN ('SYS', 'SYSTEM', 'OUTLN', 'DBSNMP')GROUP BY owner, segment_typeORDER BY size_gb DESC;
-- Table and index counts per schemaSELECT owner, (SELECT COUNT(*) FROM dba_tables WHERE owner = u.username) as tables, (SELECT COUNT(*) FROM dba_indexes WHERE owner = u.username) as indexes, (SELECT COUNT(*) FROM dba_views WHERE owner = u.username) as views, (SELECT COUNT(*) FROM dba_sequences WHERE owner = u.username) as sequences, (SELECT COUNT(*) FROM dba_procedures WHERE owner = u.username) as proceduresFROM dba_users uWHERE username NOT IN ('SYS', 'SYSTEM', 'OUTLN')ORDER BY username;3.2 PL/SQL Code Analysis
Analyze your PL/SQL codebase for migration complexity:
-- Count PL/SQL objects by typeSELECT owner, type, COUNT(*) as object_count, SUM(CASE WHEN status = 'VALID' THEN 1 ELSE 0 END) as valid_count, SUM(CASE WHEN status = 'INVALID' THEN 1 ELSE 0 END) as invalid_countFROM dba_objectsWHERE object_type IN ('PROCEDURE', 'FUNCTION', 'PACKAGE', 'PACKAGE BODY', 'TRIGGER', 'TYPE', 'TYPE BODY') AND owner NOT IN ('SYS', 'SYSTEM')GROUP BY owner, typeORDER BY owner, object_count DESC;
-- Count lines of PL/SQL codeSELECT owner, type, SUM(line) as total_linesFROM dba_sourceWHERE owner NOT IN ('SYS', 'SYSTEM')GROUP BY owner, typeORDER BY total_lines DESC;DBMS Package Usage Inventory
Identify which DBMS packages your code uses:
-- Find DBMS package dependenciesSELECT DISTINCT owner, name, referenced_name as dbms_package, typeFROM dba_dependenciesWHERE referenced_owner = 'SYS' AND referenced_name LIKE 'DBMS_%' AND owner NOT IN ('SYS', 'SYSTEM')ORDER BY referenced_name, owner, name;
-- Common patterns to search for in source codeSELECT owner, name, type, line, textFROM dba_sourceWHERE UPPER(text) LIKE '%DBMS_OUTPUT%' OR UPPER(text) LIKE '%DBMS_LOB%' OR UPPER(text) LIKE '%DBMS_SQL%' OR UPPER(text) LIKE '%DBMS_UTILITY%' OR UPPER(text) LIKE '%DBMS_SCHEDULER%' OR UPPER(text) LIKE '%UTL_FILE%' OR UPPER(text) LIKE '%DBMS_AQ%' OR UPPER(text) LIKE '%DBMS_XMLGEN%'ORDER BY owner, name, line;3.3 Schema Complexity Evaluation
Data Type Inventory
-- Identify data types in useSELECT data_type, COUNT(*) as column_count, COUNT(DISTINCT owner||'.'||table_name) as table_countFROM dba_tab_columnsWHERE owner NOT IN ('SYS', 'SYSTEM')GROUP BY data_typeORDER BY column_count DESC;Data Type Migration Risk Assessment:
| Risk Level | Data Types |
|---|---|
| Low (Direct) | NUMBER, VARCHAR2, DATE, TIMESTAMP, CLOB, BLOB, RAW |
| Medium (Verify) | BFILE, XMLTYPE, INTERVAL, LONG, LONG RAW |
| High (Convert) | SDO_GEOMETRY, ANYDATA, User-defined types |
Constraint Analysis
-- Foreign key relationshipsSELECT a.owner, a.table_name, COUNT(*) as fk_countFROM dba_constraints aWHERE a.constraint_type = 'R' AND a.owner NOT IN ('SYS', 'SYSTEM')GROUP BY a.owner, a.table_nameHAVING COUNT(*) > 5ORDER BY fk_count DESC;
-- Check constraints using Oracle-specific functionsSELECT owner, table_name, constraint_name, search_conditionFROM dba_constraintsWHERE constraint_type = 'C' AND owner NOT IN ('SYS', 'SYSTEM') AND (search_condition LIKE '%ROWNUM%' OR search_condition LIKE '%SYSDATE%' OR search_condition LIKE '%DECODE%');3.4 Application Dependencies
Document all applications connecting to Oracle:
-- Active session analysisSELECT machine, program, module, COUNT(*) as session_count, COUNT(DISTINCT username) as user_countFROM v$sessionWHERE type = 'USER'GROUP BY machine, program, moduleORDER BY session_count DESC;3.5 Migration Complexity Score
Calculate your migration complexity:
| Factor | Points | Your Score |
|---|---|---|
| Tables < 50 | 1 | |
| Tables 50-200 | 2 | |
| Tables > 200 | 3 | |
| PL/SQL LOC < 10K | 1 | |
| PL/SQL LOC 10K-100K | 2 | |
| PL/SQL LOC > 100K | 3 | |
| No DBMS_AQ usage | 0 | |
| Uses DBMS_AQ | 2 | |
| No Oracle RAC | 0 | |
| Uses Oracle RAC | 2 | |
| No Spatial data | 0 | |
| Uses SDO_GEOMETRY | 3 |
Total Score Interpretation:
- 1-4: Simple migration (1-2 weeks)
- 5-8: Medium complexity (2-6 weeks)
- 9+: Complex migration (6+ weeks)
4. Conceptual Mapping
4.1 Oracle to HeliosDB Object Mapping
| Oracle Concept | HeliosDB Equivalent | Notes |
|---|---|---|
| Database | Database | 1:1 mapping |
| Tablespace | Storage Pool | Different internal management |
| Schema | Schema | Direct mapping |
| Table | Table | Full compatibility |
| Index | Index | B-tree, Bitmap supported |
| Sequence | Sequence | Compatible syntax |
| Synonym | Synonym | Public/Private supported |
| View | View | Full SQL support |
| Materialized View | Materialized View | Refresh options supported |
| Package | Package | Full PL/SQL package support |
| Procedure | Procedure | Direct mapping |
| Function | Function | Direct mapping |
| Trigger | Trigger | All trigger types |
| DBLink | Foreign Data Wrapper | Different implementation |
| Directory | Storage Mount | File system access |
4.2 Tablespace to Storage Pool Mapping
Oracle tablespaces map to HeliosDB storage pools with different characteristics:
-- Oracle tablespace querySELECT tablespace_name, status, contents, extent_managementFROM dba_tablespaces;HeliosDB Storage Pool Configuration:
-- Create storage pool (HeliosDB)CREATE STORAGE POOL sales_pool WITH REPLICATION_FACTOR = 3 COMPRESSION = 'lz4' ENCRYPTION = 'aes256';
-- Assign table to poolCREATE TABLE sales.orders ( order_id NUMBER PRIMARY KEY, order_date DATE) STORAGE POOL sales_pool;Mapping Recommendations:
| Oracle Tablespace Type | HeliosDB Storage Pool |
|---|---|
| SYSTEM/SYSAUX | system_pool (auto-managed) |
| UNDO | Not needed (MVCC internal) |
| TEMP | Automatic temp management |
| User data | Custom storage pools |
| Index tablespace | Same pool as data (optional) |
4.3 User and Role Mapping
-- Oracle: Create userCREATE USER app_user IDENTIFIED BY password DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp QUOTA UNLIMITED ON users;
-- HeliosDB: Create userCREATE USER app_user WITH PASSWORD 'password' DEFAULT SCHEMA app_user;
-- Oracle: Grant rolesGRANT CONNECT, RESOURCE TO app_user;GRANT SELECT ON sales.orders TO app_user;
-- HeliosDB: Grant roles (compatible syntax)GRANT CONNECT, RESOURCE TO app_user;GRANT SELECT ON sales.orders TO app_user;4.4 Sequence Migration
-- Oracle sequenceCREATE SEQUENCE order_seq START WITH 1000 INCREMENT BY 1 MAXVALUE 999999999 CACHE 100 CYCLE;
-- HeliosDB sequence (compatible syntax)CREATE SEQUENCE order_seq START WITH 1000 INCREMENT BY 1 MAXVALUE 999999999 CACHE 100 CYCLE;
-- Usage is identicalSELECT order_seq.NEXTVAL FROM DUAL;INSERT INTO orders (id) VALUES (order_seq.NEXTVAL);4.5 Synonym Migration
-- Oracle public synonymCREATE PUBLIC SYNONYM emp FOR hr.employees;
-- HeliosDB (same syntax)CREATE PUBLIC SYNONYM emp FOR hr.employees;
-- Private synonymCREATE SYNONYM my_emp FOR hr.employees;5. Step-by-Step Migration
5.1 Phase 1: Schema Export Using Data Pump
Full Schema Export
# Oracle Data Pump exportexpdp system/password@ORCL \ SCHEMAS=HR,SALES,INVENTORY \ DIRECTORY=DUMP_DIR \ DUMPFILE=schema_export_%U.dmp \ LOGFILE=schema_export.log \ PARALLEL=4 \ CONTENT=ALL \ COMPRESSION=ALLSchema-Only Export (for translation)
# Export DDL onlyexpdp system/password@ORCL \ SCHEMAS=HR \ DIRECTORY=DUMP_DIR \ DUMPFILE=ddl_export.dmp \ LOGFILE=ddl_export.log \ CONTENT=METADATA_ONLYGenerate SQL DDL Scripts
-- Using DBMS_METADATASET LONG 1000000SET LONGCHUNKSIZE 1000000SET PAGESIZE 0SET LINESIZE 1000
-- Export all tables in schemaSELECT DBMS_METADATA.GET_DDL('TABLE', table_name, owner)FROM dba_tablesWHERE owner = 'HR';
-- Export all indexesSELECT DBMS_METADATA.GET_DDL('INDEX', index_name, owner)FROM dba_indexesWHERE owner = 'HR' AND index_type != 'LOB';
-- Export all procedures/functionsSELECT DBMS_METADATA.GET_DDL('PROCEDURE', object_name, owner)FROM dba_objectsWHERE owner = 'HR' AND object_type = 'PROCEDURE';
-- Export all packagesSELECT DBMS_METADATA.GET_DDL('PACKAGE', object_name, owner)FROM dba_objectsWHERE owner = 'HR' AND object_type = 'PACKAGE';5.2 Phase 2: Schema Translation for HeliosDB
Most Oracle DDL works directly in HeliosDB. Common translations needed:
Storage Clause Removal
-- Oracle DDL with storage clausesCREATE TABLE employees ( employee_id NUMBER(10) NOT NULL, first_name VARCHAR2(50), hire_date DATE DEFAULT SYSDATE)TABLESPACE usersSTORAGE (INITIAL 64K NEXT 64K)PCTFREE 10 PCTUSED 40;
-- HeliosDB equivalent (remove storage specifics)CREATE TABLE employees ( employee_id NUMBER(10) NOT NULL, first_name VARCHAR2(50), hire_date DATE DEFAULT SYSDATE);-- Or with storage pool:-- ) STORAGE POOL users_pool;Partitioning Translation
-- Oracle range partitioningCREATE TABLE sales_history ( sale_id NUMBER, sale_date DATE, amount NUMBER)PARTITION BY RANGE (sale_date) ( PARTITION p_2023 VALUES LESS THAN (DATE '2024-01-01'), PARTITION p_2024 VALUES LESS THAN (DATE '2025-01-01'), PARTITION p_max VALUES LESS THAN (MAXVALUE));
-- HeliosDB (compatible syntax)CREATE TABLE sales_history ( sale_id NUMBER, sale_date DATE, amount NUMBER)PARTITION BY RANGE (sale_date) ( PARTITION p_2023 VALUES LESS THAN (DATE '2024-01-01'), PARTITION p_2024 VALUES LESS THAN (DATE '2025-01-01'), PARTITION p_max VALUES LESS THAN (MAXVALUE));Index Translation
-- Oracle bitmap indexCREATE BITMAP INDEX idx_status ON orders(status);
-- HeliosDB (same syntax)CREATE BITMAP INDEX idx_status ON orders(status);
-- Oracle function-based indexCREATE INDEX idx_upper_name ON employees(UPPER(last_name));
-- HeliosDB (same syntax)CREATE INDEX idx_upper_name ON employees(UPPER(last_name));5.3 Phase 3: Data Migration Strategies
Strategy A: Direct Data Pump Import (Recommended)
HeliosDB can process Oracle Data Pump files directly:
-- Connect to HeliosDBsqlplus admin/password@//heliosdb-server:1521/heliosdb
-- Import from Data Pump fileIMPORT DATAPUMP FROM '/path/to/schema_export.dmp' SCHEMAS = HR, SALES TRANSFORM = STORAGE:N PARALLEL = 8;Strategy B: SQL*Loader Format Migration
# Export data from Oracle using SQL*Loadersqlldr userid=system/password@ORCL \ control=export.ctl \ data=employees.csv \ log=export.logControl file (export.ctl):
OPTIONS (SKIP=1)LOAD DATACHARACTERSET UTF8INFILE 'employees.csv'INTO TABLE employeesFIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'( employee_id, first_name, last_name, hire_date DATE "YYYY-MM-DD", salary)Import to HeliosDB:
-- Using COPY commandCOPY employees FROM '/path/to/employees.csv'WITH (FORMAT csv, HEADER true);Strategy C: Parallel ETL with Batch Processing
For large tables (>100GB), use parallel extraction:
-- Oracle: Extract in chunksSELECT /*+ PARALLEL(e, 8) */ employee_id, first_name, last_name, hire_date, salaryFROM employees eWHERE MOD(ROWNUM, 8) = 0; -- Run 8 parallel streamsHeliosDB Batch Insert:
-- Use batch insert for performanceBEGIN BATCH INSERT INSERT INTO employees VALUES (1, 'John', 'Doe', DATE '2020-01-15', 75000); INSERT INTO employees VALUES (2, 'Jane', 'Smith', DATE '2020-02-20', 82000); -- ... more rowsEND BATCH;5.4 Phase 4: PL/SQL Migration
Most PL/SQL code migrates directly. See Section 7 for details.
5.5 Phase 5: Application Cutover
Parallel Running Strategy
Week 1-2: Read-only HeliosDB testingWeek 3: Write to both, read from OracleWeek 4: Write to both, read from HeliosDBWeek 5: HeliosDB primary, Oracle standbyWeek 6: Decommission Oracle readsConnection String Changes
# Oracle connectionoracle_dsn = "oracle+cx_oracle://user:pass@oracle-host:1521/ORCL"
# HeliosDB connection (same driver works)helios_dsn = "oracle+cx_oracle://user:pass@heliosdb-host:1521/heliosdb"6. Feature Mapping
6.1 Oracle SQL Extensions in HeliosDB
DECODE Function
-- Oracle DECODE (fully supported)SELECT employee_id, DECODE(status, 'A', 'Active', 'I', 'Inactive', 'T', 'Terminated', 'Unknown') as status_descFROM employees;NVL and NVL2
-- NVL (replace NULL)SELECT NVL(commission, 0) FROM employees;
-- NVL2 (if not null / if null)SELECT NVL2(manager_id, 'Has Manager', 'Top Level') FROM employees;ROWNUM and ROWID
-- ROWNUM for limitingSELECT * FROM employees WHERE ROWNUM <= 10;
-- ROWID for row identificationSELECT ROWID, employee_id FROM employees WHERE department_id = 10;6.2 DBMS Package Mapping
DBMS_OUTPUT
-- Fully supportedBEGIN DBMS_OUTPUT.ENABLE(1000000); DBMS_OUTPUT.PUT_LINE('Processing started'); DBMS_OUTPUT.PUT('Status: '); DBMS_OUTPUT.PUT_LINE('Complete'); DBMS_OUTPUT.NEW_LINE;END;/DBMS_LOB
-- LOB operations (fully supported)DECLARE v_clob CLOB; v_length NUMBER;BEGIN SELECT document INTO v_clob FROM documents WHERE id = 1;
v_length := DBMS_LOB.GETLENGTH(v_clob); DBMS_OUTPUT.PUT_LINE('Length: ' || v_length);
-- Substring DBMS_OUTPUT.PUT_LINE(DBMS_LOB.SUBSTR(v_clob, 100, 1));
-- Append DBMS_LOB.APPEND(v_clob, ' Additional text');END;/DBMS_SQL
-- Dynamic SQL (fully supported)DECLARE v_cursor INTEGER; v_rows INTEGER;BEGIN v_cursor := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(v_cursor, 'UPDATE employees SET salary = salary * 1.1 WHERE department_id = :dept', DBMS_SQL.NATIVE);
DBMS_SQL.BIND_VARIABLE(v_cursor, ':dept', 10);
v_rows := DBMS_SQL.EXECUTE(v_cursor); DBMS_OUTPUT.PUT_LINE('Updated ' || v_rows || ' rows');
DBMS_SQL.CLOSE_CURSOR(v_cursor);END;/DBMS_SCHEDULER
-- Job scheduling (fully supported)BEGIN DBMS_SCHEDULER.CREATE_JOB( job_name => 'NIGHTLY_CLEANUP', job_type => 'STORED_PROCEDURE', job_action => 'cleanup_old_data', start_date => SYSTIMESTAMP, repeat_interval => 'FREQ=DAILY; BYHOUR=2; BYMINUTE=0', enabled => TRUE );END;/
-- Manage jobsBEGIN DBMS_SCHEDULER.RUN_JOB('NIGHTLY_CLEANUP'); DBMS_SCHEDULER.DISABLE('NIGHTLY_CLEANUP'); DBMS_SCHEDULER.DROP_JOB('NIGHTLY_CLEANUP');END;/DBMS_METADATA
-- Schema export (fully supported)SELECT DBMS_METADATA.GET_DDL('TABLE', 'EMPLOYEES', 'HR') FROM DUAL;SELECT DBMS_METADATA.GET_DEPENDENT_DDL('INDEX', 'EMPLOYEES', 'HR') FROM DUAL;UTL_FILE
-- File I/O (fully supported)DECLARE v_file UTL_FILE.FILE_TYPE; v_line VARCHAR2(32767);BEGIN v_file := UTL_FILE.FOPEN('DATA_DIR', 'output.txt', 'W'); UTL_FILE.PUT_LINE(v_file, 'Header line');
FOR rec IN (SELECT * FROM employees) LOOP UTL_FILE.PUT_LINE(v_file, rec.employee_id || ',' || rec.first_name); END LOOP;
UTL_FILE.FCLOSE(v_file);END;/6.3 Partitioning Support
-- Range partitioningCREATE TABLE sales ( sale_id NUMBER, sale_date DATE) PARTITION BY RANGE (sale_date) ( PARTITION p_q1 VALUES LESS THAN (DATE '2024-04-01'), PARTITION p_q2 VALUES LESS THAN (DATE '2024-07-01'), PARTITION p_q3 VALUES LESS THAN (DATE '2024-10-01'), PARTITION p_q4 VALUES LESS THAN (DATE '2025-01-01'));
-- List partitioningCREATE TABLE orders ( order_id NUMBER, region VARCHAR2(20)) PARTITION BY LIST (region) ( PARTITION p_east VALUES ('NY', 'NJ', 'CT'), PARTITION p_west VALUES ('CA', 'WA', 'OR'), PARTITION p_other VALUES (DEFAULT));
-- Hash partitioningCREATE TABLE customers ( customer_id NUMBER, name VARCHAR2(100)) PARTITION BY HASH (customer_id) PARTITIONS 16;6.4 Flashback to Time Travel Mapping
Oracle Flashback maps to HeliosDB Time Travel:
-- Oracle Flashback QuerySELECT * FROM employees AS OF TIMESTAMP TO_TIMESTAMP('2024-01-15 10:00:00', 'YYYY-MM-DD HH24:MI:SS');
-- HeliosDB Time Travel (identical syntax)SELECT * FROM employees AS OF TIMESTAMP TO_TIMESTAMP('2024-01-15 10:00:00', 'YYYY-MM-DD HH24:MI:SS');
-- Oracle Flashback with SCNSELECT * FROM employees AS OF SCN 12345678;
-- HeliosDB (identical syntax)SELECT * FROM employees AS OF SCN 12345678;
-- Versions between timestampsSELECT versions_starttime, versions_endtime, versions_operation, employee_id, salaryFROM employeesVERSIONS BETWEEN TIMESTAMP TO_TIMESTAMP('2024-01-01', 'YYYY-MM-DD') AND TO_TIMESTAMP('2024-01-31', 'YYYY-MM-DD')WHERE employee_id = 100;HeliosDB Time Travel Advantages:
- Configurable retention (7+ days default)
- Delta compression (<10% storage overhead)
- Sub-millisecond temporal queries
- Integrated with MVCC
7. PL/SQL Migration
7.1 Supported PL/SQL Constructs
HeliosDB provides 95% PL/SQL compatibility:
Variable Declarations
DECLARE -- Scalar types v_number NUMBER(10,2) := 100.50; v_string VARCHAR2(100) := 'Hello'; v_date DATE := SYSDATE; v_timestamp TIMESTAMP := SYSTIMESTAMP; v_boolean BOOLEAN := TRUE;
-- Constants c_tax_rate CONSTANT NUMBER := 0.08;
-- Anchored types v_salary employees.salary%TYPE; v_emp_row employees%ROWTYPE;
-- Collections TYPE num_array IS TABLE OF NUMBER INDEX BY PLS_INTEGER; v_numbers num_array;
-- Nested tables TYPE name_list IS TABLE OF VARCHAR2(100); v_names name_list := name_list('John', 'Jane', 'Bob');BEGIN -- Body NULL;END;/Control Flow
DECLARE v_grade CHAR(1); v_score NUMBER := 85;BEGIN -- IF-THEN-ELSE IF v_score >= 90 THEN v_grade := 'A'; ELSIF v_score >= 80 THEN v_grade := 'B'; ELSIF v_score >= 70 THEN v_grade := 'C'; ELSE v_grade := 'F'; END IF;
-- CASE expression v_grade := CASE WHEN v_score >= 90 THEN 'A' WHEN v_score >= 80 THEN 'B' WHEN v_score >= 70 THEN 'C' ELSE 'F' END;
-- Simple LOOP LOOP v_score := v_score - 10; EXIT WHEN v_score < 0; END LOOP;
-- WHILE loop v_score := 100; WHILE v_score > 0 LOOP v_score := v_score - 10; END LOOP;
-- FOR loop FOR i IN 1..10 LOOP DBMS_OUTPUT.PUT_LINE('Iteration: ' || i); END LOOP;
-- FOR loop with REVERSE FOR i IN REVERSE 1..10 LOOP DBMS_OUTPUT.PUT_LINE('Countdown: ' || i); END LOOP;END;/Cursors
DECLARE -- Explicit cursor CURSOR emp_cursor IS SELECT employee_id, first_name, salary FROM employees WHERE department_id = 10;
-- Cursor with parameters CURSOR dept_cursor(p_dept_id NUMBER) IS SELECT * FROM employees WHERE department_id = p_dept_id;
v_emp emp_cursor%ROWTYPE;BEGIN -- Explicit cursor operations OPEN emp_cursor; LOOP FETCH emp_cursor INTO v_emp; EXIT WHEN emp_cursor%NOTFOUND; DBMS_OUTPUT.PUT_LINE(v_emp.first_name); END LOOP; CLOSE emp_cursor;
-- Cursor FOR loop (implicit) FOR rec IN emp_cursor LOOP DBMS_OUTPUT.PUT_LINE(rec.first_name || ': ' || rec.salary); END LOOP;
-- Cursor with parameters FOR rec IN dept_cursor(20) LOOP DBMS_OUTPUT.PUT_LINE(rec.first_name); END LOOP;END;/BULK COLLECT and FORALL
DECLARE TYPE emp_tab IS TABLE OF employees%ROWTYPE; TYPE id_tab IS TABLE OF NUMBER;
v_employees emp_tab; v_ids id_tab := id_tab(1, 2, 3, 4, 5);BEGIN -- BULK COLLECT SELECT * BULK COLLECT INTO v_employees FROM employees WHERE department_id = 10;
DBMS_OUTPUT.PUT_LINE('Collected ' || v_employees.COUNT || ' rows');
-- FORALL with SAVE EXCEPTIONS FORALL i IN v_ids.FIRST..v_ids.LAST SAVE EXCEPTIONS UPDATE employees SET salary = salary * 1.1 WHERE employee_id = v_ids(i);
EXCEPTION WHEN OTHERS THEN FOR j IN 1..SQL%BULK_EXCEPTIONS.COUNT LOOP DBMS_OUTPUT.PUT_LINE('Error at index ' || SQL%BULK_EXCEPTIONS(j).ERROR_INDEX); END LOOP;END;/7.2 Exception Handling
DECLARE v_salary NUMBER;
-- Custom exception e_salary_too_high EXCEPTION; PRAGMA EXCEPTION_INIT(e_salary_too_high, -20001);BEGIN SELECT salary INTO v_salary FROM employees WHERE employee_id = 999; -- May not exist
IF v_salary > 1000000 THEN RAISE e_salary_too_high; END IF;
EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('Employee not found');
WHEN TOO_MANY_ROWS THEN DBMS_OUTPUT.PUT_LINE('Multiple employees returned');
WHEN e_salary_too_high THEN DBMS_OUTPUT.PUT_LINE('Salary exceeds maximum');
WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Error: ' || SQLCODE || ' - ' || SQLERRM); DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE); RAISE;END;/7.3 Stored Procedures
CREATE OR REPLACE PROCEDURE transfer_funds( p_from_account IN NUMBER, p_to_account IN NUMBER, p_amount IN NUMBER, p_status OUT VARCHAR2) AS v_from_balance NUMBER; e_insufficient_funds EXCEPTION;BEGIN -- Check source balance SELECT balance INTO v_from_balance FROM accounts WHERE account_id = p_from_account FOR UPDATE;
IF v_from_balance < p_amount THEN RAISE e_insufficient_funds; END IF;
-- Perform transfer UPDATE accounts SET balance = balance - p_amount WHERE account_id = p_from_account;
UPDATE accounts SET balance = balance + p_amount WHERE account_id = p_to_account;
COMMIT; p_status := 'SUCCESS';
EXCEPTION WHEN e_insufficient_funds THEN ROLLBACK; p_status := 'INSUFFICIENT_FUNDS'; WHEN OTHERS THEN ROLLBACK; p_status := 'ERROR: ' || SQLERRM;END transfer_funds;/7.4 Packages
-- Package specificationCREATE OR REPLACE PACKAGE employee_pkg AS -- Types TYPE emp_rec IS RECORD ( emp_id NUMBER, emp_name VARCHAR2(100), salary NUMBER );
TYPE emp_tab IS TABLE OF emp_rec;
-- Constants c_max_salary CONSTANT NUMBER := 500000;
-- Procedures PROCEDURE hire_employee( p_name IN VARCHAR2, p_dept_id IN NUMBER, p_salary IN NUMBER );
-- Functions FUNCTION get_employee_count(p_dept_id IN NUMBER) RETURN NUMBER; FUNCTION get_department_employees(p_dept_id IN NUMBER) RETURN emp_tab PIPELINED;END employee_pkg;/
-- Package bodyCREATE OR REPLACE PACKAGE BODY employee_pkg AS
PROCEDURE hire_employee( p_name IN VARCHAR2, p_dept_id IN NUMBER, p_salary IN NUMBER ) AS BEGIN IF p_salary > c_max_salary THEN RAISE_APPLICATION_ERROR(-20001, 'Salary exceeds maximum'); END IF;
INSERT INTO employees (employee_id, employee_name, department_id, salary) VALUES (emp_seq.NEXTVAL, p_name, p_dept_id, p_salary);
COMMIT; END hire_employee;
FUNCTION get_employee_count(p_dept_id IN NUMBER) RETURN NUMBER AS v_count NUMBER; BEGIN SELECT COUNT(*) INTO v_count FROM employees WHERE department_id = p_dept_id;
RETURN v_count; END get_employee_count;
FUNCTION get_department_employees(p_dept_id IN NUMBER) RETURN emp_tab PIPELINED AS BEGIN FOR rec IN ( SELECT employee_id, employee_name, salary FROM employees WHERE department_id = p_dept_id ) LOOP PIPE ROW(emp_rec(rec.employee_id, rec.employee_name, rec.salary)); END LOOP; RETURN; END get_department_employees;
END employee_pkg;/7.5 Triggers
-- Row-level triggerCREATE OR REPLACE TRIGGER emp_audit_triggerAFTER INSERT OR UPDATE OR DELETE ON employeesFOR EACH ROWDECLARE v_action VARCHAR2(10);BEGIN IF INSERTING THEN v_action := 'INSERT'; ELSIF UPDATING THEN v_action := 'UPDATE'; ELSIF DELETING THEN v_action := 'DELETE'; END IF;
INSERT INTO emp_audit ( audit_id, employee_id, action, action_date, old_salary, new_salary, changed_by ) VALUES ( audit_seq.NEXTVAL, NVL(:NEW.employee_id, :OLD.employee_id), v_action, SYSDATE, :OLD.salary, :NEW.salary, USER );END;/
-- Statement-level triggerCREATE OR REPLACE TRIGGER dept_stats_triggerAFTER INSERT OR UPDATE OR DELETE ON employeesDECLAREBEGIN -- Update department statistics MERGE INTO department_stats t USING ( SELECT department_id, COUNT(*) as emp_count, AVG(salary) as avg_salary FROM employees GROUP BY department_id ) s ON (t.department_id = s.department_id) WHEN MATCHED THEN UPDATE SET t.emp_count = s.emp_count, t.avg_salary = s.avg_salary WHEN NOT MATCHED THEN INSERT (department_id, emp_count, avg_salary) VALUES (s.department_id, s.emp_count, s.avg_salary);END;/
-- INSTEAD OF trigger (for views)CREATE OR REPLACE TRIGGER emp_view_triggerINSTEAD OF INSERT ON emp_department_viewFOR EACH ROWBEGIN INSERT INTO employees (employee_id, employee_name, department_id) VALUES (:NEW.employee_id, :NEW.employee_name, :NEW.department_id);END;/7.6 Conversion Patterns for Unsupported Features
DBMS_AQ (Advanced Queuing) to HeliosDB Streaming
-- Oracle AQDBMS_AQ.ENQUEUE( queue_name => 'order_queue', message_properties => msg_props, payload => order_message);
-- HeliosDB: Use streaming tableINSERT INTO order_stream (order_id, order_data, created_at)VALUES (123, '{"customer": "ABC"}', CURRENT_TIMESTAMP);
-- Consumer reads from streamSELECT * FROM order_streamWHERE processed = FALSEORDER BY created_atFOR UPDATE SKIP LOCKEDLIMIT 10;Oracle Spatial to HeliosDB Geospatial
-- Oracle SDO_GEOMETRYSELECT * FROM storesWHERE SDO_WITHIN_DISTANCE( location, SDO_GEOMETRY(2001, 4326, SDO_POINT_TYPE(-73.98, 40.75, NULL), NULL, NULL), 'distance=10 unit=km') = 'TRUE';
-- HeliosDB geospatialSELECT * FROM storesWHERE ST_DWithin( location, ST_SetSRID(ST_MakePoint(-73.98, 40.75), 4326), 10000 -- meters);8. Application Connectivity
8.1 TNS Configuration
tnsnames.ora for HeliosDB
HELIOSDB = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = heliosdb-server)(PORT = 1521)) (CONNECT_DATA = (SERVICE_NAME = heliosdb) ) )
# High availability with multiple hostsHELIOSDB_HA = (DESCRIPTION = (LOAD_BALANCE = ON) (FAILOVER = ON) (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = helios1)(PORT = 1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = helios2)(PORT = 1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = helios3)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = heliosdb) ) )8.2 JDBC Configuration
import java.sql.*;import oracle.jdbc.pool.OracleDataSource;
public class HeliosDBConnection { public static void main(String[] args) throws SQLException { // Simple connection String url = "jdbc:oracle:thin:@//heliosdb-server:1521/heliosdb"; Connection conn = DriverManager.getConnection(url, "user", "password");
// With connection pool OracleDataSource ods = new OracleDataSource(); ods.setURL("jdbc:oracle:thin:@//heliosdb-server:1521/heliosdb"); ods.setUser("user"); ods.setPassword("password");
// Pool settings ods.setConnectionCacheEnabled(true); ods.setConnectionCacheName("HELIOS_POOL");
Properties cacheProps = new Properties(); cacheProps.setProperty("MinLimit", "5"); cacheProps.setProperty("MaxLimit", "50"); cacheProps.setProperty("InitialLimit", "10"); ods.setConnectionCacheProperties(cacheProps);
Connection pooledConn = ods.getConnection(); }}8.3 Python (oracledb) Configuration
import oracledb
# Thin mode (no Oracle Client needed)oracledb.init_oracle_client() # Optional for thick mode
# Simple connectionconnection = oracledb.connect( user="admin", password="password", dsn="heliosdb-server:1521/heliosdb")
# Connection poolpool = oracledb.create_pool( user="admin", password="password", dsn="heliosdb-server:1521/heliosdb", min=5, max=50, increment=5, threaded=True, getmode=oracledb.POOL_GETMODE_WAIT)
# Get connection from poolwith pool.acquire() as connection: with connection.cursor() as cursor: cursor.execute("SELECT * FROM employees WHERE department_id = :1", [10]) for row in cursor: print(row)8.4 Node.js (oracledb) Configuration
const oracledb = require('oracledb');
// Connection poolasync function initPool() { await oracledb.createPool({ user: 'admin', password: 'password', connectString: 'heliosdb-server:1521/heliosdb', poolMin: 5, poolMax: 50, poolIncrement: 5, poolTimeout: 60 });}
// Execute queryasync function runQuery() { let connection; try { connection = await oracledb.getConnection();
const result = await connection.execute( `SELECT employee_id, first_name, salary FROM employees WHERE department_id = :deptId`, { deptId: 10 }, { outFormat: oracledb.OUT_FORMAT_OBJECT } );
console.log(result.rows); } finally { if (connection) { await connection.close(); } }}8.5 .NET (ODP.NET) Configuration
using Oracle.ManagedDataAccess.Client;
// Connection stringstring connString = @" User Id=admin; Password=password; Data Source=heliosdb-server:1521/heliosdb; Pooling=true; Min Pool Size=5; Max Pool Size=50; Connection Timeout=30";
using (OracleConnection conn = new OracleConnection(connString)){ conn.Open();
using (OracleCommand cmd = conn.CreateCommand()) { cmd.CommandText = "SELECT * FROM employees WHERE department_id = :dept"; cmd.Parameters.Add("dept", OracleDbType.Int32).Value = 10;
using (OracleDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { Console.WriteLine($"{reader["EMPLOYEE_ID"]}: {reader["FIRST_NAME"]}"); } } }}9. Post-Migration Validation
9.1 Data Integrity Validation
Row Count Verification
-- Generate comparison queriesSELECT 'SELECT ''' || table_name || ''' as table_name, COUNT(*) as row_count FROM ' || owner || '.' || table_name || ';' as validation_queryFROM dba_tablesWHERE owner = 'HR'ORDER BY table_name;
-- Execute on both Oracle and HeliosDB, compare resultsChecksum Validation
-- Oracle: Generate row checksumsSELECT table_name, ORA_HASH( LISTAGG(column_value, '|') WITHIN GROUP (ORDER BY column_name) ) as table_checksumFROM ( SELECT c.table_name, c.column_name, SUM(ORA_HASH(c.column_name)) as column_value FROM dba_tab_columns c WHERE c.owner = 'HR' GROUP BY c.table_name, c.column_name)GROUP BY table_name;
-- Compare with HeliosDBSELECT table_name, HASH(STRING_AGG(column_value::text, '|' ORDER BY column_name)) as table_checksumFROM (...)GROUP BY table_name;9.2 Functional Validation
Stored Procedure Testing
-- Create test harnessCREATE TABLE migration_test_results ( test_id NUMBER PRIMARY KEY, test_name VARCHAR2(200), test_type VARCHAR2(50), oracle_result VARCHAR2(4000), helios_result VARCHAR2(4000), match_status VARCHAR2(20), test_date TIMESTAMP DEFAULT SYSTIMESTAMP);
-- Test procedure executionDECLARE v_oracle_result VARCHAR2(4000); v_helios_result VARCHAR2(4000);BEGIN -- Execute on Oracle v_oracle_result := test_procedure_on_oracle();
-- Execute on HeliosDB v_helios_result := test_procedure_on_heliosdb();
INSERT INTO migration_test_results ( test_id, test_name, test_type, oracle_result, helios_result, match_status ) VALUES ( test_seq.NEXTVAL, 'calculate_salary', 'FUNCTION', v_oracle_result, v_helios_result, CASE WHEN v_oracle_result = v_helios_result THEN 'PASS' ELSE 'FAIL' END );END;/9.3 Performance Validation
Query Performance Comparison
-- Capture Oracle execution timesSET TIMING ONSET AUTOTRACE ON
SELECT /*+ Oracle baseline */ *FROM employees eJOIN departments d ON e.department_id = d.department_idWHERE d.location_id = 1700;
-- Compare with HeliosDBEXPLAIN ANALYZESELECT *FROM employees eJOIN departments d ON e.department_id = d.department_idWHERE d.location_id = 1700;9.4 Validation Checklist
| Category | Validation Item | Status |
|---|---|---|
| Data | Row counts match | [ ] |
| Data | Checksums match | [ ] |
| Data | Sample data spot checks | [ ] |
| Schema | All tables created | [ ] |
| Schema | All indexes created | [ ] |
| Schema | All constraints active | [ ] |
| Schema | All sequences created | [ ] |
| PL/SQL | Procedures compile | [ ] |
| PL/SQL | Functions return correct values | [ ] |
| PL/SQL | Packages compile | [ ] |
| PL/SQL | Triggers fire correctly | [ ] |
| Security | Users created | [ ] |
| Security | Grants applied | [ ] |
| Performance | Key queries perform acceptably | [ ] |
| Application | Connection successful | [ ] |
| Application | CRUD operations work | [ ] |
| Application | Transactions commit/rollback | [ ] |
10. Performance Considerations
10.1 HeliosDB Performance Features
HeliosDB provides automatic performance optimizations:
| Feature | Description | Benefit |
|---|---|---|
| Auto-Indexing | ML-based index recommendations | 30-50% query improvement |
| Adaptive Query Execution | Runtime plan optimization | Handles data skew |
| Global Distributed Cache | Multi-tier caching | 10-100x repeated queries |
| Query Pattern Learning | Learns access patterns | Proactive optimization |
| Predicate Pushdown | Filter pushdown to storage | 3-10x faster scans |
10.2 Index Optimization
-- HeliosDB auto-index recommendationEXPLAIN ANALYZE SELECT * FROM ordersWHERE customer_id = 123 AND order_date > DATE '2024-01-01';
-- Review index recommendationsSELECT * FROM heliosdb_index_recommendationsWHERE table_name = 'orders';
-- Apply recommended indexesCREATE INDEX idx_orders_cust_date ON orders(customer_id, order_date);10.3 Statistics Collection
-- Analyze tables after migrationANALYZE TABLE employees COMPUTE STATISTICS;
-- For large tables, use samplingANALYZE TABLE large_orders ESTIMATE STATISTICS SAMPLE 10 PERCENT;
-- Schedule regular statistics updatesBEGIN DBMS_SCHEDULER.CREATE_JOB( job_name => 'NIGHTLY_STATS', job_type => 'PLSQL_BLOCK', job_action => 'BEGIN ANALYZE; END;', repeat_interval => 'FREQ=DAILY; BYHOUR=3' );END;/10.4 Query Tuning
-- Enable query hints (Oracle-compatible)SELECT /*+ INDEX(e idx_emp_dept) */ *FROM employees eWHERE department_id = 10;
-- Parallel query executionSELECT /*+ PARALLEL(orders, 8) */ customer_id, SUM(amount)FROM ordersGROUP BY customer_id;
-- Use EXPLAIN PLANEXPLAIN PLAN FORSELECT * FROM employees WHERE department_id = 10;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);10.5 Memory and Resource Tuning
# HeliosDB configuration (heliosdb.toml)[oracle.memory]pga_aggregate_target = "4GB"sort_area_size = 256000hash_area_size = 512000
[oracle.optimizer]mode = "ALL_ROWS"cost_based = truequery_rewrite = true
[cache]query_result_cache_size = "1GB"metadata_cache_size = "256MB"11. Common Issues and Troubleshooting
11.1 Connection Issues
Error: ORA-12154 (TNS Alias Not Found)
Cause: TNS name not in tnsnames.ora or LDAP
Solution:
# Verify tnsnames.ora locationecho $TNS_ADMINcat $TNS_ADMIN/tnsnames.ora
# Test with Easy Connectsqlplus admin/password@//heliosdb-server:1521/heliosdbError: ORA-12541 (No Listener)
Cause: HeliosDB Oracle protocol not running
Solution:
# Check HeliosDB Oracle listener statusheliosdb status --protocol oracle
# Verify port is opennetstat -an | grep 1521telnet heliosdb-server 152111.2 SQL Compatibility Issues
Error: Invalid Column Name/Type
Cause: Reserved word or unsupported type
Solution:
-- Quote reserved wordsSELECT "LEVEL", "SIZE", "DATE" FROM my_table;
-- Check for unsupported typesSELECT column_name, data_typeFROM user_tab_columnsWHERE data_type IN ('SDO_GEOMETRY', 'ANYDATA', 'BFILE');Error: PL/SQL Compilation Error
Cause: Unsupported syntax or package
Solution:
-- Show compilation errorsSHOW ERRORS PROCEDURE my_procedure;
-- Check for unsupported packagesSELECT name, textFROM user_sourceWHERE UPPER(text) LIKE '%DBMS_AQ%' -- Not supported OR UPPER(text) LIKE '%SDO_%'; -- Not supported11.3 Data Migration Issues
Large Object (LOB) Migration Errors
Cause: LOB size or corruption
Solution:
-- Verify LOB integrity on OracleSELECT table_name, column_name, segment_nameFROM dba_lobsWHERE owner = 'HR';
-- Check for corrupted LOBsSELECT id, DBMS_LOB.GETLENGTH(document) as lob_lengthFROM documentsWHERE DBMS_LOB.GETLENGTH(document) IS NULL;Character Set Conversion Issues
Cause: Different character sets
Solution:
-- Check Oracle character setSELECT parameter, valueFROM nls_database_parametersWHERE parameter IN ('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET');
-- Configure HeliosDB to matchALTER SESSION SET NLS_CHARACTERSET = 'AL32UTF8';11.4 Performance Issues
Slow Queries After Migration
Cause: Missing statistics or indexes
Solution:
-- Rebuild statisticsANALYZE TABLE slow_table COMPUTE STATISTICS;
-- Check for missing indexesSELECT * FROM heliosdb_index_recommendationsWHERE estimated_improvement > 50;
-- Force index usage if neededSELECT /*+ INDEX(t idx_name) */ * FROM slow_table t WHERE ...;High Memory Usage
Cause: Large result sets or inefficient queries
Solution:
-- Use paginationSELECT * FROM large_tableWHERE ROWNUM <= 1000OFFSET 0 ROWS;
-- Enable result set streamingSET ARRAYSIZE 10011.5 Error Code Mapping
| Oracle Error | HeliosDB Error | Resolution |
|---|---|---|
| ORA-00001 | Unique constraint violation | Same handling |
| ORA-00054 | Resource busy | Retry transaction |
| ORA-00060 | Deadlock detected | Auto-resolved, retry |
| ORA-01403 | No data found | Same handling |
| ORA-01422 | Too many rows | Same handling |
| ORA-01555 | Snapshot too old | Increase retention |
| ORA-04031 | Shared pool exhausted | Increase cache size |
12. Rollback Procedures
12.1 Pre-Migration Rollback Preparation
Before starting migration, ensure rollback capability:
-- Create rollback savepoint in OracleCREATE RESTORE POINT pre_migration GUARANTEE FLASHBACK DATABASE;
-- Document current Oracle configurationSELECT name, value FROM v$parameter ORDER BY name;
-- Export application connection strings-- Document all TNS entries12.2 During Migration Rollback
If migration fails mid-process:
# Stop HeliosDB data ingestionheliosdb migration pause --job-id <migration-job>
# Verify Oracle is still primarysqlplus admin/password@ORACLE_PRIMARY
# Check Oracle Data Guard sync status (if using)SELECT database_role, open_mode FROM v$database;12.3 Post-Migration Rollback
If issues are discovered after cutover:
Step 1: Switch Back to Oracle
# Update DNS/Load balancer to point to Oracle# Update application connection strings
# For applications using TNS# Edit tnsnames.ora to point back to OraclePRODUCTION = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = oracle-server)(PORT = 1521)) (CONNECT_DATA = (SERVICE_NAME = ORCL)) )Step 2: Sync Data Back to Oracle
-- If using parallel write during migration-- Data should already be in Oracle
-- If not, export from HeliosDBEXPORT TABLE changed_data TO '/backup/changes.dmp'WHERE modified_date > TO_DATE('2024-01-15', 'YYYY-MM-DD');
-- Import to Oracleimpdp system/password@ORCL \ DUMPFILE=changes.dmp \ DIRECTORY=DUMP_DIR \ TABLE_EXISTS_ACTION=REPLACEStep 3: Restore Oracle from Flashback
-- If Oracle Flashback was configuredSHUTDOWN IMMEDIATE;STARTUP MOUNT;FLASHBACK DATABASE TO RESTORE POINT pre_migration;ALTER DATABASE OPEN RESETLOGS;12.4 Rollback Checklist
| Step | Action | Status |
|---|---|---|
| 1 | Stop HeliosDB writes | [ ] |
| 2 | Verify Oracle connectivity | [ ] |
| 3 | Update connection strings | [ ] |
| 4 | Test application connectivity | [ ] |
| 5 | Sync any delta data | [ ] |
| 6 | Validate data integrity | [ ] |
| 7 | Resume Oracle operations | [ ] |
| 8 | Notify stakeholders | [ ] |
12.5 Rollback Decision Criteria
Consider rollback if:
- Data integrity issues that cannot be resolved within SLA
- Performance degradation >50% on critical queries
- Application functionality failures affecting users
- Security vulnerabilities discovered
- Unplanned extended downtime
Do NOT rollback for:
- Minor performance differences (optimize instead)
- Cosmetic issues in monitoring/tooling
- Non-critical feature differences
- Issues with clear workarounds
Appendix A: Quick Reference Card
Essential Commands
-- Connect to HeliosDB via Oracle protocolsqlplus admin/password@//heliosdb:1521/heliosdb
-- Check Oracle compatibility modeSELECT SYS_CONTEXT('USERENV', 'DB_NAME') FROM DUAL;
-- View active sessionsSELECT * FROM v$session WHERE type = 'USER';
-- Check PL/SQL compilationSHOW ERRORS PROCEDURE <name>;
-- Analyze performanceEXPLAIN PLAN FOR <query>;SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);Configuration Files
| File | Location | Purpose |
|---|---|---|
| tnsnames.ora | $TNS_ADMIN/ | Connection aliases |
| heliosdb.toml | /etc/heliosdb/ | Server configuration |
| listener.ora | $TNS_ADMIN/ | Not needed for HeliosDB |
Support Resources
- HeliosDB Oracle Protocol Documentation:
/docs/reference/protocols/oracle/ - Migration Tools:
heliosdb migrate --help - Support: support@heliosdb.io
Appendix B: Migration Timeline Template
| Week | Phase | Activities |
|---|---|---|
| 1 | Assessment | Inventory, complexity analysis |
| 2 | Planning | Design migration strategy, create test plan |
| 3-4 | Schema Migration | Export DDL, translate, create in HeliosDB |
| 5-6 | Data Migration | Initial data load, verify |
| 7-8 | PL/SQL Migration | Convert procedures, functions, packages |
| 9 | Testing | Functional testing, performance testing |
| 10 | Parallel Run | Dual-write, validate |
| 11 | Cutover | Switch primary to HeliosDB |
| 12 | Stabilization | Monitor, optimize, close out |
Related Documentation:
- Oracle Protocol Configuration
- Oracle Compatibility Reference
- Oracle SQL Examples
- General Migration Guide
Document History:
- v1.0 (January 2026): Initial comprehensive guide