Oracle相關分布式數據解決方案
可能在雲計算、SOA架構下這種方案會逐漸消亡,但是目前還是比較實用的,本文簡單介紹了常用的數據同步方案,由於正在使用高級復制的解決方案,所以重點說了Oracle的高級復制
一、常見的分布式數據解決方案
如果數據庫為Oracle、數據分散的分布式系統,常可以見到入下的分布解決方案
非實時,批量同步
1.ETL工具或者自己開發的接口
一般對應於特定格式的數據文件,使用FTP服務。
數據倉庫或者數據集市可以使用ETL工具做數據整合,一般系統都是自己寫的接口程序實現。常規思路是數據導入接口表,清洗後進入正式表
導入方式非常多,如果數據量很大可以使用sqlLoder,如果數據不大,可以逐行導入並同時清洗。就我的經驗來看,將清洗邏輯放在數據庫比較好。
也有可能是通過http獲得的XML文件,這時需要自己定制XML的解析程序,讀出CDATA節。高級程序語言這方面的功能都很強大、簡單。
實時、小批量同步
1.第三方提供的
對於關鍵系統,可以使用中間件保證數據的安全、穩定。比如BEA的Tuxedo就不錯。
2.自己開發
如果都是unix機器可以使用socket編程,數據打成包發送,穩定性可以保證。經常是打成XML的格式,數據文件的自描述能力比較強。
這兩種方案在電信等系統都可以見到,還是比較可靠的。
3.Oracle自己提供的
3.1實時表接口
使用db_link和存儲過程,結合job,很靈活和強大。
3.2 Oracle高級復制
如果需要保證雙向的實時數據同步,同時復制環節又比較復雜,存在多個復制結點,可以使用Oracle的高級復制,今年在我做的房產局項目中使用了這種方案。雖然就這個項目來說,不太適用使用這種方案,但由於歷史的原因,為了一期系統的需要我們延續了這種同步方案。這篇文章主要就高級復制的過程進行說明:
二、高級復制基本概念
1.相同數據會存在於多個結點,這種環境更適宜使用高級復制
2.在不同版本和不同操作系統之間的Oracle,都可以使用advance replication
3.幾個名詞
replication object:復制對象,包括表、索引、存儲過程
replication group:復制組,復制對象的集合,一個group包含多個object,一個object只能屬於一個group
replication site:復制站點
4.multimaster replication:特點:全表復制,每個事務後都可進行復制
復制方式
異步復制:推後的時間內復制到其它master,也叫store and forward data replication
同步復制:立刻更新到其它master,也就real time data replication
procedual replication: 包生成一個wrapper,數據變化通過存儲過程完成,某個master中的procedure被調研,wapper會保證其它site中 的procedure也被調用,在有大數據量操作時可減少網絡負載
異步調用過程
DML操作(或者wappers)產生由內部觸發器一個延時rpc並放入延時事務隊列,1個site有延時事務隊列,1個隊列被多個group共用
出現錯誤將事務放入錯誤隊列,事務成功結束後,由purge job從源site的事務隊列中刪除事務
同步復制過程
DML操作被立刻捕獲,事務立刻執行,任何一個站點出錯、事務回滾,先鎖住本地行,使用after row觸發器鎖住遠端行,所有站點提交後 Oracle才會解鎖,極為依賴系統和網絡的可用性
三、高級復制創建步驟:
網上的資料很多,也很詳細,其中eygle的比較詳細的經典,大家搜一下就可以看到,我就簡單說一下,並就自己碰到的問題描述一下解決辦法
1.調整Oracle環境,建立repadmin用戶,為用法賦權
2.建立db_link
3.復制組中建立復制對象
可使用圖形化工具或者手工腳本建立,由於表很多,而且正式部署還有再次建立,這裡我使用了手工腳本方式
--創建復制組:
DBMS_REPCAT.CREATE_MASTER_REPGROUP(
gname => '"***"',
qualifIEr => '',
group_comment => '');
--在復制組裡加入復制對象:
DBMS_REPCAT.CREATE_MASTER_REPOBJECT(
gname => '"**"',
type => 'TABLE',
oname => '"TEST"',
sname => '"LFGISTEST"',
copy_rows => false,
use_existing_object => TRUE);
--對復制對象產生復制支持:
DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT(
sname => '"LFGISTEST"',
oname => '"TEST"',
type => 'TABLE');
--添加主體復制節點:
DBMS_REPCAT.ADD_MASTER_DATABASE(
gname => '"***"',
master => '***',
use_existing_objects => TRUE,
copy_rows => false,
propagation_mode => 'ASYNCHRONOUS');
--在主體定義站點啟動復制:
DBMS_REPCAT.RESUME_MASTER_ACTIVITY(gname => '"***"',true);
碰到的錯誤
1.db_link創建後無法使用,發現db_link起的名稱有問題
解決方法:如果global_names = true;db_link名稱一定要和global_name一致,修改後成功
2.添加主體復制節點時報錯:
ORA-23357: the propagator does not exist
ORA-06512: at "SYS.DBMS_REPCAT_CACHE", line 76
ORA-06512: at "SYS.DBMS_REPCAT_MAS", line 2105
ORA-06512: at "SYS.DBMS_REPCAT", line 146
ORA-06512: at line 2
可能原因:
1.global_name使用了Oracle的保留字,參考:http://Oracle-tech.blogspot.com/2008/08/ora-23375-when-adding-new-master-site.Html
修改外網(61)global_name 為OUT.WWKJ.LZFC2
alter database rename global_name to OUT.WWKJ.LZFC2;
2.REPADMIN用戶權限不足,檢查賦權限的語句,確保權限到位
3.db_link必須使用REPADMIN連接對端數據庫,我就是因為這個原因報的錯
4.據說兩台數據庫的域必須一樣
5.兩台機器的用戶和schema應該一致
解決方法:呵呵,很粗心啊,沒有用repadmin運行腳本
3.復制組中加入復制對象時候,報23312錯誤,當前站點不是masterdef
Oracle Error : ORA-23312: not the masterdef according to string
Cause: The group name is null, the group name is misspelled, the invocation or given database is not the masterdef, or one of the masters does not belIEve the invocation database is the masterdef.
Action: If the given group name and masterdef were both correct, connect to the masterdef and retry the request, or relocate the masterdef at the (errant) databases using relocate_masterdef.