资源描述
通过一个实际的例子演示异步HotLog模式CDC的实现步骤
第一步:查看数据库版本
SQL:
select * from v$version;
第二步:创建发布者并授权
1.首先在source database创建一个用户作为发布者
SQL:
create user cdcpub identified by cdcpub;
2.授予相应的权限
SQL:
grant execute_catalog_role to cdcpub;
grant select_catalog_role to cdcpub;
grant create table to cdcpub;
grant create session to cdcpub;
grant dba to cdcpub;
grant execute on dbms_cdc_publish to cdcpub;
execute dbms_streams_auth.grant_admin_privilege(grantee=>'cdcpub');
第三步:设置初始化参数
异步CDC除了要用到java pool,还需要使用stream pool,因为异步CDC和streams一样,都是采用logminer技术来从日志中获得数据。
根据文档推荐,为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
第四步:发布变化数据
1.例如要发布用户ning下的sales表
SQL:
desc ning.sales;
SQL:
grant all on ning.sales to cdcpub;
3.将数据库置于Force logging
由于异步模式是从redo logfile中获得增量数据的,那么nologging操作就会影响到数据的捕捉,所以最好能将数据库置于force logging模式。
SQL:
alter database force logging;
为了捕获update操作中各个column的redo数据,必须在数据库级别启用supplimental日志模式。
SQL:
alter database add supplemental log data;
同时在源表上为需要捕捉的列创建supplemental日志组
SQL:
alter table ning.sales
add supplemental log group log_group_sales
(id,productid,price,quantity);
如果打算捕捉所有列,也可以为所有列创建supplemental日志组
SQL:
alter table ning.sales
add supplemental log data(all) columns;
4.准备源表
SQL:
begin
dbms_capture_adm.prepare_table_instantiation(
table_name=>'ning.sales');
end;
/
5.创建chang set
SQL:
begin
dbms_cdc_publish.create_change_set(
change_set_name=>'ning_sales_hotlog',
description=>'hotlog change set for ning.sales',
change_source_name=>'HOTLOG_SOURCE',
stop_on_ddl=>'y',
begin_date=>sysdate,
end_date=>sysdate+5);
end;
/
begin
*
ERROR at line 1:
ORA-00258: manual archiving in NOARCHIVELOG mode must identify log
ORA-06512: at "SYS.DBMS_CAPTURE_ADM_INTERNAL", line 121
ORA-06512: at line 1
ORA-06512: at "SYS.DBMS_CDC_PUBLISH", line 560
ORA-06512: at line 2
看来异步HotLog模式虽然是从online redo logfile中读取数据,但还是要求数据库处于归档模式。将数据库至于归档模式以后,再次执行:
SQL:
begin
dbms_cdc_publish.create_change_set(
change_set_name=>'ning_sales_hotlog',
description=>'hotlog change set for ning.sales',
change_source_name=>'HOTLOG_SOURCE',
stop_on_ddl=>'y',
begin_date=>sysdate,
end_date=>sysdate+5);
end;
/
异步HotLog模式的change source必须是HOTLOG_SOURCE。
6.创建change table
SQL:
begin
dbms_cdc_publish.create_change_table(
owner =>'cdcpub',
change_table_name=>'sales_ct_hotlog',
change_set_name=>'ning_sales_hotlog',
source_schema=>'ning',
source_table=>'sales',
column_type_list=>'id int,productid int,price number(10,2),quantity int',
capture_values=>'both',
rs_id=>'y',
row_id=>'n',
user_id=>'n',
timestamp=>'n',
object_id=>'n',
source_colmap=>'n',
target_colmap=>'y',
options_string=>'tablespace users');
end;
/
创建好的change table定义如下
SQL:
desc cdcpub.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进程将启动。
SQL:
begin
dbms_cdc_publish.alter_change_set(
change_set_name=>'ning_sales_hotlog',
enable_capture=>'y');
end;
/
启用后,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中看到捕获到了变化数据(如果有变化的话):
SQL:
select count(*) from cdcpub.sales_ct_hotlog;
8.将change table的读取权限授予订阅者
SQL:
grant select on cdcpub.sales_ct_hotlog to cdcsub;
第五步:订阅变化数据
1.查看可以订阅的源数据表
SQL:
select * from all_source_tables;
2.查看可以订阅的change set和column
SQL:
select distinct change_set_name,column_name,pub_id
from all_published_columns
where source_schema_name='NING' and source_table_name='SALES';
3.创建订阅
SQL:
begin
dbms_cdc_subscribe.create_subscription(
change_set_name=>'ning_sales',
description=>'change data for sales',
subscription_name=>'sales_sub');
end;
/
4.订阅具体的source table和column
一个订阅可以同时包含同一个change set中的多个source table
SQL:
begin
dbms_cdc_subscribe.subscribe(
subscription_name=>'sales_sub',
source_schema=>'NING',
source_table=>'SALES',
column_list=>'id,productid,price,quantity',
subscriber_view=>'sales_view');
end;
/
订阅会创建一个叫做sales_view的订阅视图,通过该视图,我们可以获得源表的变化数据。
SQL:
desc sales_view;
Name Null? Type
----------------------------------------- -------- ----------------------------
OPERATION$ CHAR(2)
CSCN$ NUMBER
COMMIT_TIMESTAMP$ DATE
RSID$ NUMBER
SOURCE_COLMAP$ RAW(128)
TARGET_COLMAP$ RAW(128)
ID NUMBER(38)
PRICE NUMBER(10,2)
PRODUCTID NUMBER(38)
QUANTITY NUMBER(38)
5.激活订阅
不管订阅包含一个source table还是多个,只需要执行一次激活即可。
SQL:
begin
dbms_cdc_subscribe.activate_subscription(
subscription_name=>'SALES_SUB');
end;
/
6.扩展订阅窗口
在源表数据变化后,变化的数据在订阅端需要执行extend_window后才能看见
SQL:
begin
dbms_cdc_subscribe.extend_window(
subscription_name=>'SALES_SUB');
end;
/
如果是第一次执行该过程,则会在订阅段看到所有的变化数据,以后每次执行都只增加到从上次执行以来的新数据,相当于物化视图的增量刷新。
7.查询订阅视图中的数据
SQL:
select id,productid,price,quantity from sales_view;
ID PRODUCTID PRICE QUANTITY
---------- ---------- ---------- ----------
1 1 20.2 100
2 1 20.2 200
3 2 40.8 50
9.清除当前窗口中的变化数据
如果当前变化数据已经不再需要,可以清除其数据
SQL:
begin
dbms_cdc_subscribe.purge_window(
subscription_name=>'SALES_SUB');
end;
/
清除后,在订阅视图中就看不到之前的变化数据了
SQL:
select id,productid,price,quantity from sales_view;
10.停止订阅
SQL:
begin
dbms_cdc_subscribe.drop_subscription(
subscription_name=>'SALES_SUB');
end;
/
订阅视图也同时被删除
SQL:
select id,productid,price,quantity from sales_view;
展开阅读全文