Server A (DB A) 表 TBL_TB 發生 DML 變更 → 即時同步至 Server B (DB B) 同名表。假設結構相同,PK 為 ID,含 NAME 欄位。
# $ORACLE_HOME/network/admin/tnsnames.ora
MASTER2 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.2)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = master2)
)
)
Server A IP: 192.168.0.1,Server B IP: 192.168.0.2,Service: master2
CREATE PUBLIC DATABASE LINK LINKMASTER2.ORACLE.COM
CONNECT TO b_user IDENTIFIED BY "b_password"
USING 'MASTER2';
b_user:Server B 同步專用用戶LINKMASTER2.ORACLE.COM 需與 Server B GLOBAL_NAME 一致或設 GLOBAL_NAMES=FALSECREATE OR REPLACE SYNONYM TBL_TB_REMOTE
FOR b_user.TBL_TB@LINKMASTER2.ORACLE.COM;
後續可直接 SELECT * FROM TBL_TB_REMOTE 查詢異地資料。
CREATE OR REPLACE TRIGGER trg_tbl_tb_ins_sync
AFTER INSERT ON TBL_TB
FOR EACH ROW
BEGIN
INSERT INTO TBL_TB_REMOTE (ID, NAME)
VALUES (:NEW.ID, :NEW.NAME);
END;
/
CREATE OR REPLACE TRIGGER trg_tbl_tb_upd_sync
AFTER UPDATE ON TBL_TB
FOR EACH ROW
BEGIN
UPDATE TBL_TB_REMOTE
SET ID = :NEW.ID, NAME = :NEW.NAME
WHERE ID = :OLD.ID;
END;
/
CREATE OR REPLACE TRIGGER trg_tbl_tb_del_sync
AFTER DELETE ON TBL_TB
FOR EACH ROW
BEGIN
DELETE FROM TBL_TB_REMOTE WHERE ID = :OLD.ID;
END;
/
| 考量點 | 建議做法 |
|---|---|
| 觸發器類型 | Row-level (FOR EACH ROW) 確保逐行同步 |
| 觸發時機 | AFTER 確保本地交易已完成,再發起遠端 DML |
| 錯誤處理 | 加入 EXCEPTION 區塊記錄失敗、避免阻塞本地交易 |
| 遞迴同步 | 雙向同步時需防止循環:IF SYS_CONTEXT('USERENV','DB_NAME') != 'MASTER2' THEN ... END IF |
| 大量 DML | 批次操作建議停用觸發器,改用批次同步程序 |
| 網路延遲 | 同步為同步阻塞,高延遲影響本地交易回應時間 |
CREATE OR REPLACE TRIGGER trg_tbl_tb_bi_sync
AFTER INSERT OR UPDATE OR DELETE ON TBL_TB
FOR EACH ROW
DECLARE
v_local_db VARCHAR2(30) := SYS_CONTEXT('USERENV', 'DB_NAME');
BEGIN
-- 僅在本地資料庫觸發同步,避免遠端回寫再觸發
IF v_local_db = 'MASTER1' THEN
IF INSERTING THEN
INSERT INTO TBL_TB_REMOTE (ID, NAME) VALUES (:NEW.ID, :NEW.NAME);
ELSIF UPDATING THEN
UPDATE TBL_TB_REMOTE SET NAME = :NEW.NAME WHERE ID = :OLD.ID;
ELSIF DELETING THEN
DELETE FROM TBL_TB_REMOTE WHERE ID = :OLD.ID;
END IF;
END IF;
EXCEPTION
WHEN OTHERS THEN
-- 記錄同步失敗,不拋出例外避免影響本地交易
INSERT INTO sync_error_log (err_time, err_msg, sqlcode, sqlerrm, operation, pk_value)
VALUES (SYSDATE, 'Remote sync failed', SQLCODE, SQLERRM,
CASE WHEN INSERTING THEN 'I' WHEN UPDATING THEN 'U' ELSE 'D' END,
COALESCE(:NEW.ID, :OLD.ID));
END;
/
sync_error_log 表記錄失敗| 局限 | 替代方案 |
|---|---|
| 同步阻塞本地交易、高延遲敏感 | Oracle GoldenGate (非同步、日誌採集、微秒級延遲) |
| DDL 不同步、結構變更需人工協調 | GoldenGate DDL 複寫 / 變更管理流程 |
| 大量批次導入觸發器效能差 | 停用觸發器 → 批次載入 → 重新啟用 → 差異比對補同步 |
| 無衝突偵測 (最後寫入勝) | GoldenGate 衝突解決 / 應用層邏輯 |
| 無監控儀表板、運維盲區 | GoldenGate Monitor / 自建監控 |
# Server A 驗證連線 Server B
tnsping MASTER2
sqlplus b_user/b_password@MASTER2
# 檢查防火牆
telnet 192.168.0.2 1521
# 或
nc -zv 192.168.0.2 1521
關鍵提醒:Server B 防火牆必須開放 1521 埠 (或配置埠),否則 DBLINK 連線逾時 (ORA-12170/12535)。
DBLINK + 觸發器同步屬「輕量級即時複製」,適合表數少、變更頻率中等、可容忍毫秒級同步阻塞的場景。企業級關鍵業務、高併發、跨機房、需零資料損失、DDL 同步、衝突解決,請直接上 Oracle GoldenGate。