Bidirektionale Replikationen konfigurieren

Nachdem Sie die unidirektionale Replikation eingerichtet haben, können Sie mit nur wenigen zusätzlichen Schritten die Daten in die entgegengesetzte Richtung replizieren. In diesem Schnellstartbeispiel werden zwei Autonomous Transaction Processing- und Autonomous Data Warehouse-Datenbanken als Cloud-Datenbanken verwendet.

Bevor Sie beginnen

Sie benötigen zwei Datenbanken im gleichen Mandanten und in der gleichen Region, um mit diesem Schnellstart fortzufahren. Wenn Sie Beispieldaten benötigen, laden Sie Archive.zip herunter, und befolgen Sie die Anweisungen unter Übung 1, Aufgabe 3: ATP-Schema laden.

Überblick

In den folgenden Schritten wird beschrieben, wie Sie eine Zieldatenbank mit Oracle Data Pump instanziieren und die bidirektionale (wechselseitige) Replikation zwischen zwei Datenbanken in der gleichen Region einrichten.

Beschreibung von bidirectional.png folgt
Beschreibung der Abbildung bidirectional.png

Aufgabe 1: Umgebung einrichten

  1. Erstellen Sie ein Deployment.
  2. Erstellen Sie Verbindungen zu Ihren Datenbanken.
  3. Weisen Sie die Verbindungen dem Deployment zu.
  4. Aktivieren Sie zusätzliches Logging:
    ALTER DATABASE ADD SUPPLEMENTAL LOG DATA
  5. Führen Sie die folgende Abfrage aus, um sicherzustellen, dass support_mode=FULL für alle Tabellen in der Quelldatenbank gilt:
    
    select * from DBA_GOLDENGATE_SUPPORT_MODE where owner = 'SRC_OCIGGLL';
  6. Führen Sie die folgende Abfrage für Datenbank B aus, um sicherzustellen, dass support_mode=FULL für alle Tabellen in der Datenbank gilt:
    select * from DBA_GOLDENGATE_SUPPORT_MODE where owner = 'SRCMIRROR_OCIGGLL';

Aufgabe 2: Transaktionsinformationen und eine Checkpoint-Tabelle für beide Datenbanken hinzufügen

Gehen Sie in der OCI GoldenGate-Deployment-Konsole zu der Seite "Konfiguration" für den Administrationsservice, und führen Sie dann die folgenden Schritte aus:

  1. Fügen Sie Transaktionsinformationen zu den Datenbanken A und B hinzu:
    1. Geben Sie für Datenbank A SRC_OCIGGLL als Schemanamen ein.
    2. Geben Sie für Datenbank B SRCMIRROR_OCIGGLL als Schemanamen ein.

    Hinweis:

    Die Schemanamen müssen eindeutig sein und mit dem Datenbankschemanamen übereinstimmen, wenn Sie ein anderes Dataset als im folgenden Beispiel verwenden.
  2. Erstellen Sie eine Checkpoint-Tabelle für Datenbank A und B:
    1. Geben Sie für Datenbank A "SRC_OCIGGLL"."ATP_CHECKTABLE" als Checkpoint-Tabelle ein.
    2. Geben Sie für Datenbank B "SRCMIRROR_OCIGGLL"."CHECKTABLE"als Checkpoint-Tabelle ein.

Aufgabe 3: Integrierten Extract erstellen

Ein integrierter Extract erfasst fortlaufende Änderungen an der Quelldatenbank.

  1. Klicken Sie auf der Seite "Deployment-Details" auf Konsole starten.
  2. Fügen Sie einen Integrated Extract hinzu, und führen Sie diesen aus.

    Hinweis:

    Weitere Informationen zu Parametern, mit denen Sie Quelltabellen angeben können, finden Sie unter Zusätzliche Exportparameteroptionen.
    1. Hängen Sie auf der Seite "Extract-Parameter" unter EXTTRAIL <extract-name> die folgenden Zeilen an:
      -- Capture DDL operations for listed schema tables
      ddl include mapped
      
      -- Add step-by-step history of 
      -- to the report file. Very useful when troubleshooting.
      ddloptions report 
      
      -- Write capture stats per table to the report file daily.
      report at 00:01 
      
      -- Rollover the report file weekly. Useful when IE runs
      -- without being stopped/started for long periods of time to
      -- keep the report files from becoming too large.
      reportrollover at 00:01 on Sunday 
      
      -- Report total operations captured, and operations per second
      -- every 10 minutes.
      reportcount every 10 minutes, rate 
      
      -- Table list for capture
      table SRC_OCIGGLL.*;
      
      -- Exclude changes made by GGADMIN
      tranlogoptions excludeuser ggadmin

    Hinweis:

    Mit tranlogoptions excludeuser ggadmin wird verhindert, dass Transaktionen, welche von ggadmin in bidirektionalen Replikationsszenarios angewendet werden, erneut erfasst.
  3. Prüfen Sie, ob Transaktionen mit langer Ausführungszeit vorliegen:
    1. Führen Sie das folgende Skript in der Quelldatenbank aus:
      select start_scn, start_time from gv$transaction where start_scn < (select max(start_scn) from dba_capture);

      Wenn die Abfrage Zeilen zurückgibt, müssen Sie die SCN der Transaktion suchen und die Transaktion anschließend festschreiben oder zurücksetzen.

