文章摘要:
Oracle作為數據庫平台,並且有的項目使用到了Oracle的數據庫復制技術,其中也遇到了一些問題,因此在這裡,我對Oracle的復制技術談一下我個人的理解,希望能夠對采用Oracle數據庫的項目組有所幫助。其中在文中使用到的SQL腳本都是經過檢驗可以運行的。
--------------------------------------------------------------------------------
正文:
Oracle高級復制
在開始之前,需要簡單說明一下,目前公司有幾個項目都采用Oracle作為數據庫平台,並且有的項目使用到了Oracle的數據庫復制技術,其中也遇到了一些問題,因此在這裡,我對Oracle的復制技術談一下我個人的理解,希望能夠對采用Oracle數據庫的項目組有所幫助。其中在文中使用到的SQL腳本都是經過檢驗可以運行的。
首先簡單介紹和數據庫復制有關的基本概念,然後探討Oracle數據復制技術中的幾個重要模型,最後介紹Oracle的數據復制管理器以及如何利用它來配置和維護復制環境。
在文章的開頭,我想首先簡單談一下復制的基本概念,也就是什麼是復制?復制簡單地說就是在由兩個或者多個數據庫系統構成的一個分布式數據庫環境中拷貝數據的過程。Oracle高級復制,也稱為對稱復制,第一次是在Oracle 7.1.6版本中出現的,在這之前的Oracle版本中,Oracle數據復制方法僅有只讀快照形式的基本復制一種方法。隨著Oracle版本的每一次升級,數據復制的功能、管理以及速度等方面都得到了很大的改進和完善。目前,由於對分布式數據環境需求的不斷增長,越來越多的應用提出了數據復制的需求。
1.基本概念
1. 分布式數據庫技術
分布式數據庫技術是目前我們經常提及的分布式計算的一個重要組成部分,該技術允許數據在多個服務器端共享。采用分布式數據庫技術,一個本地服務器可以存取不同物理地點的遠程服務器上的數據;也可以使所有的服務器均可以持有數據的拷貝/復制,這樣分布式系統中的所有服務器均可進行本地存取。
設計一個分布式計算解決方案首先需要考慮的問題就是應用的完整性、復雜性、性能和可用性以及響應時間等,同時還需要考慮的是對於不同的應用需求是采用實時存取遠程數據還是采用延遲存取遠程數據。這對於數據復制來講就是采取實時更新復制方案還是延遲數據復制方案。
2. 同步和異步的概念
同步分發數據庫技術是一種實時遠程存取和實時更新數據的技術。這種技術可以保證應用的完整性降低了應用的復雜性,但是如果系統存在網絡存取速度很慢這樣的問題,相應響應時間就會很慢。
異步分發數據庫技術是一種延遲遠程存取和延遲傳播對數據更新的技術。這種技術具有很高的可用性和很短的響應時間。相比同步分發數據庫技術就顯得復雜一些,為了確保應用的完整性需要仔細考慮和設計。
對於實際的商業問題,必須權衡這兩種技術的利弊最終選擇最佳的解決方案,有些問題選用同步技術比較適合,也有一些問題采用異步技術是比較好的解決方案,還有一些問題必須綜合這兩種技術。
3. 復制的概念
復制,顧名思義就是將數據庫中的數據拷貝到不同物理地點的數據庫中以支持分布式應用,它是整個分布式計算解決方案的一個重要組成部分。上面介紹了同步和異步的概念,這裡針對復制也存在同步復制和異步復制的問題。
同步復制,復制數據在任何時間在任何復制節點均保持一致。如果復制環境中的任何一個節點的復制數據發生了更新操作,這種變化會立刻反映到其他所有的復制節點。這種技術適用於那些對於實時性要求較高的商業應用中。
異步復制,所有復制節點的數據在一定時間內是不同步的。如果復制環境中的其中的一個節點的復制數據發生了更新操作,這種改變將在不同的事務中被傳播和應用到其他所有復制節點。這些不同的事務間可以間隔幾秒,幾分種,幾小時,也可以是幾天之後。復制節點之間的數據臨時是不同步的,但傳播最終將保證所有復制節點間的數據一致。
4. 更新沖突
在異步復制環境中,對於所有應用最關鍵的就是要確保數據的一致性。
我們來看下面這種情況會有什麼後果發生呢?在同一時間對同一個表的同一行數據的同一列在兩個不同的地點作更新。這種情況就會發生稱之為更新沖突的錯誤。為保證數據的一致性,更新沖突必須被檢測到並且處理以確保在不同地點的數據元素保持同樣的值。更新沖突可以通過限制"所有權" 到單一節點或者將更新某個特定數據元素的權利限制到某一具體節點的方法來避免。
2.Oracle數據復制應用模型
為確保實際應用數據的一致性,必須在異步復制應用模型中考慮沖突避免或者沖突檢測和消除的方法。例如,對於一個實際商業應用,首先必須在邏輯上了解該商業應用采取的沖突避免方法和在某個節點有那些數據以及這些數據中那些是可更新的,而那些又是不可更新的。在下面的這一部分中,我們首先將詳細討論兩種常用的沖突避免方法:主站點所有權模型和動態所有權模型。然後,討論共享所有權模型以及這種模型引起的沖突檢測和處理問題,最後,討論針對Fail-over的復制配置,這種復制方案同時考慮了沖突避免和沖突檢測與消除兩種情況。
1. 主站點所有權
主站點所有權,異步復制數據被一個單一節點"所有",這些要復制的數據僅能被該節點更新,其他節點向擁有該數據的主節點訂閱(subscribe)數據,這意味著他們在本地系統上只能夠存取這些復制數據的只讀拷貝。下面是一些這樣的例子。
(1) 決策支持系統(DSS)的聯機事務處理數據的卸載。來自一個或者多個OLTP系統的數據可以被卸載到一個獨立的局部DSS中,用於只讀分析
(2) 中央信息的分發。產品信息,如價格列表等在總部節點上維護,然後將這些信息復制到遠程銷售辦事處的只讀產品目錄系統中
(3) 遠程信息的集中。許多遠程節點上的產品目錄數據復制到總部節點,這裡總部節點只需要有數據只讀的權限
一個主節點擁有一個表的完全所有權,而其他節點只能訂閱這個表的只讀拷貝。也可以是多個主節點擁有同一個表的截然不同子集或者劃分,而另一些節點則訂閱這些子集或者劃分的只讀拷貝。如,一個分布的產品目錄系統可以讓不同的銷售辦事處擁有一個表的屬於自己的一個"水平"部分,如在客戶(CUSTOMERS)表, 訂單(ORDERS)表和目錄(ITEMS)這些表中含有每個銷售辦事處為之服務的客戶和產品信息。中心總部節點可以通過訂閱每個辦事處擁有的數據來保持一個完整的所有產品和客戶信息的只讀拷貝。
2. 動態所有權
動態所有權,異步更新將復制數據從一個節點移到另一個節點,而在該過程中,必須保證在同一時刻只有一個特定的節點可以對數據進行更新。一個典型實際應用就是"海關訂單處理系統",訂單處理的典型步驟是,報關→同意→裝運→開單→收單→入帳等。應用模型可以執行其中的任何步驟,但必須保證各個不同模塊的同一個數據應該在一個綜合數據庫中。在該系統中,當且僅當訂單的狀態表明前一個步驟已經完成時,下一個應用模塊才可以執行更新訂單數據的操作。例如,"裝運"應用模塊僅能在"報關"並且得到"同意"後才能被執行。 (Delphi中的DEMO程序中提供了一個簡化版本演示程序)
通過使用動態所有權復制模型,可以將一個系統分布在多個節點和數據庫上,也就是說應用模型可以建立在不同的系統上。我們還是來看上面的例子,"報關"和"批准"這兩部分可以運行在一個系統上,"裝運"在另一個系統上,"開單"和"收單"等又可在一個系統上。在這個分布式系統中,數據可以被復制到不同的節點上,這些節點對復制的數據只要具有只讀的權限即可。如,利用復制,"報關"節點可以監視已經報關的訂單處理過程。
前面討論的主節點所有權和動態所有權復制模型具有一個共同的特征:在任何一個給定的時間點,只允許一個節點有更新數據的權利,而其余節點對於復制的數據拷貝僅有只讀權限。然而,還存在這樣的情況,允許多個節點可以更新同一個數據,在極端情況下可以是在同一時刻,這就是所說的共享所有權。
3. 共享所有權
共享所有權使用異步復制,這對於主節點和動態所有權模型來講存在一些限制。在共享所有權情況下,整個系統可以存在暫時的不一致,同時必須使用沖突檢測和消除。共享所有權模型相對於前面兩種模型具有一些新的特點。
例如,對於前面我們討論的那個采用具有水平劃分主節點復制方案來的分布式"訂單處理系統"的例子。
例如,下面這個應用,一個以年為單位管理客戶訂單的公司,對於老的訂單數據不再需要在線保存,而需要卸載到某存儲介質中。這時,如果在多個節點間復制每一獨立的行級變化效率將是非常低的。對於這種情況,可以直接在每個復制節點執行一個過程來直接進行這種更新操作。Oracle高級復制提供的分布式模式管理功能(將在下面詳細討論)可以非常方便地在多個節點上設置和維護過程級復制的遠程過程。
和Oracle的其他功能不同,Oracle的高級復制不是即插即用的,用戶必須深刻理解它們是如何工作的以及各種復制方案的優缺點。深刻理解復制的基本概念可以幫助你設計一個可靠的復制環境。
1. 實現數據庫復制的前提條件
q 數據庫支持高級復制功能:您可以用system身份登錄數據庫,查看v$option視圖,如果其中Advanced replication為TRUE,則支持高級復制功能;否則不支持。
q 數據庫初始化參數要求:
(1) db_domain = test.com.cn:指明數據庫的域名(默認的是WORLD),這裡可以用您公司的域名。
(2) global_names = true:它要求數據庫鏈接(database link)和被連接的數據庫名稱一致。 現在全局數據庫名:db_name+"."+db_domain
q 數據庫連接通暢:
運行$tnsping hr_svr與$tnsping xjtu,出現以下提示符:
Attempting to contact
(ADDRESS=(PROTOCOL=TCP)(HOST=10.1.1.200)(PORT=1521)) OK(n毫秒)則表示數據庫連接通暢,可以准備復制。
2. 系統環境參數(init.ora文件)設置(對於非缺省值)
如果要搭建Oracle高級復制環境,必須在初始化文件中設置下列參數,見表1所示。
參數名稱 推薦值 備注
processes 100 進程數,default=59如果進程數大於59數據庫將可能發生死鎖
shared_pool_size 30000000 至少30M,如果有很多的復制對象的話,則需要更多的空間
large_pool_size 500K
db_block_buffers 550K
compatible 8.0.5.0 該版本以上
db_file_multiblock_read_count 16
dml_locks 100
sequence_cache_entrIEs 30
sequence_cache_hash_buckets 23
global_names TRUE
distributed_lock_timeout 300
distributed_transactions 10
Open_links 6 復制節點多的話,需要增加
Sort_area_size 1000000
db_name RLDBA
job_queue_processes 6 定義SNP進程的啟動個數為n。系統缺省值為0,正常定義范圍為0~36,根據任務的多少,可以配置不同的數值。
job_queue_interval 60 定義系統每隔N秒喚醒該進程一次。系統缺省值為60秒,正常范圍為1~3600秒。事實上,該進程執行完當前任務後,就進入睡眠狀態,睡眠一段時間後,由系統的總控負責將其喚醒。
parallel_max_servers 10 只適用於並行傳播
parallel_min_servers 2 只適用於並行傳播
PEPLICATION_DEPENDENCY_TRACKING TRUE 如果采用並行傳播,必須設置為TRUE
(表1:Oracle高級復制環境初始化參數設置)
表1中各個參數的推薦值認為目前的復制環境只有兩個節點,一個簡單的高級復制環境,如果節點較多,且復制關系復雜,需要復制的表也很多,
則需要相應增大一些參數的值,這可以通過修改不同的參數試驗獲得。如果修改了以上這幾個參數,需要重新啟動數據庫以使參數生效。
將所有的SNAPSHOT 或者是JOB_QUEUE_KEEP_CONNECTIONS參數都刪除,因為Oracle以後已經不支持這些參數。
2.Net8參數文件
(1)sqlnet.ora文件設置
# SQLNET.ORA Network Configuration file: D:\Oracle\Ora81\network\admin\sqlnet.ora# Generated by Oracle configuration toolsSQLNET.AUTHENTICATION_SERVICES= (NTS) NAMES.DIRECTORY_PATH= (TNSNAMES, ONAMES, HOSTNAME)automatic_ipc=offnames.default_domain = worldname.default_zone = worldsqlnet.expire_time = 0DISABLE_OOB = ON
(2)tnsnames.ora文件設置
RLDBA = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = hr_svr)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = rep.world) ) )XJTU = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = xjtu)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = xjtu.world) ) )
上面Host為各個復制節點的IP地址,如果復制節點很多,則全部加入到tnsnames.ora文件中,本文作為用例中有兩個節點。
3.表空間
如果搭建Oracle高級的高級復制環境,額外需要加大一些表空間,表2是建議的初始表空間。
表空間 建議初始值 建議
SYSTEM 至少20M
ROLLBACK SEGMENTS 至少20M 建議回滾段的下一個區大小設置至少為100K。
TEMPORARY 至少10M
TOOLS 至少20M
( 表2:Oracle系統表空間大小設置 )
上面這些建議的設置是一種較小復制環境下的空間設置。如果要復制的表很多,每天的變化量很大,復制節點復雜,則需要相應增大表空間的大小,具體數據依據具體情況而定。
6.復制應用實例
上面我們對復制基本概念及復制參數的作了說明,接下來主要介紹一個Oracle快照復制的實際例子及其技術實現細節。
(1) 業務需求描述
在一個實際的數據庫應用中,如電信、人力資源管理等應用中通常都采用這樣一種解決方案,在一個行政區域內,如一個省或者一個市,在不同的地理位置架設數台數據庫服務器,這些不同地理位置的服務器具有同樣的後台數據庫。為了維護數據庫系統的一致性,對於整個行政區域應用的基本數據表應該保持一致,如果不考慮數據復制,想維護同樣的不沖突的代碼表是很困難的。下面我們不考慮實際的業務應用,只從數據庫復制角度來說明Oracle快照復制的應用。
為了維護整個系統基本數據表的一致性,比如有這樣的業務需求,對RLDBA上的一些表采用統一維護,即在一台服務器上維護。而在其他位置(如數據庫XJTU,用戶SNAP)可以直接使用這些表,也就是說在位置1具有對代碼表插入、刪除和更新的能力,而在其他地方具有同步查詢應用的能力。
(2) 應用設計
針對上述的需求,現在提出了這樣一種解決方案,也就是采用Oracle的快照復制。具體業務實現方案設計如下:
在位置1的數據庫RLDBA維護所有的表,在其余數據庫建立相對於位置1的所有表的快照。為了維護快照的方便,在位置2創建一個單獨的快照表空間和一個模式(schema),也可以稱為用戶(USER),系統中的其他用戶通過一個私有同義詞來存取這些快照。
這裡私有同義詞相對公共同義詞要好,這是因為在位置1存在一個同樣的系統,它的表是通過公共同義詞來存取的。對於快照的刷新,采用Oracle系統包DBMS_REFRESH進行,並將該刷新過程的運行定時在每天早上2:00,這樣可以減少網絡流量。對於快照的刷新形式,由於對於表的維護不是很多而且表的數據量相對較少,所以在此選擇了完全刷新,這樣就避免了管理快照日志的麻煩。下面以一個節點2(XJTU)為例來說明具體的技術實現細節。
(3) 技術實現細節
除非特別說明,下面的SQL命令都是在數據庫XJTU的SYSETM用戶下運行的。
1. 在數據庫2(XJTU)上增加數據庫1(RLDBA)的services name,可以直接在tnsnames.ora文件中增加數據庫1的services name,包括IP地址,SID以及端口號等。services name 命名為rep.world。
2. 創建一個用於連接數據庫1(RLDBA)的數據庫連接(dblink)
DROP PUBLIC DATABASE LINK rep.hr_group@rldba; //刪除Database linkCREATE PUBLIC DATABASE LINK rep.hr_group@rldba CONNECT TO rldba IDENTIFIED BY admin USING 'rldba'; //Create Database linkselect * from [email protected]_group@rldba; //Test the Database link
注:出於安全考慮,可以采用一個私有數據連接。
3. 創建一個名為snapshot_rldba的表空間來存放RLDBA快照,並創建一個和該表空間有關的名為Snap的用戶。
CREATE TABLESPACE "snapshot_rldba"LOGGING DATAFILE 'D:\Oracle\ORADATA\ORA8I\SNAPSHOT_RLDBA.ora'SIZE 30MDEFAULT STORAGE ( INITIAL 30K NEXT 15K MINEXTENTS 100 MAXEXTENTS UNLIMITED PCTINCREASE 0 ); //Create Table spaceCREATE USER snap IDENTIFIED BY snap DEFAULT TABLESPACE "snapshot_rldba"; //Create User in the table spaceGRANT CONNECT, RESOURCE TO snap; //grant role to the user
4. 運行下面的腳本文件snapsql.sql來生成創建rldba數據庫上rldba用戶表的快照腳本:
注意如果所需生成快照的表中含有類型為long的列,"select *"在這裡就不會起作用,上面的這個SQL腳本就不能自動建立生成所需快照的腳本,必須通過在select列表中顯式地添加long型列名來創建表的快照。下面是一個例子,假如我們要創建快照依賴的表T_YGJBXX中有一個列ZP類型為long,就需要單獨寫出如下的創建快照的腳本:
CREATE SNAPSHOT T_YGJBXX PCTFREE 10 PCTUSED 40TABLESPACE "snapcost_rldba "STORAGE (INITIAL 40960 NEXT 57344 PCTINCREASE 0 )USING INDEX REFRESH WITH PRIMERY KEYFOR UPDATEAS select YGID, GZBH, FZJRLB, ZP, SXZY, XCSZY from [email protected]_group@rldba; //Create snapshot
EXECUTE DBMS_SNAPSHOT.REFRESH ('snap.T_YGJBXX ')
運行腳本文件create_snapshot.sql後,就在模式snap中創建了所需要的快照。下一步就是考慮該如何刷新快照。
對於快照的刷新,可以通過一些桌面DBA工具來刷新快照也可以通過系統包dbms_snapshot.refresh來刷新一個快照:
創建或選擇實現數據庫復制的用戶和對象,給用戶賦權,數據庫對象必須有主關鍵字,如果數據庫對象沒有主關鍵字,可以運行以下SQL命令添加:
alter table dept add (constraint dept_deptno_pk primary key (deptno));
5. 創建一個定時刷新過程來定時刷新快照:
--sp_snapshot_refresh.sql CREATE OR REPLACE PROCEDURE sp_snapshot_refresh ISBEGINDBMS_REFRESH.MAKE ( NAME=>' T_YGJBXX ', LIST=>'snap. T_YGJBXX', NEXT_DATE=>TRUNC (SYSDATE+1)+2/24, INTERVAL=>'(SYSDATE+1)', IMPLICIT_DESTROY=>FALSE, LAX=>TRUE);END sp_snapshot_refresh; --創建了一個定時任務來每天早晨2:00定時刷新快照
EXECUTE sp_snapshot_refresh; //Execute the procedure
SELECT JOB, WHAT FROM DBA_JOBS; //查詢剛剛加入的這個任務
CREATE SYNONYM system.T_YGJBXX FOR snap.T_YGJBXX;//在用戶system下創建快照的私有同義詞
GRANT SELECT ON dm_gy_rydm TO system;//以snap用戶向system用戶授與快照可以select的權限。
6. 同樣的步驟在其它位置建立位置1(rldba)的表快照和定時刷新任務。這樣就可實現在位置1統一維護代碼表,在位置2和其它位置使用該表的目的。如下面的SQL語句,在位置2(xjtu)用戶snap浏覽在位置1(rldba)中的代碼表。
SELECT * FROM T_YGJBXX;
(4) 日常維護及注意事項
無論任何時候只要出現網絡連接問題,刷新就會失敗。這些錯誤信息可以在alert.log文件中找到。下面簡單介紹一下對這種問題的處理辦法:
1.首先在任務隊列中找到刷新快照的任務編號
SELECT JOB, what FROM DBA_JOBS;
2.刪除該任務
EXECUTE DBMS_JOB.REMOVE (JOBNO);
3.刪除快照組
EXECUTE DBMS_REFRESH.DESTROY ('tax_dmb_grp');
4.重新創建快照組並且重新定時任務來定時刷新快照
EXECUTE sp_snapshot_refresh('snap.T_YGJBXX')
5.快照監視
SELECT NAME, TO_CHAR(last_refresh,'DD-MON-YY HH:MM:SS') FROM DBA_SNAPSHOTS;