Stream 是Oracle 的訊息佇列(也叫OracleAdvanced Queue)技術的一種擴充應用。 Oracle 的訊息佇列是通過發布/訂閱的方式來解決事件管理。流複製(Stream replication)只是基於它的一個資料共用技術,也可以被用作一個可靈活定製的高可用性方案。它可以實現兩個資料庫之間資料庫級,schema級,Table級的資料同步,並且這種同步可以是雙向的。 Oracle Stream也是通過資料冗餘來提高可用性,這一點和Data Guard 類型。
Oracle 進階複製(Oracle advancedReplication) 和流複製(Stream Replication) 是從名稱和功能上都相似的兩種技術。但前者是基於觸發器的,後者是基於日誌挖掘(Logminer)技術。
一. Stream 的工作原理
Stream 是Oracle AdvancedQueue技術的一種擴充應用,這種技術最基本的原理就是收集事件,把時間儲存在隊列中,然後把這些事件發布給不同的訂閱者。從DBA的角度來說,就是把捕獲Oracle資料庫產生的Redo日誌,然後把這些日誌通過網路傳播到多個資料庫,其他資料庫通過應用這些日誌,達到複製變化的作用。
在Stream 環境下,複製的起點資料庫叫作Source Database,複製的終點資料庫叫作Target Database。在這兩個資料庫上都要建立一個隊列,其中的Source Database上的是發送隊列,而Target Database上的是接收隊列。
資料庫的所有操作都會被記錄在日誌中。配好Stream環境後,在Source Database上會有一個捕獲進程(Capture Process), 該進程利用Logminer技術從日誌中提取DDL,DML語句,這些語句用一種特殊的格式表達,叫作邏輯變更記錄(Logical Change Record, LCR). 一個LCR對應一個原子的行變更,因此來源資料庫上的一個DML語句,可能對應若干個LCR記錄。這些LCR會儲存到Sourece Database的本地發送隊列中。然後傳播進程(Propagation Process)把這些記錄通過網路發送到Target Database的接收隊列。在Target Database上會有一個應用進程(Apply Process),這個進程從本地的接收隊列中取出LCR記錄,然後在本地應用,實現資料同步
二. Data Guard 和Stream 區別
Date Guard有兩種類型:physicalstandby 和 logical standby。這兩中standby 都有3個功能模組:記錄傳送;日誌接收,日誌恢複。兩種standby在前兩個模組中是一樣的,都是通過LGWR或者ARCn進程發送日誌,通過RFS進程接受日誌。區別在第三個模組:
Physical Standby 使用的是MediaRecovery技術直接在資料區塊層級進行恢複,因此Physical Standby 能夠做到兩個資料庫的完全同步,沒有資料類型限制。
Logical Standby實際是通過Logminer技術,把日誌中的記錄還原成SQL語句,然後通過ApplyEngine 執行這些語句實現資料同步,因此Logical Standby不能保證資料的完全一致。比如Logical Standby 不支援某些資料類型,這一點在選擇Logical Standby時必須要考慮. Logical Standby 不支援的資料類型可以從DBA_LOGSTDBY_UNSUPPORTED是不裡查看.
SQL>SELECT * FROM DBA_LOGSTDBY_UNSUPPORTED;
Stream 使用的是LogicalStandby 第三個模組,也就是在Source Database一端,Capture 進程利用Logminer 技術把日誌內容還原成LCR,然後發送到Target Database,而在Target database 一端,也是通過Apply Engine 執行這些LCR。因此Stream在使用上也有些限制條件。這些可以從視圖ALL/DBA_STREAMS_NEWLY_SUPPORTED, ALL/DBA_STREAMS_UNSUPPORTED 查看stream複製不支援的資料類型。
SQL>SELECT table_name, reason FROMALL_STREAMS_NEWLY_SUPPORTED;
SQL>SELECT table_name, reason FROMDBA_STREAMS_NEWLY_SUPPORTED;
SQL>SELECT table_name, reason FROMDBA_STREAMS_UNSUPPORTED;
SQL>SELECT table_name, reason FROMALL_STREAMS_UNSUPPORTED;
下面以圖表的形式列舉他們的區別:
Streams |
Data Guard |
主要目的是資料共用 |
主要目的是災難恢複和高可用性 |
可以多方向同步 |
只能是單向,從Primary--> Standby |
資料粒度可以是資料庫,Schema,Table三個層級 |
只有資料庫層級 |
支援異種平台的同步(Heterogeneous Platforms) |
必須同種平台 (Homogeneous Platforms) |
參與複製的每個資料庫可以讀寫 |
只有Primary可以讀寫,Standby 唯讀 |
支援Oracle 和非Oracle 資料庫間的同步 |
只能是Oracle資料庫間 |
三. 前期規劃的幾點:
1). 確定複製集:如是資料庫級還是表級
2). 決定複製網站
3). 決定LCR是本地捕獲還是下遊捕獲
本地捕獲:在來源資料庫進行,從聯機日誌和歸檔日誌獲得LCR
下遊捕獲:在目標資料庫進行,從歸檔日誌獲得LCR.
本地捕獲可以保護更多的資料,但是會佔用來源資料庫的資源。
4). 決定複寫拓撲結構:這時要決定複製資料庫的用途,是只用於預防災難,還是平時保持空閑,或允許使用者使用。
四、簡單搭建過程
Orcl是原庫,vion是目標資料庫
1、 初始化設定(主從庫執行),執行完重啟資料庫
alter system setaq_tm_processes=2 scope=both;
alter system set global_names=true scope=both;
alter system set job_queue_processes=10 scope=both;
alter system set parallel_max_servers=20 scope=both;
alter system set undo_retention=3600 scope=both;
alter system set nls_date_format='YYYY-MM-DD HH24:MI:SS'scope=spfile;
alter system set streams_pool_size=250M scope=spfile;
alter system set utl_file_dir='*' scope=spfile;
alter system setopen_links=4 scope=spfile;
alter system set"_job_queue_interval"=1 scope=spfile;
alter system set logmnr_max_persistent_sessions=1 scope=spfile#10g 預設為1,持久的日誌挖掘會話數。
注意streams_pool_size一定要夠大,因為如果啟用了SGA_TARGET,ORACLE可能分配很少記憶體給stream導致大量資訊被spill到磁碟導致查詢DBA_APPLY,DBA_CAPTURE,DBA_PROPGATION全部狀態ENABLED但就是沒有資料被同步。
同時設定_job_queue_interval也是為了提高隊列檢查時間,防止apply出問題。
2、 確定資料庫在歸檔模式下,否則修改為歸檔模式
Startup mount
alter database archivelog;
alter database open
archive log list---查看
3、 建立帳戶,主從一樣
#建立資料表空間
createtablespace tbs_stream datafile '/home/oracle/data/tbs_stream01.dbf' size 100mautoextend on maxsize unlimited segment space management auto;
#將logminer的資料字典從system資料表空間轉移到建立的資料表空間,防止撐滿system資料表空間
executedbms_logmnr_d.set_tablespace('tbs_stream');
#使用者
createuser strmadmin identified by strmadmin
defaulttablespace tbs_stream temporary tablespace temp;
#授權
grantconnect,resource,dba,aq_administrator_role to strmadmin;
begin
dbms_streams_auth.grant_admin_privilege(
grantee=>'strmadmin',
grant_privileges=>TRUE);
end;
/
4、 配置網路
配置網路服務名
VION =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.9.134)(PORT= 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = vion)
)
)
另一個
ORCL =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST =192.168.9.132)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl)
)
)