博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

关于Change Data Capture(三)

Posted on 2010-03-08 11:48  徐正柱-  阅读(952)  评论(0)    收藏  举报

本文主要是通过一个实际的例子演示异步HotLog模式CDC的实现步骤。关于CDC的概念和模式介绍,请参考关于Change Data Capture(一)

一.版本

SYS@ning>select * fromv$version;
 
BANNER
--------------------------------------------------------------------
--
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Prod

PL/SQLRelease10.2.0.3.0 - Production
CORE    10.2.0.3.0      Production
TNSfor32-bitWindows: Version10.2.0.3.0 - Production
NLSRTLVersion10.2.0.3.0 - Production

 

二.设置发布者

1.首先在source database创建一个用户作为发布者

SYS@ning>createusercdcpubidentifiedbycdcpub;
 
Usercreated.

2.授予相应的权限

SYS@ning>grantexecute_catalog_roletocdcpub;
 
Grantsucceeded.
 
SYS@ning>grantselect_catalog_roletocdcpub;
 
Grantsucceeded.
 
SYS@ning>grantcreatetabletocdcpub;
 
Grantsucceeded.
 
SYS@ning>grantcreatesessiontocdcpub;
 
Grantsucceeded.
 
SYS@ning>grantdbatocdcpub;
 
Grantsucceeded.
 
SYS@ning>grantexecuteondbms_cdc_publishtocdcpub;
 
Grantsucceeded.
 
SYS@ning>executedbms_streams_auth.grant_admin_privilege(grantee=>'cdcpub');
 
PL/SQLproceduresuccessfullycompleted.

三.设置初始化参数

异步CDC除了要用到java pool,还需要使用stream pool,因为异步CDC和streams一样,都是采用logminer技术来从日志中获得数据。如果stream pool过小,可能导致logminer无法成功,可能在alert中出现如下错误:

LOGMINER: Begin mining logfile: E:\ORACLE\ORA10\RDBMS\ARC00662_0626260062.001
Wed Jul 11 14:38:53 2007
krvxerpt: Errors detected in process 27, role preparer.
Wed Jul 11 14:38:53 2007
krvxmrs: Leaving by exception: 4031
Wed Jul 11 14:38:53 2007
Errors in file e:\oracle\ora10\admin\ning\bdump\ning_p004_3252.trc:
ORA-04031: unable to allocate 76 bytes of shared memory (“streams pool”,”unknown object”,”Logminer LCR c”,”krvufa”)

Wed Jul 11 14:38:59 2007
Streams CAPTURE C001 with pid=29, OS id=864 stopped
Wed Jul 11 14:38:59 2007
Errors in file e:\oracle\ora10\admin\ning\bdump\ning_c001_864.trc:
ORA-01304: subordinate process error. Check alert and trace logs
ORA-04031: unable to allocate bytes of shared memory (“”,”",”",”")

根据文档推荐,为source database设置如下初始化参数:

COMPATIBLE=10.2.0
JAVA_POOL_SIZE=50000000
JOB_QUEUE_PROCESSES=(当前值) + 2
PARALLEL_MAX_SERVERS=(当前值) + (5 * (change set数目))
PROCESSES=(当前值) + (7 * (change set数目))
SESSIONS=(当前值) + (2 * (change set数目))
STREAMS_POOL_SIZE=Max(当前值,50 MB) + ((change set数目) * (21 MB))
UNDO_RETENTION=3600

 

SYS@ning> show parameter spfile;

SYS@ning>show parameter STREAMS_POOL_SIZE;

SYS@ning> alter system set JAVA_POOL_SIZE=50000000 scope=both;

SYS@ning> alter system set STREAMS_POOL_SIZE=50000000 scope=both;

SYS@ning> alter system set JOB_QUEUE_PROCESSES=4 scope=both;

 

四.发布变化数据

1.例如要发布用户ning下的sales表

SYS@ning>descning.sales;
 
Name                                      Null?       Type
 ------------------------------
-- -------- -------------------
 
ID                                                       NUMBER(38)
 
PRODUCTID                                           NUMBER(38)
 
PRICE                                                  NUMBER(10,2)
 
QUANTITY                                            NUMBER(38)

2.授予cdcpub用户对于该表的权限

SYS@ning>grantallonning.salestocdcpub;
 
Grantsucceeded.

3.将数据库置于Force logging

由于异步模式是从redo logfile中获得增量数据的,那么nologging操作就会影响到数据的捕捉,所以最好能将数据库置于force logging模式。

SYS@ning>alterdatabaseforcelogging;
 
Databasealtered.

为了捕获update操作中各个column的redo数据,必须在数据库级别启用supplimental日志模式。

SYS@ning>alterdatabaseaddsupplementallogdata;
 
Databasealtered.

同时在源表上为需要捕捉的列创建supplemental日志组

SYS@ning>altertablening.sales
 
2  addsupplementalloggrouplog_group_sales
 
3  (id,productid,price,quantity);
 
Tablealtered.

如果打算捕捉所有列,也可以为所有列创建supplemental日志组

SYS@ning>altertablening.sales
 
2  addsupplementallogdata(all)columns;
 
Tablealtered.

4.准备源表

SYS@ning>begin
 
2  dbms_capture_adm.prepare_table_instantiation(
 
3  table_name=>'ning.sales');
 
4  end;
 
5  /
 
PL/SQLproceduresuccessfullycompleted.

5.创建chang set

SYS@ning>begin
 
2  dbms_cdc_publish.create_change_set(
 
3  change_set_name=>'ning_sales_hotlog',
 
4  description=>'hotlog change set for ning.sales',
 
5  change_source_name=>'HOTLOG_SOURCE',
 
6  stop_on_ddl=>'y',
 
7  begin_date=>sysdate,
 
8  end_date=>sysdate+5);
 
9  end;
 
10  /
begin
*
ERRORatline1:
ORA-00258: manualarchivinginNOARCHIVELOGmodemustidentifylog
ORA-06512: at"SYS.DBMS_CAPTURE_ADM_INTERNAL", line121
ORA-06512: atline1
ORA-06512: at"SYS.DBMS_CDC_PUBLISH", line560
ORA-06512: atline2

看来异步HotLog模式虽然是从online redo logfile中读取数据,但还是要求数据库处于归档模式。将数据库至于归档模式以后,再次执行:

SYS@ning>begin
 
2  dbms_cdc_publish.create_change_set(
 
3  change_set_name=>'ning_sales_hotlog',
 
4  description=>'hotlog change set for ning.sales',
 
5  change_source_name=>'HOTLOG_SOURCE',
 
6  stop_on_ddl=>'y',
 
7  begin_date=>sysdate,
 
8  end_date=>sysdate+5);
 
9  end;
 
10  /
 
PL/SQLproceduresuccessfullycompleted.

异步HotLog模式的change source必须是HOTLOG_SOURCE。

6.创建change table

SYS@ning>begin
 
2  dbms_cdc_publish.create_change_table(
 
3  owner =>'cdcpub',
 
4  change_table_name=>'sales_ct_hotlog',
 
5  change_set_name=>'ning_sales_hotlog',
 
6  source_schema=>'ning',
 
7  source_table=>'sales',
 
8  column_type_list=>'id int,productid int,price number(10,2),quantity int',
 
9  capture_values=>'both',
 
10  rs_id=>'y',
 
11  row_id=>'n',
 
12  user_id=>'n',
 
13  timestamp=>'n',
 
14  object_id=>'n',
 
15  source_colmap=>'n',
 
16  target_colmap=>'y',
 
17  options_string=>'tablespace users');
 
18  end;
 
19  /
 
PL/SQLproceduresuccessfullycompleted.

创建好的change table定义如下

SYS@ning>desccdcpub.sales_ct_hotlog
 
Name                            Null?    Type
 -----------------------------
-- -------- -------------------------
 
OPERATION$                                CHAR(2)
 
CSCN$                                     NUMBER
 
COMMIT_TIMESTAMP$                         DATE
 
XIDUSN$                                   NUMBER
 
XIDSLT$                                   NUMBER
 
XIDSEQ$                                   NUMBER
 
RSID$                                     NUMBER
 
TARGET_COLMAP$                            RAW(128)
 
ID                                        NUMBER(38)
 
PRODUCTID                                 NUMBER(38)
 
PRICE                                     NUMBER(10,2)
 
QUANTITY                                  NUMBER(38)

7.启用change set

异步CDC的change set创建完以后默认是disable的,必须手工启用。启用后,oracle stream capture和apply进程将启动。

SYS@ning>begin
 
2  dbms_cdc_publish.alter_change_set(
 
3  change_set_name=>'ning_sales_hotlog',
 
4  enable_capture=>'y');
 
5  end;
 
6  /
 
PL/SQLproceduresuccessfullycompleted.

启用后,logminer进程将开始分析日志,直到alert出现如下记录,说明已经分析完所有需要的归档日志(从prepare_table_instantiation的一刻起,这也是需要将数据库置于归档模式的原因),并且开始分析当前联机日志:

LOGMINER: Begin mining logfile: E:\ORACLE\ORA10\RDBMS\ARC00698_0626260062.001
Wed Jul 11 14:54:34 2007
LOGMINER: End mining logfile: E:\ORACLE\ORA10\RDBMS\ARC00698_0626260062.001
Wed Jul 11 14:54:34 2007
LOGMINER: Begin mining logfile: D:\ORACLE\ORADATA\NING\REDO03.LOG
Wed Jul 11 14:54:35 2007
LOGMINER: End mining logfile: D:\ORACLE\ORADATA\NING\REDO03.LOG
Wed Jul 11 14:54:35 2007
LOGMINER: Begin mining logfile: D:\ORACLE\ORADATA\NING\REDO01.LOG
Wed Jul 11 14:54:35 2007
LOGMINER: End mining logfile: D:\ORACLE\ORADATA\NING\REDO01.LOG
Wed Jul 11 14:54:35 2007
LOGMINER: Begin mining logfile: D:\ORACLE\ORADATA\NING\REDO02.LOG

这时可以在change table中看到捕获到了变化数据(如果有变化的话):

SYS@ning>selectcount(*)fromcdcpub.sales_ct_hotlog;
 
 
COUNT(*)
--------
--
         4

8.将change table的读取权限授予订阅者

SYS@ning>grantselectoncdcpub.sales_ct_hotlogtocdcsub;
 
Grantsucceeded.
 
五.订阅数据变化
 
1.创建订阅
SYS@ning>begin
SYS@ning>dbms_cdc_subscribe.create_subscription(
SYS@ning>change_set_name=>'ning_sales',
SYS@ning>description=>'change data for salse',
SYS@ning>subscription_name=>'sales_sub');
SYS@ning>end;
SYS@ning>/
 
2.订阅具体的source_table和column
一个订阅可以同时包含同一个change set 中的多个source table

SYS@ning>begin
SYS@ning>dbms_cdc_subscribe.subscribe(
SYS@ning>subscription_name=>'sales_sub',
SYS@ning>source_schema=>'NING',
SYS@ning>source_table=>'SALES',
SYS@ning>column_list=>'id,productid,price,quantity',
SYS@ning>subscriber_view=>'sales_view');
vend;
SYS@ning>/
 
3.激活订阅
不管订阅包含一个source table还是多个,只需要执行一次激活即可。
SYS@ning>begin
SYS@ning>dbms_cdc_subscribe.activate_subscription(
SYS@ning>subscription_name=>'SALES_SUB');
SYS@ning>end;
SYS@ning>/
 
 
4.扩展订阅窗口
在源表数据变化,变化的数据在订阅端需要执行extend_window后才能看见

SYS@ning>begin
SYS@ning>dbms_cdc_subscribe.extend_window(
SYS@ning>subscription_name=>'SALES_SUB');
SYS@ning>end;
SYS@ning>/
如果是第一次执行该过程,则会在订阅段看到所有的变化数据,以后每次执行都只是增加到从上次执行以来的新数据,相当于物化视图的增量刷新。
 

5.清除当前窗口中的变化数据
如果当前变化数据已经不再需要,可以清除其数据

SYS@ning>begin
SYS@ning>dbms_cdc_subscribe.purge_window(
SYS@ning>subscription_name=>'SALES_SUB');
SYS@ning>end;
SYS@ning>/


清除后,在订阅视图中就看不到之前的变化数据了

 

 

6.停止订阅
SYS@ning>begin
SYS@ning>dbms_cdc_subscribe.drop_subscription(
SYS@ning>subscription_name=>'SALES_SUB');
SYS@ning>end;
SYS@ning>/

订阅视图也同时被删除

 

 

参考技术网站:

http://www.stanford.edu/dept/itss/docs/oracle/10gR2/appdev.102/b14258/d_cdcpub.htm