Aufgabe 4: Daten mit Oracle Data Pump (ExpDP) exportieren

Mit Oracle Data Pump (ExpDP) können Sie Daten aus der Quelldatenbank in Oracle Object Storage exportieren.

  1. Erstellen Sie einen Oracle Object Storage-Bucket.

    Notieren Sie sich den Namespace und den Bucket-Namen für die Export- und Importskripte.

  2. Erstellen Sie ein Authentifizierungstoken, kopieren Sie die Tokenzeichenfolge, und fügen Sie sie zur späteren Verwendung in einen Texteditor ein.
  3. Erstellen Sie Zugangsdaten in der Quelldatenbank, und ersetzen Sie <user-name> und <token> durch den Benutzernamen Ihres Oracle Cloud-Accounts und die Tokenzeichenfolge, die Sie im vorherigen Schritt erstellt haben:
    BEGIN
      DBMS_CLOUD.CREATE_CREDENTIAL(
        credential_name => 'ADB_OBJECTSTORE', 
        username => '<user-name>',
        password => '<token>'
      );
    END;
  4. Führen Sie das folgende Skript in der Quelldatenbank aus, um den Job "Daten exportieren" zu erstellen. Stellen Sie sicher, dass Sie <region>, <namespace> und <bucket-name> in der Objektspeicher-URI entsprechend ersetzen. SRC_OCIGGLL.dmp ist eine Datei, die bei der Ausführung dieses Skripts erstellt wird.
    DECLARE
    ind NUMBER;              -- Loop index
    h1 NUMBER;               -- Data Pump job handle
    percent_done NUMBER;     -- Percentage of job complete
    job_state VARCHAR2(30);  -- To keep track of job state
    le ku$_LogEntry;         -- For WIP and error messages
    js ku$_JobStatus;        -- The job status from get_status
    jd ku$_JobDesc;          -- The job description from get_status
    sts ku$_Status;          -- The status object returned by get_status
    
    BEGIN
    -- Create a (user-named) Data Pump job to do a schema export.
    h1 := DBMS_DATAPUMP.OPEN('EXPORT','SCHEMA',NULL,'SRC_OCIGGLL_EXPORT','LATEST');
    
    -- Specify a single dump file for the job (using the handle just returned
    -- and a directory object, which must already be defined and accessible
    -- to the user running this procedure.
    DBMS_DATAPUMP.ADD_FILE(h1,'https://objectstorage.<region>.oraclecloud.com/n/<namespace>/b/<bucket-name>/o/SRC_OCIGGLL.dmp','ADB_OBJECTSTORE','100MB',DBMS_DATAPUMP.KU$_FILE_TYPE_URIDUMP_FILE,1);
    
    -- A metadata filter is used to specify the schema that will be exported.
    DBMS_DATAPUMP.METADATA_FILTER(h1,'SCHEMA_EXPR','IN (''SRC_OCIGGLL'')');
    
    -- Start the job. An exception will be generated if something is not set up properly.
    DBMS_DATAPUMP.START_JOB(h1);
    
    -- The export job should now be running. In the following loop, the job
    -- is monitored until it completes. In the meantime, progress information is displayed.
    percent_done := 0;
    job_state := 'UNDEFINED';
    while (job_state != 'COMPLETED') and (job_state != 'STOPPED') loop
      dbms_datapump.get_status(h1,dbms_datapump.ku$_status_job_error + dbms_datapump.ku$_status_job_status + dbms_datapump.ku$_status_wip,-1,job_state,sts);
      js := sts.job_status;
    
    -- If the percentage done changed, display the new value.
    if js.percent_done != percent_done
    then
      dbms_output.put_line('*** Job percent done = ' || to_char(js.percent_done));
      percent_done := js.percent_done;
    end if;
    
    -- If any work-in-progress (WIP) or error messages were received for the job, display them.
    if (bitand(sts.mask,dbms_datapump.ku$_status_wip) != 0)
    then
      le := sts.wip;
    else
      if (bitand(sts.mask,dbms_datapump.ku$_status_job_error) != 0)
      then
        le := sts.error;
      else
        le := null;
      end if;
    end if;
    if le is not null
    then
      ind := le.FIRST;
      while ind is not null loop
        dbms_output.put_line(le(ind).LogText);
        ind := le.NEXT(ind);
      end loop;
    end if;
      end loop;
    
      -- Indicate that the job finished and detach from it.
      dbms_output.put_line('Job has completed');
      dbms_output.put_line('Final job state = ' || job_state);
      dbms_datapump.detach(h1);
    END;

Aufgabe 5: Zieldatenbank mit Oracle Data Pump (ImpDP) instanziieren

Mit Oracle Data Pump (ImpDP) können Sie Daten aus der Datei SRC_OCIGGLL.dmp, die aus der Quelldatenbank exportiert wurde, in die Zieldatenbank importieren.

  1. Erstellen Sie Zugangsdaten in der Zieldatenbank für den Zugriff auf Oracle Object Storage (mit denselben Informationen wie im vorherigen Abschnitt).
    BEGIN
      DBMS_CLOUD.CREATE_CREDENTIAL( 
        credential_name => 'ADB_OBJECTSTORE',
        username => '<user-name>',
        password => '<token>'
      );
    END;
  2. Führen Sie das folgende Skript in der Zieldatenbank aus, um Daten aus SRC_OCIGGLL.dmp zu importieren. Stellen Sie sicher, dass Sie <region>, <namespace> und <bucket-name> in der Objektspeicher-URI entsprechend ersetzen:
    DECLARE
    ind NUMBER;  -- Loop index
    h1 NUMBER;  -- Data Pump job handle
    percent_done NUMBER;  -- Percentage of job complete
    job_state VARCHAR2(30);  -- To keep track of job state
    le ku$_LogEntry;  -- For WIP and error messages
    js ku$_JobStatus;  -- The job status from get_status
    jd ku$_JobDesc;  -- The job description from get_status
    sts ku$_Status;  -- The status object returned by get_status
    BEGIN
    
    -- Create a (user-named) Data Pump job to do a "full" import (everything
    -- in the dump file without filtering).
    h1 := DBMS_DATAPUMP.OPEN('IMPORT','FULL',NULL,'SRCMIRROR_OCIGGLL_IMPORT');
    
    -- Specify the single dump file for the job (using the handle just returned)
    -- and directory object, which must already be defined and accessible
    -- to the user running this procedure. This is the dump file created by
    -- the export operation in the first example.
    
    DBMS_DATAPUMP.ADD_FILE(h1,'https://objectstorage.<region>.oraclecloud.com/n/<namespace>/b/<bucket-name>/o/SRC_OCIGGLL.dmp','ADB_OBJECTSTORE',null,DBMS_DATAPUMP.KU$_FILE_TYPE_URIDUMP_FILE);
    
    
    -- A metadata remap will map all schema objects from SRC_OCIGGLL to SRCMIRROR_OCIGGLL.
    DBMS_DATAPUMP.METADATA_REMAP(h1,'REMAP_SCHEMA','SRC_OCIGGLL','SRCMIRROR_OCIGGLL');
    
    -- If a table already exists in the destination schema, skip it (leave
    -- the preexisting table alone). This is the default, but it does not hurt
    -- to specify it explicitly.
    DBMS_DATAPUMP.SET_PARAMETER(h1,'TABLE_EXISTS_ACTION','SKIP');
    
    -- Start the job. An exception is returned if something is not set up properly.
    DBMS_DATAPUMP.START_JOB(h1);
    
    -- The import job should now be running. In the following loop, the job is
    -- monitored until it completes. In the meantime, progress information is
    -- displayed. Note: this is identical to the export example.
    percent_done := 0;
    job_state := 'UNDEFINED';
    while (job_state != 'COMPLETED') and (job_state != 'STOPPED') loop
      dbms_datapump.get_status(h1,
        dbms_datapump.ku$_status_job_error +
        dbms_datapump.ku$_status_job_status +
        dbms_datapump.ku$_status_wip,-1,job_state,sts);
        js := sts.job_status;
    
      -- If the percentage done changed, display the new value.
      if js.percent_done != percent_done
      then
        dbms_output.put_line('*** Job percent done = ' ||
        to_char(js.percent_done));
        percent_done := js.percent_done;
      end if;
    
      -- If any work-in-progress (WIP) or Error messages were received for the job, display them.
      if (bitand(sts.mask,dbms_datapump.ku$_status_wip) != 0)
      then
        le := sts.wip;
      else
        if (bitand(sts.mask,dbms_datapump.ku$_status_job_error) != 0)
        then
          le := sts.error;
        else
          le := null;
        end if;
      end if;
      if le is not null
      then
        ind := le.FIRST;
        while ind is not null loop
          dbms_output.put_line(le(ind).LogText);
          ind := le.NEXT(ind);
        end loop;
      end if;
    end loop;
    
    -- Indicate that the job finished and gracefully detach from it.
    dbms_output.put_line('Job has completed');
    dbms_output.put_line('Final job state = ' || job_state);
    dbms_datapump.detach(h1);
    END;

Aufgabe 6: Nicht integriertes Replicat hinzufügen und ausführen

  1. Fügen Sie ein Replicat hinzu, und führen Sie es aus.
    1. Ersetzen Sie auf dem Bildschirm Parameterdatei MAP *.*, TARGET *.*; durch das folgende Skript:
      -- Capture DDL operations for listed schema tables
      --
      ddl include mapped
      --
      -- Add step-by-step history of ddl operations captured
      -- to the report file. Very useful when troubleshooting.
      --
      ddloptions report
      --
      -- Write capture stats per table to the report file daily.
      --
      report at 00:01
      --
      -- Rollover the report file weekly. Useful when PR runs
      -- without being stopped/started for long periods of time to
      -- keep the report files from becoming too large.
      --
      reportrollover at 00:01 on Sunday
      --
      -- Report total operations captured, and operations per second
      -- every 10 minutes.
      --
      reportcount every 10 minutes, rate
      --
      -- Table map list for apply
      --
      DBOPTIONS ENABLE_INSTANTIATION_FILTERING;
      MAP SRC_OCIGGLL.*, TARGET SRCMIRROR_OCIGGLL.*;

      Hinweis:

      DBOPTIONS ENABLE_INSTATIATION_FILTERING ermöglicht die CSN-Filterung von Tabellen, die mit Oracle Data Pump importiert wurden. Weitere Informationen finden Sie in der Referenz zu DBOPTIONS.
  2. Nehmen Sie einige Änderungen an Datenbank A vor, um zu prüfen, ob sie in Datenbank B repliziert werden.

Aufgabe 7: Replikation von Datenbank B in Datenbank A konfigurieren

In den Aufgaben 1 bis 6 haben Sie die Replikation von Datenbank A in Datenbank B eingerichtet. Mit den folgenden Schritten richten Sie die Replikation von Datenbank B in Datenbank A ein.

  1. Fügen Sie in Datenbank B einen Extract hinzu, und führen Sie ihn aus. Stellen Sie sicher, dass Sie auf der Seite "Extract-Parameter" hinter EXTRAIL <extract-name> Folgendes angeben:
    -- Table list for capture
    table SRCMIRROR_OCIGGLL.*;
    
    -- Exclude changes made by GGADMIN
    tranlogoptions excludeuser ggadmin
  2. Fügen Sie in Datenbank A ein Replicat hinzu, und führen Sie es aus. Ersetzen Sie auf der Seite "Parameter" MAP *.*, TARGET *.*; durch:
    MAP SRCMIRROR_OCIGGLL.*, TARGET SRC_OCIGGLL.*;
  3. Nehmen Sie einige Änderungen an Datenbank B vor, um zu prüfen, ob sie in Datenbank A repliziert werden.

Aufgabe 8: Prozesse überwachen und verwalten

  1. Überwachen Sie die Performance.
  2. Verwalten Sie die Traildateien.