基本複製應用例項(轉)

Rounders發表於2007-08-06

基本複製應用例項。

[@more@]

作者:石驍騑 | 來自:不詳 | 點選:253 | 釋出:2001-11-8

複製是一種實現資料分佈的方法,也就是說把一個系統中的資料透過網路分佈到另外一個或者多個地理位置不同的系統中,以適應可伸
縮組織的需要、減輕主伺服器的工作負荷和提高資料的使用效率。

Oracle 8針對資料分散式計算的需要,提供了一整套功能強大的資料庫複製解決方案。Oracle 8的資料複製按功能可以分為三類:基本
(簡單)複製、高階複製和混合複製,而高階複製又可分為多主節點複製和可更新快照複製。在《資料複製中的定時任務機制》介紹了
Oracle 8中的定時複製的機制,本文將主要介紹一個Oracle快照複製的實際例子及其技術實現細節。

一、業務需求
在一個實際的資料庫應用中,如銀行、稅務等商業應用中通常都採用這樣一種解決方案,在一個行政區域內,如一個省或者一個市,在
不同的地理位置架設數臺資料庫伺服器,這些不同地理位置的伺服器具有同樣的後臺資料庫。為了維護資料庫系統的一致性,對於整個
行政區域應用的程式碼表應該保持一致,如果不考慮資料複製,想維護同樣的不衝突的程式碼表是很困難的。下面是一個實際的業務需求,
我們用這裡例子來說明Oracle快照複製的應用。

為了維護整個系統程式碼表的一致性,客戶提出了這樣的業務需求,對於系統的程式碼表採用統一維護,即在一臺伺服器上維護,如圖1所示。在位置1(資料庫Ora_db1,使用者userA)上維護程式碼表,其他位置(資料庫ora_db2,使用者userB;ora_db3,使用者userC和ora_db4,使用者UserD)可以直接使用這些程式碼表,也就是說在位置1具有對程式碼表插入、刪除和更新的能力,而在其他地方只能有查詢的能力。

二、應用設計
針對上述的需求,我們提出了這樣一種解決方案,也就是採用Oracle 8的快照複製。具體業務實現方案設計如下:

在位置1的資料庫Ora_db1維護所有的程式碼表,在其餘資料庫建立相對於位置1的所有程式碼表的快照。為了維護快照的方便,在位置2、3
和4建立一個單獨的快照表空間和一個模式(schema),系統中的其他使用者透過一個私有同義詞來存取這些快照。這裡私有同義詞相對
公共同義詞要好,這是因為在位置1存在一個同樣規範的系統,它的表是透過公共同義詞來存取的。對於快照的重新整理,採用Oracle系統
包DBMS­_REFRESH進行,並將該重新整理過程的執行定時在每天早上2:00,這樣可以減少網路流量。對於快照的重新整理形式,由於對於代
碼錶的維護不是很多而且程式碼表的資料量相對較少,所以在此選擇了完全重新整理,這樣就避免了管理快照日誌的麻煩。下面以一個節點2
(ora_db2)為例來說明具體的技術實現細節。

三、技術實現細節
除非特別說明,下面的SQL命令都是在資料庫ora_db2的SYSETM使用者下執行的。假設要複製的程式碼表有三個:dm_gy_rydm,dm_gy_jgdm和
dm_gy_yhdm。

1.在資料庫2(ora_db2)上增加資料庫1(ora_db1)的services name

可以直接在tnsnames.ora檔案中增加資料庫1的services name,包括IP地址,SID以及埠號等。Services name 命名為ora_db1.world。

2. 建立一個用於連線資料庫1(ora_db1)的資料庫連線(dblink)

SQL> CREATE PUBLIC DATABASE LINK ora_db1.world
CONNECT TO SYSTEM
IDENTIFIED BY MANAGER USING 'ora_db1.world';

出於安全考慮,可以採用一個私有資料連線。

3. 建立一個名為Snapshot_ts的表空間來存放快照,並建立一個和該表空間有關的名為Snap的使用者。

SQL > CREATE TABLESPACE snapshot_ts DATAFILE
'c:orantdbfilesprodsnapshot01.dbf' SIZE 30M
DEFAULT STORAGE (INITIAL 30 K
NEXT 15 K
MINEXTENTS 1
MAXEXTENTS 100
PCTINCREASE 0)
ONLINE
PERMANENT;


SQL > CREATE USER snap
IDENTIFIED BY snap
DEFAULT TABLESPACE snapshot_ts;


SQL > GRANT CONNECT, RESOURCE TO snap;

可以透過下面的SQL語句在ora_db1資料庫以userA使用者來粗略地估計表空間snapshot_ts的大小。

SQL > SELECT SUM(bytes)
FROM USER_SEGMENTS
WHERE SEGMENT_NAME IN
(' dm_gy_rydm',
'dm_gy_jgdm',
'dm_gy_yhdm');

4. 執行下面的指令碼檔案snapsql.sql來生成建立ora_db1資料庫上userA使用者下程式碼表的快照指令碼:

