Skip to content

OLR silently discards all transactions on a PDB where DBID differs from CON_UID #333

Description

@GavinPizza

Bug reporter information (required)

Email or GitHub username GavinPizza


Bug description

In a multitenant database, OpenLogReplicator silently discards every transaction on a pluggable database whose DBID and CON_UID differ.

The PDB filter resolves the local container's identity from V$PDBS.DBID and compares it against the container identifier carried in the 5.2 begin-transaction redo vector. Those are two different Oracle identifiers. They hold the same value on a PDB created in place, so the comparison succeeds. They diverge on a plugged PDB, so every begin vector fails the comparison and is discarded, and with no begin record the commit vectors have nothing to attach to.

Nothing in the running process indicates a problem:

  • the process stays alive and responsive
  • bytes_read, bytes_parsed, checkpoints and log_switches all advance normally
  • checkpoint files are written on schedule with correct contents
  • the writer stays connected
  • no error, exception, non-zero exit or warning is logged

Warning 60011 ("transaction with no beginning") does not fire either, since the record it would fire on is the one being discarded.

A second PDB in the same container database, on the same redo stream and the same binary, replicates correctly throughout. The only difference between them is whether DBID and CON_UID are equal.


Step-by-step reproduction instructions (required)

This is the tutorials/Oracle-to-file tutorial, run exactly as its README documents, with one PDB added and one config field changed. Steps 1 to 3 are the unmodified tutorial and establish the control. Steps 4 onward are the delta.

  1. Build the two images using the tutorial's own scripts. Both are public; neither requires a private registry.

    git clone https://github.com/bersler/OpenLogReplicator-tutorials.git
    cd OpenLogReplicator-tutorials/images
    
    # Oracle 21c XE, via Oracle's own buildContainerImage.sh
    ./oracle_database_21.3.0-xe.sh
    
    # OpenLogReplicator v2.0.0: must be pinned; the script defaults to 'master'
    OPENLOGREPLICATOR_VERSION=2.0.0 ./bersler_openlogreplicator_tutorial_prod.sh

    This produces oracle/database:21.3.0-xe and bersler/openlogreplicator:tutorial, the two image names cfg.sh expects.

    bersler_openlogreplicator_tutorial_prod.sh refuses to run as root. Run it as a non-root user in the docker group, and make sure that user can read its Docker config directory. On Docker 29 build is the buildx plugin, so an unreadable config dir makes docker build fail with a misleading unknown shorthand flag: 't' in -t.

    Everything from here runs in the tutorial directory:

    cd ../tutorials/Oracle-to-file
  2. Check the images, per the tutorial README:

    ./1.check.sh
  3. Create and start the database:

    ./2.db-start.sh

    This brings up compose.yaml, which puts the oracle service on the internal network with oradata, fra, sql and setup bind-mounted. It then waits for DATABASE IS READY TO USE and runs sql/schema-usrtbl.sql in XEPDB1. Archivelog mode and database-level supplemental logging are applied automatically along the way: setup/config.sql is mounted at /opt/oracle/scripts/setup, which the Oracle image executes at database creation. No manual archivelog step is needed.

    On a host with many CPU cores, edit the oracle service in compose.yaml before running this. Oracle derives the minimum SGA from cpu_count, and on a 48-core host the default XE sga_target of 1536M is rejected with ORA-00821: ... needs to be at least 2256M, which aborts database creation:

        environment:
          - ORACLE_CHARACTERSET=AL32UTF8
          - INIT_SGA_SIZE=3072
        cpuset: "0-7"
        build:
          context: .
          shm_size: '4gb'
        shm_size: '4gb'

    This is the only change made to any tutorial file outside scripts/OpenLogReplicator.json. On a smaller host the shipped values work unaltered.

  4. Run the tutorial to completion, unmodified. This is the control:

    ./3.olr-start.sh
    ./4.test.sh

    4.test.sh waits for exactly 9 lines in output/results.txt, prints them, and exits 0. Replication works on XEPDB1, whose DBID and CON_UID are equal:

    {"scn":2625756,"tm":1785440696000000000,"c_scn":2625756,"c_idx":1,"xid":"0x000a.005.0000028b","payload":[{"op":"begin"}]}
    {"c_scn":2625756,"c_idx":2,"xid":"0x000a.005.0000028b","payload":[{"op":"c","schema":{"owner":"USRTBL","table":"ADAM1"},"after":{"ID":1,"NAME":"Adam Leszczyński","COUNT":10,"START_TIME":1564662896000000000}}]}
    {"c_scn":2625756,"c_idx":3,"xid":"0x000a.005.0000028b","payload":[{"op":"commit"}]}
    {"scn":2625765,"tm":1785440696000000000,"c_scn":2625765,"c_idx":1,"xid":"0x0005.01a.00000229","payload":[{"op":"begin"}]}
    {"c_scn":2625765,"c_idx":2,"xid":"0x0005.01a.00000229","payload":[{"op":"u","schema":{"owner":"USRTBL","table":"ADAM1"},"before":{"ID":1,"COUNT":10},"after":{"ID":1,"COUNT":11}}]}
    {"c_scn":2625765,"c_idx":3,"xid":"0x0005.01a.00000229","payload":[{"op":"commit"}]}
    {"scn":2625768,"tm":1785440696000000000,"c_scn":2625768,"c_idx":1,"xid":"0x0004.011.00000252","payload":[{"op":"begin"}]}
    {"c_scn":2625768,"c_idx":2,"xid":"0x0004.011.00000252","payload":[{"op":"d","schema":{"owner":"USRTBL","table":"ADAM1"},"before":{"ID":1,"NAME":"Adam Leszczyński","COUNT":11,"START_TIME":1564662896000000000}}]}
    {"c_scn":2625768,"c_idx":3,"xid":"0x0004.011.00000252","payload":[{"op":"commit"}]}

    Reset before the affected run:

    ./5.olr-drop.sh

    This removes the OpenLogReplicator container, drops USROLR from XEPDB1, and deletes checkpoint, log and output. The database and USRTBL stay.

  5. Add a second PDB whose DBID and CON_UID differ. XEPDB1 stays exactly as the tutorial left it and remains the control.

    db_sql() in tutorials/common/functions.sh hardcodes ALTER SESSION SET CONTAINER = XEPDB1, so it cannot be used for this. Run against the container directly:

    docker exec -i ORA1 /bin/bash -c 'export ORACLE_SID=XE ORAENV_ASK=NO
    . oraenv
    sqlplus -S / as sysdba' <<'EOF'
    ALTER SESSION SET CONTAINER = CDB$ROOT;
    CREATE PLUGGABLE DATABASE P1 ADMIN USER pdbadm IDENTIFIED BY pdbadmpwd;
    ALTER PLUGGABLE DATABASE P1 OPEN;
    
    -- unplug and plug the same descriptor back: this mints a fresh CON_UID
    -- while DBID carries through from the descriptor
    ALTER PLUGGABLE DATABASE P1 CLOSE IMMEDIATE;
    ALTER PLUGGABLE DATABASE P1 UNPLUG INTO '/tmp/p1.xml';
    DROP PLUGGABLE DATABASE P1 KEEP DATAFILES;
    CREATE PLUGGABLE DATABASE P1 USING '/tmp/p1.xml' NOCOPY TEMPFILE REUSE;
    ALTER PLUGGABLE DATABASE P1 OPEN;
    
    SET LINESIZE 100 PAGESIZE 50
    COLUMN NAME FORMAT A12
    SELECT CON_ID, NAME, DBID, CON_UID FROM V$PDBS ORDER BY CON_ID;
    SELECT NAME, DBID, CON_UID FROM V$PDBS WHERE DBID != CON_UID;
    EOF

    DB_CREATE_FILE_DEST is already set to /opt/oracle/oradata by setup/config.sql in step 2, so the datafiles land under the bind-mounted oradata directory that OpenLogReplicator reads through path-mapping.

    The last two queries confirm the setup. The affected PDB must appear in the second one, the control must not (values differ per run; only the equal/divergent pattern matters):

        CON_ID NAME               DBID    CON_UID
    ---------- ------------ ---------- ----------
             2 PDB$SEED     2715856892 2715856892
             3 XEPDB1       4170075421 4170075421
             5 P1           1982200201 3620585990
    
    
    NAME               DBID    CON_UID
    ------------ ---------- ----------
    P1           1982200201 3620585990
    

    XEPDB1 (control) and PDB$SEED have DBID equal to CON_UID. P1 (affected) does not, so it is the only row the second query returns.

  6. Give P1 the same two users the tutorial created in XEPDB1. Only P1 needs this: XEPDB1 got USRTBL from 2.db-start.sh, and gets USROLR back from 3.olr-start.sh in step 8.

    The table owner is the maintainer's own sql/schema-usrtbl.sql with only the container changed, and without its leading DROP TABLESPACE since P1 is new:

    docker exec -i ORA1 /bin/bash -c 'export ORACLE_SID=XE ORAENV_ASK=NO
    . oraenv
    sqlplus -S / as sysdba' <<'EOF'
    ALTER SESSION SET CONTAINER = P1;
    CREATE TABLESPACE TBLS1 DATAFILE SIZE 100M AUTOEXTEND ON NEXT 100M;
    ALTER TABLESPACE TBLS1 FORCE LOGGING;
    CREATE USER USRTBL IDENTIFIED BY USRTBLPWD
      DEFAULT TABLESPACE TBLS1 TEMPORARY TABLESPACE TEMP;
    ALTER USER USRTBL QUOTA UNLIMITED ON TBLS1;
    GRANT CONNECT TO USRTBL;
    GRANT RESOURCE TO USRTBL;
    ALTER SESSION SET CONTAINER = CDB$ROOT;
    ALTER SYSTEM ARCHIVE LOG CURRENT;
    EOF

    Then apply sql/schema-usrolr.sql unmodified in P1. It already grants SELECT ON SYS.V_$PDBS, which this bug depends on. The file carries no ALTER SESSION of its own, so the container set below is what decides where it lands:

    docker exec -i ORA1 /bin/bash -c 'export ORACLE_SID=XE ORAENV_ASK=NO
    . oraenv
    sqlplus -S / as sysdba' <<'EOF'
    ALTER SESSION SET CONTAINER = P1;
    @/opt/sql/schema-usrolr.sql
    EOF

    On a first run this reports ORA-01918: user 'USROLR' does not exist, because schema-usrolr.sql opens with DROP USER USROLR CASCADE; and expects to be re-run. It is harmless: SQL*Plus continues, and the user is created by the next statement.

    Verified: 47 object grants land on USROLR, SELECT ON SYS.V_$PDBS among them.

  7. Create the test table in each PDB and enable supplemental logging on it. XEPDB1 needs it again because test.sql ends with DROP TABLE, so step 3 left no table behind. This is the table definition from sql/test.sql, unmodified:

    ALTER SESSION SET CONTAINER = <P1 | XEPDB1>;
    CREATE TABLE USRTBL.ADAM1(
      ID         NUMBER NOT NULL,
      NAME       VARCHAR2(30),
      COUNT      NUMBER,
      START_TIME TIMESTAMP
    );
    ALTER TABLE USRTBL.ADAM1 ADD CONSTRAINT ADAM1PK PRIMARY KEY(ID);
    ALTER TABLE USRTBL.ADAM1 ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS;
  8. Point OpenLogReplicator at the affected PDB. This is scripts/OpenLogReplicator.json exactly as the tutorial ships it, the same file that produced the control output in step 3, with a single field changed: server, from //oracle:1521/XEPDB1 to //oracle:1521/P1. Nothing else differs, so the complete file is:

    {
      "version": "2.0.0",
      "log-level": 3,
      "metrics": {
        "type": "prometheus",
        "bind": "0.0.0.0:8080"
      },
      "source": [
        {
          "alias": "S1",
          "name": "ORA1",
          "reader": {
            "type": "online",
            "path-mapping": ["/opt/oracle/oradata", "/opt/oradata", "/opt/oracle/fra", "/opt/fra"],
            "user": "USROLR",
            "password": "USROLRPWD",
            "server": "//oracle:1521/P1"
          },
          "format": {
            "type": "json"
          },
          "filter": {
            "table": [
              {"owner": "USRTBL", "table": "ADAM.*"}
            ]
          }
        }
      ],
      "target": [
        {
          "alias": "T1",
          "source": "S1",
          "writer": {"type": "file", "output": "/opt/output/results.txt"}
        }
      ]
    }

    path-mapping is required whenever OLR runs in a different container from Oracle; without it the redo reader fails in a way unrelated to this bug. metrics is top level in 2.0.0, and the version string is validated.

    This is the complete file used in the reproduction. Reverting that one field to the shipped value gives the control run in step 11.

  9. Start OpenLogReplicator with the tutorial's own script, which now picks up the edited config:

    ./3.olr-start.sh

    It recreates checkpoint, log and output, brings up the openlogreplicator profile, and polls the Prometheus endpoint until service_state{state="replicating"} 1. It reaches that state on P1 and exits 0, which is part of the problem being reported: by every signal the tutorial checks, replication is running.

    On this second invocation it also prints mkdir: cannot create directory 'dump': File exists, because 5.olr-drop.sh leaves dump in place. The script expects this and continues.

    It also re-runs schema-usrolr.sql against XEPDB1, restoring the user that 5.olr-drop.sh dropped in step 3. That is harmless here and is what leaves XEPDB1 ready for the control run in step 11.

  10. Execute the workload in the affected PDB. This is the DML from the same tutorials/Oracle-to-file/sql/test.sql, stopping after the second COMMIT:

    ALTER SESSION SET CONTAINER = P1;
    INSERT INTO USRTBL.ADAM1 VALUES (1, 'Adam Leszczynski', 10, TO_DATE('2019-08-01 12:34:56', 'YYYY-MM-DD HH24:MI:SS'));
    COMMIT;
    UPDATE USRTBL.ADAM1 SET COUNT = COUNT + 1;
    COMMIT;

    The one change from test.sql is spelling the name in ASCII. The original 'Adam Leszczyński' needs NLS_LANG set correctly on whichever client runs it, or the ń is stored as replacement characters. That is a client charset issue unrelated to this bug, and it only makes the output harder to compare.

  11. Observe the incorrect behaviour.

    Actual result: /opt/output/results.txt is never created. The output directory stays empty.

    The DML did commit. Querying the affected PDB afterwards shows both statements landed:

    ALTER SESSION SET CONTAINER = P1;
    SELECT ID, COUNT FROM USRTBL.ADAM1;
    
            ID      COUNT
    ---------- ----------
             1         11      -- inserted as 10, updated to 11

    The complete OLR log for that run is 45 lines, reproduced in full below apart from the 20 - found: <table> schema-load lines elided in the middle. It contains one WARN, the cold-start notice that no checkpoint file exists yet, and no ERROR:

    2026-07-30 19:47:55 INFO  00000 OpenLogReplicator v2.0.0 (C) 2018-2026 by Adam Leszczynski (aleszczynski@bersler.com), see LICENSE file for licensing information
    2026-07-30 19:47:55 INFO  00000 arch: x86_64, build-arch: , system: Linux, release: 6.1.0-44-amd64, build: Release, compiled: 2026-07-28 23:10, modules: Kafka OCI Prometheus Protobuf
    2026-07-30 19:47:55 INFO  00000 starting Prometheus metrics, listening on: 0.0.0.0:8080
    2026-07-30 19:47:55 INFO  00000 adding source: S1
    2026-07-30 19:47:55 INFO  00000 adding target: T1
    2026-07-30 19:47:55 INFO  00000 writer is starting with Writer: file:/opt/output/results.txt
    2026-07-30 19:47:55 WARN  10003 file: checkpoint/ORA1-chkpt.json - get metadata returned: No such file or directory
    2026-07-30 19:47:55 INFO  00000 connecting to the database instance of ORA1 to //oracle:1521/P1
    2026-07-30 19:47:55 INFO  00000 version: Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production, context: XE, resetlogs: 0, activation: 0, con_id: 5, con_name: P1
    2026-07-30 19:47:55 INFO  00000 loading character mapping for AL32UTF8
    2026-07-30 19:47:55 INFO  00000 loading character mapping for AL16UTF16
    2026-07-30 19:47:55 INFO  00000 online redo log: /opt/oradata/XE/redo01.log
    2026-07-30 19:47:55 INFO  00000 online redo log: /opt/oradata/XE/redo02.log
    2026-07-30 19:47:55 INFO  00000 online redo log: /opt/oradata/XE/redo03.log
    2026-07-30 19:47:55 INFO  00000 timezone: +00:00, db-timezone: +00:00, log-timezone: +00:00, host-timezone: +00:00
    2026-07-30 19:47:55 INFO  00000 Replicator for ORA1 in online mode is starting from NOW
    2026-07-30 19:47:55 INFO  00000 current resetlogs is: 1239997100
    2026-07-30 19:47:55 INFO  00000 first data SCN: 0
    2026-07-30 19:47:55 INFO  00000 starting sequence not found - starting with new batch with seq: 12
    2026-07-30 19:47:55 INFO  00000 reading dictionaries for scn: 2636366
    ...
    2026-07-30 19:47:57 INFO  00000 - found: USRTBL.ADAM1 (dataobj: 75808, obj: 75808, columns: 4, lobs: 0, lob-idx: 0)
    ...
    2026-07-30 19:47:57 INFO  00000 last confirmed scn: 2636366, starting sequence: 12, offset: 0
    2026-07-30 19:47:57 INFO  00000 resume writer
    2026-07-30 19:47:57 INFO  00000 found redo log version: 21.0.0, activation: 3121120875, resetlogs: 1239997100, page: 512, sequence: 12, SID: XE, endian: LITTLE
    2026-07-30 19:47:57 INFO  00000 processing redo log: group: 3 scn: 2636347 to 0 seq: 12 path: /opt/oradata/XE/redo03.log offset: 1024
    2026-07-30 19:47:57 INFO  00000 new activation detected: 3121120875
    

    OLR found the filtered table USRTBL.ADAM1 during schema load, opened its writer on the output file, and reported itself replicating. Nothing further was logged: the workload committed at 19:49 and the log ends at 19:47:57. Warning 60011 never fires here, since the record it would fire on is the one being discarded.

    The Prometheus endpoint the tutorial itself polls tells the same story. Scraped from the running container after the workload committed:

    bytes_read                              7438336
    bytes_parsed                             457216
    bytes_confirmed                           91312
    checkpoints{filter="out"}                   778
    messages_confirmed                          775
    dml_ops{filter="out",type="insert"}           0
    dml_ops{filter="out",type="update"}           0
    dml_ops{filter="out",type="commit"}           0
    messages_sent                                 0
    service_state{state="replicating"}            1
    

    The process reads and parses megabytes of redo, checkpoints 778 times, and reports replicating. Every dml_ops counter and messages_sent stay at zero.

    Expected result: the six JSON records the control PDB produces in step 11.

  12. Repeat steps 7 to 9 against the control PDB XEPDB1, to confirm the contrast holds for this exact workload and not only for the full test.sql of step 3. Restore server to the shipped //oracle:1521/XEPDB1, set CONTAINER = XEPDB1 in step 9, and change nothing else. Output is produced normally:

    {"scn":2638500,"tm":1785441136000000000,"c_scn":2638500,"c_idx":1,"xid":"0x000a.003.00000291","payload":[{"op":"begin"}]}
    {"c_scn":2638500,"c_idx":2,"xid":"0x000a.003.00000291","payload":[{"op":"c","schema":{"owner":"USRTBL","table":"ADAM1"},"after":{"ID":1,"NAME":"Adam Leszczynski","COUNT":10,"START_TIME":1564662896000000000}}]}
    {"c_scn":2638500,"c_idx":3,"xid":"0x000a.003.00000291","payload":[{"op":"commit"}]}
    {"scn":2638510,"tm":1785441136000000000,"c_scn":2638510,"c_idx":1,"xid":"0x000a.012.00000290","payload":[{"op":"begin"}]}
    {"c_scn":2638510,"c_idx":2,"xid":"0x000a.012.00000290","payload":[{"op":"u","schema":{"owner":"USRTBL","table":"ADAM1"},"before":{"ID":1,"COUNT":10},"after":{"ID":1,"COUNT":11}}]}
    {"c_scn":2638510,"c_idx":3,"xid":"0x000a.012.00000290","payload":[{"op":"commit"}]}

    These six records appeared within one second of the COMMIT. On P1 the same workload produced nothing in 150 seconds. Run the control against the same binary in the same session, changing nothing but server.


