Oracle to PostgreSQL Time-Window Data Reload Implementation Guide
Overview
Prerequisites
Step 1: Prepare Target PostgreSQL Environment
-- Connect to your PostgreSQL database psql -h <postgres-host> -p <postgres-port> -U <username> -d <database> -- Create staging schema CREATE SCHEMA IF NOT EXISTS staging; -- Create staging tables mirroring your production tables CREATE TABLE staging.customers ( customer_id INTEGER PRIMARY KEY, name VARCHAR(100), email VARCHAR(100), status VARCHAR(20), created_at TIMESTAMP, updated_at TIMESTAMP, _dms_processing_status VARCHAR(20) DEFAULT 'NEW' ); CREATE TABLE staging.orders ( order_id INTEGER PRIMARY KEY, customer_id INTEGER, amount NUMERIC(10,2), order_date TIMESTAMP, updated_at TIMESTAMP, _dms_processing_status VARCHAR(20) DEFAULT 'NEW' ); -- Create indexes for optimization CREATE INDEX idx_customers_updated_at ON staging.customers(updated_at); CREATE INDEX idx_orders_updated_at ON staging.orders(updated_at); -- Create admin schema for logging and monitoring CREATE SCHEMA IF NOT EXISTS admin; -- Create log tables CREATE TABLE admin.merge_logs ( id SERIAL PRIMARY KEY, table_name VARCHAR(100), merge_time TIMESTAMP, records_updated INT, records_inserted INT ); CREATE TABLE admin.merge_summary ( id SERIAL PRIMARY KEY, merge_start TIMESTAMP, merge_end TIMESTAMP, status VARCHAR(20), notes TEXT );CREATE OR REPLACE PROCEDURE merge_time_window_data() LANGUAGE plpgsql AS $$ DECLARE merge_start_time TIMESTAMP; merge_end_time TIMESTAMP; records_updated INT; records_inserted INT; BEGIN -- Record start time for logging merge_start_time := CURRENT_TIMESTAMP; -- Begin transaction BEGIN -- Merge customers table WITH updated_rows AS ( UPDATE production.customers p SET name = s.name, email = s.email, status = s.status, updated_at = s.updated_at FROM staging.customers s WHERE p.customer_id = s.customer_id AND s.updated_at > p.updated_at RETURNING p.customer_id ) SELECT COUNT(*) INTO records_updated FROM updated_rows; -- Insert new records WITH inserted_rows AS ( INSERT INTO production.customers SELECT s.customer_id, s.name, s.email, s.status, s.created_at, s.updated_at FROM staging.customers s LEFT JOIN production.customers p ON s.customer_id = p.customer_id WHERE p.customer_id IS NULL RETURNING 1 ) SELECT COUNT(*) INTO records_inserted FROM inserted_rows; -- Log merge results INSERT INTO admin.merge_logs (table_name, merge_time, records_updated, records_inserted) VALUES ('customers', CURRENT_TIMESTAMP, records_updated, records_inserted); -- Repeat for orders table WITH updated_orders AS ( UPDATE production.orders p SET customer_id = s.customer_id, amount = s.amount, order_date = s.order_date, updated_at = s.updated_at FROM staging.orders s WHERE p.order_id = s.order_id AND s.updated_at > p.updated_at RETURNING p.order_id ) SELECT COUNT(*) INTO records_updated FROM updated_orders; WITH inserted_orders AS ( INSERT INTO production.orders SELECT s.order_id, s.customer_id, s.amount, s.order_date, s.updated_at FROM staging.orders s LEFT JOIN production.orders p ON s.order_id = p.order_id WHERE p.order_id IS NULL RETURNING 1 ) SELECT COUNT(*) INTO records_inserted FROM inserted_orders; INSERT INTO admin.merge_logs (table_name, merge_time, records_updated, records_inserted) VALUES ('orders', CURRENT_TIMESTAMP, records_updated, records_inserted); -- Mark all staging records as processed UPDATE staging.customers SET _dms_processing_status = 'PROCESSED'; UPDATE staging.orders SET _dms_processing_status = 'PROCESSED'; -- Commit transaction COMMIT; merge_end_time := CURRENT_TIMESTAMP; -- Log overall merge statistics INSERT INTO admin.merge_summary (merge_start, merge_end, status, notes) VALUES (merge_start_time, merge_end_time, 'SUCCESS', 'Merged Oracle data from time window'); EXCEPTION WHEN OTHERS THEN -- Roll back transaction on error ROLLBACK; -- Log error INSERT INTO admin.merge_summary (merge_start, merge_end, status, notes) VALUES (merge_start_time, CURRENT_TIMESTAMP, 'FAILED', 'Error: ' || SQLERRM); -- Re-raise exception RAISE; END; END; $$;CREATE OR REPLACE VIEW admin.oracle_pg_migration_status AS SELECT 'customers' AS table_name, COUNT(*) AS total_records, SUM(CASE WHEN _dms_processing_status = 'NEW' THEN 1 ELSE 0 END) AS pending_records, SUM(CASE WHEN _dms_processing_status = 'PROCESSED' THEN 1 ELSE 0 END) AS processed_records, SUM(CASE WHEN _dms_processing_status = 'ERROR' THEN 1 ELSE 0 END) AS error_records FROM staging.customers UNION ALL SELECT 'orders' AS table_name, COUNT(*) AS total_records, SUM(CASE WHEN _dms_processing_status = 'NEW' THEN 1 ELSE 0 END) AS pending_records, SUM(CASE WHEN _dms_processing_status = 'PROCESSED' THEN 1 ELSE 0 END) AS processed_records, SUM(CASE WHEN _dms_processing_status = 'ERROR' THEN 1 ELSE 0 END) AS error_records FROM staging.orders;
Step 2: Configure DMS Time-Window Migration
Step 3: Create and Run the Orchestration Script
Step 4: Monitor and Validate the Process
Step 5: Troubleshooting Common Issues
Step 6: Finalizing the Process
Additional Considerations
Last updated