設定雙向複寫
設定單向複製之後,只需幾個額外步驟即可以相反方向複製資料。這個快速入門範例使用 Autonomous AI Transaction Processing 和 Autonomous AI Lakehouse 作為其兩個雲端資料庫。
開始之前
您必須在相同的租用戶和區域有兩個現有的資料庫,才能繼續進行此快速啟動。如果您需要範例資料,請下載 Archive.zip ,然後依照 Lab 1,Task 3:Load the ATP schema 中的指示進行操作
概觀
下列步驟將引導您瞭解如何使用 Oracle Data Pump 建立目標資料庫,並在相同區域中的兩個資料庫之間設定雙向 (雙向) 複寫。

作業 1:設定環境
-
建立部署。
-
啟用補充記錄日誌:
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA -
執行下列查詢,確定來源資料庫中所有表格的
support_mode=FULL:select * from DBA_GOLDENGATE_SUPPORT_MODE where owner = 'SRC_OCIGGLL'; -
在資料庫 B 執行下列查詢,以確保資料庫中所有表格的
support_mode=FULL:select * from DBA_GOLDENGATE_SUPPORT_MODE where owner = 'SRCMIRROR_OCIGGLL';
工作 2:新增兩個資料庫的交易資訊和檢查點表格
在 OCI GoldenGate 部署主控台中,移至「管理服務」的「組態」畫面,然後完成下列項目:
-
在資料庫 A 和 B 上新增交易資訊:
-
若為資料庫 A,請在「綱要名稱」輸入
SRC_OCIGGLL。 -
若為資料庫 B,請輸入
SRCMIRROR_OCIGGLL作為綱要名稱。注意:如果您使用與此範例不同的資料集,綱要名稱應該是唯一的,並且符合您的資料庫綱要名稱。
-
-
-
若為資料庫 A,請輸入檢查點表格的
"SRC_OCIGGLL"."ATP_CHECKTABLE"。 -
對於資料庫 B,輸入檢查點表格的
"SRCMIRROR_OCIGGLL"."CHECKTABLE"。
-
任務 3:建立整合式擷取
「整合式擷取」會擷取來源資料庫的持續變更。
-
在部署詳細資料頁面上,選取啟動主控台。
-
備註:請參閱其他擷取參數選項,以取得可用於指定來源表格之參數的詳細資訊。
-
在「擷取參數」頁面上,將下列行附加至
EXTTRAIL <extract-name>下:-- 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注意:
tranlogoptions excludeuser ggadmin可避免在雙向複製案例中重新擷取ggadmin所套用的交易。
-
-
檢查長時間執行的交易:
-
在來源資料庫上執行下列命令檔:
select start_scn, start_time from gv$transaction where start_scn < (select max(start_scn) from dba_capture);如果查詢傳回任何資料列,則您必須找出交易的 SCN,然後確認或倒回交易。
-
工作 4:使用 Oracle Data Pump (ExpDP) 匯出資料
使用 Oracle Data Pump (ExpDP) 將資料從來源資料庫匯出至 Oracle Object Store。
-
記下用於「匯出」和「匯入」命令檔的命名空間和儲存桶名稱。
-
建立認證權杖,然後將權杖字串複製並貼到文字編輯器以供日後使用。
-
在您的來源資料庫中建立證明資料,將
<user-name>和<token>取代為您的 Oracle Cloud 帳戶使用者名稱和您在上一個步驟中建立的權杖字串:BEGIN DBMS_CLOUD.CREATE_CREDENTIAL( credential_name => 'ADB_OBJECTSTORE', username => '<user-name>', password => '<token>' ); END; -
在您的來源資料庫中執行下列命令檔,以建立「匯出資料」工作。請確定已相應地取代物件存放區 URI 中的
<region>、<namespace>及<bucket-name>。SRC_OCIGGLL.dmp是執行此命令檔時將建立的檔案。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;
作業 5:使用 Oracle Data Pump (ImpDP) 建立目標資料庫
使用 Oracle Data Pump (ImpDP) 從來源資料庫匯出的 SRC_OCIGGLL.dmp,將資料匯入目標資料庫。
-
在您的目標資料庫中建立證明資料以存取 Oracle Object Store (使用前一節中的相同資訊)。
BEGIN DBMS_CLOUD.CREATE_CREDENTIAL( credential_name => 'ADB_OBJECTSTORE', username => '<user-name>', password => '<token>' ); END; -
在目標資料庫中執行下列命令檔,以從
SRC_OCIGGLL.dmp匯入資料。請確定已相應地取代物件存放區 URI 中的<region>、<namespace>及<bucket-name>: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;
工作 6:新增和執行非整合式 Replicat
-
-
在參數檔畫面上,使用下列指令碼取代
MAP *.*, TARGET *.*;:-- 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.*;注意:
DBOPTIONS ENABLE_INSTATIATION_FILTERING會對使用 Oracle Data Pump 匯入的表格啟用 CSN 篩選。如需詳細資訊,請參閱 DBOPTIONS Reference 。
-
-
對資料庫 A 執行一些變更以查看複製至資料庫 B 的變更。
作業 7:設定從資料庫 B 複製到資料庫 A
作業 1 到 6 已建立從資料庫 A 到資料庫 B 的複製。下列步驟設定從資料庫 B 複製到資料庫 A。
-
在資料庫 B 新增並執行 Extract 。在 EXTRAIL <extract-name> 之後的擷取參數頁面上,請確定您包含:
-- Table list for capture table SRCMIRROR_OCIGGLL.*; -- Exclude changes made by GGADMIN tranlogoptions excludeuser ggadmin -
新增並執行 Replicat 至資料庫 A。在「參數」頁面上,以下列項目取代
MAP *.*, TARGET *.*;:MAP SRCMIRROR_OCIGGLL.*, TARGET SRC_OCIGGLL.*; -
對資料庫 B 執行一些變更以查看複製至資料庫 A 的變更。