Search docs.molo17.com
    Configuration guide Connectors

    Set up Oracle LogMiner CDC end to end

    This guide takes you from an Oracle database that is not ready for change data capture to a running Gluesync pipeline that copies an Oracle schema to PostgreSQL with a snapshot and live changes. The database work is written for the DBA and is done once. The rest is done in the Control Plane. The last part shows what you see when a grant is missing, when supplemental logging is off, when the archived redo logs are gone, and after a database restart, and how to recover each time.

    In this guide

    You will learn how to enable ARCHIVELOG mode and supplemental logging, create a dedicated LogMiner user and a data user with only the grants Gluesync needs, create an Oracle LogMiner source connection and a PostgreSQL target connection, map two tables, run a snapshot followed by CDC, check inserts, updates and deletes with SQL, choose between service name, SID, a custom connection string and a TNS alias with a wallet, and recover from the failures that customers meet most often.

    Quick information

    Goal

    Replicate an Oracle multitenant database (CDB with a PDB) to PostgreSQL with Oracle LogMiner, using users that have only the required grants

    Audience

    Oracle DBAs and Gluesync users who set up and operate Oracle sources

    Level

    Intermediate

    Time required

    About 60 minutes

    Area

    Oracle database → Control Plane → Data pipelines → Oracle LogMiner source

    Applies to

    Gluesync 2.3

    Before you begin

    Make sure that:

    1. You have an Oracle Database 19c or later with a container database (CDB) and a pluggable database (PDB), and you can connect to it as SYSDBA (the guide uses the CDB ORCLCDB and the PDB ORCL);

    2. The Oracle listener accepts connections from the host that runs Core Hub, on the port that you will enter in Gluesync (the guide uses oracle-logminer-docs:1521);

    3. You have a schema with the tables to replicate. The examples use the tables CUSTOMERS and ORDERS in the schema SHOP (see the optional first step if you want to create them);

    4. You have a PostgreSQL target that Core Hub can reach, with a schema that already contains empty tables with matching columns (the examples use the schema ora_cdc);

    5. You can sign in to the Gluesync Control Plane with a role that can create pipelines;

    6. You can run SQL against the Oracle database and the PostgreSQL target, for example with SQL*Plus and psql.

    Enabling ARCHIVELOG mode needs a restart of the Oracle instance. Plan it with the owners of the database. Do not follow the troubleshooting experiments in this guide (deleting archived logs, switching supplemental logging off, restarting the instance) on a production database.

    This guide covers a CDB with a PDB, which is the default layout of Oracle 19c. For a database without containers (single instance) the steps are the same except that the LogMiner user is an ordinary user (without the C## prefix) created in that database, and the LogMiner database is the same service as the Database name. See Oracle LogMiner setup (single-instance). Oracle RAC has extra settings that this guide does not cover: see Oracle LogMiner agent.

    Guide steps

    Optional: create the sample tables

    SQL

    Skip this step if you already have the tables to replicate. It creates the schema SHOP in the PDB, with 200 customers and 1,000 orders, and the empty target tables in PostgreSQL.

    1. Connect to the CDB as SYSDBA and run the Oracle script;

    2. Connect to the PostgreSQL target and run the PostgreSQL script.

    -- Oracle, as SYSDBA, in the PDB
    ALTER SESSION SET CONTAINER = ORCL;
    
    CREATE USER SHOP IDENTIFIED BY "<shop password>" DEFAULT TABLESPACE USERS QUOTA UNLIMITED ON USERS;
    GRANT CREATE SESSION TO SHOP;
    
    CREATE TABLE SHOP.CUSTOMERS (
      ID           NUMBER(10)    PRIMARY KEY,
      FULL_NAME    VARCHAR2(100) NOT NULL,
      EMAIL        VARCHAR2(150),
      COUNTRY      VARCHAR2(2),
      TIER         VARCHAR2(10),
      STATUS       VARCHAR2(10),
      CREDIT_LIMIT NUMBER(12,2),
      CREATED_AT   TIMESTAMP DEFAULT SYSTIMESTAMP
    );
    
    CREATE TABLE SHOP.ORDERS (
      ID          NUMBER(10)    PRIMARY KEY,
      CUSTOMER_ID NUMBER(10)    NOT NULL,
      AMOUNT      NUMBER(12,2),
      CURRENCY    VARCHAR2(3),
      STATUS      VARCHAR2(10),
      ORDER_DATE  DATE
    );
    
    INSERT INTO SHOP.CUSTOMERS
    SELECT LEVEL, 'Customer '||LEVEL, 'customer'||LEVEL||'@example.com',
      CASE MOD(LEVEL,8) WHEN 0 THEN 'IT' WHEN 1 THEN 'DE' WHEN 2 THEN 'US' WHEN 3 THEN 'FR'
                        WHEN 4 THEN 'ES' WHEN 5 THEN 'GB' WHEN 6 THEN 'JP' ELSE 'BR' END,
      CASE MOD(LEVEL,4) WHEN 0 THEN 'bronze' WHEN 1 THEN 'silver' WHEN 2 THEN 'gold' ELSE 'platinum' END,
      CASE WHEN MOD(LEVEL,7)=0 THEN 'suspended' WHEN MOD(LEVEL,5)=0 THEN 'inactive' ELSE 'active' END,
      1000 + MOD(LEVEL,10)*500, SYSTIMESTAMP
    FROM DUAL CONNECT BY LEVEL <= 200;
    
    INSERT INTO SHOP.ORDERS
    SELECT LEVEL, MOD(LEVEL,200)+1, ROUND(10 + MOD(LEVEL*37,490) + MOD(LEVEL,100)/100,2),
      CASE MOD(LEVEL,3) WHEN 0 THEN 'EUR' WHEN 1 THEN 'USD' ELSE 'GBP' END,
      CASE MOD(LEVEL,5) WHEN 0 THEN 'new' WHEN 1 THEN 'paid' WHEN 2 THEN 'shipped'
                        WHEN 3 THEN 'delivered' ELSE 'cancelled' END,
      TRUNC(SYSDATE) - MOD(LEVEL,90)
    FROM DUAL CONNECT BY LEVEL <= 1000;
    COMMIT;
    -- PostgreSQL target
    CREATE SCHEMA IF NOT EXISTS ora_cdc;
    
    CREATE TABLE ora_cdc.customers (
      id           numeric(10,0) PRIMARY KEY,
      full_name    varchar(100)  NOT NULL,
      email        varchar(150),
      country      varchar(2),
      tier         varchar(10),
      status       varchar(10),
      credit_limit numeric(12,2),
      created_at   timestamp
    );
    
    CREATE TABLE ora_cdc.orders (
      id          numeric(10,0) PRIMARY KEY,
      customer_id numeric(10,0) NOT NULL,
      amount      numeric(12,2),
      currency    varchar(3),
      status      varchar(10),
      order_date  timestamp
    );
    Expected result

    SELECT COUNT(*) FROM SHOP.CUSTOMERS returns 200 and SELECT COUNT(*) FROM SHOP.ORDERS returns 1000 in Oracle. The two PostgreSQL tables exist and are empty.

    With a PostgreSQL target, if you pick a target table that does not exist, the field mapping dialog shows Target table has no columns and you cannot continue. Create the tables first, as above.

    Enable ARCHIVELOG mode

    SQL

    LogMiner reads the redo that Oracle writes. Oracle keeps that redo available after the online redo logs are reused only when the database archives them, so the database must run in ARCHIVELOG mode.

    1. Connect to the CDB root as SYSDBA (for example with sqlplus / as sysdba);

    2. Check the current mode. If it already returns ARCHIVELOG, skip the next two actions;

    3. Restart the instance in the mount state and switch the mode;

    4. Open the database and the pluggable databases, and save the state of the pluggable databases, so that they open again after a restart.

    SELECT log_mode FROM v$database;
    
    SHUTDOWN IMMEDIATE
    STARTUP MOUNT
    ALTER DATABASE ARCHIVELOG;
    ALTER DATABASE OPEN;
    
    ALTER PLUGGABLE DATABASE ALL OPEN;
    ALTER PLUGGABLE DATABASE ALL SAVE STATE;
    
    ARCHIVE LOG LIST
    Expected result

    SELECT log_mode FROM v$database returns ARCHIVELOG, and ARCHIVE LOG LIST reads Database log mode: Archive Mode and Automatic archival: Enabled. Note the Archive destination: it is the folder that you must keep free (see Keep the archived logs, and free space safely).

    ALTER PLUGGABLE DATABASE ALL SAVE STATE matters later. Without it, a restarted instance leaves the PDB closed, and Gluesync reports ORA-16331: container "ORCL" is not open until a DBA opens it (see After a database restart).

    Enable supplemental logging for the database

    SQL

    Supplemental logging makes Oracle write extra columns into the redo, so that LogMiner can tell which row a change belongs to. Database-level logging is required.

    1. In the CDB root, enable minimal and primary key supplemental logging;

    2. Check the result.

    ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
    ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS;
    
    SELECT supplemental_log_data_min, supplemental_log_data_pk FROM v$database;
    Expected result

    The query returns YES in both columns.

    If database-level supplemental logging is off, Gluesync does not report an error and the entities stay Active, but no insert, update or delete reaches the target. See Supplemental logging is off.

    Create the LogMiner user with only the required grants

    SQL

    Gluesync uses two Oracle users. The LogMiner user connects to the CDB root and reads the redo of every PDB, so it is a common user (its name starts with C##). The data user connects to the PDB and reads the tables for the snapshot. Keeping them separate lets you give each one the least privilege.

    1. In the CDB root, create the common user;

    2. Grant it the five privileges below, for all containers.

    CREATE USER C##GS_LOGMINER IDENTIFIED BY "<LogMiner password>" CONTAINER=ALL;
    
    GRANT CREATE SESSION,
          LOGMINING,
          SELECT ANY TRANSACTION,
          EXECUTE_CATALOG_ROLE,
          SELECT_CATALOG_ROLE
       TO C##GS_LOGMINER CONTAINER=ALL;
    Grant What Gluesync uses it for What you see without it

    CREATE SESSION

    Log in to the CDB root.

    ORA-01045: user C##GS_LOGMINER lacks CREATE SESSION privilege; logon denied.

    LOGMINING

    Start a LogMiner session and read the changes.

    ORA-01031: insufficient privileges, with SYS.DBMS_LOGMNR in the message.

    EXECUTE_CATALOG_ROLE

    Run the DBMS_LOGMNR package.

    PLS-00201: identifier 'DBMS_LOGMNR' must be declared.

    SELECT_CATALOG_ROLE

    Read the V$ and GV$ views that hold the log files, the archived logs, the current SCN and the open transactions. SELECT ANY DICTIONARY, which the agent reference pages list, also works (we ran the pipeline with it instead) and gives more access than needed.

    ORA-00942: table or view does not exist.

    SELECT ANY TRANSACTION

    The agent checks for it and the agent reference pages list it. In our test on Oracle 19c Gluesync replicated inserts, updates and deletes also with this privilege revoked, so it is the one grant that you can drop if your security team requires the strictest minimum.

    Nothing visible in our test.

    Expected result

    SELECT privilege FROM dba_sys_privs WHERE grantee = 'C##GS_LOGMINER' returns CREATE SESSION, LOGMINING and SELECT ANY TRANSACTION, and SELECT granted_role FROM dba_role_privs WHERE grantee = 'C##GS_LOGMINER' returns EXECUTE_CATALOG_ROLE and SELECT_CATALOG_ROLE.

    You do not need SET CONTAINER, ALTER USER …​ SET CONTAINER_DATA = ALL, a default tablespace or a quota for this user, which the multitenant setup page of the agent reference includes. The user owns no data and connects to the CDB root only. We ran the whole guide without them.

    Create the data user and enable table-level logging in the PDB

    SQL

    1. Switch to the PDB;

    2. Create the data user, with the right to log in only;

    3. Enable full (all columns) supplemental logging on every table that you replicate;

    4. Grant SELECT on those tables to the data user and to the LogMiner user.

    ALTER SESSION SET CONTAINER = ORCL;
    
    CREATE USER GS_READER IDENTIFIED BY "<data user password>";
    GRANT CREATE SESSION TO GS_READER;
    
    ALTER TABLE SHOP.CUSTOMERS ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS;
    ALTER TABLE SHOP.ORDERS    ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS;
    
    GRANT SELECT ON SHOP.CUSTOMERS TO GS_READER;
    GRANT SELECT ON SHOP.ORDERS    TO GS_READER;
    GRANT SELECT ON SHOP.CUSTOMERS TO C##GS_LOGMINER;
    GRANT SELECT ON SHOP.ORDERS    TO C##GS_LOGMINER;
    Expected result

    SELECT table_name, log_group_type FROM dba_log_groups WHERE owner = 'SHOP' returns one ALL COLUMN LOGGING group for each table. The data user has CREATE SESSION and SELECT on the tables only.

    Full table-level logging is recommended, not mandatory. Without it Oracle writes only the changed columns of an update, and Gluesync reads the full row again from the source for every update. In our test that returned correct data. It costs one extra read for each update, so use it for every table that changes often.

    Open the pipeline wizard and select Oracle LogMiner

    UI

    1. Open Data pipelines;

    2. Select the + button (Create pipeline) above the list of pipelines. The Agents setup wizard opens on 1. Setup source;

    3. Select the Oracle Database tile. The tile shows 4 connectors available;

    4. Select Oracle LogMiner agent.

    Agents setup wizard with the Oracle Database tile selected and the four connectors listed; the Oracle LogMiner agent is marked with annotation 1
    Figure 1. Select the Oracle Database tile, then the Oracle LogMiner agent.
    Expected result

    The connection form of the Oracle LogMiner agent opens, with the tabs Base settings and Advanced settings.

    Enter the source connection and test it

    UI

    1. In Host name / Address and Port, enter the Oracle listener (oracle-logminer-docs and 1521);

    2. In Database name, enter the service name of the PDB (ORCL);

    3. In Username and Password, enter the data user (GS_READER);

    4. In LogMiner username and LogMiner password, enter the common user (C##GS_LOGMINER);

    5. In LogMiner database, enter the service name of the CDB root (ORCLCDB);

    6. Optional: under Advanced connection properties select Add property, select the key Connection type and check the value. The default is SERVICE_NAME;

    7. Select Test and continue.

    Oracle LogMiner connection form filled with host
    Figure 2. Annotation 1 is the listener, 2 the PDB service, 3 the data user, 4 the LogMiner user, 5 the CDB root service, 6 the connection type and 7 the test button.
    Expected result

    The wizard shows the source card Oracle Database with GS_READER@oracle-logminer-docs:1521 and a green check mark. Select Next.

    Setup source step showing the Oracle Database card with the green check mark
    Figure 3. Annotation 1 is the tested source connection and 2 the Next button.

    The test checks the data user only. In our test a wrong LogMiner password also passed it, so the green check does not prove that the LogMiner credentials are right. Before you continue, connect as the LogMiner user to the CDB root service (for example sqlplus "C##GS_LOGMINER"@//oracle-logminer-docs:1521/ORCLCDB). A missing LogMiner grant shows up only when the first entity starts, as a notification (see A grant is missing).

    Do not leave an empty row in Advanced settings (an Add property row without a key). Test and continue then does nothing and the error is shown only on the Advanced settings tab, which is easy to miss. Delete the empty row with its trash icon.

    Add the PostgreSQL target and name the pipeline

    UI

    1. On 2. Setup target(s), search for postgres and select PostgreSQL CDC agent;

    2. Enter Host name / Address, Port, Database name, Username and Password of the target (the examples use pgsql-target, 5432 and shop);

    3. Select Test and continue, then Next;

    4. On 3. Ready, enter Oracle LogMiner demo in Pipeline name;

    5. Select Finish.

    Setup target step with the search field containing postgres and the PostgreSQL CDC agent card marked with annotation 1
    Figure 4. Select the PostgreSQL agent.
    PostgreSQL connection form with host pgsql-target
    Figure 5. Annotation 1 is the listener of the target, 2 the database, 3 the target user and 4 the test button.
    Ready step with the pipeline name Oracle LogMiner demo marked 1 and the Finish button marked 2
    Figure 6. Name the pipeline and select Finish.
    Expected result

    The pipeline Oracle LogMiner demo opens with the message No entities found, the source icon of Oracle and the status chip Active.

    Select the tables and map them to the target schema

    UI

    1. In the pipeline, select Entities. The page Listing database objects for ORCL opens;

    2. In the Object browser, expand the schema SHOP and tick CUSTOMERS and ORDERS;

    3. In Selected entities, select the Field mapping icon of CUSTOMERS;

    4. In Target Schema, enter ora_cdc and select it from the list. In Target Table, select customers;

    5. Check that every field of the source is linked to a field of the target, then select Confirm;

    6. Repeat for ORDERS, with the target table orders;

    7. Select Confirm and continue.

    Field mapping dialog with the source SHOP.CUSTOMERS on the left and the target ora_cdc.customers on the right
    Figure 7. Annotation 1 is the target schema, 2 the target table and 3 the Confirm button of the field mapping dialog.
    Object browser with the schema SHOP expanded
    Figure 8. Annotation 1 is the schema, 2 the ticked tables, 3 the target shown next to each table and 4 Confirm and continue.
    Expected result

    The pipeline shows the entities SHOP.CUSTOMERS and SHOP.ORDERS in the Hold group.

    Check the Target Schema of every entity. The dialog suggests a target schema that matches the name of the source schema (shop here). If a schema with that name exists on the target, it can already contain tables with the same names, and the entity would write into them.

    Start the snapshot and CDC

    UI

    1. Select the checkbox in the header of the entity table to select both entities;

    2. Select Start CDC in the blue bar. The dialog Sync changes (CDC) opens;

    3. In Start from, keep Full copy (Recommended for the first start);

    4. In Data already in the target, keep Keep and merge;

    5. Select Start entity.

    Sync changes (CDC) dialog with the Full copy tile marked 1
    Figure 9. Annotation 1 is Full copy, 2 is Keep and merge and 3 is Start entity.
    Entity table with SHOP.CUSTOMERS and SHOP.ORDERS in the Active group with the green CDC icon
    Figure 10. Annotation 1 is the Active group and 2 the entities with the CDC status icon.
    Expected result

    Within a few seconds both entities move to the Active group. The snapshot has copied 200 customers and 1,000 orders and Gluesync now follows the redo for new changes.

    Check the snapshot

    UI + SQL

    1. Open the entity SHOP.CUSTOMERS (the chevron at the end of its row);

    2. In Inspect tables, select Count both;

    3. In PostgreSQL, count the rows of both tables.

    Entity detail page of SHOP.CUSTOMERS with Count both marked 1
    Figure 11. Annotation 1 is Count both, 2 the source count and 3 the target count.
    SELECT 'customers' AS table_name, count(*) FROM ora_cdc.customers
    UNION ALL
    SELECT 'orders', count(*) FROM ora_cdc.orders;
    Expected result

    Count both shows 200 on both sides with a difference of 0, and the query returns 200 for customers and 1000 for orders.

    Check inserts, updates and deletes

    SQL

    Run each Oracle statement as the owner of the tables (here SHOP), then run the PostgreSQL query. Put each statement on its own line, and run COMMIT as its own statement, so that the transaction is committed. Gluesync reads the redo only after the commit.

    1. Insert a customer in Oracle and look for it in PostgreSQL;

    2. Update the same customer and check the target;

    3. Delete the customer and check that it is gone.

    -- Oracle
    INSERT INTO SHOP.CUSTOMERS (ID, FULL_NAME, EMAIL, COUNTRY, TIER, STATUS, CREDIT_LIMIT)
      VALUES (201, 'Ada Lovelace', 'ada@example.com', 'GB', 'gold', 'active', 5000);
    COMMIT;
    
    -- PostgreSQL, after about 10 seconds
    SELECT id, full_name, tier, credit_limit FROM ora_cdc.customers WHERE id = 201;
    -- Oracle
    UPDATE SHOP.CUSTOMERS SET TIER = 'platinum', CREDIT_LIMIT = 9000 WHERE ID = 201;
    COMMIT;
    
    -- PostgreSQL
    SELECT id, full_name, tier, credit_limit FROM ora_cdc.customers WHERE id = 201;
    -- Oracle
    DELETE FROM SHOP.CUSTOMERS WHERE ID = 201;
    COMMIT;
    
    -- PostgreSQL
    SELECT count(*) FROM ora_cdc.customers WHERE id = 201;
    Expected result

    After the insert the query returns 201 | Ada Lovelace | gold | 5000.00. After the update it returns 201 | Ada Lovelace | platinum | 9000.00, with the name unchanged. After the delete it returns 0. A transaction that changes many rows (for example 500 inserted, 100 updated and 100 deleted orders) arrives complete: the counts and the sum of amount match on both sides.

    Choose how Gluesync connects to Oracle

    The connection form has more than the fields that you filled in. This table lists what we tested.

    Option How to set it What we observed

    Service name

    Database name holds the service name of the PDB (ORCL). LogMiner database holds the service name of the CDB root (ORCLCDB). Connection type is SERVICE_NAME by default.

    Works with a listener that registers the services dynamically, which is the default of Oracle 19c.

    SID

    Under Advanced connection properties, add Connection type and enter SID. Database name and LogMiner database then hold SIDs.

    A PDB has no SID. With SID and a listener that registers only services, Test and continue fails with ORA-12505: Cannot connect to database. SID ORCL is not registered with the listener. Use SID only for a database whose SID the listener knows.

    Custom connection string

    In Base settings, under Settings, enter a JDBC descriptor in Connection string, for example jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracle-logminer-docs)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCL))).

    Test and continue succeeds. The string replaces the connection of the data user. The LogMiner connection is built from the host, the port and LogMiner database.

    TNS alias with a wallet folder

    Under Advanced connection properties add Use wallet (switch on), Instance name (the TNS alias of the data user’s database, for example GS_ORCL), Wallet path (the folder that contains tnsnames.ora, as Core Hub sees it) and LogMiner instance name (the TNS alias of the CDB root, for example GS_ORCLCDB).

    The alias is resolved from the tnsnames.ora in Wallet path. Gluesync still sends the user name and password that you enter in the form: in our test a wrong password failed with ORA-01017 even though the wallet stored the right credentials and sqlnet.ora set SQLNET.WALLET_OVERRIDE = TRUE.

    Source connection form with Use wallet switched on
    Figure 12. Annotation 1 is the error of a Wallet path that Core Hub cannot read and 2 the Wallet path property.

    Wallet path is a path inside the Core Hub container, not on the machine that runs Docker. If you enter a path of the host, Test and continue fails with ORA-12263: Failed to access tnsnames.ora in the directory configured as TNS admin. In the Linux kit the folder data/core-hub of the installation is mounted as /opt/gluesync/data, so put the wallet folder under it and enter /opt/gluesync/data/<folder>. The folder must be readable by Core Hub.

    Recover from the failures you are most likely to meet

    Gluesync reports these problems as notifications, and most of them leave the entities Active. Open the bell icon and select Open notifications hub, then search for Oracle LogMiner (see Notifications and alerts). Expand a row with its arrow to read the full message. Gluesync collapses a repeated error into one row with a counter, for example Oracle LogMiner error (7).

    A grant is missing

    Notifications hub filtered by Oracle LogMiner with the row Oracle LogMiner error expanded and showing ORA-00942 table or view does not exist
    Figure 13. Annotation 1 is the search for Oracle LogMiner and 2 the expanded notification with the Oracle error.

    When you remove a grant from C##GS_LOGMINER and start the entities again, the entities stay Active and the notification Oracle LogMiner error appears, repeated at every retry. The message tells you which grant is missing:

    Message in the notification Missing grant

    [Thread 1] ORA-00942: table or view does not exist

    SELECT_CATALOG_ROLE (or SELECT ANY DICTIONARY). The message does not name the view.

    Failed to add log file …​: ORA-01031: insufficient privileges ORA-06512: at "SYS.DBMS_LOGMNR"

    LOGMINING

    ORA-06550 …​ PLS-00201: identifier 'DBMS_LOGMNR' must be declared

    EXECUTE_CATALOG_ROLE

    1. As SYSDBA in the CDB root, grant the missing privilege again, for example GRANT SELECT_CATALOG_ROLE TO C##GS_LOGMINER CONTAINER=ALL;;

    2. Wait. Gluesync retries with a growing delay (up to 60 seconds by default), so replication resumes by itself within about a minute. You do not need to restart the pipeline;

    3. Make a change in Oracle and check that it reaches the target. Changes made while the grant was missing are not lost: in our test a row inserted while SELECT_CATALOG_ROLE was revoked reached the target about 30 seconds after the grant was restored.

    Supplemental logging is off

    There are two cases, with different effects.

    What is missing What happens What to do

    Table-level logging (ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS) on one table

    Replication keeps working. Gluesync reads the full row again from Oracle for each update, which is slower. Nothing is shown in the Control Plane.

    Run ALTER TABLE <owner>.<table> ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS and pause and start the entity again. Do not remove the logging from a table while its entity runs: in our test the target then received a row with only the changed column filled in (the entity went to Error with Not null violation Error because the other columns arrived empty). If it happens, restore the logging and run a Full copy (see below).

    Database-level logging (ADD SUPPLEMENTAL LOG DATA)

    No error, no notification, entities stay Active, but no insert, update or delete is captured, even on tables that have table-level logging. Changes made in that period are lost for good when you enable the logging again.

    Enable the logging again (see step "Enable supplemental logging for the database"), then run a Full copy with Empty the table first on every entity that changed in the meantime.

    Re-sync an entity with a Full copy

    Use this to bring the target back in line after missing changes: after a redo gap, after database-level supplemental logging was off, or after a Not null violation caused by missing table-level logging.

    1. In the entity table, select the entities and select Pause, then Pause entity. Gluesync keeps the checkpoint and deletes nothing;

    2. Select the paused entities and select Start CDC;

    3. In Start from, select Full copy;

    4. In Data already in the target, select Empty the table first if rows may have been deleted on the source in the meantime, or Keep and merge if only inserts and updates were missed. Keep and merge leaves behind rows that were deleted on the source;

    5. If you chose Empty the table first, tick I understand that rows in the target will be deleted;

    6. Select Start entity.

    Sync changes (CDC) dialog for SHOP.CUSTOMERS and SHOP.NOLOG with Full copy marked 1
    Figure 14. Annotation 1 is Full copy, 2 Empty the table first, 3 the confirmation and 4 Start entity.

    When the copy finishes, compare the counts with Count both and check the rows that you know changed. In our test the target had again the same rows, values and count as the source (a deleted row gone, an updated value restored).

    The archived redo logs are gone (lost SCN)

    Gluesync stores the position it has read (the SCN) and resumes from it after a pause or a restart. If Oracle no longer has the redo for that position, because the archived logs were deleted or the retention was too short, LogMiner cannot read it.

    Notifications hub filtered by redo gap with the warning Oracle LogMiner redo gap ORA-01291 expanded
    Figure 15. Annotation 1 is the search for redo gap and 2 the notification with the SCN where Gluesync resumed.

    What you see, in our test (we paused the pipeline, changed rows, switched the log file five times and removed the archived logs, once at the operating system and once with RMAN):

    • The entities start and stay Active;

    • One or more warnings Oracle LogMiner: redo gap (ORA-01291) appear. Each one says that Gluesync could not mine the redo for an SCN, moved its checkpoint forward to the next archived log that still exists (or to the current SCN when none exists) and skipped "approximately N SCNs";

    • The changes in the skipped range never reach the target. New changes after the gap do.

    To recover:

    1. Treat every redo gap warning as data loss on the affected entities;

    2. Run a Full copy of the entities that read tables changed in the gap, as described in Re-sync an entity with a Full copy. You do not need to reset any checkpoint: Gluesync has already moved it past the gap, and the Full copy starts a new snapshot and follows the live changes from there;

    3. Fix the cause (see Keep the archived logs, and free space safely).

    Keep the archived logs, and free space safely

    Gluesync needs an archived log until it has read it. Keep the logs for longer than the longest time an entity can be paused or stopped, and monitor the free space of the Archive destination that ARCHIVE LOG LIST shows. If the disk fills up and the database stops archiving, you can purge the logs with RMAN. Purge only logs that every entity has already read: the number at the beginning of Last Transaction ID on the entity detail page is the SCN that the entity has reached, and V$ARCHIVED_LOG.NEXT_CHANGE# tells you which log ends before that SCN.

    SELECT sequence#, first_change#, next_change#, deleted
    FROM v$archived_log
    ORDER BY sequence#;

    Keep these RMAN commands at hand. Run them in rman target / as the Oracle owner:

    LIST ARCHIVELOG ALL;
    CROSSCHECK ARCHIVELOG ALL;
    DELETE NOPROMPT EXPIRED ARCHIVELOG ALL;
    DELETE NOPROMPT ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE-1';
    DELETE NOPROMPT ARCHIVELOG UNTIL SEQUENCE 120 THREAD 1;

    CROSSCHECK followed by DELETE EXPIRED removes the records of logs that were deleted at the operating system, which otherwise keep showing as available. COMPLETED BEFORE and UNTIL SEQUENCE delete the old logs and keep the recent ones. Replace 120 with the first sequence that you want to keep.

    DELETE NOPROMPT ARCHIVELOG ALL removes every archived log, including the ones that Gluesync has not read. Use it only after you have paused or stopped the pipeline or accepted a Full copy afterwards.

    After a database restart

    When you restart Oracle while the pipeline runs, Gluesync shows Oracle LogMiner Critical Error notifications while the instance is down or starting, with messages such as ORA-01089: immediate shutdown or close in progress, ORA-12528: TNS:listener: all appropriate instances are blocking new connections and ORA-12514: Cannot connect to database. Service ORCLCDB is not registered with the listener. The entities stay Active. When the instance is open, Gluesync reconnects by itself and continues from its checkpoint: in our test a row inserted after the restart reached the target within 10 seconds, with no action in the Control Plane.

    If the PDB stays closed after the restart (the PDB state was not saved), the notification changes to ORA-16331: container "ORCL" is not open. Open the PDB and save its state, and Gluesync recovers by itself:

    ALTER PLUGGABLE DATABASE ORCL OPEN;
    ALTER PLUGGABLE DATABASE ORCL SAVE STATE;
    Verify the result

    You have set up Oracle LogMiner end to end if:

    • SELECT log_mode FROM v$database returns ARCHIVELOG, and database-level supplemental logging is YES;

    • The LogMiner user has only CREATE SESSION, LOGMINING, SELECT ANY TRANSACTION, EXECUTE_CATALOG_ROLE and SELECT_CATALOG_ROLE, and the data user has only CREATE SESSION and SELECT on the replicated tables;

    • The pipeline Oracle LogMiner demo shows SHOP.CUSTOMERS and SHOP.ORDERS in the Active group;

    • Count both shows the same count for source and target, and the snapshot copied 200 and 1000 rows;

    • An insert, an update and a delete in Oracle reach the target within about 10 seconds;

    • The notifications hub shows no Oracle LogMiner error or redo gap notification that you have not explained.

    Troubleshooting

    Problem Possible cause What to do

    Test and continue fails with ORA-01017: invalid username/password; logon denied

    The user name or the password of the data user is wrong, or (with a wallet) you rely on the credentials stored in the wallet.

    Enter the real user name and password in the form. Gluesync sends what you type.

    Test and continue fails with ORA-12505 (SID not registered) or ORA-12514 (service not registered)

    Connection type is SID but the listener registers only services, or the service name is wrong.

    Use SERVICE_NAME. Check the service names with lsnrctl status: the PDB service for Database name, the CDB service for LogMiner database.

    Test and continue fails with ORA-12263: Failed to access tnsnames.ora

    Wallet path is a path of the host, or the folder is not readable by Core Hub.

    Use the path as Core Hub sees it (for example /opt/gluesync/data/<folder>) and make the files readable.

    The notification Oracle LogMiner error repeats with ORA-00942, ORA-01031 or PLS-00201

    A grant of the LogMiner user is missing.

    See A grant is missing. Grant it again and wait for the retry.

    Entities are Active but nothing reaches the target and there is no error

    Database-level supplemental logging is off.

    See Supplemental logging is off, then run a Full copy.

    The warning Oracle LogMiner: redo gap (ORA-01291) appears

    The archived logs for the position of the entity were deleted.

    See The archived redo logs are gone (lost SCN).

    Oracle LogMiner Critical Error with ORA-12514, ORA-12528 or ORA-01089

    The Oracle instance is down or starting.

    Wait. Gluesync reconnects by itself. See After a database restart.

    Oracle LogMiner error with ORA-16331: container "ORCL" is not open

    The PDB did not open after a restart.

    Open the PDB and save its state, as in After a database restart.

    The entity is in Error with Not null violation Error and rows with empty columns

    Table-level supplemental logging was removed while the entity was running.

    Add the logging again and run a Full copy. See Supplemental logging is off.

    Contact MOLO17 Support if you need assistance with Oracle LogMiner.