Environment details (required)

  • Official binary signature/version:

    2026-07-29 14:11:26 INFO  00000 OpenLogReplicator v2.0.0 (C) 2018-2026 by Adam Leszczynski (aleszczynski@bersler.com), see LICENSE file for licensing information
    2026-07-29 14:11:26 INFO  00000 arch: x86_64, build-arch: , system: Linux, release: 6.1.0-44-amd64, build: Release, compiled: 2026-07-28 23:10, modules: Kafka OCI Prometheus Protobuf
    

    Built from official v2.0.0 source via bersler/OpenLogReplicator-docker; no signed binary is published for any release.

  • OpenLogReplicator version or commit hash: v2.0.0 (release tag)

  • Oracle version and edition: Oracle Database 21c Express Edition, 21.3.0.0.0 (oracle/database:21.3.0-xe, built via Oracle's own buildContainerImage.sh -v 21.3.0 -x)

  • Operating system: Debian GNU/Linux, kernel 6.1.0-44-amd64

  • Docker version: 29.1.5

Technical environment (required)

  • Oracle version and edition: Oracle Database 21c Express Edition, 21.3.0.0.0
  • Operating system and kernel version: Linux 6.1.0-44-amd64
  • RAC and/or ASM usage: No RAC. No ASM. Single instance, filesystem storage.

Multitenant configuration details

Single container database. The reproduction above uses two pluggable databases sharing one physical redo stream: XEPDB1 (control, DBID == CON_UID) and P1 (affected, DBID != CON_UID). No Data Guard.

We first hit this in production at larger scale: one CDB, 7 PDBs, one OpenLogReplicator process per PDB, each with its own config file, state directory and ports.

The split is visible per-PDB in V$PDBS: of the seven, the two that emitted nothing were exactly the two whose DBID and CON_UID had diverged. No other property tracked it.


Supporting evidence

Measurements from our own deployment, offered as observation rather than as a proposed change.

Divergence tracks the failure across seven PDBs

SELECT CON_ID, NAME, DBID, CON_UID FROM V$PDBS ORDER BY CON_ID;
CON_ID NAME DBID CON_UID equal? CDC output
2 PDB$SEED 1678743204 1678743204 yes —
3 PDB_A 3442438105 3442438105 yes —
4 PDB_B 1060685388 1060685388 yes —
6 DB1 3552666917 1243036531 no none
7 DB2 1484546789 1529555758 no none
9 TEST_1 1374007921 1374007921 yes correct
10 TEST_2 3005762508 3005762508 yes —

All seven share one redo stream and run the same binary. Both PDBs with divergent identifiers produced no output at all, while TEST_1, the matching-identifier PDB under the same CDC configuration, replicated correctly throughout.

Oracle's own container identity

Oracle diagnostic dump for the affected PDB:

PdbInfo:  Id=6 Name=DB1 Uid=1243036531 DBid=3552666917
          Guid=<redacted> State=OPEN
          ...
          PostPlugCompletionSCN=0x00000010ededa6c4
con_id/con_uid/con_name: 6/1243036531/DB1

Oracle keys the container on con_id/con_uid/con_name. DBid is a separate attribute and is not part of that tuple. The non-zero PostPlugCompletionSCN indicates this PDB was plugged in rather than created in place.

Observed counters on an affected PDB

After a cold START at a current SCN with no prior checkpoint state:

bytes_read       283,785,728
bytes_parsed     238,671,872
checkpoints           12,452
dml_ops                    0
messages_sent              0

A second affected PDB over the same window: bytes_read 277,113,344, bytes_parsed 234,126,336, checkpoints 12,201, dml_ops 0, messages_sent 0. A control PDB on the same redo stream and the same binary emitted normally throughout.

Committed DML on a filtered table with PRIMARY KEY LOGGING never appeared in the output and never incremented dml_ops. No warning was logged.

The two sides of the comparison are different identifiers

The local container identity is resolved by a query against V$PDBS, while the value it is compared against is read from the pdb field of the 5.2 begin-transaction vector. Those are not the same identifier.

Whatever the vector carries, on these PDBs it is not DBID. The comparison fails on exactly the PDBs where DBID and CON_UID diverge, and succeeds on every PDB where the two columns happen to coincide. That is what makes the defect invisible on a PDB created in place.

Oracle's own dump above is consistent with that reading: the container is keyed on con_id/con_uid/con_name, and DBid sits outside that tuple as a separate attribute.

Resolving the identity against the matching column instead, with no other change on the same host against the same redo, moved both silent PDBs to correct output:

PDB bytes_parsed dml_ops messages_sent
DB1 7,709,696 647 30
DB2 7,386,624 306 30
TEST_1 33,571,840 1,425 33

Delivery was confirmed end to end by writing a row into Oracle and watching it arrive in the target database.

Reported as an observation about which identifier the redo carries, not as a proposed change. Verifying any change is for the maintainer and the private test suite.

Ruled out before we looked at the identifiers

  • Schema load: 15,638 objects, 934 tables, 37,685 columns, matching the working PDB.
  • Supplemental logging: 172 log groups, tables under test on PRIMARY KEY LOGGING.
  • Configuration: identical to the working PDB apart from name, ports, state path and start-scn.
  • Grants: SELECT on SYS.V_$PDBS present, no 10034.
  • Replay position: reproduced from a cold START at a current SCN with all checkpoint files removed.
  • Absence of workload: disproved by committed DML.
  • Uninitialised memory: the resolved identity was stable and correct across six consecutive checkpoints in one run.

Acknowledgement

  • Fully reproducible, step-by-step scenario provided
  • Understood that non-reproducible bugs cannot be fixed
  • Understood that incomplete reports may be closed without further action

Official Binary Signature/Version:

2026-07-29 14:11:26 INFO  00000 OpenLogReplicator v2.0.0 (C) 2018-2026 by Adam Leszczynski (aleszczynski@bersler.com), see LICENSE file for licensing information
2026-07-29 14:11:26 INFO  00000 arch: x86_64, build-arch: , system: Linux, release: 6.1.0-44-amd64, build: Release, compiled: 2026-07-28 23:10, modules: Kafka OCI Prometheus Protobuf

Built from the official v2.0.0 release source via bersler/OpenLogReplicator-docker. No signed binary is published for any release; every GitHub release ships zero binary assets, so this banner is the only version/build string the software emits.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions