分散式應用需求推動資料複寫技術演進。Oracle 高級複寫透過在不同物理站點複製資料物件,建立分散式資料環境。與分散式資料庫不同,複寫讓所有站點擁有相同資料物件的可用副本。典型場景:分支機構資料每日彙總至總部,兼具備份與統計分析功能。本文以 A 公司總部 (北京) 與三分支 (上海、杭州、武漢) 為例,詳細說明單向唯讀物化視圖複寫的建立流程。
ORACL,總部建立對應 SHORACL, HZORACL, WHORACL)。總部建立集中資料庫,版本不低於分支,為每分支建立獨立表空間與 Schema。
本例採異步複寫,每日刷新一次。
CONNECT system/passwd@SH
CREATE USER repadmin IDENTIFIED BY repadmin;
BEGIN DBMS_REPCAT_ADMIN.GRANT_ADMIN_ANY_SCHEMA(username => 'repadmin'); END; /
GRANT COMMENT ANY TABLE TO repadmin;
GRANT LOCK ANY TABLE TO repadmin;
GRANT SELECT ANY DICTIONARY TO repadmin; -- 若需使用視圖管理器
BEGIN DBMS_DEFER_SYS.REGISTER_PROPAGATOR(username => 'repadmin'); END; /
CONNECT repadmin/repadmin@SH
BEGIN DBMS_DEFER_SYS.SCHEDULE_PURGE(next_date => SYSDATE, interval => 'SYSDATE + 1', delay_seconds => 0); END; /
CONNECT system/passwd@SH
CREATE USER proxy_bjoracle IDENTIFIED BY proxy_bjoracle;
BEGIN DBMS_REPCAT_ADMIN.REGISTER_USER_REPGROUP(user_name => 'proxy_bjoracle', privilege_type => 'proxy_snapadmin', list_of_gnames => NULL); END; /
GRANT SELECT_CATALOG_ROLE TO proxy_bjoracle;
CONNECT repadmin/repadmin@SH
BEGIN DBMS_REPCAT.CREATE_MASTER_REPGROUP(gname => 'sh_rep'); END; /
-- 加入表
BEGIN DBMS_REPCAT.CREATE_MASTER_REPOBJECT(gname => 'sh_rep', type => 'TABLE', oname => 'CREDIT_CARD', sname => 'SHORACL', use_existing_object => TRUE, copy_rows => TRUE); END; /
-- 加入索引
BEGIN DBMS_REPCAT.CREATE_MASTER_REPOBJECT(gname => 'sh_rep', type => 'INDEX', oname => 'INDEX_CREDIT_CARD', sname => 'SHORACL', use_existing_object => TRUE, copy_rows => FALSE); END; /
-- 若無主鍵,指定替代鍵
BEGIN DBMS_REPCAT.SET_COLUMNS(sname => 'SHORACL', oname => 'CREDIT_CARD', column_list => 'CREDIT_CARD_ID'); END; /
-- 產生複寫支援 (觸發器、套件)
BEGIN DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT(sname => 'SHORACL', oname => 'CREDIT_CARD', type => 'TABLE', min_communication => TRUE); END; /
CREATE MATERIALIZED VIEW LOG ON SHORACL.CREDIT_CARD;
-- 無主鍵表用:
CREATE MATERIALIZED VIEW LOG ON SHORACL.CREDIT_CARD WITH ROWID EXCLUDING NEW VALUES;
BEGIN DBMS_REPCAT.RESUME_MASTER_ACTIVITY(name => 'sh_rep'); END; /
CREATE PUBLIC DATABASE LINK ORACLSH USING 'Oracle.shanghai.com';
-- 或使用 TNS 描述
CREATE PUBLIC DATABASE LINK ORACLSH USING '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=oracl)))';
CREATE DATABASE LINK ORACLSH CONNECT TO proxy_bjoracle IDENTIFIED BY proxy_bjoracle;
BEGIN DBMS_DEFER_SYS.SCHEDULE_PUSH(destination => 'ORACLSH', interval => 'SYSDATE + 1', next_date => SYSDATE, stop_on_error => FALSE, delay_seconds => 0, parallelism => 0); END; /
CONNECT SHORACL/SHORACL@BJ
CREATE DATABASE LINK ORACLSH CONNECT TO ORACL IDENTIFIED BY ORACL;
CONNECT mvadmin/mvadmin@BJ
CREATE MATERIALIZED VIEW SHORACL.CREDIT_CARD REFRESH FAST WITH PRIMARY KEY AS SELECT * FROM ORACL.CREDIT_CARD@ORACLSH;
-- 無主鍵用 ROWID
CREATE MATERIALIZED VIEW SHORACL.CREDIT_CARD REFRESH FAST WITH ROWID AS SELECT * FROM ORACL.CREDIT_CARD@ORACLSH;
BEGIN DBMS_REFRESH.MAKE(name => 'mvadmin.sh_refresh', list => '', next_date => SYSDATE, interval => 'SYSDATE + 1', implicit_destroy => FALSE, rollback_seg => '', push_deferred_rpc => TRUE, refresh_after_errors => FALSE); END; /
BEGIN DBMS_REFRESH.ADD(name => 'mvadmin.sh_refresh', list => 'SHORACL.CREDIT_CARD', lax => TRUE); END; /
SYS.DBA_JOBS 確認生成清除、推送、刷新三類作業。JOB_QUEUE_PROCESSES 參數 > 0 (預設為 0,需修改 init.ora 並重啟)。DBA_JOBS.FAILURES,失敗 16 次或間隔超過排程間隔會標記為 BROKEN,需手動 DBMS_JOB.RUN(job_no) 重跑並排查錯誤。重複上述流程,修改站點名稱 (HZ/WH)、Schema (HZORACL/WHORACL)、資料庫連結名稱 (ORACLHZ/ORACLWH)、群組名稱 (hz_rep/wh_rep)、代理用戶 (proxy_bjoracle_hz 等) 即可。總部最終將擁有 7 個排程作業 (1 清除 + 3 推送 + 3 刷新)。
本文示範最基礎的唯讀物化視圖異步複寫。Oracle 高級複寫還支援可更新物化視圖、多主站點同步/異步複寫、程序式複寫等進階功能。實務上應依系統即時性、效能需求選擇適當架構。