1.CDC简介1.1.CDC是一种数据增量处理技术在构建数据仓库系统的ETL过程中,增量数据的抽取是一个非常关键的环节.对解决方案一般有两点要求:l准确性,能够将业务系统中的数据按一定的频率准确的取到数据仓库中l性能,不能对业务系统造成太大的压力,影响现有业务目前,最为常用的ETL增量数据处理方式有三种:l时间戳l日志对比(CDC)l全面数据对比三种方式各有优劣,时间戳是目前应用比较普遍的方式。在Oracle=中推出了两种主要的ETL方案,一种是我们熟悉的物化视图(materializedview),另一种就是本文将要介绍的CDC组件(ChangeDataCapture改变数据捕获)。CDC特性是在Oracle9i数据库中引入的。CDC能够帮助你识别从上次提取之后发生变化的数据。利用CDC,在对源表进行INSERT、UPDATE或DELETE等操作的同时就可以提取数据,并且变化的数据被保存在数据库的变化表中。这样就可以捕获发生变化的数据,然后利用数据库视图以一种可控的方式提供给目标系统。1.2.CDC与传统增量处理方式的对比分析我们对比一下CDC方式与传统的全表对比与时间戳方式。全表对比使用数据仓库中的当前表与业务系统表进行对比,取得变化了的数据,典型是使用minus语句:?12SELECT*FROMnew_versionMINUSSELECT*FROMold_version;使用全表对比有以下几方面的问题:l需要将业务系统中表全部转输,造成很高的网络负载l需要对两版本的表进行全表扫描,性能代价非常高l无法反映数据的历史状态,如无法捕捉库存的历史变化记录还有一种常用的方式是时间戳,它是以业务表中某一个字段的值,作为判断新旧数据的标志。如,”病人费用记录”中的登记时间,每次只抽取上次抽取记录时间以后产生的数据。时间戳方式存在以下问题:l无法捕获对时间戳以前数据的delete和update操作,在数据准确性上受到了一定的限制。而类似于ZLHIS这种业务系统对已经发生的数据进行update和delete操作非常普遍(如划价记录转收费记录),应用场景受到了限制。l要求业务系统的表必须一个可以标识新旧数据的列,而某些表没有设置这种列。1.3.CDC的发布订立模型CDC体系结构基于发布者/订阅者模型。发布者捕捉变化数据并提供给订阅者。订阅者使用从发布者那里获得的变化数据。通常,CDC系统拥有一个发布者和多个订阅者。发布者首先需要识别捕获变化数据所需的源表。然后,它捕捉变化的数据并将其保存在特别创建的变化表中。它还使订阅者能够控制对变化数据的访问。订阅者需要清楚自己感兴趣的是哪些变化数据。一个订阅者可能不会对发布者发布的所有数据都感兴趣。订阅者需要创建一个订阅者视图来访问经发布者授权可以访问的变化数据。CDC有几个重要的基本概念需要先明确一下:l源表(SourceTable),业务数据库的需要捕获数据的源表l变化表(ChangeTable),保存从源表捕获的变化数据(包括各种DML产生的数据)l变化集(ChangeSet),是保证事务一致性的数据集合。一个变化集对应多个变化表l订阅视图(SubscriptionView),提供给读取变化表数据的视图l订阅窗口(SubscriptionWindow),定义了查看变化数据的时间范围.就象一个观察变化数据的滑动窗口。变化数据处理完成后,可以对清除订阅窗口。1.4.CDC的同步与异步模式l同步模式,实时的捕获变化数据并存储到变化表中,发布者与订阅都位于同一数据库中。下图说明了同步模式的基本架构。l异步模式,以Oracle流复制技术为基础,由于流复制比较复杂,本文档不涉及异步模式的CDC1.5.CDC相关的数据库对象(Package)l包(Package)nDBMS_CDC_PUBLISH,用于定义发布操作nDBMS_CDC_SUBSCRIBE,用于定义订阅操作l角色nEXECUTE_CATALOG_ROLEnSELECT_CATALOG_ROLEnCREATETABLEandCREATESESSIONprivilegesnEXECUTEontheDBMS_CDC_PUBLISHpackagel视图nALL_SOURCE_TABLES源表nALL_PUBLISHED_COLUMNS发布的表列nAll_Subscribed_Columns订阅的表列nAll_Subscriptions所有订阅nAll_Subscribed_Tables已经订阅的表2.CDC的实施步骤2.1.初始化2.1.1.设置初始化参数由于CDC需要在后台开启作业,需要将参数JOB_QUEUE_PROCESSES增加2个,java_pool_size至少在50M以上。?12345SQLaltersystemsetjob_queue_processes=14;SystemalteredSQLaltersystemsetjava_pool_size=50m;SystemalteredSQL2.1.2.创建订阅、发布用户、表空间?1234SQLcreatetablespacets_cdcpubdatafile'E:\oracle\product\10.2.0\oradata\orc1\ts_cdcpub.dbf'size100m;TablespacecreatedSQLcreateusercdc_publisheridentifiedbycdc_publisherde56faulttablespacets_cdcpub;UsercreatedSQLcreateusercdc_subcriberidentifiedbycdc_subcriberdefaulttablespacets_cdcpub;Usercreated2.1.3.授予相关权限?1234567891011121314SQLGRANTCREATESESSIONTOcdc_publisher;GrantsucceededSQLGRANTCREATETABLETOcdc_publisher;GrantsucceededSQLGRANTCREATETABLESPACETOcdc_publisher;GrantsucceededSQLGRANTUNLIMITEDTABLESPACETOcdc_publisher;GrantsucceededSQLGRANTSELECT_CATALOG_ROLETOcdc_publisher;GrantsucceededSQLGRANTEXECUTE_CATALOG_ROLETOcdc_publisher;GrantsucceededSQLGRANTEXECUTEONDBMS_CDC_PUBLISHTOcdc_publisher;Grantsucceeded2.1.4.在ZLHIS用户下,创建测试表?1234567891011121314SQLCreateTableperson(idNumber,NameVarchar(10),sexVarchar(2));TablecreatedSQLinsertintopersonvalues(0,'毛泽东','男');1rowinsertedSQLinsertintopersonvalues(0,'彭德怀','男');1rowinsertedSQLinsertintopersonvalues(0,'邓颖操','女');1rowinsertedSQLcommit;CommitcompleteSQLgrantallonpersontocdc_publisher;GrantsucceededSQLgrantallonpersontocdc_subscriber;Grantsucceeded2.2.发布数据2.2.1.创建改变集在同步方式的CDC中,change_source_name参数必须使用默认的改变源,SYNC_SOURCE?123456789SQLBEGIN2DBMS_CDC_PUBLISH.CREATE_CHANGE_SET(3change_set_name='person_change_set',--改变集4description='Changesetforpersoninfo',5change_source_name='SYNC_SOURCE');6END;7/PL/SQLproceduresuccessfullycompletedSQL2.2.2.创建改变表指定源table,和源模式,注意区别owner与source_schema,owner是指发布用户,而不是源表的所有者?123SQLBEGIN2DBMS_CDC_PUBLISH.CREATE_CHANGE_TABLE(3owner='cdc_publisher',45678910111213141516174change_table_name='person_ct',5change_set_name='person_change_set',6source_schema='zlhis',7source_table='person',8column_type_list='IDnumber,NAMEVARCHAR2(10),sexvarchar2(2)',9capture_values='both',10rs_id='y',11row_id='n',12user_id='n',13timestamp='n',14object_id='n',15source_colmap='y',16target_colmap='y',17options_string='TABLESPACETS_CDCPUB');18END;19/PL/SQLproceduresuccessfullycompletedSQL18192021options_string,指定改变表的存储参数。options_string参数可以使用除partition以外的所有createtable中指定的存储参数,如tablespace、pctfree等。2.2.3.将改变表(ChangeTable)的权限授权给订阅者?12SQLgrantselectonperson_cttocdc_subscriber;Grantsucceeded2.3.订阅数据2.3.1.查看发布信息当发布者,发布了相关的改变表后,会生成一个惟一的发布id(publicationID),可以查阅视图ALL_PUBLISHED_COLUMNS以获取已经发布的表及字段信息?12345678SQLselectchange_set_name,pub_id,source_table_namefromALL_PUBLISHED_COLUMNS;CHANGE_SET_NAMEPUB_IDSOURCE_TABLE_NAME----------------------------------------------------------------------PERSON_CHANGE_SET70403PERSONPERSON_CHANGE_SET70403PERSONPERSON_CHANGE_SET70403PERSON6rowsselectedSQL2.3.2.创建订阅使用DBMS_CDC_SUBSCRIBE.CREATE_SUBSCRIPTION创建订阅操作,一次订阅与改变集对应,由于改变集与源表之间是一对多的关系,所以一次订阅就可以订阅多张表.?123456SQLBEGIN2DBMS_CDC_SUBSCRIBE.CREATE_SUBSCRIPTION(3change_set_name='PERSON_CHANGE_SET',4description='Changedataforperson',5subscription_name='PERSON_SUB');6END;787/PL/SQLproceduresuccessfully