/* Snapsql.sql */
spool c:snapcreate_snapshot.sql
SELECT 'CREATE SNAPSHOT SNAP.'
|| TABLE_NAME
|| ' PCTFREE 10 PCTUSED 40 TABLESPACE snapshot_ts '
|| ' STORAGE (INITIAL ' || INITIAL_EXTENT
|| ' NEXT ' || NEXT_EXTENT || ' PCTINCREASE 0 )'
|| ' AS SELECT * FROM userA.'
|| TABLE_NAME
||
FROM USER_TABLES
WHERE TABLE_NAME IN(
(' dm_gy_rydm',
'dm_gy_jgdm',
'dm_gy_yhdm');
spool off


注意上面這個生成所需錶快照的指令碼有一定的侷限性,如果所需生成快照的表中含有型別為long的列,‘select *’在這裡就不會起作用
,上面的這個SQL指令碼就不能自動建立生成所需快照的指令碼,必須透過在select列表中顯式地新增long型列名來建立表的快照。下面是一
個例子,假如我們要建立快照依賴的表dm_gy_note中有一個列note型別為long,就需要單獨寫出如下的建立快照的指令碼:

CREATE SNAPSHOT snap.dm_gy_note
PCTFREE 10 PCTUSED 40
TABLESPACE snapcost_ts
STORAGE (INITIAL 40960 NEXT 57344 PCTINCREASE 0 )
AS SELECT dm, dmmc,note
FROM ;
SQL > @snapsql.sql


5. 透過執行第4步建立的指令碼檔案create_snapshot.sql來建立所有的快照, 在指令碼檔案中包含下面這樣的程式碼:

CREATE SNAPSHOT snap. dm_gy_rydm
PCTFREE 10 PCTUSED 40
TABLESPACE snapshot_ts
STORAGE (INITIAL 163840 NEXT 57344 PCTINCREASE 0)
AS SELECT * FROM userA. dm_gy_rydm @ora_db1.world;

執行指令碼檔案create_snapshot.sql後,就在模式snap中建立了所需要的快照。下一步就是考慮該如何重新整理快照。對於快照的重新整理,可以
透過一些桌面DBA工具來重新整理快照也可以透過系統包dbms_snapshot.refresh來重新整理一個快照:

SQL > EXECUTE DBMS_SNAPSHOT.REFRESH
('snap.dm_gy_rydm')

6. 建立一個定時重新整理過程來定時重新整理快照:

/*sp_snapshot_refresh.sql */
CREATE OR REPLACE PROCEDURE sp_snapshot_refresh IS
BEGIN
DBMS_REFRESH.MAKE (
NAME=>'tax_dmb_grp',
LIST=>'snap. dm_gy_rydm,
'snap.dm_gy_jgdm',
'snap.dm_gy_yhdm',
NEXT_DATE=>TRUNC (SYSDATE+1)+2/24,
INTERVAL=>'(SYSDATE+1)',
IMPLICIT_DESTROY=>FALSE,
LAX=>TRUE);
END;
/
SQL > EXECUTE sp_snapshot_refresh


這樣就建立了一個定時任務來每天早晨2:00定時重新整理快照。執行下面的SQL語句就可以看到剛剛加入的這個任務。

SQL > SELECT JOB, WHAT FROM DBA_JOBS;

7. 在使用者userB下建立快照的私有同義詞:

SQL > CREATE SYNONYM userB.dm_gy_rydm FOR snap.dm_gy_rydm;

8. 以Snap使用者向userB使用者授與快照可以select的許可權。

SQL > GRANT SELECT ON dm_gy_rydm TO userB;

同樣的步驟在位置3(ora_db2)和位置4(ora_db3)建立位置1(ora_db1)的程式碼表快照和定時重新整理任務。這樣就可實現在位置1統一
維護程式碼表,在位置2、3和4使用該程式碼表的目的。如下面的SQL語句,在位置2(ora_db2)使用者UserB瀏覽在位置1(ora_db1)中的代
碼錶。

SQL > SELECT * FROM dm_gy_rydm;

四、日常維護
無論任何時候只要出現網路連線問題,重新整理就會失敗。這些錯誤資訊可以在alert log檔案中找到。下面簡單介紹一下對這種問題的處理
辦法:

1. 首先在任務佇列中找到重新整理快照的的任務編號

SQL > SELECT JOB,what FROM DBA_JOBS;

2. 刪除該任務

SQL > EXECUTE DBMS_JOB.REMOVE (JOBNO);

3. 刪除快照組

SQL > EXECUTE DBMS_REFRESH.DESTROY ('tax_dmb_grp');

4. 重新建立快照組並且重新定時任務來定時重新整理快照

SQL > EXECUTE sp_snapshot_refresh

五、快照監視

快照可以透過下面的SQL語句來監視

SQL > SELECT NAME,
TO_CHAR(last_refresh,'DD-MON-YY HH:MM:SS')
FROM DBA_SNAPSHOTS;

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9417382/viewspace-932284/,如需轉載,請註明出處,否則將追究法律責任。

相關文章